Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

WLAN ルーター偽装を検出するための取得データを使用した深層ニューラル ネットワークのテスト

この例では、取得データを使用して無線周波数 (RF) 指紋の畳み込みニューラル ネットワーク (CNN) の学習を行う方法を示します。ソフトウェア無線 (SDR) を使用して、実際のルーターから無線ローカル エリア ネットワーク (WLAN) ビーコン フレームを取得します。SDR をもう 1 つプログラムして未知のビーコン フレームを送信し、それらを取得します。それらの取得した信号で CNN の学習を行います。その後、ルーター偽装者として既知のいずれかのルーターのメディア アクセス制御 (MAC) アドレスでビーコン信号を送信するソフトウェア無線 (SDR) をプログラムし、それを CNN を使用して偽装者として識別します。

ルーター偽装およびシミュレーション データを使用したネットワーク設計の検証の詳細については、WLAN ルーター偽装を検出するためのシミュレーション データを使用した深層ニューラル ネットワークの設計の例を参照してください。

取得データを使用した学習

実際の WLAN ルーターから、802.11a/g/n/ac OFDM 非高スループット (非 HT) ビーコン フレームのデータセットを収集します。WLAN ルーター偽装を検出するためのシミュレーション データを使用した深層ニューラル ネットワークの設計の例で説明しているように、データ依存性を回避するため、プリアンブルのレガシ ロング トレーニング フィールド (L-LTF) のみが学習単位として使用されます。

この例では、次の図に示すシナリオを使用してデータが収集されています。オブザーバーは固定された ADALM-PLUTO 無線機です。既知のルーターのデータは次のようにして収集しました。

  1. ルーターで使用される WLAN チャネルに基づいてオブザーバーの中心周波数を設定

  2. ビーコン フレームを受信

  3. L-LTF 信号を抽出

  4. MAC アドレスを復号化してラベルとして使用

  5. L-LTF 信号をそのラベルと共に保存

  6. 手順 2 ~ 5 を繰り返して numKnownRouters のルーターから numFramesPerRouter フレームを収集

未知のルーターのビーコン フレームのシミュレーションでは、移動する ADALM-PLUTO 無線機を送信機として使用しています。この無線機からランダムな MAC アドレスでビーコン フレームを繰り返し送信します。未知のルーターのデータは次のようにして収集しました。

  1. ランダムな MAC アドレスでビーコン フレームを生成

  2. ADALM-PLUTO 無線機を使用したビーコン フレームの繰り返し送信を開始

  3. NUMFRAMES のビーコン フレームを収集

  4. L-LTF 信号を抽出

  5. L-LTF フレームをラベル "Unknown" で保存

  6. 無線機を別の位置に移動

  7. 手順 3 ~ 6 を繰り返して NUMLOC の位置からデータを収集

この既知と未知のルーターを組み合わせたデータセットを使用して、WLAN ルーター偽装を検出するためのシミュレーション データを使用した深層ニューラル ネットワークの設計の例と同じ DL モデルの学習を行います。

この例では、学習データと学習済みネットワークを https://www.mathworks.com/supportfiles/spc/RFFingerprinting/RFFingerprintingCapturedData_R2023a.tar からダウンロードします。インターネット接続がない場合は、インターネットに接続したコンピューターで手動でファイルをダウンロードし、この例のファイルと同じディレクトリに保存してください。プライバシー上の理由から、ダウンロード データ内の MAC アドレスは匿名化されています。この例の結果を再現するには、次の付録の説明に従って独自のデータを取得してください。付録: 既知および未知のルーターのデータの収集

rfFingerprintingDownloadData('captured')
Starting download of data files from:
	https://www.mathworks.com/supportfiles/spc/RFFingerprinting/RFFingerprintingCapturedData_R2023a.tar
Download and extracting files done

