كتاب "باش والأمن السيبراني: الهجوم والدفاع والتحليل من سطر أوامر لينكس"

صورةمرحبا ، هابروجيتلي! يمكن أن يكون سطر الأوامر أداة مثالية للأمن السيبراني. مرونة مذهلة وتوافر مطلق يحولان واجهة سطر الأوامر القياسية (CLI) إلى حل أساسي إذا كانت لديك الخبرة المناسبة.

يتحدث المؤلفان بول ترونكون وكارل ألبينغ عن أدوات وحيل سطر الأوامر التي تساعد على جمع البيانات مع حماية استباقية ، وتحليل السجلات ومراقبة حالة الشبكة. سوف يتعلم Pentesters كيفية تنفيذ الهجمات باستخدام وظائف هائلة مدمجة تقريبًا في أي إصدار من Linux.


لمن هذا الكتاب؟


كتاب "باش والأمن السيبراني" مخصص لأولئك الذين يرغبون في تعلم كيفية العمل مع سطر الأوامر في سياق أمن الكمبيوتر. لا يتمثل هدفنا في استبدال الأدوات الموجودة بنصوص سطر الأوامر ، بل لتعليمك كيفية استخدام سطر الأوامر بشكل فعال لتحسين الوظائف الحالية.

طوال الكتاب ، نقدم أمثلة على طرق الأمان مثل جمع البيانات وتحليلها واختبار الاختراق. الغرض من هذه الأمثلة هو إظهار إمكانيات سطر الأوامر وتعريفك ببعض الطرق الأساسية المستخدمة في الأدوات عالية المستوى.

هذا الكتاب ليس مقدمة للبرمجة ، على الرغم من أن بعض المفاهيم العامة التي يغطيها الجزء الأول.

مراقبة السجل في الوقت الحقيقي


تعد القدرة على تحليل مجلة بعد وقوع حدث مهارة مهمة. ولكن من المهم بنفس القدر أن تكون قادرًا على استخراج المعلومات من ملف السجل في الوقت الفعلي من أجل اكتشاف الإجراءات الخبيثة أو المشبوهة في وقت حدوثها. في هذا الفصل ، سننظر في طرق قراءة إدخالات دفتر اليومية أثناء إنشائها وتنسيقها لعرض التحليلات وإنشاء تنبيهات بناءً على مؤشرات التهديد المعروفة لتشغيل النظام أو الشبكة (مؤشرات الاختراق).

مراقبة سجل النص


إن أسهل طريقة لمراقبة تسجيل الدخول في الوقت الحقيقي هي استخدام الأمر tail مع المعلمة –f - فهو يقرأ الملف باستمرار ويعرضه في وضع ثابت عند إضافة خطوط جديدة. كما هو الحال في الفصول السابقة ، على سبيل المثال ، سنستخدم سجل الوصول إلى خادم الويب Apache ، ولكن الطرق الموضحة ذات صلة بأي سجل نصي. لتتبع سجل الوصول إلى Apache باستخدام الأمر tail ، أدخل ما يلي:

tail -f /var/logs/apache2/access.log

يمكن تمرير الإخراج من الأمر tail إلى الأمر grep ، لذلك سيتم عرض السجلات المطابقة لمعايير معينة فقط. يتتبع المثال التالي سجل الوصول إلى Apache ويعرض الإدخالات المقابلة لعنوان IP معين:

tail -f /var/logs/apache2/access.log | grep '10.0.0.152'

يمكنك أيضًا استخدام التعبيرات العادية. في هذا المثال ، سيتم عرض السجلات التي تعرض رمز حالة HTTP 404 "لم يتم العثور على الصفحة" ؛ تمت إضافة الخيار -i لتجاهل حالة الأحرف:

tail -f /var/logs/apache2/access.log | egrep -i 'HTTP/.*" 404'

