איך להחתים סקריפט של PowerShell (ולהריץ אותו ביעילות)

האם יש לך צורך לוודא שאף אחד לא יבצע שינויים בתסריטים שלך ויעבירם כמקוריים? אם כן, אז עליך ללמוד איך לחתום על תסריטי PowerShell. החתימה מוסיפה את זהות המוציא לאור של התסריט כך שהמשתמשים יכולים להחליט האם לסמוך על מקור התסריט.

במאמר זה, למד כיצד לוודא שרק תסריטים אמינים יורצו בסביבתך על ידי לימוד כיצד לחתום על תסריטי PowerShell.

דרישות מוקדמות

אם אתה מתכוון לעקוב אחר הדוגמאות במאמר זה, עליך להיות ברשותך את הדברים הבאים.

  • A computer running on a recent version of the Windows operating system. This article uses Windows 10 version 20H2.
  • Windows PowerShell 5.1 או PowerShell 6+. הדוגמאות במאמר זה יעשו שימוש ב־PowerShell v7.1.3.
  • A sample PowerShell script for signing. Feel free to create a script with any name and in any folder you want. This article will use a sample script called C:\ATA\myscript.ps1 that contains the code below.
Write-Host "Script Execution - OK"

השגת תעודת חתימת קוד

לפני שתלמד כיצד לחתום על תסריטי PowerShell, עליך להשיג תעודת חתימת קוד תחילה. בעולם של Microsoft, תעודות חתימת קוד ידועות גם בשם תעודות Authenticode.

A code signing certificate is one type of digital certificate whose purpose for signing files. Signing a file or code with a code signing certificate adds proof that the file came from the publisher who signed it.

היכן תשיג תעודת חתימת קוד תלוי איפה אתה מתכוון להפיץ או להפיק את התסריטים שחתמת. וכמו תמיד, המחיר הוא גורם משמעותי גם כן.

  • גלובלי / ציבורי – תצטרך תעודה שמנפיקה שלה הוא רשות אישורים (CA) ברמה גלובלית ומהותה. דוגמאות לרשויות כאלו הן GeoTrust ו־DigiCert. תעודות אלו אינן חינמיות. לדוגמה, תעודת Authenticode של DigiCert תעלה לך 474 דולר לשנה כפי שכתבו.
  • פנימי / רשת מקומית – אם יש לך שרת רשות אישורים (CA) פנימי, אתה יכול לבקש ולהוריד תעודת חתימה מהשרת הפנימי שלך.
  • אישי / פיתוח – למבחן או לשימוש בפיתוח אישי, תעודה בעצמך חתומה יכולה להיות מספקת. סוג זה של תעודת חתימה היא אשר תשתמש בה במאמר זה.

יצירת תעודת חתימה עצמית לחתימת קוד

קראת בחלק הקודם כי בלימוד כיצד לחתום על סקריפט PowerShell, תצטרך תחילה תעודת חתימה לקוד. מכיוון שתערובת במבחן האישי רק לצורך ניסוי אישי, תעודה שנחתמת עצמית יספיק. אבל איפה תקבל אותה?

כפי ששמו מרמז, חתומה עצמית אומרת שהמחשב המקומי שלך יינפק תעודת חתימה לעצמו. כדי ליצור תעודה כזו, עקוב אחר השלבים הבאים.

1. פתח את PowerShell כמנהל על המחשב שלך.

2. העתק את הפקודה למטה והרץ אותה ב-PowerShell. הפקודה משתמשת בפקודת ה-New-SelfSignedCertificate כדי ליצור תעודת חתימה חדשה לקוד. שם התעודה הוא ATA Authenticode בתוך חניית התעודות האישית של המחשב המקומי.

פקודת ה-New-SelfSignedCertificate תומכת רק ביצירת תעודות בחניית התעודות האישית של המשתמש הנוכחי (cert:\CurrentUser\My) או בחניית התעודות האישית של המחשב המקומי (cert:\LocalMachine\My). תעודות ב-cert:\LocalMachine\My זמינות ברחבי המחשב.

הפקודה גם מאחסנת את אובייקט התעודה במשתנה $authenticode לשימוש בשלב הבא.

# יצירת תעודת Authenticode עצמית בחניית התעודות האישית של המחשב המקומי.
 $authenticode = New-SelfSignedCertificate -Subject "ATA Authenticode" -CertStoreLocation Cert:\LocalMachine\My -Type CodeSigningCert