この例を迅速に実行するには、ダウンロードした事前学習済みのネットワークを使用します。コンピューターでネットワークに学習させるには、"Train network now" オプションを選択します (つまり、trainNow を true に設定します)。このネットワークの学習にかかる時間は、NVIDIA® GeForce RTX 3080 GPU で約 25 秒、Intel® Xeon W-2133 CPU @ 3.6 GHz で約 2 分です。

trainNow = false;  %#ok<*UNRCH> 

この例では、4 台の既知のルーターのデータを使用します。データセットにはルーターあたり 3600 のフレームが含まれており、その 90% を学習フレームとして使用し、10% をテスト フレームとして使用します。

numKnownRouters = 4;
numFramesPerRouter = 3600;
numTrainingFramesPerRouter = numFramesPerRouter * 0.9;
numTestFramesPerRouter = numFramesPerRouter * 0.1;
frameLength = 160;

既知および未知のルーターのデータの前処理

収集した複素ベースバンド データを同相成分と直交成分に分割し、frameLength x 2 x 1 x numFramesPerRouter*numKnownRouters の行列に形状変更します。未知のルーターのデータについて同じ処理を繰り返します。次のコードでは、前に収集した事前処理済みのデータを使用しています。独自のデータを使用するには、先に次の付録の説明に従ってデータを収集します。付録: 既知および未知のルーターのデータの収集rfFingerprintingCapturedDataUser.mat および rfFingerprintingCapturedUnknownFramesUser.mat という名前の新しいデータ ファイルをこの例と同じディレクトリにコピーします。その後、それらのファイルを読み込むように load コマンドを更新します。

if trainNow
  % Load known router data
  load('rfFingerprintingCapturedData.mat')
  
  % Create label vectors
  yTrain = repelem(MACAddresses, numTrainingFramesPerRouter);
  yTest = repelem(MACAddresses, numTestFramesPerRouter);
  
  % Separate between I and Q
  numTrainingSamples = numTrainingFramesPerRouter*numKnownRouters*frameLength;
  xTrainingFrames = xTrainingFrames(1:numTrainingSamples,1);
  xTrainingFrames = [real(xTrainingFrames), imag(xTrainingFrames)];
  numTestSamples = numTestFramesPerRouter*numKnownRouters*frameLength;
  xTestFrames = xTestFrames(1:numTestSamples,1);
  xTestFrames = [real(xTestFrames), imag(xTestFrames)];
  
  % Reshape dataset into an frameLength x 2 x 1 x numTrainingFramesPerRouter*numKnownRouters matrix
  xTrainingFrames = permute(...
    reshape(xTrainingFrames,[frameLength,numTrainingFramesPerRouter*numKnownRouters, 2, 1]),...
    [1 3 4 2]);
  
  % Reshape dataset into an frameLength x 2 x 1 x numTestFramesPerRouter*numKnownRouters matrix
  xTestFrames = permute(...
    reshape(xTestFrames,[frameLength,numTestFramesPerRouter*numKnownRouters, 2, 1]),...
    [1 3 4 2]);
  
  % Load unknown router data
  load('rfFingerprintingCapturedUnknownFrames.mat')
  
  % Number of training units
  numUnknownFrames = size(unknownFrames, 4);
  
  % Split data into 90% training and 10% test
  numUnknownTrainingFrames = floor(numUnknownFrames*0.9);
  numUnknownTest = numUnknownFrames - numUnknownTrainingFrames;
  
  % Add ADALM-PLUTO data into training and test datasets
  xTrainingFrames(:,:,:,(1:numUnknownTrainingFrames) + numTrainingFramesPerRouter*numKnownRouters) ...
    = unknownFrames(:,:,:, 1:numUnknownTrainingFrames);
  xTestFrames(:,:,:,(1:numUnknownTest) + numTestFramesPerRouter*numKnownRouters) ...
    = unknownFrames(:,:,:, (1:numUnknownTest) + numUnknownTrainingFrames);
  
  % Shuffle data
  vr = randperm(numKnownRouters*numTrainingFramesPerRouter+numUnknownTrainingFrames);
  xTrainingFrames = xTrainingFrames(:,:,:,vr);
  
  % Add "unknown" label and shuffle
  yTrain = [yTrain, repmat("Unknown", [1, numUnknownTrainingFrames])];
  yTrain = categorical(yTrain(vr));
  
  yTest = [yTest, repmat("Unknown", [1, numUnknownTest])];
  yTest = categorical(yTest);
