Security」カテゴリーアーカイブ

Let’s Encrypt の証明書をブラウザ上で簡単取得

参照サイト

証明書の確認 cat cert.pem |openssl x509 -text -noout

実際に取得するサイト

 Let’s Encrypt へ登録

Emailを入力して、署名鍵を取得

2. チャレンジトークンの取得

3. ドメイン名の所有確認

4. 証明書発行申請

5. 発行された証明書

cert.pem (サーバ証明書)、chain.pem (中間証明書)、fullchain.pem (サーバ証明書 + 中間証明書)と、STEP4で取得した秘密鍵をサーバーへ設置する

/etc/letsencrypt/archive/live/b17.ddns.net/

インストールの確認

$cat cert.pem |openssl x509 -text -noout

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:85:92:51:53:66:49:fe:d6:7a:17:6a:1a:9f:aa:ab:c2:4c
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Let's Encrypt, CN = R11
        Validity
            Not Before: Jan  8 00:12:59 2025 GMT
            Not After : Apr  8 00:12:58 2025 GMT
        Subject: CN = rfsec.ddns.net

Microsoft Defender for Businessを試してみる

インプレスの記事

中小規模向けEDR「Microsoft Defender for Business」って何? 体験版でチェック!

準備 次のリンクから、Microsoft 365 Business Premiumの1ケ月のお試しを申し込む(クレジットカードの登録が必要)

https://www.microsoft.com/ja-jp/microsoft-365/business/microsoft-365-business-premium?SilentAuth=1&activetab=pivot%3aoverviewtab

申し込みが完了すると、アカウントを取得すると次のような機能へログインが可能となる。以下のそれぞれのリンクから、設定や機能の紹介ページを参照できるが、英文のままだったり、機械翻訳の日本語だったりするが、めげずに進む必要がある。

また、25人までの利用者アカウントを作成できる。利用者アカウントの作成は次のリンから https://portal.azure.com/

Microsoft 365 管理センター https://admin.microsoft.com/

また、マイクロソフトオフィス製品のインストール等は、次のリンクからhttps://portal.office.com/

Microsoft Defender for Businessは、次のリンクから
https://security.microsoft.com/

Teamsの設定等は、次のリンクから
https://teams.microsoft.com/

Microsoft Defender for Businessのセットアップ

Microsoft Defender for Businessでは Windows HOMEは対象外なので、注意が必要。

https://docs.microsoft.com/en-us/microsoft-365/security/defender-business/mdb-setup-configuration?view=o365-worldwide

セットアップのSTEP

ガイド付きのセットアップ手順:https://admin.microsoft.com/#/m365setupwizard

別途料金が発生するオプション Microsoft Defender for Office 365 (プラン 1)

1台あたり220円/月

“安全なリンク” や “安全な添付ファイル” などの最新の電子メール保護技術です。Exchange Online Protection の防御を補完して、高度な攻撃からメールボックスを保護

Seleniumでスクレイピングの準備

$sudo apt-get update
$sudo apt install chromium-chromedriver
$sddo cp /usr/lib/chromium-browser/chromedriver /usr/bin
$pip install selenium
$pip install webdriver_manager

紛らわしい点:webdriver_managerとwebdrivermanagerの両方が存在し、機能が同じではない。webdriver_managerの方が良さそう。

Webサイトのタイトルを取得してみる。

from selenium import webdriver
import time

#---------------------------------------------------------------------------------------
# 処理開始
#---------------------------------------------------------------------------------------
# ブラウザをheadlessモード実行
print("\nブラウザを設定")
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',options=options)
driver.implicitly_wait(10)

# サイトにアクセス
print("サイトにアクセス開始")
URL="https://rfsec.ddns.net/db/"
driver.get(URL)
time.sleep(3)
# driver.find_elements_by_css_selector("xxx") 的な処理を自由に
print("サイトのタイトル:", driver.title)

認証があるサイトの場合(中華製ネットワークカメラ)

import time
import base64
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

def get_auth_header(user, password):
    b64 = "Basic " + base64.b64encode('{}:{}'.format(user, password).encode('utf-8')).decode('utf-8')
    return {"Authorization": b64}