3. לאחר מכן, כדי להוסיף אמון של המחשב בתעודה החדשה שיצרת, הוסף את תעודת החתימה העצמית ל־רשות התעודות האמון המקומית ול־הוצאים לאור האמונות המקומיים. כדי לעשות זאת, העתק את הקוד למטה והרץ אותו ב-PowerShell.

# הוסף את תעודת האימות העצמית של Authenticode לאחסון תעודות השורש של המחשב.
## צור אובייקט שיצג את חניין התעודות LocalMachine\Root.
 $rootStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("Root","LocalMachine")
## פתח את חניין תעודות השורש לקריאה וכתיבה.
 $rootStore.Open("ReadWrite")
## הוסף את התעודה שמאוחסנת במשתנה $authenticode.
 $rootStore.Add($authenticode)
## סגור את חניין תעודות השורש.
 $rootStore.Close()
 
# הוסף את תעודת האימות העצמית של Authenticode לאחסון תעודות המוציאים המהימנים של המחשב.
## צור אובייקט שיצג את חניין התעודות LocalMachine\TrustedPublisher.
 $publisherStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPublisher","LocalMachine")
## פתח את חניין תעודות המוציאים המהימנים לקריאה וכתיבה.
 $publisherStore.Open("ReadWrite")
## הוסף את התעודה שמאוחסנת במשתנה $authenticode.
 $publisherStore.Add($authenticode)
## סגור את חניין תעודות המוציאים המהימנים.
 $publisherStore.Close()

יש שלושה סיבות עיקריות להתקנת התעודות העצמיות בשלושה חנייני תעודות שונים.

  • התעודה שיצרת בחניין התעודות Personal היא התעודה שתשתמש כתעודת חתימת קוד.
  • העתקת התעודה אותה לחניין התעודות Trusted Publishers מבטיחה כי המחשב המקומי שלך יאמין במוציא החותם על התסריט. PowerShell בודק את התעודה בחניין זה כדי לאמת את חתימת התסריט.
  • לבסוף, הוספת התעודה המופעלת עצמאית לתוך ה־רשותי האישור של שורש האימות מבטיחה שהמחשב המקומי שלך יאמין בתעודות באחסון ה־אישי וה־מוֹצְאִי אמון.

4. כדי לאמת שהתעודה עם נושא ATA Authenticode קיימת באחסונות ה־אישי, שורש ו־מוציאי האמון של התעודות במחשב, הריץ את הפקודות הבאות בפוורשל.

# לאמת אם התעודה Authenticode המופעלת עצמאית קיימת באחסון התעודות האישיות של המחשב
 Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# לאמת אם התעודה Authenticode המופעלת עצמאית קיימת באחסון התעודות של שורש המחשב
 Get-ChildItem Cert:\LocalMachine\Root | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# לאמת אם התעודה Authenticode המופעלת עצמאית קיימת באחסון התעודות של מוציאי האמון של המחשב
 Get-ChildItem Cert:\LocalMachine\TrustedPublisher | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
Confirming the creation of the new self-signed certificate

5. כדי להציג את ה־תעודה ב-GUI במקום זאת, פתח את תוסף Snap-in לתעודות וחפש את התעודה שיצרת תחת התיקייה תעודות בתוך האחסונות ה־אישי, רשותי האישור של שורש, ו־מוציאי האמון.

Viewing certificates in the Microsoft Management Console (MMC)

איך לחתום על סקריפטים של PowerShell

עכשיו שיצרת והתקנת את אישור החתימה שלך לקוד בשלושת חנויות התעודות, אתה מוכן להשתמש בו כדי לחתום על סקריפט PowerShell הדוגמא שלך. כאשר נדרש לחתום על סקריפטים, פקודת ה-Set-AuthenticodeSignature היא הכוכב העיקרי.

כדי לחתום על סקריפט ה-PowerShell, הריץ את הקוד למטה ב-PowerShell. הפקודה הראשונה משיגה את תעודת החתימה של הקוד מחנות התעודות האישית של המחשב המקומי. הפקודה השנייה מוסיפה חתימה דיגיטלית לקובץ הסקריפט של PowerShell.

# קבל את תעודת החתימה של הקוד מחנות התעודות של המחשב המקומי בשם *ATA Authenticode* ושמור אותה במשתנה $codeCertificate.
$codeCertificate = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}