end

CNN の学習

シミュレーション データを使用した学習の例と同じ NN アーキテクチャと学習オプションを使用します。

poolSize = [2 1];
strideSize = [2 1];
% Create network architecture
layers = [
  imageInputLayer([frameLength 2 1], 'Normalization', 'none', 'Name', 'Input Layer')
  
  convolution2dLayer([7 1], 50, 'Padding', [1 0], 'Name', 'CNN1')
  batchNormalizationLayer('Name', 'BN1')
  leakyReluLayer('Name', 'LeakyReLu1')
  maxPooling2dLayer(poolSize, 'Stride', strideSize, 'Name', 'MaxPool1')
  
  convolution2dLayer([7 2], 50, 'Padding', [1 0], 'Name', 'CNN2')
  batchNormalizationLayer('Name', 'BN2')
  leakyReluLayer('Name', 'LeakyReLu2')
  maxPooling2dLayer(poolSize, 'Stride', strideSize, 'Name', 'MaxPool2')
  
  fullyConnectedLayer(256, 'Name', 'FC1')
  leakyReluLayer('Name', 'LeakyReLu3')
  dropoutLayer(0.5, 'Name', 'DropOut1')
  
  fullyConnectedLayer(80, 'Name', 'FC2')
  leakyReluLayer('Name', 'LeakyReLu4')
  dropoutLayer(0.5, 'Name', 'DropOut2')
  
  fullyConnectedLayer(numKnownRouters+1, 'Name', 'FC3')
  softmaxLayer('Name', 'SoftMax')
  classificationLayer('Name', 'Output')
  ];

ミニバッチ サイズが 256 の ADAM オプティマイザーを使用するように学習オプションを構成します。ハイパーパラメーターの最適化が [1] で行われているため、テスト フレームを検証に使用します。

既定では、'ExecutionEnvironment' は 'auto' に設定されており、利用可能な場合は GPU が学習に使用されます。そうでない場合、trainNetwork (Deep Learning Toolbox)では CPU が学習に使用されます。実行環境を明示的に設定するには、ExecutionEnvironment'cpu''gpu''multi-gpu'、または 'parallel' のいずれかに設定します。

if trainNow
  miniBatchSize = 256;
  iterPerEpoch = floor((numTrainingFramesPerRouter*numKnownRouters + numUnknownTrainingFrames)/miniBatchSize);

  options = trainingOptions('adam', ...
    'MaxEpochs', 12, ...
    'ValidationData',{xTestFrames, yTest}, ...
    'ValidationFrequency', iterPerEpoch, ...
    'Verbose',false, ...
    'LearnRateSchedule','piecewise', ...
    'InitialLearnRate', 0.001, ...
    'LearnRateDropFactor', 0.5, ...
    'LearnRateDropPeriod', 2, ...
    'MiniBatchSize', miniBatchSize, ...
    'Plots','training-progress', ...
    'Shuffle', 'every-epoch');
  
  % Train the network
  capturedDataNet = trainNetwork(xTrainingFrames, yTrain, layers, options);
else
  load('rfFingerprintingCapturedDataTrainedNN_R2023a.mat','capturedDataNet','xTestFrames','yTest','MACAddresses')
end

次のプロットは、ネットワークの学習を単一の NVIDIA GeForce RTX 3080 GPU を搭載したコンピューターで実行した場合の進行状況を示したものです。このネットワークは 12 エポックで 100% の正確性に収束しています。

混同行列を生成します。