# Webdriver ManagerでChromeDriverを取得
driver = webdriver.Chrome(executable_path=ChromeDriverManager().install())

# Authorizationヘッダを付与
driver.execute_cdp_cmd("Network.enable", {})
driver.execute_cdp_cmd("Network.setExtraHTTPHeaders", {"headers": get_auth_header("admin", "")})
# Basic認証が必要なページにアクセス
driver.get('http://192.168.68.128')
time.sleep(5)

driver.close()
driver.quit()

数独の問題サイトから問題を取得して、解く。

#  ここからがseleniumのコード
#  問題サイト http://numberplace.net/
#
from selenium import webdriver
import time
import numpy as np

def disp(results):
    msg=""
    for r in results:
        for y in range(9):
            for x in range(9):
                c = r._values[y][x]
                c = str(c)
                d = row2[y][x]
                if d != 0:
                    msg=msg+'('+ c + ') '
                else:
                    msg=msg+'-'+ c + '- ' 
            msg=msg+"\n"
    print(msg)

#---------------------------------------------------------------------------------------
# 処理開始
#---------------------------------------------------------------------------------------
# ブラウザをheadlessモード実行
print("\nブラウザを設定")
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',options=options)
driver.implicitly_wait(2)

# サイトにアクセス
for num in range(5):
    URL="http://numberplace.net/?no="+str(num+1)
    print("サイトにアクセス開始:",URL)
    driver.get(URL)
    time.sleep(2)
    lines= driver.page_source.splitlines()
    for line in lines:
        if 'toi' in line:
            q = line.split(' ')[3].replace("'","").replace(";","")
            q=list(q)
            #print(q)
            qi = [int(s) for s in q]
            #print(qi)
            q2 = np.array(qi)
            row2=np.array(q2).reshape(-1,9).tolist()
            grid = solver.Grid(row2)
            print(grid)
            results = solver.solve_all(grid)
            disp(results)
            break
print('Done.')

PythonからSSLでメールを送信

STARTTLSを使わない場合

import smtplib, ssl

#送信に利用するメールサーバの設定(プロバイダーのメールアカウント、SMTPサーバー)
username= "aaa@bbb.ccc.ddd"
password=  "xxxxx"
mail_server="smtp.eeee.ffff" # SMTP Server
port=465

#偽装送信元 
fake_from= "donaldtrump@gmail.com"
fake_name= "Donald Trump"

#メールの宛先
to_email= 'hoge@hoge.hoge'
to_name= 'hoge@hoge.hoge'

subject= "Bonjour"
content= "This is the fbi. OPEN UP"
message= f"From: {fake_name} <{fake_from}>\nTo: {to_name} <{to_email}>\nSubject: {subject}\n\n{content}"
server = smtplib.SMTP_SSL(mail_server,port, context=ssl.create_default_context())
server.login(username, password)
server.sendmail(username, to_email, message.encode())
server.close()

MIME機能を付加して、日本語・HTMLのメールを送信

通信のデバッグ情報を表示するには server.set_debuglevel(True) を挿入

import smtplib,ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
smtp_host = 'mail.xxx.xxx' #Mailサーバを指定
smtp_port = 465
smtp_account_id = 'hogehoge' #ユーザー名を指定
smtp_account_pass = 'xxxxxxx' #パスワードを入力
from_mail = "hoge <hoge@xxxx.xxx.xx>"  # 送信元メールアドレス
to_mail = "HOGE <HOGE@xxxx.xxx>"  # 送信先メールアドレス
msg = MIMEMultipart('alternative')
msg['Subject'] = "タイトル" #件名を入力
msg['From'] = from_mail
msg['To'] = to_mail
text = "送信テストです。.nマルチパートで送っています。.nどうですか?"
html = """
<html>
  <head></head>
  <body>
    <p style='font-size:16.0pt;font-family:游ゴシック'>送信テストです。</p>
    <p>マルチパートで送っています。</p>
    <p>どうですか?</p>
  </body>
</html>
"""

part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
msg.attach(part1)
msg.attach(part2)

server = smtplib.SMTP_SSL(smtp_host, smtp_port, context=ssl.create_default_context())
#server.set_debuglevel(True)
server.login(smtp_account_id, smtp_account_pass)
server.sendmail(from_mail, to_mail, msg.as_string())
server.quit()
print('Done.')