للمسح من معلومات غريبة ، يجب تمرير الإخراج إلى الأمر cut. يراقب هذا المثال سجل الوصول للاستعلامات التي تؤدي إلى رمز الحالة 404 ، ثم يستخدم طريقة القطع لعرض التاريخ / الوقت والصفحة المطلوبة فقط: بعد ذلك ، لإزالة الأقواس المربعة وعلامات الاقتباس المزدوجة ، يمكنك توجيه الإخراج إلى tr -d ' [] "".

$ tail -f access.log | egrep --line-buffered 'HTTP/.*" 404' | cut -d' ' -f4-7
[29/Jul/2018:13:10:05 -0400] "GET /test
[29/Jul/2018:13:16:17 -0400] "GET /test.txt
[29/Jul/2018:13:17:37 -0400] "GET /favicon.ico




ملاحظة: يُستخدم خيار --line-buffering للأمر egrep هنا. هذا يجبر egrep على الطباعة إلى stdout في كل مرة يحدث فيها انقطاع للخط. بدون هذه المعلمة ، سيحدث التخزين المؤقت ولن يتم إرسال الإخراج إلى الأمر cut حتى تمتلئ المخزن المؤقت. لا نريد الانتظار طويلا. يسمح هذا الخيار للأمر egrep بكتابة كل سطر كما هو موجود.

أوامر سطر

الأوامر ماذا يحدث أثناء التخزين المؤقت؟ تخيل egrep العثور على الكثير من السلاسل المطابقة للنمط المحدد. في هذه الحالة، egrep سيكون لها الكثير من المخرجات. لكن الناتج (في الواقع ، أي إدخال أو إخراج) أغلى بكثير (يستغرق وقتًا أطول) من معالجة البيانات (البحث النصي). وبالتالي ، كلما قل عدد مكالمات الإدخال / الإخراج ، زاد كفاءة البرنامج.

grep , , . . grep . , grep 50 . , 50 , , . 50 !

egrep, , . egrep , , . , , , , . , .

, , tail -f ( ), . , « », . . .

, egrep , . , .


يمكنك استخدام أوامر الذيل و egrep لمراقبة السجل وعرض أي إدخالات تتوافق مع الأنماط المعروفة للأنشطة المشبوهة أو الضارة ، والتي يشار إليها غالبًا باسم IOC. يمكنك إنشاء نظام كشف التسلل البسيط (IDS). أولاً ، قم بإنشاء ملف يحتوي على أنماط التعبير العادي لـ IOC ، كما هو موضح في المثال 8.1.

مثال 8.1. ioc.txt (1) هذا القالب (../) هو مؤشر على هجوم دليل دوار: يحاول مهاجم الخروج من دليل العمل الحالي والوصول إلى الملفات التي لا يمكن الوصول إليه. (2) تُستخدم ملفات Linux etc / passwd و etc / shadow لمصادقة النظام ويجب عدم الوصول إليها مطلقًا عبر خادم الويب. (3)

\.\./ (1)
etc/passwd (2)
etc/shadow
cmd\.exe (3)
/bin/sh
/bin/bash





إن عرض ملفات cmd.exe أو / bin / sh أو / bin / bash هو مؤشر على الاتصال العكسي الذي أرجعه خادم الويب. غالبًا ما يشير الاتصال العكسي إلى محاولة عملية ناجحة.

لاحظ أنه يجب أن تكون IOCs بتنسيق regex ، حيث سيتم استخدامها لاحقًا بواسطة الأمر egrep.

يمكن استخدام ملف ioc.txt مع خيار egrep -f. تخبر هذه المعلمة egrep بالبحث في أنماط التعبير العادية من الملف المحدد. هذا يسمح لك باستخدام الأمر tail لمراقبة ملف السجل ، وكلما تمت إضافة كل سجل ، سيتم مقارنة سطر القراءة مع جميع القوالب الموجودة في ملف IOC ، مع عرض أي سجل مناظر. هنا مثال:

tail -f /var/logs/apache2/access.log | egrep -i -f ioc.txt

بالإضافة إلى ذلك ، يمكن استخدام الأمر tee لعرض التحذيرات على الشاشة في آن واحد وحفظها للمعالجة اللاحقة في ملفها الخاص: مرة أخرى ، هناك حاجة إلى الخيار - المخزن مؤقتًا للخط لضمان عدم وجود مشاكل ناتجة عن التخزين المؤقت لمخرجات الأمر.