figure
yTestPred = classify(capturedDataNet,xTestFrames,ExecutionEnvironment='cpu');
cm = confusionchart(yTest, yTestPred);
cm.Title = 'Confusion Matrix for Test Data';
cm.RowSummary = 'row-normalized';

SDR によるテスト

分類 "Unknown" に対する学習済みネットワークの性能をテストします。既知のルーターと 1 台の未知のルーターの MAC アドレスでビーコン フレームを生成します。それらのフレームを ADALM-PLUTO 無線機を使用して送信し、別の ADALM-PLUTO 無線機を使用して受信します。それらの 2 台の無線機の間で作成されるチャネル障害と RF 劣化要因は実際のルーターとオブザーバーの間で作成されるものと異なるため、ニューラル ネットワークではすべての受信信号が "Unknown" と分類されるはずです。受信した MAC アドレスが既知の場合、システムは送信元をルーター偽装者として宣言します。受信した MAC アドレスが未知の場合、システムは送信元を未知のルーターとして宣言します。このテストを実行するには、送信用と受信用に 2 台の ADALM-PLUTO 無線機が必要です。また、Communication Toolbox Support Package for ADALM-PLUTO Radio をインストールする必要があります。

波形生成

異なる MAC アドレスのビーコン フレームで構成される送信波形を生成します。それらの WLAN フレームを送信機から繰り返し送信します。受信機で WLAN フレームを取得し、受信した MAC アドレスと学習済み NN で検出された RF 指紋を使用してルーター偽装者であるかどうかを判別します。

chanBW='CBW20';     % Channel Bandwidth
osf = 2;            % Oversampling Factor
frameLength=160;    % Frame Length in samples
% Create Beacon frame-body configuration object
frameBodyConfig = wlanMACManagementConfig;

% Create Beacon frame configuration object
beaconFrameConfig = wlanMACFrameConfig('FrameType', 'Beacon');
beaconFrameConfig.ManagementConfig = frameBodyConfig;

% Create interpolation and decimation objects
decimator = dsp.FIRDecimator('DecimationFactor',osf);

% Save known MAC addresses
knownMACAddresses = MACAddresses;
MACAddressesToSimulate = [MACAddresses, "ABCDEFABCDEF"];

% Create WLAN waveform with the MAC addresses of known routers and an
% unknown router
txWaveform = zeros(1540,5);
for i = 1:length(MACAddressesToSimulate)
  
  % Set MAC Address
  beaconFrameConfig.Address2 = MACAddressesToSimulate(i);
  
  % Generate Beacon frame bits
  [beacon, mpduLength] = wlanMACFrame(beaconFrameConfig, 'OutputFormat', 'bits');
  
  nonHTcfg = wlanNonHTConfig(...
    'ChannelBandwidth', chanBW,...
    "MCS", 1,...
    "PSDULength", mpduLength);
  txWaveform(:,i) = [wlanWaveformGenerator(beacon, nonHTcfg); zeros(20,1)];
end

txWaveform = txWaveform(:);

% Get center frequency for channel 153 in 5 GHz band
fc = wlanChannelFrequency(153, 5);
fs = wlanSampleRate(nonHTcfg);

txSig  = resample(txWaveform,osf,1);

% Samples per frame in Burst Mode
spf = length(txSig)/length(MACAddressesToSimulate);

runSDRSection = false;
if helperIsPlutoSDRInstalled()  
  radios = findPlutoRadio();
  if length(radios) >= 2
    runSDRSection = true;
  else
    disp("Two ADALM-PLUTO radios are needed. Skipping SDR test.")
  end
else
    disp("Communications Toolbox Support Package for Analog Devices ADALM-PLUTO Radio not found.")
    disp("Click Add-Ons in the Home tab of the MATLAB toolstrip to install the support package.")
    disp("Skipping SDR test.")
end


