-
سه شنبه, ۶ آبان ۱۳۹۹، ۰۹:۴۴ ب.ظ
-
۹۴۷
میدونی File Signature چیه ؟ آموزش ساخت ابزار تشخیص نوع یک فایل با پایتون
درود به همه !
امروز با یه آموزش باحال دیگه در خدمت شما هستیم . من همیشه وقتی از یه منبع ناشناس یه فایلی رو دانلود میکنم (به خصوص فایل اجرایی) همیشه قبل از اجرا با ابزار هایی مثل Virus Total اسکن میکنم فایل رو تا حداقل یکم مطمئن بشم این فایل ویروس نیست . اما امروز میخوایم ابزاری بنویسیم که از طریق محتوای فایل (نه فرمت فایل) به درستی نوع فایل رو تشخیص بده و درنتیجه بفهمه هر فایل پس از باز شدن چه واکنشی میتونه داشته باشه . با ما همراه باشید ...
در ابتدا شاید فک کنین خب برای اینکار که ما نیازی به برنامه نداریم که !!!! خیلی راحت از طریق فرمت فایل (mp3 , exe , mp4 , pdf , ...) میتونیم بفهمیم نوع فایل چیه و چه واکنشی میتونه پس از اجرا داشته باشه . بله نظر شما درسته ولی خب یه موضوعی هست باید بدونین . هکر ها میتونن با استفاده از ابزار هایی مثل Hex Editor ها کاری کنن که برای مثال یک فایل خودشو به حالت یه فایل صوتی نشون بده ولی وقتی اجرا میشه مانند یه فایل اجرایی (exe) واکنش نشون بده !!!!!!!
در کل میتونه یه کارایی شبیه به این انجام بده و نهایتا منجر به این میشه که شما متوجه نوع اصلی فایل مخرب نشین .
حالا برنامه ی ما میاد محتوای باینری خود فایل رو برسی میکنه و از طریق اون تشخیص میده که این فایل چه نوع فایلیه بنابراین وابسته به فرمت نیست که به راحتی دور بخوره .
اما چه شکلی میشه از محتوای فایل فهمید .
ما مفهومی دارین تحت عنوان file signature . هر نوع فایل (صوتی ، تصویری ، اجرایی و ....) یک امضای مشخص یا بهتره بگم یک signature مخصوص به خودشو داره که محتوای اون فایل با این امضا شروع میشه . برای مثال امضاء فایل های xml ، عدد مبنای شانزده زیر است :
3c 3f 78 6d 6c 20
این به این معناس که ما هر فایل xml رو که در نظر بگیریم ، محتوای داخلش با 3c 3f 78 6d 6c 20 شروع میشه . در تصویر زیر من یک فایل xml رو با یک hex editor باز کردم و میبینید که این موضوع داخلش صدق میکنه .
به خاطر همینه که سیستم عاملی مثل لینوکس بدونه اینکه فرمت فایل رو بهش توجه کنه میتونه نوع فایل رو تشخیص بده .
خیلی خب پس تا اینجا متوجه شدیم که با نگاه کردن به چند بخش اول محتوای هر فایل میتونیم نوع اون فایل رو تشخیص بدیم . بنابراین کاری که میکنیم اینه که یه فایل متنی درست میکنیم و لیست signature هایی که نیاز داریم رو به همراه نوع فایل داخلش مینویسیم بینشونم دونقطه (:) میزاریم . برای مثال من از فایل زیر برای اسکریپتم استفاده میکنم :
255044462d:pdf 7F454C46:LSB 3c3f786d6c20:XML 4344303031:iso
در لینک زیر لیست تمام فرمت فایل ها و امضا های آن ها مشخص شده :
https://en.wikipedia.org/wiki/List_of_file_signatures
اسکریپت میاد بخش اول محتوای فایل رو در حالت باینری میبینه و به مبنای 16 تبدیلش میکنه . سپس با امضاء های داخل فایل متنی که درست کردیم مقایسه میکنه و در نتیجه نوع فایل رو تشخیص میده .
اسکریپت نیاز به کتابخونه ای نداره .
سورس اسکریپت :
# https://MrPython.blog.ir signatures = input("Signature File : ") # ask for Signature List signatures = open(signatures) # Open Signature List signatures = signatures.readlines() # Read Signature List's Lines
file = input("File : ") # ask for Target File file = open(file,"rb") # Open Target File in <Read Binary> Mode -> (rb) file = file.read().hex() # Read and Convert Target File Data to Hex(16)
file = file[0:20].upper() # get first parts of Target File Data
for line in signatures: try: sign = line.split(":")[0].strip("\n").upper() # Get Signature Hex fileformat = line.split(":")[1].strip("\n") # Get Signature File Format except: continue if sign in file: print("\n========================") print("{} File".format(fileformat.upper())) print("========================") break
توضیح سورس کد :
در ابتدا از کاربر اسم فایل متنی که لیست signature ها داخلش هست رو پرسیدیم و اون فایل رو باز کردیم . پس از باز کردن اون فایل ، خط به خط اون فایل رو با استفاده از متد readlines داخل لیست signatures ذخیره کردیم .
بعد از اون اسم فایلی که قراره نوعشو مشخص کنیم رو از کاربر پرسیدیم و اون فایل رو در حالت باینری باز کردیم . سپس 20 بخش اول محتوای فایل رو جدا کردیم (معمولا signature فایل ها بیشتر از 20 بایت نمیشه بنابراین همون 20 تا اول کافیه) . سپس یه حلقه ی for روی لیست امضاء ها اجرا کردیم و به ازای هر خط اون با استفاده از متد split کد مبنای ۱۶ امضا و اسم فرمت فایل مربوط به اون کد امضا رو جدا کردیم و داخل دو متغییر sign و fileformat ریختیم . بعد چک کردیم اگه اون کد مبنای ۱۶ که همون امضای مشخص هر فرمت فایل هستش داخل 20 بخش اول فایل(فایلی که قراره نوعشو مشخص کنیم) بود ، پس یعنی نوعش مشخص شده و به کاربر نشون دادیم .
من اسکریپت رو اجرا کردم . لیست رو بهش دادم و یه فایل pdf هم برای شناسایی بهش دادم . در تصویر میبینیم که به درستی اونو مشخص کرده . توجه کنید حتی اگه فرمت فایل رو هم عوض کنید بازم تشخیص میده چون شما محتوای فایل رو عوض نکردید .
یا حق !
Telegarm Channel : @mrpythonblog