这个文章将教你如何使用qmk固件在键盘上创建一个“后门”。

什么是QMK?

它是一个开源键盘固件,可以阅读qmk组合功能,比如屏幕锁定的一组击键,因此当用户锁定计算机时,它将击键注入目标计算机。

获得Shell

Keyboard Recon

最重要的一步就是识别受害者键盘使用的PCB。我们可以通过以下几种方式完成:1.社会工程学2.打开keyboard case3.成为键盘大佬

获取QMK固件项目

git clone https://github.com/qmk/qmk_firmware.git
cd qmk_firmware
util/(linux|macos)_install.sh

启用和配置组合功能

假设现在您已获取受害者的键盘PCB,转到qmk_firmware/keyboards/<PCB_MODEL>/然后在rules.mk文件的最后一行添加COMBO_ENABLE = yes,然后还要修改文件config.h下面几行:

#define COMBO_COUNT 1
#define COMBO_TERM 300

COMBO_COUNT变量是您将配置的挂钩的数量,COMBO_TERM是固件检测键组合的毫秒时间。

创建HOOK

然后将默认密钥映射复制并新建一个名为keylogger的密钥映射

cd qmk_firmware/keyboards/<PCB_MODEL>/keymaps
mkdir keylogger
cp -R default/* keylogger
cd keylogger/

编辑keymap.c文件并在#include "action_layer.h“行后插入恶意代码,您需要做的第一件事是使用您的钩子名称创建一个枚举函数:

enum combo_events {
  LOCK_SCREEN
}

然后你需要设置你想挂钩的组合键,在这个例子中让我们挂钩WIN + L锁定屏幕:const  uint16_t PROGMEM lock_screen_combo [] = {KC_LGUI,KC_L,COMBO_END};如果您想挂钩其他键,只需查看

编译代码

返回qmk项目根目录并运行:make <KEYBOARD_PCB>:keylogger如果没有错误,你做的一切都正确,并准备好继续前进。

引导模式

要将键盘置于引导模式,请按照QMK信息

Poc

PoC使用xd60 PCB视频地址

参考来源github,由周大涛编译,转载请注明来自FreeBuf.COM

0×01 前言

使用 radare2 逆向 iOS Swift 应用程序,我们将使用iGoat应用程序。我们的目标是反编译iOS Swift应用程序的外观。这是以前iGoat Objective C项目的Swift版本。使用OWASP iGoat,您可以学习iOS Swift应用程序中的漏洞。
Image让我们开始Keychain练习吧:KeychainExerciseVC.swift

class KeychainExerciseVC: UIViewController {
    @IBOutlet weak var usernameTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        secureStore(userName: "iGoat", password: "taoGi")
    }
    func secureStore(userName: String, password: String) {
        do {
            // This is a new account, create a new keychain item with the account name.
            let passwordItem = KeychainPasswordItem(service: "SaveUser",
                                                    account: userName,
                                                    accessGroup: nil)
            // Save the password for the new item.
            try passwordItem.savePassword(password)
        } catch {
            fatalError("Error updating keychain - \(error)")
        }
    }

一旦viewDidLoad()被调用,它会调用secureStore与userName: "iGoat"password: "taoGi"。我们研究的目的就是了解这些方法在反汇编中是什么样子的。

准备开始

在我们开始之前,我们必须减少二进制文件体积。这可以使用radare2的rabin2完成:

$ cd Payload/iGoat-Swift.app
$ rabin2 -x iGoat-Swift

这将创建一个包含两个二进制文件(32/64位)的文件夹iGoat-Swift.fat/,打开32位二进制,进行分析,并启用字符串模拟:

$ r2 -e bin.demanglecmd=true -e emu.str=true iGoat-Swift.fat/iGoat-Swift.arm_32.0
[0x000bfe60]> aaaa

让我们看看我们可以找到关于二进制各部分中的swift的内容:

iS~swift
09 0x0022f400 10501 0x00233400 10501 -r-x 9.__TEXT.__swift3_typeref
10 0x00231d08   456 0x00235d08   456 -r-x 10.__TEXT.__swift3_assocty
11 0x00231ed0   656 0x00235ed0   656 -r-x 11.__TEXT.__swift2_proto
12 0x00232160  3284 0x00236160  3284 -r-x 12.__TEXT.__swift3_fieldmd
13 0x00232e34    60 0x00236e34    60 -r-x 13.__TEXT.__swift3_builtin
14 0x00232e70  2772 0x00236e70  2772 -r-x 14.__TEXT.__swift3_reflstr
16 0x002339ec  1552 0x002379ec  1552 -r-x 16.__TEXT.__swift3_capture

我们当前的方法不是很好(仅使用r2检查二进制,仅静态方法),我们不能指望在反汇编中找到很多东西。 我们将在以后的学习中了解如何获取更多信息(小小剧透:也涉及r2)。我们假装我们没有看到源代码,因为我们现在就是在做“Keychain Exercise”。输入ic?

$ r2 --
 -- Radare2, what else?
[0x00000000]> ic?
| ic                 List classes, methods and fields
| icc                List classes, methods and fields in Header Format

检查classes

首先我们来看看这些类:

ic~+class | grep iGoat
...
0x00281678 [0x000efe48 - 0x000f0378] (sz 1328) class 0 iGoat_Swift.HTMLViewController
0x002816b0 [0x000f4b48 - 0x000f4d60] (sz 536) class 0 iGoat_Swift.CenterContainmentSegue
0x002816c8 [0x000f4f68 - 0x000f5578] (sz 1552) class 0 iGoat_Swift.KeychainExerciseVC
0x002816ec [0x000f86bc - 0x000f8a6c] (sz 944) class 0 iGoat_Swift.CutAndPasteExerciseVC
0x00281704 [0x000f8bf0 - 0x000f92c4] (sz 1748) class 0 iGoat_Swift.BinaryPatchingVC
0x00281720 [0x000f94e4 - 0x000f9fa8] (sz 2756) class 0 iGoat_Swift.URLSchemeAttackExerciseVC
...

我们可以iGoat_Swift.KeychainExerciseVC在地址中找到0x002816c8

检查flags

另一种选择是查看flags(f)和grep(~)case insensitive(+Keychain

[0x00044798]> f~+Keychain
0x001f2330 38 str.TtC11iGoat_Swift18KeychainExerciseVC
...
0x001f2450 26 str.Error_updating_keychain
0x001f4ccf 52 str.Unexpected_error__d_deleting_identity_from_keychain
0x001f801a 49 str.CBLOpenIDConnectAuthorizer_keychainAttributes
0x001f80fd 34 str.:_No_ID_token_found_in_Keychain
0x001f8170 32 str.:_Read_ID_token_from_Keychain
...
0x002816c8 1 class.iGoat_Swift.KeychainExerciseVC
0x000f4f68 1 method.iGoat_Swift.KeychainExerciseVC.usernameTextField
0x000f4f8c 1 method.iGoat_Swift.KeychainExerciseVC.setUsernameTextField:
0x000f4fa4 1 method.iGoat_Swift.KeychainExerciseVC.passwordTextField
0x000f4fc8 1 method.iGoat_Swift.KeychainExerciseVC.setPasswordTextField:
0x000f4fe0 1 method.iGoat_Swift.KeychainExerciseVC.viewDidLoad
0x000f5094 1 method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender:
0x000f5290 368 method.iGoat_Swift.KeychainExerciseVC.initWithNibName:bundle:
0x000f5578 1 method.iGoat_Swift.KeychainExerciseVC.initWithCoder:

我们再次看到iGoat_Swift.KeychainExerciseVC地址中的类0x002816c8

class信息

我们还可以获得有关此class的完整信息:

[0x00044f44]> ic iGoat_Swift.KeychainExerciseVC
class iGoat_Swift.KeychainExerciseVC
0x000f4f68 method iGoat_Swift.KeychainExerciseVC      usernameTextField
0x000f4f8c method iGoat_Swift.KeychainExerciseVC      setUsernameTextField:
0x000f4fa4 method iGoat_Swift.KeychainExerciseVC      passwordTextField
0x000f4fc8 method iGoat_Swift.KeychainExerciseVC      setPasswordTextField:
0x000f4fe0 method iGoat_Swift.KeychainExerciseVC      viewDidLoad
0x000f5094 method iGoat_Swift.KeychainExerciseVC      loginActionWithSender:
0x000f5290 method iGoat_Swift.KeychainExerciseVC      initWithNibName:bundle:
0x000f5578 method iGoat_Swift.KeychainExerciseVC      initWithCoder:
0x000f5140 method iGoat_Swift.KeychainExerciseVC      .cxx_destruct

注意viewDidLoad位于的方法0x000f4fe0。提示:icc用于一个很好的类似c-header的输出:

@interface iGoat_Swift.KeychainExerciseVC :
{
   iGoat_Swift.KeychainExerciseVC::(ivar)usernameTextField
   iGoat_Swift.KeychainExerciseVC::(ivar)passwordTextField
}
- (void) setUsernameTextField:
- (void) setPasswordTextField:
- (void) viewDidLoad
- (void) loginActionWithSender:
@end

如果您需要,可以将其保存到文件中,icc > iGoat-Swift.arm_32.0.h或者只显示内部较少的文件:icc~..func viewDidLoad():在视图控制器将其视图层次结构加载到内存后调用此方法。无论视图层次结构是从nib文件加载还是在loadView()方法中以编程方式创建,都会调用此方法。我们通常会覆盖此方法以对从nib文件加载的视图执行其他初始化。在这里,我们将找到练习的主要代码。如果我们要找0x000f4fe0,我们会看到它被标记为method.iGoat_Swift.KeychainExerciseVC.viewDidLoad(我们之前在旗帜中看到过)。

反编译

我们找到了“切入点”,让我们仔细检查一下。

viewDidLoad

r2显示以下反汇编:

[0x000f4ff4]> pdf
            ;-- method.iGoat_Swift.KeychainExerciseVC.viewDidLoad:
╭ (fcn) sub.objc_retain_fe0 180
│   sub.objc_retain_fe0 ();
│           ; var int local_0h @ sp+0x0
│           ; var int local_4h @ sp+0x4
│           ; var int local_8h @ sp+0x8
│           ; var int local_ch @ sp+0xc
│           ; UNKNOWN XREF from str. (+0x14)
│           0x000f4fe0      b0402de9       push {r4, r5, r7, lr}
│           0x000f4fe4      08708de2       add r7, sp, 8
│           0x000f4fe8      10d04de2       sub sp, sp, 0x10            ; "T"
│           0x000f4fec      e4560ce3       movw r5, 0xc6e4
│           0x000f4ff0      0040a0e1       mov r4, r0
│           0x000f4ff4      185040e3       movt r5, 0x18
│           0x000f4ff8      05509fe7       ldr r5, [0x000f5000]        ; [0xf5000:4]=0xe3550000
│           0x000f4ffc      0aae03eb       bl sym.imp.objc_retain
│           ; DATA XREF from sub.objc_retain_fe0 (0xf4ff8)
│           0x000f5000      000055e3       cmp r5, 0
│       ╭─< 0x000f5004      0a00001a       bne 0xf5034                 ; likely
│       │   0x000f5008      2c0009e3       movw r0, 0x902c
│       │   0x000f500c      180040e3       movt r0, 0x18
│       │   0x000f5010      00008fe0       add r0, pc, r0
│       │   0x000f5014      080080e2       add r0, r0, 8               ; 0x27e04c ; aav.0x0027e04c
│       │   0x000f5018      6076ffeb       bl sym.func.000d29a0; sym.func.000d29a0(0x27e04c)
│       │   0x000f501c      0050a0e1       mov r5, r0                  ; aav.0x0027e04c
│       │   0x000f5020      b0060ce3       movw r0, 0xc6b0
│       │   0x000f5024      180040e3       movt r0, 0x18
│       │   0x000f5028      5bf07ff5       dmb ish
│       │   0x000f502c      00008fe0       add r0, pc, r0
│       │   0x000f5030      005080e5       str r5, [r0]
│       │   ; CODE XREF from sub.objc_retain_fe0 (0xf5004)
│       ╰─> 0x000f5034      08408de5       str r4, [sp + local_8h]
│           0x000f5038      08008de2       add r0, sp, 8
│           0x000f503c      0c508de5       str r5, [sp + local_ch]
│           0x000f5040      641203e3       movw r1, 0x3264             ; 'd2'
│           0x000f5044      181040e3       movt r1, 0x18
│           0x000f5048      01109fe7       ldr r1, [0x000f5050]        ; [0xf5050:4]=0xe30a085c
│           0x000f504c      e6ad03eb       bl sym.imp.objc_msgSendSuper2
│           ; DATA XREF from sub.objc_retain_fe0 (0xf5048)
│           0x000f5050      5c080ae3       movw r0, 0xa85c
│           0x000f5054      0010a0e3       mov r1, 0
│           0x000f5058      0f0040e3       movt r0, 0xf
│           0x000f505c      30330de3       movw r3, 0xd330
│           0x000f5060      0f3040e3       movt r3, 0xf
│           0x000f5064      04108de5       str r1, [sp + local_4h]
│           0x000f5068      0510a0e3       mov r1, 5
│           0x000f506c      00008fe0       add r0, pc, r0              ; 0x1ef8d0 ; "iGoat" ; str.iGoat
│           0x000f5070      03308fe0       add r3, pc, r3              ; 0x1f23a8 ; "taoGi" ; str.taoGi
│           0x000f5074      00108de5       str r1, [sp]
│           0x000f5078      0510a0e3       mov r1, 5
│           0x000f507c      0020a0e3       mov r2, 0
│           0x000f5080      c50100eb       bl sub.SaveUser_79c
│           0x000f5084      0400a0e1       mov r0, r4
│           0x000f5088      e3ad03eb       bl sym.imp.objc_release
│           0x000f508c      08d047e2       sub sp, r7, 8
╰           0x000f5090      b080bde8       pop {r4, r5, r7, pc}        ; r13

方法摘要:

[0x000f4ff4]> pds
0x000f4ffc bl sym.imp.objc_retain
0x000f5018 bl sym.func.000d29a0
0x000f504c bl sym.imp.objc_msgSendSuper2
0x000f506c str.iGoat
0x000f5070 str.taoGi
0x000f5080 bl sub.SaveUser_79c
0x000f5088 bl sym.imp.objc_release
;-- method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender::
0x000f50a8 bl sym.imp.objc_retain
0x000f50b0 bl sym.imp.objc_retain
0x000f50b8 bl sub.swift_unknownWeakLoadStrong_d5c
0x000f50c0 bl sym.imp.objc_release
0x000f50d0 b sym.imp.objc_release

需要注意的事项:1.func viewDidLoad()变成objc_retain: sub.objc_retain_fe02.我们可以看到,即使在摘要中我们也可以找到字符串iGoattaoGi。3.它sub.SaveUser_79c使用这些字符串调用子例程。

sub.SaveUser_79c

子程序sub.SaveUser_79c位于0x000f579c:

[0x000f4ff4]> s sub.SaveUser_79c
[0x000f579c]> pdf
╭ (fcn) sub.SaveUser_79c 516
│   sub.SaveUser_79c ();
│           ; var int local_0h @ sp+0x0
│           ; var int local_4h @ sp+0x4
│           ; var int local_8h @ sp+0x8
│           ; var int local_ch @ sp+0xc
│           ; var int local_10h @ sp+0x10
│           ; var int local_14h @ sp+0x14
│           ; var int local_18h @ sp+0x18
│           ; var int local_1ch @ sp+0x1c
│           ; var int local_20h @ sp+0x20
│           ; var int local_24h @ sp+0x24
│           ; var int local_28h @ sp+0x28
│           ; var int local_2ch @ sp+0x2c
│           ; var int local_30h @ sp+0x30
│           ; var int local_34h @ sp+0x34
│           ; var int local_48h @ sp+0x48
│           ; var int local_4ch @ sp+0x4c
│           ; CALL XREF from sub.objc_retain_fe0 (0xf5080)
│           0x000f579c      f0402de9       push {r4, r5, r6, r7, lr}
│           0x000f57a0      0c708de2       add r7, sp, 0xc
│           0x000f57a4      00052de9       push {r8, sl}
│           0x000f57a8      028b2ded       vpush {d8}
│           0x000f57ac      58d04de2       sub sp, sp, 0x58            ; 'X'
│           0x000f57b0      0340a0e1       mov r4, r3
│           0x000f57b4      a53b0ce3       movw r3, 0xcba5
│           0x000f57b8      0f3040e3       movt r3, 0xf
│           0x000f57bc      0c5097e5       ldr r5, [r7, 0xc]
│           0x000f57c0      03308fe0       add r3, pc, r3              ; 0x1f236d ; "SaveUser" ; str.SaveUser
│           0x000f57c4      2c308de5       str r3, [sp + local_2ch]
│           0x000f57c8      0830a0e3       mov r3, 8
│           0x000f57cc      0060a0e3       mov r6, 0
│           0x000f57d0      30308de5       str r3, [sp + local_30h]
│           0x000f57d4      38308de2       add r3, sp, 0x38
│           0x000f57d8      34608de5       str r6, [sp + local_34h]
│           0x000f57dc      470083e8       stm r3, {r0, r1, r2, r6}
│           0x000f57e0      0100a0e3       mov r0, 1
│           0x000f57e4      48608de5       str r6, [sp + local_48h]
│           0x000f57e8      4c608de5       str r6, [sp + local_4ch]
│           0x000f57ec      5000cde5       strb r0, [sp, 0x50]
│           0x000f57f0      0500a0e1       mov r0, r5
│           0x000f57f4      30ae03eb       bl sym.imp.swift_unknownRetain
│           0x000f57f8      081097e5       ldr r1, [r7, 8]
│           0x000f57fc      2c308de2       add r3, sp, 0x2c
│           0x000f5800      0400a0e1       mov r0, r4
│           0x000f5804      0520a0e1       mov r2, r5
│           0x000f5808      0080a0e3       mov r8, 0
│           0x000f580c      dea400eb       bl sub._b8c; sub._b8c(0x0, 0x4042f04f)
│           0x000f5810      000058e3       cmp r8, 0
│           0x000f5814      1cd04702       subeq sp, r7, 0x1c
│           0x000f5818      028bbd0c       vpopeq {d8}
│           0x000f581c      0005bd08       popeq {r8, sl}
│           0x000f5820      f080bd08       popeq {r4, r5, r6, r7, pc}  ; aav.0x000cf2c0
│           0x000f5824      2fe1ffeb       bl sym.func.000edce8
│           0x000f5828      3810a0e3       mov r1, 0x38                ; '8'
│           0x000f582c      0320a0e3       mov r2, 3
│           0x000f5830      0350a0e3       mov r5, 3
│           0x000f5834      99c2ffeb       bl sym.func.000e62a0; sym.func.000e62a0(0x0)
│           0x000f5838      0040a0e1       mov r4, r0
│           0x000f583c      000c0ce3       movw r0, 0xcc00             ; "xD"
│           0x000f5840      0f0040e3       movt r0, 0xf
│           0x000f5844      0610a0e3       mov r1, 6
│           0x000f5848      00008fe0       add r0, pc, r0              ; 0x1f2450 ; "Error updating keychain - " ; str.Error_updating_keychain
...

方法摘要:

[0x000f579c]> pds
0x000f57c0 str.SaveUser
0x000f57f4 bl sym.imp.swift_unknownRetain
0x000f580c bl sub._b8c
0x000f5824 bl sym.func.000edce8
0x000f5834 bl sym.func.000e62a0
0x000f5848 str.Error_updating_keychain
0x000f5868 bl sym.func.000f0e34

需要注意的事项:1.XREF来自viewDidLoad; CALL XREF from sub.objc_retain_fe0 (0xf5080)。2.字符串 SaveUser。3.函数调用:sym.func.000edce8sym.func.000e62a0sym.func.000f0e34>。4.字符串 Error updating keychain -所以我们猜测它试图在这里更新Keychain。现在我们看到了这个字符串Error updating keychain - ……想象一下,我们还没有通过查看classes(ic)而是通过查看strings(iz)来开始,这也是一种非常常见的方法。

iz~+keychain
1530 0x001ee330 0x001f2330  37  38 (4.__TEXT.__cstring) ascii _TtC11iGoat_Swift18KeychainExerciseVC
1533 0x001ee380 0x001f2380  39  40 (4.__TEXT.__cstring) ascii Error reading password from keychain -
1535 0x001ee3b0 0x001f23b0 154 155 (4.__TEXT.__cstring) ascii /Users/swaroop.yermalkar/AWS/iGoat-Swift-master/iGoat-Swift/iGoat-Swift/Source/Exercises/InsecureLocalDataStorage/KeychainAnalyze/KeychainExerciseVC.swift
1536 0x001ee450 0x001f2450  26  27 (4.__TEXT.__cstring) ascii Error updating keychain -
...
axt @ 0x001f2450
sub.SaveUser_79c 0xf5848 [DATA] add r0, pc, r0

*参考来源:grepharder,由周大涛编译,转载请注明来自FreeBuf.COM

滥用PowerShell的威胁还在不断增长,攻击者在不断寻找新的方式滥用PowerShell来传播银行木马、后门、勒索软件和加密货币挖矿恶意软件,以及最近的无文件恶意软件和恶意WMI记录。

事实上,PowerShell的灵活性和强大的功能使其成为网络犯罪分子的潜在工具。比如,PowerShell可以被滥用来在被入侵的网络中“内网漫游”(lateral movement)和保持驻留。

2018年1月,微软发布PowerShell Core,PowerShell Core是为异类环境和混合云而构建的跨平台(Windows、macOS 和 Linux)且开源的新版 PowerShell。因为PowerShell Core可能会和PowerShell一样被滥用用于攻击其他操作系统平台。

研究人员列举了一些攻击者可能滥用PowerShell Core的策略。这些POC可以帮助更好的理解、检测和预防潜在的威胁。研究人员利用PowerShell Core开发的PoC可以在Windows、Linux和mac OS上运行。研究人员使用的攻击者技术大多是来自于之前基于PowerShell的功能。

但是要想成功滥用PowerShell Core,还需要注意一些事项。比如,PowerShell Core并非在所有平台都是默认安装的,也就是说恶意软件创建者不能轻易的入侵没有安装PowerShell Core的机器。对unix和类Unix系统,文件系统的差异需要黑客添加一或两行代码才能执行恶意软件。比如,下载的ELF文件并不是可执行文件,要执行的话就需要对其属性进行修改。PowerShell Core的功能还在开发中,因为其应对滥用的安全机制也就比较弱。

微信截图_20181203141217.png

PowerShell和PowerShell Core比较

如上图所示,PowerShell Core可以安装在Windows 7之后的Windows操作系统,Linux (Kali, Fedora 27/28, Ubuntu等),macOS 10.12+ (Sierra及之后的操作系统),Windows IoT和Nano服务器。

滥用PowerShell Core PoC

Windows: DownloadFile场景

感染链是从一封垃圾邮件中的恶意附件开始的。在开启了文件的宏内容后,一个命令行和PowerShell Core脚本就会运行来下载和执行payload。

图1. 在Windows操作系统中滥用PowerShell Core DownloadFile的感染链

图2 用DownloadFile来提取payload的样本PowerShell Core脚本

Linux and mac OS: DownloadString场景

因为Linux和macOS terminal是一样的,因此滥用PowerShell Core的威胁在这两个操作系统是上都可以运行。假设恶意软件是通过垃圾邮件或漏洞利用到达的,可以创建一个PowerShell脚本来完成final payload的下载和执行。通过terminal执行的初始脚本会下载另一个可以提取final payload的PowerShell Core脚本,并修改其属性为executable。这就是为什么通过terminal或PowerShell Core脚本下载的文件在Linux和macOS系统中默认是不可执行的。

图3. 在Linux和macOS中滥用PowerShell Core DownloadString的感染链

图4. 使用DownloadString来提取payload的样本PowerShell Core脚本

 

图 5 下载的用来提取和执行final payload的PowerShell脚本

Windows: 滥用MultiPoolMiner和PowerShell Core

PowerShell Core可以与其他合法或灰色工具一起被滥用。对加密货币挖矿相关的活动,研究人员测试了开源工具MultiPoolMiner,该工具需要PowerShell Core才能正常运行。

研究人员在复现过程中,首先检查MultiPoolMiner包的start.bat文件,其中包括默认的命令和参数。进一步分析发现它会通过PowerShell Core(pwsh)来执行命令。如果系统中没有安装,就下载和安装PowerShell Core,然后继续执行。

 

图6. MultiPoolMiner的Start.bat会下载和执行PowerShell Core

在执行了batch文件后,开始检查系统的说明并下载所有支持的挖矿机应用和benchmark。这是为系统安装最优的加密货币挖矿机。下图是benchmark和加密货币挖矿进程执行的过程。

图7. MultiPoolMiner的benchmark和加密货币挖矿进程

最佳实践

考虑到PowerShell Core被滥用带来的影响,研究人员建议用户采用最佳实践来减少滥用PowerShell Core带来的威胁:

· 应用行为监控这样的安全机制,这可以帮助检测、监控和预防系统中执行的恶意活动。好的行为监控系统不仅可以拦截恶意软件相关的行为,还可以监控和预防不寻常的行为,比如文档中的恶意宏唤醒PowerShell Core。

· 深度防御。沙箱可以提供多一层的安全防护。应用防火墙、IDPS系统都可以帮助阻止C2通信和数据泄露这样的行为。

· 应用最新的补丁来预防漏洞被利用。

· 最小权限原则。限制PowerShell和PowerShell Core的使用,移除或禁用非必须的和过时的插件和组件,以减小系统的攻击面。

这是网络安全界疯狂的一年。它以一声巨响开始,Olympic Destroyer瞄准2月份的冬季奥运会,试图破坏开幕式。事情变得更加疯狂,加密货币挖矿软件随处可见,而VPNFilter在夏天风靡全球。全年网络安全新闻从未缺席,Talos一直在解析所有这些新闻。随着年末临近,回顾我们发现的最突出的恶意软件以及看到的主要趋势,其中一些预计将持续到2019年。请关注我们的恶意软件年度回顾以及今年发现的主要攻击事件的时间表。

图片2.png

Olympic Destroyer

Olympic Destroyer今年年初开始爆发。该攻击击首次出现在韩国冬奥会开幕式之夜,令奥运会的票务网站暂时宕机,并感染了举行开幕仪式体育场内的系统。Talos发现了一些恶意软件样本,表明恶意行为者希望破坏开幕式,因为恶意软件只包含破坏性功能。在接下来的几周里,研究人员试图找出攻击的幕后黑手。但是,恶意软件包含了几个虚假的标志,这使得归因溯源变得异常棘手。Olympic Destroyer在今年晚些时候以另一种变体回归,使得它更难以被发现。

VPNFilter

图片3.png

几个月后,VPNFilter风靡全球。Talos在五月份首先披露了这次攻击的细节。当时,我们发布了有关恶意软件的所有调查结果,试图告知消费者他们应该尽快重置无线路由器。我们估计,可以完全接管路由器并限制用户访问互联网的VPNFilter已经感染了全球500,000台设备。

虽然攻击者从未触发过VPNFilter,但它有可能非常严重。如果未被发现,恶意软件可以窃取用户的网站凭据并监控Modbus SCADA协议,甚至可以完全阻止设备。从设备中删除VPNFilter的唯一方法是完全重启设备(我们甚至依据此建议制作了专门的新闻)。在初始报告发布之后,Talos研究人员仍继续研究该恶意软件。我们对VPNFilter的理解不断加深,并在6月份发布了我们的最新发现。Talos发现恶意软件感染了其他几家供应商的设备,并且一个新的第3阶段模块可使恶意软件的所有样本都能够完全关闭受感染的设备。然而,它并未止步。攻击者最终在VPNFilter上增加了7个新的第3阶段模块,使恶意软件具备更强大的破坏能力。这些新功能允许攻击者传输数据,伪装与命令和控制(C2)服务器的通信,包括加密隧道功能。

加密货币挖掘软件

加密货币的价格在2017年底到2018年初全面飙升。传统勒索软件的攻击者突然看到了新的收入来源。随着时间的推移,我们看到更多的加密货币挖掘软件出现,取代了流行的勒索软件。在1月份,当我们看到一系列基于矿池的矿工出现时,Talos首先报道了这些矿工(这些矿工利用计算机秘密挖掘加密货币)。攻击者不再希望能够获得一笔大额支付,而是每天以加密货币的形式收钱。对于用户而言,这意味着如果他们的系统超时工作,就有可能产生更高的能源费用,并且对于不涉及采矿的其他事务而言,计算能力会降低。任何遭受这些矿工袭击的机构都面临着更大的风险。最终,我们发现了“Rocke”,一位能讲中文的攻击者,成为加密货币挖掘软件的最大用户之一。 Rocke全年使用各种工具包分发和执行加密恶意软件,这些工具包包括Git存储库,HttpFileServers,通过shell脚本和JavaScript后门释放挖矿软件。当时,我们预测Rocke会将社交工程作为诱骗用户下载加密货币挖掘软件的另一种方式。在这一年中,加密货币的价格已大幅跳水。这使得矿工的利润低于以往。但是,我们不能期望加密货币挖掘软件短时间内就会消失。

移动恶意软件

越来越多的消费者转向用移动设备取代台式机来满足他们的日常需求。随着越来越多的日常消费者使用智能手机购物,发送电子邮件等等,攻击者可以利用那些可能不太了解在线威胁的人。这为移动恶意软件打开了大门,移动恶意软件依赖于欺骗用户使恶意应用程序能够访问本不应该访问的内容。在某些情况下,攻击者已经获得了完全接管移动设备的能力,就像我们在7月份在印度发现的小型活动一样。在一个小型活动中,Talos发现了13个受移动设备管理(MDM)软件感染的设备,这些设备可能允许攻击者利用合法应用程序的恶意功能,从而泄露联系人、照片、消息和位置等信息。在晚些时候,我们发现此攻击系列针对的设备数量超出了我们最初的预期,甚至将攻击与另一位有Android设备定位历史的攻击者联系起来。另一个技巧是攻击者今年喜欢在移动设备上使用伪装。就我们在10月份发现了GPlayed而言,攻击者能够欺骗用户下载一个伪装成合法的Google Play应用商店的恶意应用。安装后,恶意应用程序可以加载插件并注入脚本。最终,GPlayed发展到了这样的程度:它包含了一个试图窃取用户登录凭证到金融服务网站的银行木马。

一、样本简介

深信服EDR安全团队,最近捕获到一款新型勒索病毒家族样本Vendetta。Vendetta是一款使用.NET框架开发的勒索病毒样本,会加密主机系统中大部分文件后缀名的文件,加密后缀为.vendetta,同时其具有Telegram通信功能,通过Telegram发送相应的主机进程信息以及加密信息,最后进行自删除。勒索信息内容如下所示:

1545903250(1).png

二、详细分析

1.样本使用.NET框架开发,无加壳,如下所示:

1.png

2.判断程序是否已经运行,如果已经运行,则退出,如下所示:

2.png

3.生成日志文件log.html,如下所示:

3.png

4.判断系统所在区域,如果为以下国家区域,则退出,如下所示:

4.png

相应的国家区域列表,如下所示:

Russian、Russian (Belarus)、Russian (Kyrgyzstan)、Russian (Kazakhstan)、
Russian (Moldova)、Russian (Russia)、Russian (Ukraine)、Bashkir (Russia)、
Chechen (Russia)、Church Slavic (Russia)、Ossetic (Russia)、Sakha (Russia)、
Tatar (Russia)、Ukrainian、Ukrainian (Ukraine)、Azerbaijani、Azerbaijani (Cyrillic)、Azerbaijani (Cyrillic, Azerbaijan)、Azerbaijani (Latin)
Azerbaijani (Latin, Azerbaijan)、Armenian、Armenian (Armenia)、
Belarusian、Belarusian (Belarus)、Kazakh (Kazakhstan)、Kyrgyz、
Kyrgyz (Kyrgyzstan)、Kazakh、Romanian (Moldova)、Tajik、
Tajik (Cyrillic)、Tajik (Cyrillic, Tajikistan)、Uzbek、
Uzbek (Perso-Arabic)、Uzbek (Perso-Arabic, Afghanistan)、Uzbek (Cyrillic)、
Uzbek (Cyrillic, Uzbekistan)、Uzbek (Latin)、Uzbek (Latin, Uzbekistan)、
Turkmen、Turkmen (Turkmenistan)

5.枚举进程信息,然后生成进程信息文件processes.csv,并写入进程信息,如下所示:

5.png

6.枚举进程,结束掉相应的进程列表中的进程,如下所示:

6.png

相应的进程列表,如下所示:

notepad、devenv、msbuild、taskmgr、spoolsv、skypebackgroundhost、skypeapp、
searchui、samsungrapidsvc、redis-server、postgres、perfwatson2、open server x64、
open server x32、open server x86、open server、nginx、named、mysqld、mongod、
memcached、jenkins、java、httpd、googleupdate、ftp、chrome、calculator、
firefox、winword、microsoftedge、microsoftedgecp、cmsserver、zf、dsq、
sqlsrvr、qqeimguard、企业QQ、qqeimplatform、tv_x64、teamviewer 13、wpscloudsvr、
WPS服务程序、提供账号登录、云存储等服务、teamviewer_service、igfxtray、igfxhk、
igfxem、igfxcuiservice、tv_w32、ss_privoxy、privoxy、userclient、qqprotect、
mqsvc、gnaupdaemon、mysqld-nt

7.随机生成password,如下所示:

7.png

使用RSA的公钥加密相应的password,并生password文件,如下所示:

8.png

RSA的公钥从公钥配置文件public.xml中读取,如下所示:

9.png

8.获取要加密的文件后缀名列表,一共三千多个,如下所示:

10.png

9.创建文件加密线程,如下所示:

11.png

遍历磁盘文件,如下所示:

12.png

如果文件存放在以下目录,则不进行加密,如下所示:

13.png

相应的目录列表,如下所示:

· %ApplicationData%

· %AllUsersProfile%

· %ProgramData%

· %ProgramFiles%

· C:\Intel

· C:\Nvidia

· C:\intel

· C:\nvidia

· C:\Users\All Users

· C:\Users\All users

· C:\Users\all users

· C:\Users\Public

· C:\Users\public

· C:\Users\acdgq\Desktop

· C:\Windows

· C:\Program Files

· C:\Program Files\Common Files

· C:\Program Files\Common Files\Microsoft\Exchange Server

· C:\Program Files\Common Files\Microsoft SQL Server

· C:\Program Files\Microsoft\Exchange Server

· C:\Program Files (x86)\Microsoft\Exchange Server

· C:\Program Files\Microsoft SQL Server

· C:\Program Files (x86)\Microsoft SQL Server

对遍历到的目录或文件进行相关处理,如下所示:

14.png

并保存相应的加密文件和非加密文件的文件信息encFiles.json、nonEncFiles.json,如下所示:

15.png

加密文件内容,如下所示:

16.png

10.加密文件的过程,如下所示:

17.png

根据文件的大小,执行不同的加密程序,相应的加密程序如下所示:

18.png

加密后的文件为[加密后的原文件名]+vendetta,如果生成的加密后的文件名大于等于248,则使用[原文件名]+vendetta2为加密后的文件名,如下所示:

19.png

加密后的文件,如下所示:

20.png

11.获取主机的相关ID,创建Telegram通讯连接,将之前生成的加密密钥以及进程列表信息通过Telegram发送,如下所示:

21.png

12.加密完成之后,通过Telegram发送相应的信息以及生成的配置文件等,如下所示:

22.png

13.生成相应的勒索信息超文本文件How to decrypt files.html,如下所示:

23.png

并设置为自启动项,如下所示:

24.png

14.最后进行自删除操作,如下所示:

25.png

三、解决方案

深信服安全团队再次提醒广大用户,勒索病毒以防为主,目前大部分勒索病毒加密后的文件都无法解密,注意日常防范措施:

1.不要点击来源不明的邮件附件,不从不明网站下载软件

2.及时给主机打补丁(永恒之蓝漏洞补丁),修复相应的高危漏洞

3.对重要的数据文件定期进行非本地备份

4.尽量关闭不必要的文件共享权限以及关闭不必要的端口,如:445,135,139,3389等

5.RDP远程服务器等连接尽量使用强密码,不要使用弱密码

6.安装专业的终端安全防护软件,为主机提供端点防护和病毒检测清理功能

 2018 年信息安全事件频发,信息安全的技能、人才需求大增。现在,不管是普通的企业,还是专业的安全厂商,都不可避免的需要掌握和运用好信息安全的知识、技能,以便在需要的时候,能够御敌千里。所谓养兵千日,用兵一时,拥有一支完善的团队或完整的流程,可以保障企业在出现重大安全事件时,能有条不紊的进行处置,及时把破坏范围缩小。

深信服EDR安全团队,全年参与了各种重大流行病毒和安全事件的应急响应,在此,我们将团队一整年的思考和所形成的流程,共享出来,期望能给未来即将从事,或者长期从事应急响应、安全研究的人,一些启迪。

我们大致从八个方面阐述,分别是:应急响应的整体思路、应急响应的基本流程、应急工具集简介、系统日志及日志分析、威胁情报的作用、常见病毒及分类、理解漏洞和补丁、技能提升建议。

一、应急响应的整体思路

应急响应的整体思路,就是上层有指导性原则和思想,下层有技能、知识点与工具,共同推进和保障应急响应流程的全生命周期。

应急响应的整体思路和基本流程

 

原则和指导性思路

3W1H原则:3W即Who、What、Why,1H即How,做应急响应要带着疑问来做事,一定要收集清楚这些信息。网络拓扑是怎么样的?需求是啥?发生了什么事?你能做什么?用户用了什么产品?产品版本多少?病毒库版本多少?多少主机中了?主机是普通PC还是服务器?服务器是做什么的?……信息收集越多,对应急响应越有利。

易失性原则:做应急响应免不了要做信息收集和取证的,但这里是有一定的先后顺序的,即最容易丢失的据,应该最先收集,其它的依次类推。

要素原则:做应急响应,主要是抓关键证据,即要素,这些要素包括样本、流量、日志、进程及模块、内存、启动项。

避害原则:做应急响应,要做到趋利避害,不能问题还没有解决,反而引入了新的问题。譬如,自己使用的工具被感染而不知情;给用户使用不恰当的工具或软件造成客户主机出现问题;给别人发样本,不加密,不压缩,导致别人误点中毒,最极端的场景就是给别人发勒索样本不加密压缩,导致别人误点中毒。

技能、知识点与工具

应急工具集:应急响应必要的一套工具集合,可协助应急人员做分析,提高效率。

日志分析:能对日志进行分析,包括但不限于系统日志(Windows/Linux等)、应用日志、安全设备日志(防火墙、防病毒、态势感知等)。

威胁情报:安全事件可能不是孤立的,安全站点或搜索站点能找到安全事件的关联信息。

漏洞补丁知识:知道漏洞与补丁的关系,它们在应急响应中的角色,了解常见漏洞及补丁。

常见病毒及分类:知道病毒大致的分类以及常见的病毒。

样本分析:至少能对样本进行一次简单动态的分析。

操作系统知识:至少对Windows系统和Linux系统的有一定的知识储备,知道其基础的工作原理。

二、应急响应的基本流程

应急响应大致可以分为五个部分,其基本流程包括收集信息、判断类型、深入分析、清理处置、产出报告。       

应急响应的整体思路和基本流程

收集信息:收集客户信息和中毒主机信息,包括样本。

判断类型:判断是否是安全事件,何种安全事件,勒索、挖矿、断网、DoS等等。

深入分析:日志分析、进程分析、启动项分析、样本分析。

清理处置:直接杀掉进程,删除文件,打补丁,抑或是修复文件。

产出报告:整理并输出完整的安全事件报告。

应急响应的整体思路和基本流程

勒索和挖矿事件,可以占比50%以上,而且这两种安全事件业务特征极其鲜明,因此可以单独提流程出来处置。

信息收集表

客户名称 什么区域的什么客户
感染主机数 感染了多数台主机
补丁情况 打了哪些补丁,是否存在补丁漏打
中毒现象 勒索/挖矿/DoS/僵尸网络/后门/木马
帐号密码 确认是否有弱密码
对外开发端口 对外开发了哪些端口
开启的服务 开启了哪些服务
操作系统版本 操作系统版本信息
客户需求 确认客户具体需求

应急响应的整体思路和基本流程

取证要素:取证并非毫无头绪的,病毒本身必然有网络行为,内存必然有其二进制代码,它要么是单独的进程模块,要么是进程的dll/so模块,通常,为了保活,它极可能还有自己的启动项、网络心跳包。

总之,可以归结为如下4点要素:流量、内存、模块、启动项。

流量分析可以使用Wireshark,主要分析下当前主机访问了哪些域名、URL、服务,或者有哪些外网IP在访问本地主机的哪些端口、服务和目录,又使用了何种协议等等。

例如,使用Wireshark观察到,主机访问了sjb555.3322.org这种动态域名,即可粗略猜测这是一个C&C服务器(如何判断一个域名是可疑域名,可以参考后文)。

应急响应的整体思路和基本流程

有时候,可以根据网络协议来直接过滤分析流量。譬如,目前IRC协议已经很少被使用了,但利用IRC建立僵尸网络通道的现象仍比较普遍。使用Wireshark,直接在过滤条件里输入“irc”,回车看是否有相关流量。

如下图,刚好看到有相关的IRC协议流量,这便是可疑的。

应急响应的整体思路和基本流程

Wireshark执行下“Follow TCP Stream”操作,查看到当前Botnet主机正在加入一个IRC频道。另外,也可以从目的IP下手,可查到这是一个恶意IRC僵尸网络服务器。

应急响应的整体思路和基本流程

网络流量这块,如果具体到对应建立的连接,也可使用TCPView工具进行查看。如下,我们使用TCPView查到了2条连接:

chenyu-57068a53.localdomain.2671-> 170.178.191.191:6667

chenyu-57068a53.localdomain.2674-> amsterdam.nl.eu.undernet.org.6667

应急响应的整体思路和基本流程

当我们分析病毒进程遇到困难的时候,其内存便是我们查找问题的最后一道防线。

以某Linux服务器应急事件为例子,如下图,我们找到三个病毒进程[ksoftirqd/7]的父子关系,可以看到,11275拉起了11276和11277,但11275是1号进程拉起来的,即init是其父进程。

应急响应的整体思路和基本流程

这意味着,实际的父进程(原始病毒文件)在当前状态下是追查不到的了。

进程树已经追踪不到父进程了,能下手的地方不多。如反汇编[ksoftirqd/7]对应的病毒文件,则对于一次应急响应事件来说,时间是仓促的(不够)。但简单这样想,即不管病毒文件做了何种混淆、何种加壳,在最终运行于内存之上的代码上,终归是原始代码,至少堆栈就有不少信息。

Linux环境下dump内存,可以使用系统自带的gdb,键入命令 gdb attach 11275,attach到病毒进程11275,在gdb环境下,使用dump binary memory file start_addr end_addr将11275有效内存空间dump下来。

譬如:file为输出文件,可以指定为 11275.dump,start_addr是起始地址,end_addr是终止地址,例 dump binary memory /tmp/11275.dump 0×13838000 0×13839000 (这里仅仅只是举例,实际地址在gdb中获取)

对于内存文件11275.dump,采用命令 strings -n8 11275.dump,获取长度8及以上的字符串内容,我们发现有如下一行:

/etc/security/ntps.conf

这是在病毒运行内存里面发现的,要么是病毒配置文件,要么是原始病毒文件。

我们 cd /etc/security 并使用 ls -al查看内容如下:

应急响应的整体思路和基本流程

可以看到,ntps.conf并非一个配置文件,它是可执行的(使用file命令可以知道这是个ELF可执行文件),文件修改时间应该是伪造的。 

三、应急工具集简介

工欲善其事,必先利其器,所谓巧妇难为无米之炊,其实应急响应亦是如此。应急响应和安全研究人员,必须事先就备好完整一套的工具集,随时可以取用。

应急响应的整体思路和基本流程

应急工具类型

流量分析工具:常用的流量分析工具是Wireshark、TCPView,也可以使用科来网络分析工具,Linux下对tcpdump比较熟悉的,也可以使用tcpdump。

进程分析工具:能对进程相关联信息进行分析的工具,主要是ProcessHacker和PC Hunter等。

启动项分析工具:主要是AutoRuns工具,便于定位病毒启动项。

专杀工具:有些流行病毒家族,通常对杀软有抑制性,或者本身有感染性,需要专杀工具去查杀和修复正常文件。

辅助工具:WinHex、文件Hash工具、Everything搜索工具、Unlocker文件解锁工具等。

内存扫描工具:主要是MemScanner。

应急响应的整体思路和基本流程

四、系统日志及日志分析

日志类型

Windows系统日志:Windows系统自带的审计日志、操作日志、故障日志。

Linux系统日志:Linux系统自带的审计日志、操作日志、故障日志。

应用日志:包括但不限于Web应用等众多繁杂的日志。

Windows系统日志

日志路径:C:\Windows\System32\winevt\Logs

必看日志:Security.evtx、System.evtx、Application.evtx

应急响应的整体思路和基本流程应急响应的整体思路和基本流程应急响应的整体思路和基本流程

Linux系统日志

日志路径:/var/log

必看日志:secure、history

应急响应的整体思路和基本流程

多数日志都是可读易懂的,譬如很容易就能看出来,下面这个日志记录了ssh爆破过程。

应急响应的整体思路和基本流程

五、威胁情报的作用

在安全事件中,威胁情报有时候会给我们提供大量有用的信息,甚至直接推动了安全事件的快速响应。

应急响应的整体思路和基本流程

威胁情报的元素,包括但不限于域名、URL、IP、文件Hash、文件路径、文件名、数字签名、备案信息、排名信息。

威胁情报的获取源

谷歌:www.google.com

百度:www.baidu.com

Virustotal:www.virustotal.com

微步在线:x.threatbook.cn

腾讯哈勃:habo.qq.com

Virscan:virusscan.jotti.org

Freebuf:www.freebuf.com

Jotti:virusscan.jotti.org

Scandir:www.scandir.com

Alexa排名:www.alexa.com

备案查询:beian.cndns.com

深信服安全中心:sec.sangfor.com.cn

深信服威胁分析平台:wiki.sec.sangfor.com.cn

深信服EDR安全软件中心:edr.sangfor.com.cn

威胁情报中,域名扮演着极为基础和关键的角色,URL也是以域名为基础的。这里列举若干类域名,是属于黑客常用(偏爱)的域名,取证过程中需要重点关注这类域名的信息。

随机域名(DGA):

内网IP利用特定的随机算法生成域名(DGA),同时黑客会利用该随机算法注册域名,这样就可以避免因为长期与某个域名或者IP通信而被封堵。

例如,内网某个源IP短时间内大量解析了如下域名(日志截图)

应急响应的整体思路和基本流程

观察这些域名,可以发现,这些域名的“字符特征”看上去就是随机的。域名的发明(DNS)就是为了人类方便记忆而诞生的,所以,我们往往会去注册一些容易记忆且读起来朗朗上口的域名,显然例子中的域名就不具备这一特征。DGA这种反其道而行之的行为显然不是人访问网站发出来的,必然是病毒利用某种算法来实现的。

动态域名:

动态域名是子域名开放给其他人使用,并且子域名绑定的IP是可以动态获取的,大多数是免费的,因此常被黑客所使用,如 abc.3322.org (3322.org就是动态域名提供者,子域名abc.3322.org可以被别人所使用)。

常见的动态域名提供商:

'f3322.net','3322.org','7766.org','8866.org','9966.org','8800.org','2288.org','6600.org', 'f3322.org', 'ddns.net','xicp.net', 'vicp.net','wicp.net','oicp.net','xicp.net','vicp.cc','eicp.net','uicp.cn','51vip.biz','xicp.cn','uicp.net','vicp.hk','5166.info','coyo.eu','imblog.in','imzone.in','imshop.in','imbbs.in','imwork.net','iego.cn','vicp.co','iego.net','1366.co','1866.co','3utilities.com','bounceme.net','ddnsking.com','gotdns.ch','hopto.org','myftp.biz','myftp.org','myvnc.com','no-ip.biz','no-ip.info','no-ip.org','noip.me','redirectme.net','servebeer.com','serveblog.net','servecounterstrike.com','serveftp.com','servegame.com','servehalflife.com','servehttp.com','serveminecraft.net','servemp3.com','servepics.com','servequake.com','sytes.net','webhop.me','zapto.org','dynamic-dns.net','epac.to','longmusic.com','compress.to','wikaba.com','zzux.com','dumb1.com','1dumb.com','onedumb.com','wha.la','youdontcare.com','yourtrap.com','2waky.com','sexidude.com','mefound.com','organiccrap.com','toythieves.com','justdied.com','jungleheart.com','mrbasic.com','mrbonus.com','x24hr.com','dns04.com','dns05.com','zyns.com','my03.com','fartit.com','itemdb.com','instanthq.com','xxuz.com','jkub.com','itsaol.com','faqserv.com','jetos.com','qpoe.com','qhigh.com','vizvaz.com','mrface.com','isasecret.com','mrslove.com','otzo.com','sellclassics.com','americanunfinished.com','serveusers.com','serveuser.com','freetcp.com','ddns.info','ns01.info','ns02.info','myftp.info','mydad.info','mymom.info','mypicture.info','myz.info','squirly.info','toh.info','xxxy.info','freewww.info','freeddns.com','myddns.com','dynamicdns.biz','ns01.biz','ns02.biz','xxxy.biz','sexxxy.biz','freewww.biz','www1.biz','dhcp.biz','edns.biz','ftp1.biz','mywww.biz','gr8domain.biz','gr8name.biz','ftpserver.biz','wwwhost.biz','moneyhome.biz','port25.biz','esmtp.biz','sixth.biz','ninth.biz','got-game.org','bigmoney.biz','dns2.us','dns1.us','ns02.us','ns01.us','almostmy.com','ocry.com','ourhobby.com','pcanywhere.net','ygto.com','ddns.ms','ddns.us','gettrials.com','4mydomain.com','25u.com','4dq.com','4pu.com','3-a.net','dsmtp.com','mynumber.org','ns1.name','ns2.name','ns3.name','changeip.name','ddns.name','rebatesrule.net','ezua.com','sendsmtp.com','trickip.net','trickip.org','dnsrd.com','lflinkup.com','lflinkup.net','lflinkup.org','lflink.com','dns-dns.com','proxydns.com','myftp.name','dyndns.pro','changeip.net','mysecondarydns.com','changeip.org','dns-stuff.com','dynssl.com','mylftv.com','mynetav.net','mynetav.org','ikwb.com','acmetoy.com','ddns.mobi','dnset.com','authorizeddns.net','authorizeddns.org','authorizeddns.us','cleansite.biz'。

f3322.net、3322.org、7766.org等等这些就是动态域名提供商。

应急响应的整体思路和基本流程

sjb555.3322.org就是一个动态域名,在VirusTotal上被标记为恶意的。

应急响应的整体思路和基本流程 这类域名常常是病毒的温床,不管是国家互联网应急中心,还是中国反网络病毒联盟,都是重点观察对象。企业级用户很少会主动去使用动态域名。

应急响应的整体思路和基本流程

近期域名:

域名都是有创建时间(注册时间)的,Alexa全球排名百万之内的域名,都是很早之前就注册了的,从几年到十几、二十几年不等。黑客攻击要逃避防火墙的封堵,极可能在实施的时候,再去注册一个域名。注册一个字母长度大于7的域名,费用并不高,甚至可以低至 8元/年(还有些是免费的)。黑客之所以倾向这么做,是因为旧域名,很可能已经被安全机构列入黑名单中(也就是说,已经被封堵了)。

试想,企业级用户,无缘无故为什么要去访问一个刚刚注册的域名呢?

例如,防火墙产生日志如下,观察到,日志产生时间为 2016年1月27日,访问的站点为 cazwmwez.info。

应急响应的整体思路和基本流程

接下来,我们来查查该域名的注册时间。

方式:通过VirusTotal查询即可。在Whois lookup这一栏,如图,观察Creation Date即注册时间为 2016年1月12日,RegistryExpiry Date即过期时间 为 1年之后。很明显,这个是一个刚刚注册且很短命的域名(此域名来源于某一真实中毒客户,当时介入取证调查时间点为2016年2月初,也就是说不到1个月),域名的所有者并没有打算长期维护。此外,域名的所有者也不是客户的(询问客户得知)。

应急响应的整体思路和基本流程

暗网代理域名:

暗网,也叫Tor网络,此网络的访问、传输流量是不可追踪溯源的,因此是黑色产业链的温床。要访问暗网,要么病毒自己实现Tor客户端,要么通过Tor代理来访问Tor网络,而通过Tor代理访问的流量是未加密的,其直接使用Tor代理访问Tor站点服务器。

因此,暗网代理域名是可以被检测到的。

例如访问https://abbujjh5vqtq77wg.onion.link/由于二级域名onion.link属于Tor代理域名,所以认定此次访问行为是Tor网络访问行为,且为非法访问可能性极高。

顶级域名:

不是所有的顶级域名都需要特别关注,要从客户业务出发,去反推客户主机为何要访问相关的顶级域名。也就是说,这里面有一批顶级域名,实际客户业务是不需要去访问的,那么剩下的就只有黑客行为了。下表给出的,就是这样一批顶级域名(包括但不限于以下顶级域名):

顶级域名 申请地区或机构 为何重点关注
.ru 俄罗斯 俄罗斯盛产黑客
.ws 东萨摩亚 不知名国家,易申请,难追踪注册者
.cc 科科斯群岛 不知名国家,易申请,难追踪注册者
.pw 帕劳 不知名国家,易申请,难追踪注册者
.bz 伯利兹 不知名国家,易申请,难追踪注册者
.su 苏联 前苏联虽然解体了,顶级域名还在使用,且多与黑产有关
.bw 伯兹瓦纳 不知名国家,易申请,难追踪注册者
.gw 几内亚比绍 不知名国家,易申请,难追踪注册者
.ms 蒙塞拉特岛 不知名国家,易申请,难追踪注册者
.mz 莫桑比克 不知名国家,易申请,难追踪注册者

这里举个例子,我们在某台告警主机上,使用Wireshark抓网络网络,直接过滤DNS协议如下:

应急响应的整体思路和基本流程

可以看到,此主机解析了大量.pw站点的域名,如koqqveoukgjc.pw,.pw是帕劳国家顶级域名,此国家是一个非常小的岛国,跟中国大陆都没有建交,国内企业有需要访问他们站点的可能性低到零(或者有业务在帕劳的可能性)。

六、常见病毒及分类

勒索病毒:能对用户文件进行加密的病毒。

应急响应的整体思路和基本流程

挖矿病毒:消耗用户CPU、GPU资源,进行大量运算,获取加密货币的病毒。

应急响应的整体思路和基本流程

蠕虫:自动复制自身的副本到其它主机的病毒。

木马:隐蔽性强,多用于监控用户行为或盗取用户数据的病毒。

感染型病毒:能将自身恶意代码插入正常文件的病毒。

脚本病毒:使用脚本编写的病毒。

宏病毒:宏是微软公司为其Office软件包设计的一个特殊功能,由于其功能强大,使得黑客可以通过精心构造的宏代码来实现恶意操作,这些代码就叫做宏病毒。宏病毒常以垃圾邮件的方式对用户进行攻击,因为伪造的Office文档不容易引起用户的怀疑,所以当用户毫无防备的打开Office文档并启用宏之后,宏病毒便开始了运行,对用户主机进行恶意操作。

僵尸网络病毒:能形成大型的一对多,多对多控制的远程控制病毒。

后门:在主机上开放端口允许远程非授权访问。

以感染型病毒为例,需要知道并了解其原理:

正常PE文件的执行流程入下:

应急响应的整体思路和基本流程

[1] 从PE头中提取入口点地址EP。

[2] 定位到EP处的PE代码。

[3] 开始执行PE代码。

被感染的PE文件的执行流程入下,其中多了恶意代码环节:

应急响应的整体思路和基本流程

[1] 从PE头中提取入口点地址EP。

[2] 通过篡改EP或覆盖原始入口点代码的方式,使EP指向恶意代码。

[3] 执行恶意代码。

[4] 恶意代码执行完后,跳回到原PE代码处执行。

应急响应的整体思路和基本流程

虽然感染的总体思路都是让宿主文件先执行恶意代码,执行完后再跳回到原始代码,但每种病毒家族实现的方式却不尽相同。我总结为四类,复杂度由低到高依次为:偏移式、覆盖式、加密式、混淆式。

专业术语:入口点EP(Entry Point),原始入口点OEP(Original Entry Point)。

偏移式是最多感染型病毒使用的感染方式,病毒会将恶意代码注入到宿主文件的一个空闲位置,然后修改PE头中的EP地址,使其指向恶意代码起始处。被感染文件运行后就会先执行恶意代码,恶意代码执行完成后,会获取OEP的偏移(每个病毒家族的OEP偏移值藏在不同的地方),然后将执行流跳回到OEP处,执行宿主文件原始代码。

七、理解漏洞和补丁

漏洞和补丁,在应急响应中是不可或缺。如果黑客是通过某种漏洞入侵系统的,而在应急响应中,无法找出黑客所利用的漏洞,就会意味着,入侵行为可以反复发生。在终端侧,就会表现为病毒清理不干净,杀了又来,所以一定要找出漏洞。

找到漏洞后,就需要打上相应的补丁,这样才是一次完整的处置。

怎么查看系统补丁情况?以Windows为例,直接打开cmd,输入命令systeminfo即可获取。

应急响应的整体思路和基本流程应急响应的整体思路和基本流程

漏洞是什么:漏洞是指一个系统存在的弱点或缺陷。

怎么来的:系统设计时的缺陷或编码时产生的错误。

有什么后果:黑客的侵入及病毒的驻留,数据丢失和篡改、隐私泄露,系统被控制并作为入侵其他主机系统的跳板,等等。

解决方法:打补丁。

八、技能提升建议

多关注安全信息:多关注安全公司发布的一些安全信息,多关注,多学习。

多研读安全书籍:多研读安全书籍,推荐《恶意代码分析实战》等。

应急响应的整体思路和基本流程

多逛安全论坛:推荐多看看Freebuf、看雪学院等。

多在安全沟通群里问:不懂就问。

多实践:多实践,出了安全问题,多尝试自己动手解决。

 *本文作者:千里目安全实验室,转载请注明来自 FreeBuf.COM

*文章原创作者:路过你身边topcoder,本文属于FreeBuf原创奖励计划,未经许可禁止转载

序言

PHP的mt_rand函数作为一个随机数生成工具在程序中被广泛使用,但是大家都忽略了一个事实,mt_rand生成的随机数不是一个真正的随机数,而是一个伪随机数,不能应用于生成安全令牌、核心加解密key等等,所以很多知名程序都出现过对mt_rand函数的错误使用而导致的安全问题。php_mt_seed是一个破解mt_rand函数种子的工具,对它应用场景的深刻理解和应用能极大的提升漏洞发现的可能和利用的成功率。本文将详细介绍PHP mt_rand函数的安全问题及php_mt_seed应用场景。

PHP mt_rand函数简介

PHP的mt_rand函数作为一个随机数生成工具在程序中被广泛使用,该函数用了 Mersenne Twister 算法的特性作为随机数发生器,它产生随机数值的平均速度比 libc 提供的 rand() 快四倍。mt_rand函数有两个可选参数 min 和 max,如果没有提供可选参数,mt_rand函数将返回返回 0 到 mt_getrandmax() 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)。

常用的使用方式如下:

<?php

echo mt_rand() . "\n";

echo mt_rand() . "\n";

echo mt_rand(5, 15);

?>

以上程序的输出结果如下:

1604716014

1478613278

6

伪随机数

伪随机数是用确定性的算法计算出来的随机数序列,它并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。伪随机数的生成方法有线性同余法、单向散列函数法、密码法等。

PHP mt_rand引起的安全问题

mt_rand就是一个伪随机数生成函数,它由可确定的函数,通过一个种子产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)。

简单假设一下 mt_rand()内部生成随机数的函数为: rand = seed+(i*10) 其中 seed 是随机数种子, i 是第几次调用这个随机数函数。当我们同时知道 i 和 rand 两个值的时候,就能很容易的算出seed的值来。比如 rand=21 , i=2 代入函数 21=seed+(2*10) 得到 seed=1 。是不是很简单,当我们拿到seed之后,就能计算出当 i 为任意值时候的 rand 的值了。

我们已经知道随机数的生成是依赖特定的函数,上面曾经假设为 rand = seed+(i*10) 。对于这样一个简单的函数,我们当然可以直接计算出一个解来,但 mt_rand实际使用的函数可是相当复杂且无法逆运算的。有效的破解方法其实是穷举所有的种子并根据种子生成随机数序列再跟已知的随机数序列做比对来验证种子是否正确。php_mt_seed就是这么一个工具,它的速度非常快。它可以根据单次mt_rand()的输出结果直接爆破出可能的种子,当然也可以爆破类似mt_rand(1,100)这样限定了MIN MAX输出的种子。

最后要提一下php官网manual的一个坑,mt_rand中文版和英文版的介绍是不一样的,可以看到英文版多了一块黄色的 Caution 警告:

捕获.PNG

很多国内开发者估计都是看的中文版的介绍而在程序中使用了mt_rand()来生成安全令牌、核心加解密key等等导致严重的安全问题。

这里我们还要注意一点,每一次mt_rand被调用都会根据seed和当前调用的次数i来计算出一个伪随机数,而且seed是自动播种的(自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 给随机数发生器播种 ,因为现在是由系统自动完成的)。那么问题就来了,到底系统自动完成播种是在什么时候,如果每次调用mt_rand()都会自动播种那么破解seed也就没意义了。关于这一点manual并没有给出详细信息。通过对源代码的分析可以看到每次调用mt_rand()都会先检查是否已经播种。如果已经播种就直接产生随机数,否则调用php_mt_srand来播种。也就是说每个php cgi进程期间,只有第一次调用mt_rand()会自动播种。接下来都会根据这个第一次播种的种子来生成随机数。而php的几种运行模式中除了CGI(每个请求启动一个cgi进程,请求结束后关闭。每次都要重新读取php.ini 环境变量等导致效率低下,现在用的应该不多了)以外,基本都是一个进程处理完请求之后standby等待下一个,处理多个请求之后才会回收(超时也会回收)。总的来说,就是php的自动播种发生在php cgi进程中第一次调用mt_rand()的时候。跟访问的页面无关,只要是同一个进程处理的请求,都会共享同一个最初自动播种的种子。

下面我们来看一下mt_rand的克星php_mt_srand。

php_mt_seed简介及使用说明

php_mt_seed是一个破解mt_rand函数seed的工具,在最简单的调用模式下,它能通过mt_rand第一次输出的值寻找mt_rand的seed,在更高级的模式中它能匹配不是第一次输出的和不明确具体输出的情况。

mt_rand的算法从PHP 3.0.6开始就一直在变化,php_mt_seed 4.0 支持以下几个大的版本: PHP 3.0.7 to 5.2.0,PHP 5.2.1 to 7.0.x, and PHP 7.1.0+

php_mt_seed基于命令行运行,命令行可以使用1,2,4或者更多的参数。这些参数需要详细说明mt_rand()的输出。

一个参数

当只有一个参数的时候,这个参数代表mt_rand第一次输出的值。

两个参数

当有两个参数的时候,他们代表mt_rand第一次输出应该位于什么区间内。

第一个参数为最小值,第二个参数为最大值。

四个参数(高级模式)

前两个参数表示mt_rand第一次输出的区间,后两个参数表示mt_rand输出的区间。

多于五个参数(高级模式)

每四个参数一组,但是最后一组可以是1,2或4个参数。每一组引用对应的输出。

php_mt_seed应用场景

直接使用mt_rand生成的随机数

假设下面的代码为用户密码的随机生成代码:

<?php

function user_password() {

return mt_rand();

}

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

运行后我们可以得到三个用户的密码

QQ截图20181214214913.png

假设我们现在得到了第一个用户的密码:1412203388

通过这个密码我们可以猜测出后面两个用户的密码。

下面我们运行php_mt_seed找出seed,命令如下:

./php_mt_seed.exe 1412203388

运行截图如下:

QQ截图20181214214935.png

这里我用于测试的服务器的PHP版本为5.4.45,那么seed就可能是2078089285,下面写一段PHP代码来测试一下。

<?php

mt_srand(2078089285);//手工播种

for($i=0;$i<3;$i++){

echo mt_rand()." ";

}

运行结果如下:

QQ截图20181214215800.png

完全解密了其它两个用户的密码。

使用经过转换后的mt_rand随机序列

下面是我们更常见到的生成随机数的代码:

<?php

function user_password($length = 10) {

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

$pass = '';

for ($i = 0; $i < $length; $i++) {

$pass .= $allowable_characters[mt_rand(0, $len)];

}

return $pass;

}

mt_srand(time());

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

?>

运行后我们可以得到三个用户的密码:

QQ截图20181214220413.png

假设我们现在得到了第一个用户的密码:paJHuuKv3H

我们要写一个程序,先是把字母还原成为生成的随机数,然后在拼接成php_mt_seed需要的参数。代码如下:

<?php

$pass_now = "paJHuuKv3H";

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

for($j = 0; $j < strlen($pass_now); $j++)

{

for ($i = 0; $i < $len; $i++) {

if($pass_now[$j] == $allowable_characters[$i])

{

echo "$i $i 0 56 ";

break;

}

}

}

运行结果如下:

QQ截图20181214220835.png

执行如下命令:

./php_mt_seed.exe 14 14 0 56 0 0 0 56 33 33 0 56 32 32 0 56 19 19 0 56 19 19 0 56 34 34 0 56 20 20 0 56 50 50 0 56 32 32 0 56

运行结果如下:

QQ截图20181214221155.png

得到seed为1544796235,写解密代码如下:

<?php

function user_password($length = 10) {

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

$pass = '';

for ($i = 0; $i < $length; $i++) {

$pass .= $allowable_characters[mt_rand(0, $len)];

}

return $pass;

}

mt_srand(1544796235);

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

运行截图如下:

QQ截图20181214221557.png

完全解密了其它两个用户的密码。

下面列出一个实际的例子:

Discuz X3.3 authkey生成算法的安全性漏洞

这里只做简要介绍,如需查看详细内容请看参考文献3。

Discuz官方于2017年8月1号发布最新版X3.4版本,在最新版本中修复了多个安全问题。

用户在初次安装软件时,系统会自动生成一个authkey写入全局配置文件和数据库,之后安装文件会被删除。该authkey用于对普通用户的cookie进行加密等密码学操作,但是由于生成算法过于简单,可以利用公开信息进行本地爆破。

Discuz_X3.3_SC_UTF8uploadinstallindex.php中authkey的生成方法如下:

$authkey = substr(md5($_SERVER['SERVER_ADDR'].$_SERVER['HTTP_USER_AGENT'].$dbhost.$dbuser.$dbpw.$dbname.$username.$password.$pconnect.substr($timestamp, 0, 6)), 8, 6).random(10);

可以看出authkey主要由两部分组成:

MD5的一部分(前6位) + random生成的10位

跟入random函数:

QQ截图20181214222347.png

由于字符生成集合是固定的,且没有重复字符,那么函数中每一次生成hash都唯一对应了chars数组中的一个位置,而且是使用同一个seed生成的。

在之后的代码中使用了同样的random函数:

$_config['cookie']['cookiepre'] = random(4).'_';

Cookie的前四个字节是已知的,并且使用了同样的random函数,那么思路很明显:

通过已知的4位,算出random使用的种子,进而得到authkey后10位。那剩下的就需要搞定前6位,根据其生成算法,只好选择爆破的方式,由于数量太大,就一定要选择一个本地爆破的方式(即使用到authkey而且加密后的结果是已知的)。

在调用authcode函数很多的地方都可以进行校验,在这里使用找回密码链接中的id和sign参数。

sign生成的方法如下:

function dsign($str, $length = 16){

return substr(md5($str.getglobal('config/security/authkey')), 0, ($length ? max(8, $length) : 16));

}

爆破authkey 的流程:

1.通过cookie前缀爆破随机数的seed。使用php_mt_seed工具。

2.用seed生成random(10),得到所有可能的authkey后缀。

3.给自己的账号发送一封找回密码邮件,取出找回密码链接。

4.用生成的后缀爆破前6位,范围是0×000000-0xffffff,和找回密码url拼接后做MD5求出sign。

5.将求出的sign和找回密码链接中的sign对比,相等即停止,获取当前的authkey。

总结

说了这么多,那到底随机数怎么不安全了呢?其实函数本身没有问题,官方也明确提示了生成的随机数不应用于安全加密用途(虽然中文版本manual没写)。问题在于开发者并没有意识到这并不是一个真随机数 。我们已经知道,通过已知的随机数序列可以爆破出种子。也就是说,只要任意页面中存在输出随机数或者其衍生值(可逆推随机值),那么其他任意页面的随机数将不再是“随机数”。常见的输出随机数的例子比如验证码,随机文件名等等。常见的随机数用于安全验证的比如找回密码校验值,比如加密key等等。PHP随机数的应用范围很广,很多知名的程序也出现过很多严重的问题,但是,目前这个方面还是没有得到足够的重视,一定还有很多很多地方存在着类似的漏洞等待着我们去发现。

参考文献

[1]http://www.php.net/manual/zh/function.mt-rand.php

[2]http://www.php.cn/php-weizijiaocheng-380106.html

[3]https://www.seebug.org/vuldb/ssvid-96371

[4]https://www.openwall.com/php_mt_seed/

[5]https://github.com/lepiaf/php_mt_seed

[6]https://baike.baidu.com/item/%E4%BC%AA%E9%9A%8F%E6%9C%BA%E6%95%B0/104358?fr=aladdin

*文章原创作者:路过你身边topcoder,本文属于FreeBuf原创奖励计划,未经许可禁止转载

*文章原创作者:路过你身边topcoder,本文属于FreeBuf原创奖励计划,未经许可禁止转载

序言

PHP的mt_rand函数作为一个随机数生成工具在程序中被广泛使用,但是大家都忽略了一个事实,mt_rand生成的随机数不是一个真正的随机数,而是一个伪随机数,不能应用于生成安全令牌、核心加解密key等等,所以很多知名程序都出现过对mt_rand函数的错误使用而导致的安全问题。php_mt_seed是一个破解mt_rand函数种子的工具,对它应用场景的深刻理解和应用能极大的提升漏洞发现的可能和利用的成功率。本文将详细介绍PHP mt_rand函数的安全问题及php_mt_seed应用场景。

PHP mt_rand函数简介

PHP的mt_rand函数作为一个随机数生成工具在程序中被广泛使用,该函数用了 Mersenne Twister 算法的特性作为随机数发生器,它产生随机数值的平均速度比 libc 提供的 rand() 快四倍。mt_rand函数有两个可选参数 min 和 max,如果没有提供可选参数,mt_rand函数将返回返回 0 到 mt_getrandmax() 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)。

常用的使用方式如下:

<?php

echo mt_rand() . "\n";

echo mt_rand() . "\n";

echo mt_rand(5, 15);

?>

以上程序的输出结果如下:

1604716014

1478613278

6

伪随机数

伪随机数是用确定性的算法计算出来的随机数序列,它并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。伪随机数可以用计算机大量生成,在模拟研究中为了提高模拟效率,一般采用伪随机数代替真正的随机数。模拟中使用的一般是循环周期极长并能通过随机数检验的伪随机数,以保证计算结果的随机性。伪随机数的生成方法有线性同余法、单向散列函数法、密码法等。

PHP mt_rand引起的安全问题

mt_rand就是一个伪随机数生成函数,它由可确定的函数,通过一个种子产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)。

简单假设一下 mt_rand()内部生成随机数的函数为: rand = seed+(i*10) 其中 seed 是随机数种子, i 是第几次调用这个随机数函数。当我们同时知道 i 和 rand 两个值的时候,就能很容易的算出seed的值来。比如 rand=21 , i=2 代入函数 21=seed+(2*10) 得到 seed=1 。是不是很简单,当我们拿到seed之后,就能计算出当 i 为任意值时候的 rand 的值了。

我们已经知道随机数的生成是依赖特定的函数,上面曾经假设为 rand = seed+(i*10) 。对于这样一个简单的函数,我们当然可以直接计算出一个解来,但 mt_rand实际使用的函数可是相当复杂且无法逆运算的。有效的破解方法其实是穷举所有的种子并根据种子生成随机数序列再跟已知的随机数序列做比对来验证种子是否正确。php_mt_seed就是这么一个工具,它的速度非常快。它可以根据单次mt_rand()的输出结果直接爆破出可能的种子,当然也可以爆破类似mt_rand(1,100)这样限定了MIN MAX输出的种子。

最后要提一下php官网manual的一个坑,mt_rand中文版和英文版的介绍是不一样的,可以看到英文版多了一块黄色的 Caution 警告:

捕获.PNG

很多国内开发者估计都是看的中文版的介绍而在程序中使用了mt_rand()来生成安全令牌、核心加解密key等等导致严重的安全问题。

这里我们还要注意一点,每一次mt_rand被调用都会根据seed和当前调用的次数i来计算出一个伪随机数,而且seed是自动播种的(自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 给随机数发生器播种 ,因为现在是由系统自动完成的)。那么问题就来了,到底系统自动完成播种是在什么时候,如果每次调用mt_rand()都会自动播种那么破解seed也就没意义了。关于这一点manual并没有给出详细信息。通过对源代码的分析可以看到每次调用mt_rand()都会先检查是否已经播种。如果已经播种就直接产生随机数,否则调用php_mt_srand来播种。也就是说每个php cgi进程期间,只有第一次调用mt_rand()会自动播种。接下来都会根据这个第一次播种的种子来生成随机数。而php的几种运行模式中除了CGI(每个请求启动一个cgi进程,请求结束后关闭。每次都要重新读取php.ini 环境变量等导致效率低下,现在用的应该不多了)以外,基本都是一个进程处理完请求之后standby等待下一个,处理多个请求之后才会回收(超时也会回收)。总的来说,就是php的自动播种发生在php cgi进程中第一次调用mt_rand()的时候。跟访问的页面无关,只要是同一个进程处理的请求,都会共享同一个最初自动播种的种子。

下面我们来看一下mt_rand的克星php_mt_srand。

php_mt_seed简介及使用说明

php_mt_seed是一个破解mt_rand函数seed的工具,在最简单的调用模式下,它能通过mt_rand第一次输出的值寻找mt_rand的seed,在更高级的模式中它能匹配不是第一次输出的和不明确具体输出的情况。

mt_rand的算法从PHP 3.0.6开始就一直在变化,php_mt_seed 4.0 支持以下几个大的版本: PHP 3.0.7 to 5.2.0,PHP 5.2.1 to 7.0.x, and PHP 7.1.0+

php_mt_seed基于命令行运行,命令行可以使用1,2,4或者更多的参数。这些参数需要详细说明mt_rand()的输出。

一个参数

当只有一个参数的时候,这个参数代表mt_rand第一次输出的值。

两个参数

当有两个参数的时候,他们代表mt_rand第一次输出应该位于什么区间内。

第一个参数为最小值,第二个参数为最大值。

四个参数(高级模式)

前两个参数表示mt_rand第一次输出的区间,后两个参数表示mt_rand输出的区间。

多于五个参数(高级模式)

每四个参数一组,但是最后一组可以是1,2或4个参数。每一组引用对应的输出。

php_mt_seed应用场景

直接使用mt_rand生成的随机数

假设下面的代码为用户密码的随机生成代码:

<?php

function user_password() {

return mt_rand();

}

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

运行后我们可以得到三个用户的密码

QQ截图20181214214913.png

假设我们现在得到了第一个用户的密码:1412203388

通过这个密码我们可以猜测出后面两个用户的密码。

下面我们运行php_mt_seed找出seed,命令如下:

./php_mt_seed.exe 1412203388

运行截图如下:

QQ截图20181214214935.png

这里我用于测试的服务器的PHP版本为5.4.45,那么seed就可能是2078089285,下面写一段PHP代码来测试一下。

<?php

mt_srand(2078089285);//手工播种

for($i=0;$i<3;$i++){

echo mt_rand()." ";

}

运行结果如下:

QQ截图20181214215800.png

完全解密了其它两个用户的密码。

使用经过转换后的mt_rand随机序列

下面是我们更常见到的生成随机数的代码:

<?php

function user_password($length = 10) {

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

$pass = '';

for ($i = 0; $i < $length; $i++) {

$pass .= $allowable_characters[mt_rand(0, $len)];

}

return $pass;

}

mt_srand(time());

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

?>

运行后我们可以得到三个用户的密码:

QQ截图20181214220413.png

假设我们现在得到了第一个用户的密码:paJHuuKv3H

我们要写一个程序,先是把字母还原成为生成的随机数,然后在拼接成php_mt_seed需要的参数。代码如下:

<?php

$pass_now = "paJHuuKv3H";

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

for($j = 0; $j < strlen($pass_now); $j++)

{

for ($i = 0; $i < $len; $i++) {

if($pass_now[$j] == $allowable_characters[$i])

{

echo "$i $i 0 56 ";

break;

}

}

}

运行结果如下:

QQ截图20181214220835.png

执行如下命令:

./php_mt_seed.exe 14 14 0 56 0 0 0 56 33 33 0 56 32 32 0 56 19 19 0 56 19 19 0 56 34 34 0 56 20 20 0 56 50 50 0 56 32 32 0 56

运行结果如下:

QQ截图20181214221155.png

得到seed为1544796235,写解密代码如下:

<?php

function user_password($length = 10) {

$allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';

$len = strlen($allowable_characters) - 1;

$pass = '';

for ($i = 0; $i < $length; $i++) {

$pass .= $allowable_characters[mt_rand(0, $len)];

}

return $pass;

}

mt_srand(1544796235);

echo user_password(), "\n";

echo user_password(), "\n";

echo user_password(), "\n";

运行截图如下:

QQ截图20181214221557.png

完全解密了其它两个用户的密码。

下面列出一个实际的例子:

Discuz X3.3 authkey生成算法的安全性漏洞

这里只做简要介绍,如需查看详细内容请看参考文献3。

Discuz官方于2017年8月1号发布最新版X3.4版本,在最新版本中修复了多个安全问题。

用户在初次安装软件时,系统会自动生成一个authkey写入全局配置文件和数据库,之后安装文件会被删除。该authkey用于对普通用户的cookie进行加密等密码学操作,但是由于生成算法过于简单,可以利用公开信息进行本地爆破。

Discuz_X3.3_SC_UTF8uploadinstallindex.php中authkey的生成方法如下:

$authkey = substr(md5($_SERVER['SERVER_ADDR'].$_SERVER['HTTP_USER_AGENT'].$dbhost.$dbuser.$dbpw.$dbname.$username.$password.$pconnect.substr($timestamp, 0, 6)), 8, 6).random(10);

可以看出authkey主要由两部分组成:

MD5的一部分(前6位) + random生成的10位

跟入random函数:

QQ截图20181214222347.png

由于字符生成集合是固定的,且没有重复字符,那么函数中每一次生成hash都唯一对应了chars数组中的一个位置,而且是使用同一个seed生成的。

在之后的代码中使用了同样的random函数:

$_config['cookie']['cookiepre'] = random(4).'_';

Cookie的前四个字节是已知的,并且使用了同样的random函数,那么思路很明显:

通过已知的4位,算出random使用的种子,进而得到authkey后10位。那剩下的就需要搞定前6位,根据其生成算法,只好选择爆破的方式,由于数量太大,就一定要选择一个本地爆破的方式(即使用到authkey而且加密后的结果是已知的)。

在调用authcode函数很多的地方都可以进行校验,在这里使用找回密码链接中的id和sign参数。

sign生成的方法如下:

function dsign($str, $length = 16){

return substr(md5($str.getglobal('config/security/authkey')), 0, ($length ? max(8, $length) : 16));

}

爆破authkey 的流程:

1.通过cookie前缀爆破随机数的seed。使用php_mt_seed工具。

2.用seed生成random(10),得到所有可能的authkey后缀。

3.给自己的账号发送一封找回密码邮件,取出找回密码链接。

4.用生成的后缀爆破前6位,范围是0×000000-0xffffff,和找回密码url拼接后做MD5求出sign。

5.将求出的sign和找回密码链接中的sign对比,相等即停止,获取当前的authkey。

总结

说了这么多,那到底随机数怎么不安全了呢?其实函数本身没有问题,官方也明确提示了生成的随机数不应用于安全加密用途(虽然中文版本manual没写)。问题在于开发者并没有意识到这并不是一个真随机数 。我们已经知道,通过已知的随机数序列可以爆破出种子。也就是说,只要任意页面中存在输出随机数或者其衍生值(可逆推随机值),那么其他任意页面的随机数将不再是“随机数”。常见的输出随机数的例子比如验证码,随机文件名等等。常见的随机数用于安全验证的比如找回密码校验值,比如加密key等等。PHP随机数的应用范围很广,很多知名的程序也出现过很多严重的问题,但是,目前这个方面还是没有得到足够的重视,一定还有很多很多地方存在着类似的漏洞等待着我们去发现。

参考文献

[1]http://www.php.net/manual/zh/function.mt-rand.php

[2]http://www.php.cn/php-weizijiaocheng-380106.html

[3]https://www.seebug.org/vuldb/ssvid-96371

[4]https://www.openwall.com/php_mt_seed/

[5]https://github.com/lepiaf/php_mt_seed

[6]https://baike.baidu.com/item/%E4%BC%AA%E9%9A%8F%E6%9C%BA%E6%95%B0/104358?fr=aladdin

*文章原创作者:路过你身边topcoder,本文属于FreeBuf原创奖励计划,未经许可禁止转载

在花了大量时间分析各种maldoc之后,我意识到它们有一个共同点。看看下面这张图表:
2018-11-07_01.png
我意识到许多maldoc使用CMD来启动下一个阶段。当然,并不是所有的maldoc都遵循这个图表。有一些maldocs直接从VBA请求(或其变体)恶意软件,而CMD根本没有使用。所以我想,如果我监视CMD进程并从命令行提取数据会怎么样呢?这样,我就可以从VBA宏中获得没有被混淆的输出,而不必遍历代码并手动转储内容。又如果我监视CMD进程,挂起它,提取命令行数据,然后杀掉它,会怎么样呢?我不仅能够快速、轻松地获得VBA宏输出,而且还可以避免机器损坏。CMD观察者就是这样诞生的。我去了恶意软件流量分析站点,抓了几个maldocs,启动了这是Emotet maldoc。
2018-11-07_03.png这是Hancitor
2018-11-07_04.png这是Trickbot。
2018-11-07_05.png我将写一篇关于如何去混淆DOSfuscated脚本的后续文章。如果您对CMD Watcher感兴趣,可以从Tools页面下载它。

*参考来源kahusecurity,由周大涛编译,转载请注明来自FreeBuf.COM

2018-12-12_152636.png时光荏苒,距离MS08-067漏洞的出现已经过去十年了,与其它安全事件不同,MS08-067漏洞经历了辉煌的一页,具有里程碑意义,就连当时负责处理该漏洞的人都印象深刻记忆犹新。基于微软威胁情报总经理John Lambert的回忆,我们采访了当时处理该漏洞响应事件的一线工程师,力求从他们那里得到关于MS08-067漏洞的最真实感受,全面回顾这个引发Conficke蠕虫的严重安全事件。(点此参考微软关于MS08-067的技术分析回顾)

采访嘉宾介绍

Dustin Childs,2008年时任微软安全应急响应中心(MSRC)安全项目经理(SPM),现任职趋势科技Trend Micro Zero Day Initiative。

Ziv Mador,2008年时任微软恶意软件防护中心(MMPC)高级项目经理,现任Trustwave公司Spiderlabs安全研究副总。

Phillip Misner,2008年时任微软安全应急响应中心(MSRC)安全项目经理(SPM),现任微软安全应急响应中心首席安全经理。

Q:在对MS08-067漏洞的处理应对中,你们当时的角色是什么?

Dustin:当时是2008年的10月,我那会在任微软安全应急响应中心(MSRC)任职安全经理,我的工作就是协调影响Windows操作系统漏洞的各种响应事件,另外还负责漏洞公告的编写发布。最终,MS08-067漏洞的各种工作也交到了我的手上,前后我一共发布了11条漏洞公告,但其严重的带外安全更新(Out-Of-Band Update)我没负责。这是我当时经手过的最严重的安全事件,可以说有些措手不及,并且我还自己亲手去编写漏洞公告。那个时候社会对信息安全的认知理解非常落后,我们还一度被《大众科学》杂志评比为第六名最令人作呕的工作,他们认为,我们微软安全人员的工作只比生物实验室中做动物防腐处理的人员稍好一些,还说我们是雷德蒙德(微软总部)土地神(Redmond security gnome)。

带外安全更新(Out-Of-Band Update):是指在正常发布时间以外的某个时间发布的更新,例如,微软通常会在每个月的第二个星期二,发布当前Windows产品存在的安全更新,以此来敦促用户下载更新进行系统修复。发布带外补丁的通常原因是出现了意想不到的、广泛的、破坏性强的漏洞,可能会引发病毒、蠕虫或特洛伊木马,对大量互联网用户造成影响。通常,0-day漏洞更新就会采用带外安全更新方式来进行补丁修复。

Ziv:  回想2008年,那时我任职微软恶意软件防护中心(MMPC)高级项目经理,我的工作职责就是代表恶意软件防护团队,在软件安全响应事件流程(SSIRP)中进行处理协调相关事宜。其中,会与微软安全应急响应中心(MSRC)和恶意软件分析师团队共同合作,进行一些漏洞和潜在利用代码的识别了解,以此制订恶意软件检测规则,收集采集数据评估恶意软件的传播方式和规模。可以说,MS08-067漏洞和之后的Conficker蠕虫变体,算是我们处理过的最严重的安全事件了,前后持续了数月之久。

2018-12-12_152712.pngPhillip:那个时候,我是微软软件安全响应事件流程(SSIRP)机制的危机处理领导,负责对监测到的一些主动攻击,进行一些安全动员和响应。在该角色工作中,我主要实施了风险理解的推动和一些相关的技术性工程计划,以及协调整体的应对措施。

Q: 你们当时对MS08-067漏洞有什么难忘的回忆?

Dustin: 当时看到微软的各个部门通力合作来处理这个漏洞,我个人还是比较惊讶的,我们微软总部、印度和欧洲的分公司团队几乎都是在全天候工作状态模式。有一件事我印象特别深刻,当针对MS08-067漏洞进行首次安全响应事件流程(SSIRP)会议时,会议室里坐满了15多人,还有很多专家是通过电话会议专线接入的,当Phillip解释完这个漏洞的相关情况之后,会议气氛突然陷入了瞬时的沉默,因为我们知道伴随这个漏洞而来的将是大量的蠕虫病毒。

从那一刻起,我们明白战斗已经开始了。没有经历过这种大场面的人可能没有那种体会,当时房间里坐着的都是一众信息安全专家,他们都曾亲自应对过Melissa、Nimda、Slammer、Sasser和Code Red等超级蠕虫病毒。另外比较有意思就是,出于应急优先,我只要解释一下MS08-067漏洞的情况,就能马上协调调配工作人员来参与响应处理。

2018-12-12_152730.png我当时谈的更多的是,是否要基于这个漏洞做一些中等风险的评级,所有人都清楚其中的利害关系。针对这个漏洞,当时微软所有人不分昼夜地进行了17天的应对处理工作。另一个引人注目的事情是,其广泛的漏洞影响范围,基于NT的系统都涉及其中,除Windows Server 2008 Core外,所有Windows系统,包括Windows 2000/XP/Server 2003/Vista/Server 2008的各个版本,甚至还包括测试阶段的Windows 7 Pro-Beta。我们甚至还被要求针对Windows ME 和Win 98这两个古老系统制作相关的漏洞补丁,甚至我还听说,为了应对史蒂夫·鲍尔默即将召开的Win 7测试版发布会,我们需要加紧重新制作新的系统DVD安装盘,以备现场分发的Win 7光盘系统不受影响。

Ziv: 首先是,John Lambert领导的微软可信计算团队向我们提供了这个惊人的Windows 0-day漏洞消息,他们的团队研发出了从崩溃报告中判断识别未知0-day漏洞的方法,利用该方法,他们能跟踪利用MS08-067漏洞进行攻击尝试的崩溃次数,一旦识别出了相当的次数,微软恶意软件防护中心(MMPC)的分析师就会立即进行相应的防病毒签名开发,以帮助我们发现其漏洞利用代码。当时,尽管我们维护着一个大型的恶意软件库,但好在没有发现太多基于MS08-067漏洞的传播类非复制型恶意软件样本。之后,配合微软官方发布的MS08-067安全更新,我们也对外公布了针对该漏洞的公共签名,帮助企业和个人用户能更好地防护攻击识别线索,以最大程度地减少受影响范围。

我们知道,随着社会公共领域的不断信息化,将会有更多的恶意软件随之而来,在安全补丁尚未打全之前,坏人和犯罪份子绝不会错过这种漏洞利用的良机。也就在MS08-067漏洞事件期间,我也应景地写了一篇官方博客,标题就叫做 “赶快打补丁,要快!”。

不出所料,微软发布的这个重要的带外安全更新(Out-Of-Band Update)迅速引发了媒体关注,就连当时还为《华盛顿邮报》撰稿的Brian Krebs也发布了文章进行跟进报道

6a0133f264aa62970b022ad39aef93200d-800wi.jpg接着,在接下来的几天内,我们屏住呼吸,每小时不间断地检查监测数据,网络中出现了大量的系统崩溃报告反馈,很明显,有人正利用这个漏洞对目标系统进行攻击尝试。在MS08-067出现后一个月的11月初,基于该漏洞新的恶意软件变体出现了,但好在其传播感染性不高。但就在几周之后,基于MS08-067漏洞的Conficker蠕虫大量爆发了,这点可以在后续的访谈中我们再作讲述。

tele.pngPhillip: MS08-067应该算是第一起在大面积传播感染之前,我们能够在早期发现一些攻击线索的事件。我记得,当时我们发现了阻止其造成广泛攻击的方法,非常兴奋,也正是这一机会促使我们公司内部抓紧研发了漏洞解决方案。我们分散在世界各地的团队共同合作,从漏洞出现到补丁发布,前后只用了17天的时间,在当时这已经算是非常快的速度和节奏了。此外,MS08-067漏洞事件给我的另外一个记忆就是,直接导致了之后微软对重要带外安全更新的发布增加。在漏洞出现之初,我们检测到每天只有一两次的该漏洞利用攻击,显然一开始它造成的网络攻击不算广泛,后来在10月15日左右,我们从监测数据上可以看到,其攻击已经上升为每天12次了。诚然说,尽管12次并不算什么大数字,而且我们监测到的攻击也都是一些失败的攻击利用尝试, 但这说明一种跳跃性的波动趋势,至少从风险层面来说,它存在一种大的波动可能。

我们所监测到的网络攻击者,与像Slammer或Blaster这样的传播感染蠕虫之间的不同之处就在于,攻击者利用漏洞攻击带有一定的意图,当我们在讨论补丁发布和修复方案时,我也在会上重复强调了这个问题。最终,我们决定了一个风险优先的平衡快速修复方案。只是在补丁发布之后,当我们从攻击者利用的网络基础设施中进行信息提取时才发现,早前我们监测到的攻击正处于增长趋势,是后续大规模攻击的前期铺垫(可以从这里的报告中看到具体变化)。

MS08-067漏洞给我另外记忆较深的事就是其补丁发布,其提前公告描述(Advanced Notification Summary)是在正式补丁发布前一天就公布的,短短的五句话让业界措手不及。

2018-12-11_152750.png那个时候,这种带外安全更新非常少见,常常与一些野外攻击相关。当时引起的反应就是,反恶意软件供应商们都在争先恐后地寻找攻击线索,但确实当时只有微软观察到了这些攻击。在在面积攻击发生之前,我们使用的技术和监测手段派上了用场,提供了重要的参考。从某种层面上说,我们也限制住了攻击者,一旦安全更新发布,攻击者利用的网络基础设施就会被识别发现,该漏洞就不能再继续被利用了。所在,在MS08-067漏洞造成大面积攻击之前,我们能及时发布更新补丁,多少还是非常欣慰的。

Q: 你认为对MS08-067衍生攻击的应急响应如何?

Dustin: 对我来说,有两件事非常明显,首先,一开始我们做的漏洞公告是1.0版的,在下载我们发布的安全更新之后,系统中的修复会很快生成,剩下的时间就是系统的一些修复测试,它会确保漏洞能被有效修复,且不会产生其它问题。和我其它的工作经历相比,我认为MS08-067事件是微软全力以赴共同保护客户的一个典型案例。

另外,我们做得好的就是如何来说清楚这件事。通常的漏洞更新会统一放在星期二的更新公告日中,但对于这个漏洞来说,我们做了三个公告,每个公告都是对60多个问题回答的综合描述。我们全力与公关和营销伙伴合作,尽量让大众知道安装此更新的重要性,我们甚至把更新公告放到了msn.com首页上,反正我们想出了任何可以提醒人们安装该重要更新的方法。

我们这么煞费苦心,是有原因的,从这一点上来说,也可以反映出后期基于MS08-067的Conficker蠕虫变化规律,刚开始出现的Conficker.A版本造成的影响有限,仅使用了服务漏洞进行传播,后期的Conficker.B就加入了NetBIOS感染方式,成为了所谓的互联网猛兽。

narrow.pngZiv: 当MS08-067事件发生时,我已经在微软恶意软件保护中心工作了五年多,在该响应事件中,我看到微软和安全社区的运作方式有了显著改善,能积极对这种事件做出响应。MS08-067事件时,微软的整个响应过程已经很成熟了,包括微软安全响应中心、可信计算团队、微软恶意软件保护中心、客户支持团队、Windows产品团队、安全通信、现场和政府外联人员在内的各部门,都能做到有序高效的运作,应急过程包括明确参与团队的代表人员,然后根据需要在短时间内发起协调动员,而且,安全响应事件流程(SSIRP)的战时会议效率很高,通常15分钟左右就会召开一次会议。

创新为成功做出了重要贡献, John Lambert领导的团队能从数百万份崩溃报告中识别出了潜在未知的0-day漏洞,这种方法非常厉害,能提早预防MS08-067此类高危漏洞的广泛利用,我们可据此发布安全更新,及时为Windows客户提供安全保护。

就当时,对于我所在的团队MMPC来说,底层基础设施在过去几年中有了显著改善,能很好地支持了我们的技术需求。每天都有大量恶意可疑的文件被收集、扫描并存储在我们的系统中,这使得我们能够快速识别新的恶意软件,并对其进行分析,获得必要的技术信息,例如它利用了哪些漏洞,它是如何传播的,以及它连接到了哪些恶意服务器或URL链接。在有些情况下,其它安全供应商和机构也会向我们提供恶意软件样本,进一步加强了我们阻止疫情蔓延的能力。MMPC利用全球数亿台用户计算机系统的综合兼容性技术(Microsoft Compatibility Telemetry)来收集数据,其中最流行的工具就是微软恶意软件删除工具 (MSRT),但我们也受益于其它安全产品,如OneCare和Forefront系列产品,此类客户系统数据让作为一名响应协调员的我,能够评估漏洞爆发的规模及其在全球的蔓延程度,这一点上,客户系统崩溃数据和来自客户现场的报告反馈,能帮助公司决策如何从战略上应对这一事件。

tools.pngPhillip: 回顾对MS08-067漏洞的应急响应,我觉得有两个方面我们做得非常好,那就是响应速度和为不同受众获取正确的风险数据。首先,就像之前他们说到的,我们动用了公司世界级的努力来制作漏洞补丁,那时候,微软大多数服务工程师都集中在总部的华盛顿雷德蒙德和印度的海德拉巴,从地域上来说是完全分开的,但是,公司的各个工程师团队都竭尽全力夜以继日地开干,最终完美地完成了补丁的开发和测试工作。这些团队投入的奉献精神和辛勤工作令人瞩目,我由衷地向他们致敬,感谢他们为更好地保护客户所做的一切努力。

其次,是我们能从该事件中总结经验,把整个事件中涉及的相关信息和风险数据都作了归纳整理。十年过去了,我忘记了当时对MS08-067漏洞响应付出的详细努力,当时应用了一些新的通信工具,如高级通告服务(Advanced Notification Service)、微软主动保护计划( MAPP )和我们的官方博客,同时,这些措施和手段也帮助微软定义了未来几年的安全对策。那天,我们坚持了信任和保护客户的原则,而这些都来源于可信计算的价值所在,也是微软在21世纪初艰难前行过程中吸取的经验教训。

Q: 从这次事件的结果中,我们希望吸取或总结出什么好的经验教训?

Dustin: 我从中得到的经验是,向客户传达实际风险非常重要。对大多数人来说,安全更新通常被认为是带有一点干扰性或令人讨厌的东西,有些人对他们不太友好信任,但充分的证据表明防止系统遭受攻击入侵的最佳方法也就是及时安装可用的安全更新。对身处行业中的我们来说,我们需要更好地制作出高质量的安全更新,并且需要一种公开坦率地解释安全更新所能缓解的风险。

Ziv: 我的经验就是,遇到这种事情时,需要进行一些内部的漏洞和恶意软件相互关系的交流,其次,更重要的是进行一些与外部的沟通,因为这样才能为其它组织机构和团队提供更多有参考价值的信息。MS08-067漏洞事件时,我们当时发布了很多漏洞公告、技术博客和分析文章,有成千上万的点击阅读量。很明显的是,在这几个月中,有很多安全从业人员和团队需要从各种渠道,来获取可靠的信息和指导方针,而他们利用我们发布的这些信息,可以最大程度地降低缓解资产系统的安全风险。

Phillip: 如果说需要从这个事件中吸取一个教训的话,我认为就是在当时的2008年,整个基于微软的生态系统是存在漏洞和风险的,亟需进行相应的系统缓解加固和修复。当我们在2017年为WannaCry 和 Petya 撰写技术博客时,我觉得那种场景和当时的MS08-067漏洞事件似曾相识,九年之后这种感觉再次浮现。九年之中,整个安全行业在技术和应急响应以及承载系统方面都有了大幅度的提升发展,但尽管如此,感觉我们在更新修复和系统保护方面还没有走在前面。我希望在未来几年中,当另一次攻击出现时,我们行业构建的整个安全生态系统能做到更好更充分的应对和准备。

MS08-067漏洞事件的反思

今年是MS08-067漏洞事件的整整十周年,我们的反思和回忆,并不代表该事件对整个安全生态、行业响应或我们个人的职业生涯造成了影响,而是我们认为,该事件是安全史上的一个典型时刻,值得我们去深入了解。非常感谢John Lambert在几年前发表的MS08-067漏洞事件回忆录,它帮我们认识到,即使身处今天这样复杂的攻击威胁下,MS08-067漏洞事件仍然具有参考和借鉴意义。

Q: Dustin,关于对该事件的回顾,你还有什么想要说的吗?

Dustin: 就这样吧,当时我不能确定 “我微软职业生涯的顶峰”是什么,但MS08-067的漏洞公告和之后的应急响应相关措施绝对可以在安全史上排名前五,我个人很自豪当时是这个团队的一员,就连现在,我仍然还会和别人说,MS08-067的漏洞公告是 “我的” 公告。

Ziv: MS08-067漏洞响应处理是我个人经历独特的体验,它是集创新、奉献和协调为一体,并以保护客户免受即将到来的攻击为前提的一次工作经历,我们这些亲身参与其中的人,对在当下危机中扮演的角色有着强烈的自豪感。

好吧,谢谢三位嘉宾的真实分享,也感谢大家的捧场和阅读。希望在信息生态系统面临新威胁时,我们能综合总结到一些非常有用的经验。在下一篇博客中,我们将讨论Conficker蠕虫的爆发,Conficker蠕虫利用了MS08-067漏洞,对当时全球大量组织机构造成了破坏性影响。下次见!

*参考来源:spiderlabs,clouds编译,转载请注明来自FreeBuf.COM