ปิดใช้งานการป้องกันสแต็กบน Ubuntu สำหรับบัฟเฟอร์โอเวอร์โฟลว์โดยไม่มีแฟล็กคอมไพเลอร์ C


10

ฉันต้องการลองใช้รหัสเชลล์และฉันต้องการปิดใช้งานการป้องกัน linux

ฉันรู้ว่าฉันสามารถคอมไพล์โดยใช้ค่าสถานะ แต่ฉันรู้ว่ามีวิธีอื่นอยู่แล้วในการปิดใช้งานการป้องกันเหล่านี้โดยทั่วไปฉันจำไม่ได้ คุณสามารถช่วยฉันได้ไหม?

คำตอบ:


6

การป้องกันสแต็คจะกระทำโดยคอมไพเลอร์ (เพิ่มข้อมูลพิเศษบางอย่างลงในสแต็กและซ่อนการโทรบางครั้งตรวจสอบสติเมื่อกลับมา) ไม่สามารถปิดใช้งานได้โดยไม่ต้องรวบรวมใหม่ มันเป็นส่วนหนึ่งของจุดจริงๆ ...


6
ASLR ต้องการให้ระบบปฏิบัติการใช้งานที่รันไทม์ บิต NX ยังต้องการการสนับสนุนระบบ ส่วนใดที่ไม่สามารถใช้งานได้ในขณะทำงาน
Jeff Ferland

25

เพื่อขยายว่า vonbrand มีอะไร (อย่างถูกต้อง +1) กล่าวว่ามีสองส่วนในการป้องกันสแต็กของ Linux

หมู่เกาะคานารี

Stack canaries คือคุณสมบัติที่บังคับใช้คอมไพเลอร์ vonbrand อ้างถึง สิ่งเหล่านี้ไม่สามารถปิดใช้งานได้หากไม่มีการคอมไพล์ใหม่

เพื่อพิสูจน์ตัวคุณเองและดูว่าพวกเขาทำงานอย่างไรใช้รหัสต่อไปนี้:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

int mybadfunction(char* a_bad_idea)
{
    char what[100];
    strcpy(what, a_bad_idea);
    printf("You passed %s\n", what);
}

int main(int argc, char** argv)
{
    printf("Tralalalaala\n");
    mybadfunction(argv[1]);
}

ตอนนี้รวบรวมว่า ( gcc -fstack-protector -masm=intel -S test.c) เป็นสิ่ง gnu ตามที่จะมีความสุขในการรวบรวมและอ่านผลลัพธ์ จุดสำคัญคือเมื่อออกจากmybadfunctionฟังก์ชั่นมีโค้ดเล็ก ๆ นี้:

    mov edx, DWORD PTR [ebp-12]
    xor edx, DWORD PTR gs:20
    je  .L2
    call    __stack_chk_fail

ในขณะที่คุณสามารถคาดเดาว่าสละคุกกี้สแต็คจากและเปรียบเทียบกับค่าที่[ebp-12] gs:20ไม่ตรงกันหรือ จากนั้นจะเรียกใช้ฟังก์ชัน__stack_chk_failใน glibc ซึ่งฆ่าโปรแกรมของคุณที่นั่น

มีวิธีการทำงานรอบนี้ในแง่ของการเขียนการหาประโยชน์มี แต่วิธีที่ง่ายในแง่ของการสร้างกรณีทดสอบ shellcode -fno-stack-protectorคือการรวบรวมโปรแกรมของคุณด้วย

หน้าที่ไม่สามารถดำเนินการได้

มีข้อควรพิจารณาอื่น ๆ เกี่ยวกับระบบ Linux ที่ทันสมัย หากคุณทำการทดสอบ shellcode ปกติ:

char buffer[] = {...};

typedef void (* func)(void);

int main(int argc, char** argv)
{
    func f = (func) buffer;
    f();
    return 0;
}

modern GCC / Linux จะจับคู่.rodataส่วนของไฟล์ PE แบบอ่านอย่างเดียวโดยไม่มีสิทธิ์ดำเนินการ คุณต้องปิดการทำงานดังกล่าวซึ่งสามารถทำได้โดยใช้ตัวอย่างโค้ดจากโพสต์บล็อกนี้ แนวคิดพื้นฐาน: คุณใช้mprotectเพื่อเพิ่มการอนุญาตที่คุณต้องการในเพจที่มีข้อมูล shellcode อยู่

สแต็กที่ไม่สามารถเรียกทำงานได้

หากคุณกำลังจะทดสอบสถานการณ์การหาประโยชน์แบบดั้งเดิมเช่นโค้ดที่ไม่ดีของฉันด้านบนด้วย shellcode ของคุณคุณต้องตรวจสอบให้แน่ใจว่าสแต็กสามารถเรียกใช้งานได้ในกรณีง่าย ๆ รูปแบบไฟล์ PE มีช่องสำหรับการพิจารณาว่าสแต็คเป็นปฏิบัติการ - คุณสามารถสอบถามและควบคุมนี้กับexecstack หากต้องการเปิดใช้งานสแต็กที่รันได้ให้รัน

execstack -s /path/to/myprog

สิ่งนี้สามารถทำได้บนโปรแกรมที่ไม่มีกฎเกณฑ์โดยไม่จำเป็นต้องทำการคอมไพล์ใหม่ แต่จะไม่ปิดการใช้งานคีรีบูนโดยอัตโนมัติ

เพิ่มโบนัส: aslr:

echo 0 > /proc/sys/kernel/randomize_va_spaceหากต้องการเปิดที่ปิด

คุณเพิ่งบอกใครสักคนถึงวิธีการใช้ประโยชน์จากนกเพนกวินที่มีค่าของฉัน

ไม่การหาประโยชน์ใด ๆ จะต้องทำงานกับกองซ้อนคีรีนูน (ไม่สำคัญมาก) และค้นหาโปรแกรมที่มีexecstackชุดหรือตั้งค่า (หมายความว่ามันสามารถรันคำสั่งตามอำเภอใจแล้ว) หรือใช้เทคนิคที่ยากขึ้นเช่นกลับไปเป็น libc / return การเขียนโปรแกรมแบบมุ่งเน้น


0

คุณสามารถปิดการใช้งานการป้องกันบางอย่าง (การตรวจจับยอดเยี่ยมแบบสแต็กและการเรียกใช้งานสแต็ก) ด้วยตัวเลือกเหล่านี้

--z execstack
-f no-stack-protector

คุณสามารถปิด ASLR (การสุ่มเลย์เอาต์พื้นที่ที่อยู่) ด้วย Bash ด้วยคำสั่ง:

echo 0 > /proc/sys/kernel/randomize_va_space
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.