Help us understand the problem. What is going on with this article?

マルウェア自衛のためのちょっとしたスクリプト

皆様、在宅ワーク万歳な日々を過ごしでしょうか?
先週は久々に現場に駆り出されましたが、
電車内はコロナ禍なんて嘘のような様子でした

コロナとは…:thinking:

セキュリティ需要の高まり

それはさておき、在宅の増えた昨今では端末のセキュリティについて
考えることも増えたのではないかと思います。

最近だとEMOTETなどのようなマルウェアなどのニュースを見聞きして
怖いなと警戒心が一時的に高まったりすることもあるかとおもいます。

でも日時が立つとそんな警戒心なども薄れて、変なサイトにアクセスしてしまったり、
行きつけのサイトに変なものを埋め込まれたりする可能性も
無きにしも非ずです。

そんなマルウェアが私たちの端末で悪さをするには
自動起動登録する必要があります。
なので、日々自動起動されるプログラムを確認することで、
うちに忍び込む不審な輩に気づくきっかけになったら…!

bouhan_camera_dorobou[1].png

というわけで「autorunsc.exe」という便利なツールを使用して、
自動起動プログラムの際をログ収集するスクリプトを書いてみました。

import部分

import subprocess
import zipfile
import os
import sys
import urllib.request as req
import pandas as pd
from glob import glob
from plyer import notification
from alittleuseful import loglotate

# pip install pandas
# pip install plyer
# pip install git+https://github.com/ardnico/main

alittleusefulは私が個人的にgithubで公開してる、
ログを書き込むライブラリです
他にも変な機能を公開していますが、よければ使ってくれたら
嬉しいかなって。。。

命名定義

csv_file = f'{os.getcwd()}\\out.csv'
rcsv_file = f'{os.getcwd()}\\out_old.csv'
enc = "utf-16"
URL = "https://download.sysinternals.com/files/Autoruns.zip"
zip_file = "A.zip"
path='.'
logger = loglotate(
    logname = "StartUpSec",
    outputdir = [os.getcwd()],
    lsize = 100000,
    num = 20,
    timestanp = 1 # 1:on other:off
)

静的命名や関数の呼び出し部分です

関数:autorunsc.exeのダウンロード

def download_tool(tf:bool):
    # file download
    if tf == False:
        logger.write('[INFO]Because the tool has not existed, the one will download')
        req.urlretrieve(URL,zip_file)
        with zipfile.ZipFile(zip_file, 'r') as z_file:
            try:
                z_file.extractall(path=path)
                logger.write("[SUCCESS]Tool download succeeded")
            except Exception as e:
                logger.write('[ERROR]Failed to download or unzip autorunsc.exe')
                logger.write(f'[ERROR]{e}')
                sys.exit(0)

「autorunsc.exe」が存在しなかった場合、requestを使用して
ツールをダウンロードします。
ダウンロードがZIP解凍まで行います。

関数:「autorunsc.exe」の実行から自動起動プログラムの比較まで

def get_log():
    if os.path.exists(rcsv_file) == True:
        try:
            os.remove(rcsv_file)
        except Exception as e:
            logger.write('[ERROR]Failed to remove oldcsvfile')
            logger.write(f'[ERROR]{e}')
            sys.exit(0)
    if os.path.exists(csv_file) == True:
        try:
            os.rename(csv_file,rcsv_file)
            df_old = pd.read_csv(rcsv_file,encoding=enc)
        except Exception as e:
            logger.write('[ERROR]Failed to rename oldcsvfile')
            logger.write(f'[ERROR]{e}')
            sys.exit(0)
    else:
        df_old = ''
    with open(csv_file, mode='w', encoding=enc) as fp:
        cp = subprocess.run([f'{os.getcwd()}\\autorunsc.exe','-nobanner','-c','-a','*'], encoding=enc, stdout=fp)
    try:
        if df_old == '':
            flag = 0
        else:
            flag = 2
    except:
        if len(df_old.index) <= 0:
            flag = 0
        else:
            flag = 1
    if flag==0 or flag==2:
        logger.write("[INFO]StartUp Program's log has created")
    else:
        with open(csv_file,encoding=enc) as f:
            data = f.read().split('\n')
        with open(rcsv_file,encoding=enc) as f:
            data2 = f.read().split('\n')
        l_diff = list(set(data)^set(data2))
        if len(l_diff) > 0:
            logger.write("[DIFF INFO]The difference of the startup program has existed")
            for i in l_diff:
                logger.write(f"[DIFF]{i}")
                notification.notify(
                    title='The difference of startup program has existed',
                    message=i,
                    app_name='Diff notify'
                )
        else:
            logger.write("[INFO]The difference did not exsist")

CSVファイルの扱いで少々長くなってしまいましたが、
動きとしては以下の通りです。

  1. CSVファイルをローテーション
  2. 最新のCSVと一世代前のCSVファイルの内容を比較
  3. 差異が存在する場合ログに書き込み+ポップ通知

実行部分

if __name__ == "__main__":
    os.chdir(r"C:\python\notebooks\StartUpProgramSec")
    tooltf = os.path.exists(f"{os.getcwd()}\\autorunsc.exe")
    download_tool(tooltf)
    get_log()
    logger.write("[INFO]The process completed")

以上です。

ちょっとでも在宅ワークを安全なものにして、
普及されることを祈って…
tomneko1215B1328_TP_V.jpg

nico4316
勉強中です
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away