if runSDRSection
  % Set up PlutoSDR transmitter
  deviceNameSDR = 'Pluto';
  txGain = 0;
  txSDR = sdrtx(deviceNameSDR);
  txSDR.RadioID = 'usb:0';
  txSDR.BasebandSampleRate = fs*osf;
  txSDR.CenterFrequency = fc;
  txSDR.Gain = txGain;
  
  % Set up PlutoSDR Receiver
  rxSDR = sdrrx(deviceNameSDR);
  rxSDR.RadioID = 'usb:1';
  rxSDR.BasebandSampleRate = txSDR.BasebandSampleRate;
  rxSDR.CenterFrequency = txSDR.CenterFrequency;
  rxSDR.GainSource ='Manual';
  rxSDR.Gain = 30;
  rxSDR.OutputDataType = 'double';
  rxSDR.EnableBurstMode=true;
  rxSDR.NumFramesInBurst = 20;
  rxSDR.SamplesPerFrame = osf*spf;
end

分類用の L-LTF

各ビーコン フレームのプリアンブルにある L-LTF シーケンスを NN への入力単位として使用します。rfFingerprintingNonHTFrontEnd System object™ を使用して、WLAN パケットの検出、同期タスクの実行、および L-LTF シーケンスとデータの抽出が行われます。また、MAC アドレスの復号化も行われます。さらに、データが前処理され、学習済みネットワークを使用して分類されます。

if runSDRSection
  numLLTF = 20;       % Number of L-LTF captured for Testing
  
  rxFrontEnd = rfFingerprintingNonHTFrontEnd('ChannelBandwidth', 'CBW20');
  
  disp("The known MAC addresses are:");
  disp(knownMACAddresses)
  
  % Set PlutoSDR to transmit repeatedly
  disp('Starting transmitter')
  transmitRepeat(txSDR, txSig);
  
  % Captured Frames counter
  numCapturedFrames = 0;
  
  disp('Starting receiver')
  % Loop until numLLTF frames are collected
  while numCapturedFrames < numLLTF
    
    % Receive data using PlutoSDR
    rxSig = rxSDR();

    rxSig = decimator(rxSig);
    
    % Perform front-end processing and payload buffering
    [payloadFull, cfgNonHT, rxNonHTData, chanEst, noiseVar, LLTF] = ...
      rxFrontEnd(rxSig);
    
    if payloadFull
      
      % Recover payload bits
      recBits = wlanNonHTDataRecover(rxNonHTData, chanEst, ...
        noiseVar, cfgNonHT, 'EqualizationMethod', 'ZF');
      
      % Decode and evaluate recovered bits
      [mpduCfg, ~, success] = wlanMPDUDecode(recBits, cfgNonHT);
      
      if success == wlanMACDecodeStatus.Success
        % Update counter
        numCapturedFrames = numCapturedFrames+1;
        
        % Create real-valued input
        LLTF = [real(LLTF), imag(LLTF)];
        LLTF = permute(reshape(LLTF,frameLength ,[] , 2, 1), [1 3 4 2]);
        
        ypred = classify(capturedDataNet, LLTF);
        
        if sum(contains(knownMACAddresses, mpduCfg.Address2)) ~= 0
          if categorical(convertCharsToStrings(mpduCfg.Address2))~=ypred
            disp(strcat("MAC Address ", mpduCfg.Address2," is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED"))
          else
            disp(strcat("MAC Address ", mpduCfg.Address2," is known, fingerprint match"))
          end
        else
          disp(strcat("MAC Address ", mpduCfg.Address2," is not recognized, unknown device"));
        end
      end
    end
  end
  release(txSDR)
end
The known MAC addresses are:
    "71B63A2D0B83"    "A3F8AC0F2253"    "EF11D125044A"    "F636A97E07E7"