無線でAirGapを超える

無線でAirGapを超える実験(その1 Raspberry Pi)

イスラエスのベン・グリオン大学の研究チームが様々な手段でAirGapを超える実験を発表していて、これまでに、電波、音波、熱などの例が紹介されています。
かねてから、ネタの一つとして無線で実験してみたいと思っていたのですが、最近になってようやく実験を開始しました。

最初は、GPIOを備え、敷居が低そうなRaspberry Piで実験を試みました。RaspberrPiでは、FM変調で音楽などを流す試みが発表されています。手始めに、これを実験してみましたが、githubからダウンロードして、簡単に再現することができました。このソフトはあらかじめ用意したwavファイルの音楽を流したり、マイクロフォンやLINE入力からのオーディオ信号をFM変調で送信できるようになっています。調べてみると、RaspberryPiには3個のGPCLKポートが備わっていて、このポートから、内蔵のクロックを基にしてプログラマブルに周波数を設定可能なハードウェアとなっています。

GPCLK General Purpose CLock https://pinout.xyz/pinout/gpclk

GPIO端子に出力される信号は、基本的には矩形波なので、RF信号の振幅が変化するような変調は、外部のハードウェアなしには実装できません。FM電波とした理由も、そこにあるものと思われます。プログラマブルにクロックを設定できる仕組みを利用し、GPCLK端子へ出力する周波数をうまく制御してFM変調を実現しているようです。クロック生成の詳細は、この記事などが参考になります

RaspberryPiのFM送信機のソフトを利用してデジタルデータを送信するには、データからQPSKなどの信号を音声データとして生成し、wavファイルに落として変調用のファイルとすれば、比較的簡単に実現できそうな気がします(APSK変調)。もっと安直な方法として、GPCLK端子から、あるの周波数の信号を断続して出力すれば、搬送波の断続による原始的なCW変調が実現できそうなので、こちらの方式で実験をしてみました。クロックの生成で、参考にた記事は、こちらの Miscellaneous related code セクションにあるMinimal Clock Accessのコードです。

クロックの制御部分だけをC言語で記述し、残りの部分は、これまた安直にPHPで記述しています。

無線でAirGapを超える

(その2 Windows10 RS-232CポートのON/OFF)

PCには、Raspberry Piと違ってGPIOのような物理的にアクセス可能なデバイスは用意されていない。そこで、最近のPCの標準装備からはほとんど姿を消したものの、RS232C(特に法人向けのPCには、数年前まで、標準装備されていたように記憶していますが、、、?)ポートには、ハードウェアによるフロー制御に利用可能なRTS端子があることを思い出した。

この端子を、高速でON/OFFすることで、電波として放射できないか、実験をしてみた。RTS端子をオシロで観測した様子。46KHz程度で、周期がかなり変動している。

動画の左側は、Raspberry Pi3のGPIO端子をソフトウエアでOn/Offした時のスペクトラム波形。右側がPCのRS-232C端子をOn/Offした際の、スペクトラム波形。WindowsではOn/Off周期の変動が大きく、スペクトラムが大きく広がっている。

プログラム例


#include <windows.h>
#include<stdio.h>
int main()
{
  HANDLE hComm;
  int Status;
  int n;
  unsigned clockDivisor = 0;
  hComm = CreateFile("COM1",                //port name
                      GENERIC_READ | GENERIC_WRITE, //Read/Write
                      0,                            // No Sharing
                      NULL,                         // No Security
                      OPEN_EXISTING,// Open existing port only
                      0,            // Non Overlapped I/O
                      NULL);        // Null for Comm Devices
  if (hComm == INVALID_HANDLE_VALUE)
      printf("Error in opening serial port");
  else {
      printf("opening serial port successful");
      for(n=0;n<100000;n++){                         // ここのループでRF信号を放射
     	Status = EscapeCommFunction(hComm, SETRTS);  // RTS ON
      	Status = EscapeCommFunction(hComm, CLRRTS);  // RTS OFF
      }
      printf("Done...\n");
      uSleep(5000000);
      }
  CloseHandle(hComm);//Closing the Serial Port
  return 0;
}