tail -f /var/logs/apache2/access.log | egrep --line-buffered -i -f ioc.txt |
tee -a interesting.txt




مراقبة سجل ويندوز


كما ذكرنا من قبل ، يجب عليك استخدام الأمر wevtutil للوصول إلى أحداث Windows. على الرغم من أن هذا الأمر عالمي ، إلا أنه لا يحتوي على وظائف مثل الذيل ، والذي يمكن استخدامه لاسترداد السجلات الواردة الجديدة. ولكن هناك طريقة للخروج - استخدم نص bash بسيطًا يمكن أن يوفر نفس الوظيفة (مثال 8.2).

مثال 8.2. wintail.sh

#!/bin/bash -
#
# Bash  
# wintail.sh
#
# :
#    tail   Windows
#
# : ./wintail.sh
#

WINLOG="Application" (1)

LASTLOG=$(wevtutil qe "$WINLOG" //c:1 //rd:true //f:text) (2)

while true
do
      CURRENTLOG=$(wevtutil qe "$WINLOG" //c:1 //rd:true //f:text) (3)
      if [[ "$CURRENTLOG" != "$LASTLOG" ]]
      then
            echo "$CURRENTLOG"
            echo "----------------------------------"
            LASTLOG="$CURRENTLOG"
      fi
done

(1) يحدد هذا المتغير سجل Windows الذي تريد تتبعه. للحصول على قائمة بالسجلات المتاحة حاليًا على النظام ، يمكنك استخدام الأمر wevtutil el.

(2) هنا ، يتم تنفيذ wevtutil لطلب ملف السجل المحدد. تُرجع المعلمة c: 1 إدخال سجل واحد فقط. تسمح المعلمة rd: true للأمر بقراءة أحدث إدخال للسجل. أخيرًا ، f: text يعيد النتيجة في نص عادي ، وليس بتنسيق XML ، مما يجعل من السهل قراءة النتيجة من الشاشة.

(3)تقوم الأسطر القليلة التالية بتشغيل الأمر wevtutil مرة أخرى وتتم مقارنة إدخال السجل الذي تم تلقيه مؤخرًا بأخر سطر مطبوع على الشاشة. إذا كانت تختلف عن بعضها البعض ، فهذا يعني أنه كانت هناك تغييرات في السجل. في هذه الحالة ، يتم عرض إدخال جديد. إذا كانت السجلات التي تتم مقارنتها هي نفسها ، فلن يحدث شيء ويعود الأمر wevtutil ويبدأ البحث والمقارنة مرة أخرى.

إنشاء الرسم البياني في الوقت الحقيقي


يوفر الأمر tail -f تدفق البيانات الحالي. ولكن ماذا لو كنت ترغب في حساب عدد الأسطر التي تمت إضافتها إلى الملف لفترة زمنية معينة؟ يمكنك مراقبة دفق البيانات هذا ، وبدء جهاز توقيت وإجراء العد خلال فترة زمنية محددة ؛ ثم يجب إيقاف العد والإبلاغ عن النتائج.

يمكن تقسيم هذا العمل إلى عمليتين للبرامج النصية: أحدهما يقرأ الأسطر ، والآخر يشاهد الوقت. يقوم المؤقت بإعلام عداد الخط باستخدام آلية اتصال POSIX المعيارية والمعالجة تسمى إشارة. الإشارة عبارة عن مقاطعة برمجية ، وهناك أنواع مختلفة من الإشارات. بعضها مميت - يؤدي إلى نهاية العملية (على سبيل المثال ، استثناء في عملية الفاصلة العائمة). يمكن تجاهل معظم هذه الإشارات أو التقاطها. يتم اتخاذ إجراء عند التقاط إشارة. العديد من هذه الإشارات لها غرض محدد مسبقًا في نظام التشغيل. سنستخدم واحدة من الإشارات المتاحة للمستخدمين. هذه هي إشارة SIGUSR1 (والأخرى هي SIGUSR2).

يمكن أن تقوم برامج نصية Shell بالتقاط المقاطعات باستخدام الأمر trap المدمج. بمساعدته ، يمكنك تحديد أمر يحدد الإجراء الذي تريد القيام به عند تلقي إشارة ، وقائمة من الإشارات التي تؤدي إلى استدعاء هذا الأمر. على سبيل المثال:

trap warnmsg SIGINT

يؤدي هذا إلى استدعاء الأمر warnmsg (البرنامج النصي أو الوظيفة الخاصة بنا) كلما تلقى البرنامج النصي shell إشارة SIGINT ، على سبيل المثال ، عند الضغط على Ctrl + C لمقاطعة عملية قيد التشغيل.

يوضح المثال 8.3 برنامج نصي يقوم بإجراء حساب.

مثال 8.3 وبير. sh

#!/bin/bash -
#
# Bash  
# looper.sh
#
# :
#    
#
# : ./looper.sh [filename]
# filename —  ,   ,
#  : log.file
#

function interval ()                                           (1)
{
      echo $(date '+%y%m%d %H%M%S') $cnt                       (2)
      cnt=0
}

declare -i cnt=0
trap interval SIGUSR1                                          (3)

shopt -s lastpipe                                              (4)

tail -f --pid=$$ ${1:-log.file} | while read aline             (5)
do
     let cnt++
done

(1) سيتم استدعاء وظيفة الفاصل الزمني عند استلام كل إشارة. بالطبع ، يجب تحديد الفاصل الزمني قبل أن نتمكن من تسميته واستخدام فخ في تعبيرنا.

(2) يتم استدعاء أمر التاريخ لتوفير طابع زمني لقيمة المتغير cnt الذي نقوم بطباعته. بعد عرض العداد ، نعيد تعيين هذه القيمة إلى 0 لبدء العد التنازلي للفاصل الزمني التالي.

(3) الآن بعد أن تم تعريف الفاصل الزمني ، يمكننا الإشارة إلى أن الوظيفة يتم استدعاؤها عندما تتلقى عمليتنا الإشارة SIGUSR1.

(4)هذه خطوة غي غاية الأهمية. عادة ، عندما يكون هناك خط أنابيب أوامر (على سبيل المثال ، ls-l | grep rwx | wc) ، يتم تنفيذ أجزاء من خط الأنابيب (كل أمر) على شبكات فرعية وتنتهي كل عملية بمعرف العملية الخاص بها. قد يكون هذا مشكلة لهذا السيناريو ، لأن حلقة while ستكون في قشرة فرعية بمعرف عملية مختلف. مهما كانت العملية التي تبدأ ، لن يعرف البرنامج النصي looper.sh معرف عملية حلقة الوقت لإرسال إشارة إليه. بالإضافة إلى ذلك ، لا يؤدي تغيير قيمة المتغير cnt في القشرة الفرعية إلى تغيير قيمة cnt في العملية الرئيسية ، لذا ستقوم إشارة العملية الرئيسية في كل مرة بتعيين القيمة إلى 0. يمكنك حل هذه المشكلة باستخدام الأمر shopt ، الذي يضبط المعلمة (-s) على الأنبوب الأخير. يخبر القشرة بعدم إنشاء قشرة فرعية للأمر الأخير في خط الأنابيب ،وتشغيل هذا الأمر في نفس عملية البرنامج النصي نفسه. في حالتنا ، هذا يعني أنه سيتم تنفيذ الأمر tail في قشرة فرعية (أي في عملية أخرى) ، وستصبح حلقة while جزءًا من عملية البرنامج النصي الرئيسية. ملاحظة: لا يتوفر خيار shell هذا إلا في إصدار bash 4.x والإصدارات الأحدث وفقط للأغلفة غير التفاعلية (مثل النصوص البرمجية).

(5) هذا هو الأمر tail -f بمعلمة --pid أخرى. نشير إلى معرف العملية ، والتي ، عند الانتهاء من هذه العملية ، ستنهي الأمر الذيل. نحدد معرف العملية للنص البرمجي الحالي $$ لعرضه. يسمح لك هذا الإجراء بتنظيف العمليات وعدم ترك أمر الذيل الذي تم تنفيذه في الخلفية (إذا ، على سبيل المثال ، يعمل هذا النص البرمجي في الخلفية ؛ مثال 8.4).

يبدأ النص البرمجي tailcount.sh ويوقف النص البرمجي باستخدام ساعة توقيت (مؤقت) ويحسب الفترات الزمنية.

مثال 8.4. tailcount.sh

#!/bin/bash -
#
# Bash  
# tailcount.sh
#
# :
#    n 
#
# : ./tailcount.sh [filename]
#     filename:  looper.sh
#

#  —    
function cleanup ()
{
      [[ -n $LOPID ]] && kill $LOPID          (1)
}

trap cleanup EXIT                             (2)
bash looper.sh $1 &                           (3)
LOPID=$!                                      (4)
#   
sleep 3

while true
do
      kill -SIGUSR1 $LOPID
      sleep 5
done >&2                                      (5)

(1) نظرًا لأن هذا البرنامج النصي سيشغل نصوصًا أخرى ، فيجب تنظيفه بعد العمل. إذا تم تخزين معرف العملية في LOPID ، فسيخزن المتغير القيمة ، وبالتالي سترسل الوظيفة إشارة إلى هذه العملية باستخدام الأمر kill. إذا لم تحدد إشارة محددة في أمر الإيقاف ، فسيتم إرسال إشارة SIGTERM افتراضيًا.

(2) الأمر EXIT ليس إشارة. هذه حالة خاصة عندما تخبر عبارة الاعتراض الصدفة باستدعاء هذه الوظيفة (في هذه الحالة التنظيف) إذا كانت الصدفة التي تنفذ هذا البرنامج النصي على وشك الإغلاق.

(3)الآن يبدأ العمل الحقيقي. يتم تشغيل البرنامج النصي looper.sh ، والذي سيتم تشغيله في الخلفية: لكي يعمل هذا البرنامج النصي طوال الدورة (بدون انتظار الأمر لإكمال العمل) ، يتم فصله عن لوحة المفاتيح.

(4) هنا ، يتم تخزين معرف عملية البرنامج النصي الذي بدأناه للتو في الخلفية.

(5) عملية إعادة التوجيه هذه هي مجرد إجراء احترازي. يجب ألا يتم خلط جميع المخرجات القادمة من حلقة من الوقت أو من عبارات القتل / النوم (على الرغم من أننا لا نتوقعها) مع أي ناتج من وظيفة looper.sh ، والتي ، على الرغم من أنها تعمل في الخلفية ، ترسلها إلى stdout على أي حال. لذلك ، نعيد توجيه البيانات من stdout إلى stderr.

للتلخيص ، نرى أنه على الرغم من وضع دالة looper.sh في الخلفية ، يتم تخزين معرف العملية الخاص بها في متغير shell. كل خمس ثوانٍ ، يرسل البرنامج النصي tailcount.sh إشارة SIGUSR1 إلى هذه العملية (التي يتم تنفيذها في وظيفة looper.sh) ، والتي بدورها تستدعي البرنامج النصي looper.sh لطباعة العدد الحالي من الخطوط الثابتة فيه وإعادة تشغيل العد. بعد الخروج ، سيتم مسح البرنامج النصي tailcount.sh عن طريق إرسال إشارة SIGTERM إلى وظيفة looper.sh لمقاطعته.

بمساعدة نصين كتابيين - برنامج نصي يقوم بإجراء عد الأسطر ، ونص برمجي مع ساعة توقيت (مؤقت) يتحكم في البرنامج النصي الأول - يمكنك الحصول على الإخراج (عدد الأسطر لفترة معينة) ، بناءً على البرنامج النصي التالي الذي سيقوم بإنشاء رسم بياني. يطلق عليه مثل هذا:

bash tailcount.sh | bash livebar.sh

يقرأ البرنامج النصي livebar.sh البيانات من stdin ويطبع الإخراج إلى stdout ، سطر واحد لكل سطر إدخال (مثال 8.5).

مثال 8.5 livebar.sh

#!/bin/bash -
#
# Bash  
# livebar.sh
#
# :
#    «» 
#
# :
# <output from other script or program> | bash livebar.sh
#

function pr_bar ()                                         (1)
{
      local raw maxraw scaled
      raw=$1
      maxraw=$2
      ((scaled=(maxbar*raw)/maxraw))
      ((scaled == 0)) && scaled=1 #   
      for((i=0; i<scaled; i++)) ; do printf '#' ; done
      printf '\n'

} # pr_bar

maxbar=60     #         (2)
MAX=60
while read dayst timst qty
do
      if (( qty > MAX ))                                   (3)
      then
           let MAX=$qty+$qty/4    #   
           echo "                      **** rescaling: MAX=$MAX"
      fi
      printf '%6.6s %6.6s %4d:' $dayst $timst $qty         (4)
      pr_bar $qty $MAX
done

(1) تعرض الدالة pr_bar سلسلة من علامات التصنيف التي تم قياسها استنادًا إلى المعلمات المقدمة إلى الحجم الأقصى. قد تبدو هذه الميزة مألوفة ، كما استخدمناها سابقًا في البرنامج النصي histogram.sh.

(2) هذا هو أطول حجم لعلامة التصنيف التي يمكننا السماح بها (يتم ذلك بدون التفاف السطر).

(3)كم سيكون حجم القيم المطلوب عرضها؟ بدون معرفة ذلك مسبقًا (على الرغم من أنه يمكن توفير هذه البيانات إلى النص البرمجي كوسيطة) ، فإن النص البرمجي سيتتبع الحد الأقصى. إذا تم تجاوز هذا الحد الأقصى ، فستبدأ القيمة في "التدرج" والخطوط المعروضة الآن ، وسيتم أيضًا تغيير حجم الخطوط المستقبلية إلى الحد الأقصى الجديد. يضيف النص البرمجي 25٪ إلى الحد الأقصى للقيمة ، لذلك ليس من الضروري تغيير القيمة إذا زادت القيمة الجديدة التالية في كل مرة بنسبة 1-2٪ فقط.

(4)تحدد printf الحد الأدنى والأقصى لعرض أول حقلين يتم طباعتهما. هذه هي طوابع التاريخ والوقت التي سيتم اقتطاعها إذا تم تجاوز قيم العرض. لعرض القيمة بالكامل ، حدد عرضها المكون من أربعة أحرف. في هذه الحالة ، على الرغم من القيود ، سيتم طباعة جميع القيم. إذا كان عدد الأحرف في القيم أقل من أربعة ، فسيتم استكمال الأحرف المفقودة بمسافات.

نظرًا لأنه تتم قراءة هذا النص البرمجي من stdin ، يمكنك تشغيله بنفسك لترى كيف يتصرف. هنا مثال:

$ bash  livebar.sh
201010 1020 20
201010     1020 20:####################
201010 1020 70
                       **** rescaling: MAX=87
201010     1020 70:################################################
201010 1020 75
201010 1020 75:###################################################
^C

في هذا المثال ، يتم خلط الإدخال مع الإخراج. يمكنك أيضًا وضع الإدخال في ملف وإعادة توجيهه إلى برنامج نصي لرؤية الإخراج فقط:

$ bash livebar.sh < testdata.txt
bash livebar.sh < x.data
201010 1020 20:####################
                 **** rescaling: MAX=87
201010 1020 70:################################################
201010 1020 75:###################################################
$

»يمكن العثور على مزيد من المعلومات حول الكتاب على موقع الناشر على الإنترنت
» المحتويات
» مقتطفات

لـ Khabrozhiteley خصم 25 ٪ على القسيمة - Bash

عند دفع النسخة الورقية من الكتاب ، يتم إرسال كتاب إلكتروني عبر البريد الإلكتروني.

All Articles