Starting transmitter
## Establishing connection to hardware. This process can take several seconds.
## Waveform transmission has started successfully and will repeat indefinitely. 
## Call the release method to stop the transmission.
Starting receiver
## Establishing connection to hardware. This process can take several seconds.
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address 71B63A2D0B83 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address EF11D125044A is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address ABCDEFABCDEF is not recognized, unknown device
MAC Address A3F8AC0F2253 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED
MAC Address F636A97E07E7 is known, fingerprint mismatch, ROUTER IMPERSONATOR DETECTED

その他の調査

次の付録の説明に従って独自のルーターからデータを取得します。付録: 既知および未知のルーターのデータの収集。そのデータでニューラル ネットワークの学習を行い、ネットワークの性能をテストします。

付録: 補助関数

付録: 既知および未知のルーターのデータの収集

既知の (信頼済み) ルーターのデータの収集には rfFingerprintingRouterDataCollection を使用します。この関数は、商用の 802.11 ハードウェアから送信された 802.11a/g/n/ac OFDM 非 HT ビーコン フレームから L-LTF 信号を抽出します。詳細については、の例を参照してください。L-LTF 信号と対応するルーターの MAC アドレスを使用して、RF 指紋のニューラル ネットワークの学習を行います。この方法は、ルーターとそのアンテナが固定されていて、意図せずに動くことはほとんどない場合に特に効果的です。たとえば、ほとんどのオフィス環境では、ルーターは天井に取り付けられています。次の手順に従います。

  1. ADALM-PLUTO 無線機をオブザーバー無線機として使用する PC に接続します。

  2. その無線機をできるだけ多くのルーターから信号を受信できる中央の位置に設置します。無線機が動かないように固定します。オブザーバー無線機は、可能であれば天井または壁面の高い位置に設置してください。

  3. ルーターのチャネル番号を確認します。チャネル番号は、電話機で Wi-Fi® アナライザー アプリを使用して確認できます。

  4. "rfFingerprintingRouterDataCollection(channel)" を実行してデータ収集を開始します。channel は Wi-Fi のチャネル番号です。

  5. "max(abs(LLTF))" の値を監視します。1.2 よりも大きいか 0.01 よりも小さい場合は、関数 rfFingerprintingRouterDataCollection の GAIN の入力を使用して受信機のゲインを調整します。

未知のルーターのデータの収集には補助関数 rfFingerprintingUnknownClassDataCollectionTx および rfFingerprintingUnknownClassDataCollectionRx を使用します。これらの関数は、L-LTF 信号を送受信する 2 台の ADALM-PLUTO 無線機を設定します。受信した信号と既知のルーターの信号の組み合わせでニューラル ネットワークの学習が行われます。2 台の ADALM-PLUTO 無線機が必要であり、2 台の別々の PC に接続することが推奨されます。次の手順に従います。

  1. ADALM-PLUTO 無線機を未知のルーターとして動作する固定の PC に接続します。

  2. "rfFingerprintingUnknownClassDataCollectionTx" を実行して送信を開始します。

  3. もう 1 台の ADALM-PLUTO 無線機をオブザーバーとして機能するモバイル PC に接続します。

  4. "rfFingerprintingUnknownClassDataCollectionRx" を実行してデータ収集を開始します。この関数は、既定では各位置で 200 フレームずつ収集します。各位置が別々の未知のルーターを表します。

  5. 新しい位置に移動するように関数から指示されたら、オブザーバー無線機を新しい位置に移動します。既定では、この関数は 10 か所からデータを収集します。

  6. オブザーバーがビーコンをまったく受信しないかほとんど受信しない場合、オブザーバーを送信機の近くに移動します。

  7. データ収集が完了したら、送信元無線機の MATLAB® セッションで "release(sdrTransmitter)" を呼び出します。

参考文献

[1] K. Sankhe, M. Belgiovine, F. Zhou, S. Riyaz, S. Ioannidis and K. Chowdhury, "ORACLE: Optimized Radio clAssification through Convolutional neuraL nEtworks," IEEE INFOCOM 2019 - IEEE Conference on Computer Communications, Paris, France, 2019, pp. 370-378.

関連するトピック