# חתום על סקריפט ה-PowerShell
# פרמטרים:
# נתיב קובץ - מציין את נתיב הקובץ של סקריפט ה-PowerShell לחתימה, לדוגמה C:\ATA\myscript.ps1.
# תעודה - מציין את התעודה לשימוש בעת חתימת הסקריפט.
# שרת חותמת זמן - מציין את שרת החותמת המהימנה שמוסיף חותמת זמן לחתימה הדיגיטלית של הסקריפט שלך. הוספת חותמת זמן מבטיחה שהקוד שלך לא יפוג כאשר תעודת החתימה תפוג.
Set-AuthenticodeSignature -FilePath C:\ATA\myscript.ps1 -Certificate $codeCertificate -TimeStampServer *<http://timestamp.digicert.com>*

רוב מפעילי האישורים המהימנים יש שרת חותמת זמן timestamp server וניתן למצוא אותם באתרי האינטרנט של הספקים. לדוגמה, שרת החותמת זמן של DigiCert הוא http://timestamp.digicert.com ולComodo יש http://timestamp.comodoca.com.

לאחר חתימה על הסקריפט, יש לראות פלט דומה לצילום המסך שלהלן.

How to Sign PowerShell Scripts

בדיקת חתימה דיגיטלית של סקריפט PowerShell

עד כה, חתמת על סקריפט PowerShell באמצעות האישור העצמי שיצרת. אבל איך אתה יודע אם הסקריפט באמת כולל חתימה דיגיטלית?

פתיחת הקוד

דרך אחת לאשר את חתימת הסקריפט היא לפתוח את הסקריפט ולצפות בקוד בעורך טקסט. כמו בדוגמה למטה, הסקריפט החתום מכיל בלוק חתימה בסוף הקוד. בלוק החתימה מתחיל ב# SIG # Begin signature block ומסתיים ב# SIG # End signature block.

Viewing the digital signature in the script’s content

מחיקת בלוק החתימה הדיגיטלית מהקוד של הסקריפט תחזיר אותו להיות לא חתום.

פתיחת תכונות הקובץ של הסקריפט

דרך נוספת לבדוק את חתימת הסקריפט היא לפתוח את תכונות הקובץ של הסקריפט ב- Windows Explorer. לשם כך:

  1. בְּעִזְרַת Windows Explorer, נוּוֵט לִמְקוֹם הַתַּסְרֵיט שֶל PowerShell. בַּדְּיֵיקָנוּ, הַתַּסְרֵיט נִמְצָא בְּC:\ATA\myscript.ps1.
  2. לְחַץ יְמִינָה עַל הַתַּסְרֵיט וּלְחַץ עַל מאפיינים.
  3. בְּחַלוֹן הַמְּאֻפְרָטִים שֶל הַקוֹבַץ, לְחַץ עַל כַּרְטִיסַת חתימות דיגיטליות, וְתִרְאֶה חָתִימָה דִיגִיטַלִית תַחַת רשימת החתימות.
Viewing the digital signature in the script’s file properties

בְּאֵמֶר הַפְקִידָה שֶל Get-AuthenticodeSignature

אתָה יכול לפתור שֶׁבְּ PowerShell גַם אפשֶׁר תִּתְאַפֵּשׁ. הַפְּקוּדָה שֶאַתָּה יכול לְהִקְרוֹת כְּדי לְאָחוֹז בְּחַתִּימַת קוֹבֵץ הַיא Get-AuthenticodeSignature.

כְּדי לְקַבֵּל אֶת הַחָתִימָה הַדִיגִיטַלִית שֶל הַתַּסְרֵיט, הַרְץ אֶת הַפְּקוּדָה הַבֵּאָה. הַפְּקוּדָה תְּקַבֵּל אֶת הַחָתִימָה שֶל C:\ATA\myscript.ps1 הַקוֹבֵץ. הַפְּקוּדָה Select-Object -Property * תַּצְג אֶת כָּל פֶּרֶטֵי הַחָתִימָה.

Get-AuthenticodeSignature -FilePath C:\\ATA\\myscript.ps1 | Select-Object -Property *

לְאַחַר בִּצְעוֹ שֶל הַפְּקוּדָה, תִּרְאֶה תוֹצָאָה דוֹמָה לַתְּמוּר שֶבְּמַסְךְ מִתַּחַת. כַּאֲשֶׁר אַתָּה יכול לִרְאוֹת, פְּרוֹפֶרְטִי הַתּוֹעֵד מַצְיִינִים אֶת פְּרוֹטוֹקוֹל הַחֲתִימָה. וְהַנְּכוֹן, הַנִּכְתָּב כַּאֲשֶׁר SignerCertificate מַצְיִין אֶת פְּרוֹטוֹקוֹל הַתּוֹעֵד חוֹתֶמֶת וְTimerStamperCertificate מַצְיִין אֶת הַתּוֹעֵד שֶׁל שֶׁרֵת הַזְּמַן.