LANのパケット監視

WannaCryは、LANの中ではsmb(445/TCP)で感染するということなので、簡易な監視のツールを作ってみました。
ミラーしたセグメントのパケットをtcpdumpでキャプチャし、PHPのスクリプトで観測したパケットの数を可視化します。
使い方は、次のような感じ、、、

#tcpdump -ntttti eth0 port 445 | visualize.php

visualize.php は、定期的にhtmlファイルを生成ます
利用者はブラウザでhtmlファイルを閲覧します。
htmlファイルは (例えば10秒毎に)自身をrefreshします。

表示される、画像の1マスは、ノード(PCやサーバ)間のパケット数を色で表現しています。
通信がまったく観測されない場合は濃い青色で観測されたパケット数が多いと黄色~赤に変化します。
また、マスの中の1文字は、観測したパケットの数に応じて、0-9,A-Z…..と表示しています。

#!/usr/bin/php
<?php
/*
        Usage:
        tcpdump -nttttr xxxxx.pcap port 445 | ./p445.php
*/

$MIN_TH = 5;
$fp=fopen("php://stdin","r");
for($i=1;$i<255;$i++){
        for($j=1;$j<255;$j++){
                $buf[$i][$j]=0;
        }
}
$n=0;$prev_min=0;
while($in=fgets($fp)){
        $t=explode(" ",$in);
        $date=$t[0]." ".$t[1];
        $tmp =explode(":",$t[1]);       // hh:mm:ss.xxxxx
        $min =$tmp[1];                  // min
        if(isset($t[3])){
                $s=explode(".",$t[3]);
                if(isset($s[3])) {
                        $ip1=$s[3];
                        $d=explode(".",$t[5]);
                        $ip2=$d[3];
//                      echo "$ip1,$ip2\n";
                        $buf[$ip1][$ip2]++;
                }
        }

        $n++;
        if(($n % 2000)==0 || ($min - $prev_min) > $MIN_TH) {
                MkHTML($buf,$date);
                $prev_min = $min;
        }
}

fclose($fp);
MkHTML($buf,$date);
echo "Finished!!!\n";


function MkHTML($buf,$date){

        $date="<H3>$date</H3>";
        $header="<!DOCTYPE HTML><HTML><HEAD><meta http-equiv=\"refresh\" content=\"10\"></HEAD><BODY>";
        $msg="<H3>$date</H3>\n<TABLE>\n";
        for($i=1;$i<255;$i++){
                $sum=0;
                for($j=1;$j<255;$j++){
                        $sum+=$buf[$j][$i];
                }
                $iSum[$i]=$sum;
//              echo "$i,$iSum[$i]\n";
        }

        for($i=1;$i<255;$i++){
                $tmp="<TR><TD>$i</TD>";$sum=0;
                for($j=1;$j<255;$j++){
                        $var=$buf[$i][$j];
                        $pt=".";
                        if($var<63) {
                                if($var<10) {
                                        $pt=$var;
                                } else {
                                        $pt=chr(ord('A')+$var-10);
                                }
                        }
                        $sum+=$var;
                        $var=20*log($var+1);
                        $color=set_color($var);
                        if($iSum[$j]!=0) $tmp.= "<TD BGCOLOR=$color>10.8.0.$j\">$pt</TD>";

                }
                if($sum !=0 ) {
                        $msg.=$tmp;
                        $msg.="</TR>\n";
                }
        }

        $msg.="</TABLE>\n<H3>$date</H3></BODY></HTML>\n";
        $fw=fopen("/var/www/html/cross.html","w");
        fputs($fw,$header);
        fputs($fw,$msg);
        fclose($fw);
}


function set_color($x){
   if ($x<64) {
       $r=0; $g= $x*4 ; $b=255;
   } else {
       if ($x<128){
           $r=4*( $x -64 );$g=255;$b=255-$r;
       } else {
           if ($x<192){
               $b=4*( $x - 128 );$r=255;$g=255-$b;
           } else {
               $r=255;$g=0;$b=255-4*( $x -192);
           }
       }
   }
   return "#".sprintf("%02x%02x%02x",$r,$g,$b);
}
?>