Viewing the digital signature in PowerShell

לְהַפְעִיל תַּסְרֵיט PowerShell שֶחוֹתָם

בָּנֶקֶבִּים זֶה, אַתָּה חָתַם תַּסְרֵיט PowerShell וּבִדַּקְתָּ כִּי הַחָתִימָה הַדִיגִיטַלִית נוֹמֵדֶת. אך, הַמַּבְחָן הָאַחֲרוֹן שֶל הַאִם אַתָּה בִּיצַעְתָּ אֶת כָּל הַשְׁלִימוּת הַנְּכוֹנוֹת הוּא לְהַפְעִיל אֶת הַתַּסְרֵיט וּלְאַשְׁרוֹגֵשׁ כִּי הוּא רוֹדֵף.

PowerShell מציע יכולת אבטחה המגן על המשתמשים מהרצת סקריפטים בצורה לא כוונית. היכולת הזו נקראת Execution Policies. בהתאם למדיניות ההרצה, PowerShell יכול למנוע או לאפשר את הרצת הסקריפטים.

כדי להבין את המדיניות השונות להרצת סקריפטים ואיך הן משפיעות על הרצתם, יש להסתכל על PowerShell Execution Policies: Understanding and Managing.

כדי להריץ סקריפט שנחתם ב-PowerShell, יש לבצע את השלבים הבאים.

ראשית, יש לשנות את מדיניות ההרצה ל-AllSigned כדי לוודא שרק סקריפטים שנחתמו יכולים להרוץ. מבלי לבצע את השלב הזה, לא ניתן לבדוק באופן מדויק אם הסקריפט שנחתם עובד. לכך, יש להפעיל את פקודת Set-ExecutionPolicy כמנהל PowerShell ולהריץ את הפקודה למטה.

Set-ExecutionPolicy AllSigned

בשלב הבא, יש להריץ את הסקריפט שנחתם ב-PowerShell.

C:\ATA\myscript.ps1

הסקריפט צריך להתקיים בלעדיו של שגיאות או אזהרות, כפי שניתן לראות בתוצאה למטה.

Running the signed script without errors

אך, אם לאחר מכן הסקריפט לא חתום כראוי או בכלל לא חתום, תקבל שגיאה דומה לתמונה למטה. במקרה כזה, יש לבצע שוב את השלבים ולנסות לחתום מחדש על הסקריפט.

Running a script with errors regarding the digital signature

מה קורה אם בסופו של דבר עדכנת את הסקריפט שלך? האם החתימה הדיגיטלית עדיין תהיה תקפה? התשובה היא לא. כל שינוי בסקריפט שחתום יבטל את חתימתו הדיגיטלית. הרצת הסקריפט ששונה תכשל ותתוצא בשגיאה.

עקוב אחר השלבים האלה כדי לבדוק סקריפט חתום ששונה.

1. פתח את הסקריפט myscript.ps1 שחתום בעורך קוד או טקסט.

2. שנה את הקוד כך שתוסיף תו, כמו קו תחתון בדוגמה זו. אל תשנה דבר אחר.

Editing the signed script

3. שמור את הסקריפט לאחר שינוי הקוד.

4. לבסוף, בצע את הסקריפט ששונה בפוורשל על ידי הרצת הפקודה שלהלן.

C:\ATA\myscript.ps1

מאחר ששינית את הסקריפט החתום, הרצת הסקריפט תוביל להופעת השגיאה המוצגת למטה. יהיה עליך לחתום על הסקריפט מחדש כדי לעדכן ולתקן את החתימה הדיגיטלית שלו.

Running a signed script with a broken digital signature

A digital signature does not guarantee that nobody modified the script from its original version. Any PowerShell script with malicious code may be digitally signed, too. Always practice caution when running scripts from sources you do not fully trust.

מסקנה

במאמר זה, למדת למה חשוב לחתום על סקריפטי PowerShell בהתאם למדיניות הביצוע. גם למדת איך להבדיל בין סקריפט שחתום וסקריפט שלא חתום. לבסוף, למדת איך לחתום על סקריפטי PowerShell באופן דיגיטלי וכיצד לבדוק ולהפעיל אותם.

עכשיו שאתה יודע איך לחתום על סקריפטים של PowerShell, האם תתחיל לחתום על סקריפטים לפני שאתה מפיץ או ממיר אותם?

Source:
https://adamtheautomator.com/how-to-sign-powershell-script/