Bài giảng Lập trình an toàn - Chương 7: Anti, Tampering - Lương Ánh Hoàng
Mục tiêu: Phát hiện chương trình đã bị crack chưa (Detecting modification)
Kỹ thuật:
- Tính MD5, SHA1, hoặc HMAC mã lệnh của file thực thi.
- Đánh dấu một đoạn trong chương trình sẽ dùng để lưu mã băm file thực thi và ghi giá trị băm vào đó bằng một chương trình Hex edit khác.
- Tại thời điể’m runtime tính lại giá trị băm của file thực thi và so sánh với mã băm trước đó.
Ví dụ:
// Khai báo xâu đánh dấu mã băm
char * md5hash = "AAAAXXXXXXXXXXXXXXXX";
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char hash[16];// Giá trị băm tính được
unsigned char expectedhash[16];// Giá trị băm lưu trong file
FILE * fp = fopen(argv[0],"rb");// Mở file để tính lại giá trị băm unsigned char * pFile ;
fseek(fp,0,SEEK_END);
int len = ftell(fp); 120
7.1 Phát hiện thay đổi mã lệnh
Ví dụ:
pFile = (unsigned char*)malloc(len);
fseek(fp,0,SEEK_SET);
fread(pFile,1,len,fp);
md5hash = 0;
// Dò tìm giá trị băm trong file
if ((pFile[i]=='A')&&(pFile[i+1]=='A')&&
(pFile[i+2]=='A')&&(pFile[i+3]=='A'))
{ memcpy(expectedhash,pFile+i+4,16); memset(pFile+i+4,0,16);
}
MD5(pFile,len,hash);
printf("File hash:");
print_md5(hash); printf("Expected hash:"); print_md5(expectedhash);
if (memcmp(hash,expectedhash,16))
{
printf("File verification failed");
} , „
getch();
return 0;
Tóm tắt nội dung tài liệu: Bài giảng Lập trình an toàn - Chương 7: Anti, Tampering - Lương Ánh Hoàng
Chương 7. Anti-Tampering Lương Ánh Hoàng hoangla@soict.hut.edu.vn Nội dung Phát hiện thay đổi (Detecting modification) Che giấu mã (Code hiding) Sử dụng con trỏ hàm (Function Pointer) Giấu xâu (String hiding) Phát hiện debugger (Anti-Debugger) Self-modifying code Giải pháp tổ’ng thể Phát hiện thay đổi mã lệnh Mục tiêu: Phát hiện chương trình đã bị crack chưa (Detecting modification) Kỹ thuật: Tính MD5, SHA1, hoặc HMAC mã lệnh của file thực thi. Đánh dấu một đoạn trong chương trình sẽ dùng để lưu mã băm file thực thi và ghi giá trị băm vào đó bằng một chương trình Hex edit khác. Tại thời điể’m runtime tính lại giá trị băm của file thực thi và so sánh với mã băm trước đó. Ví dụ: // Khai báo xâu đánh dấu mã băm char * md5hash = "AAAAXXXXXXXXXXXXXXXX"; int _tmain(int argc, _TCHAR* argv[]) { unsigned char hash[16];// Giá trị băm tính được unsigned char expectedhash[16];// Giá trị băm lưu trong file FILE * fp = fopen(argv[0],"rb");// Mở file để tính lại giá trị băm unsigned char * pFile ; fseek(fp,0,SEEK_END); int len = ftell(fp); 120 Phát hiện thay đổi mã lệnh Ví dụ: pFile = (unsigned char*)malloc(len); fseek(fp,0,SEEK_SET); fread(pFile,1,len,fp); md5hash = 0; for (int i=0;i<len-20;i++) // Dò tìm giá trị băm trong file if ((pFile[i]=='A')&&(pFile[i+1]=='A')&& (pFile[i+2]=='A')&&(pFile[i+3]=='A')) // Lưu ra mảng khác // Xóa trắng giá trị này trong file // Tính lại giá trị băm { memcpy(expectedhash,pFile+i+4,16); memset(pFile+i+4,0,16); } MD5(pFile,len,hash); printf("File hash:"); print_md5(hash); printf("Expected hash:"); print_md5(expectedhash); if (memcmp(hash,expectedhash,16)) { printf("File verification failed"); } , „ getch(); return 0; Phát hiện thay đổi mã lệnh Hạn chế Dễ bị đánh bại nếu sử dụng hash vì cracker cũng có thể tính lại giá trị băm và sửa file cho chính xác. Nếu sử dụng HMAC thì phải lưu mật khẩu ở đâu đó Lưu trong file: Cũng sẽ bị cracker dò ra Lưu trên internet: cần có kết nối internet và dễ dàng bị dò ra nếu dùng sniffer. CURL n.z Che giấu mã Mục tiêu Gây khó khăn cho quá trình dịch ngược và phân tích bằng các disassembler (Obfuscating code). Windasm, OllyDbg, IDA Che giấu các cấu trúc điều khiển quan trọng trong chương trình. Cấu trúc điều kiện Cấu trúc lặp Kỹ thuật Cần sự hỗ trợ của trình biên dịch Thực hiện ở mức hợp ngữ Sử dụng các điều kiện so sánh “bất thường” So sánh khác thay vì bằng Vòng lặp giảm thay vì tăng. Vòng lặp có chỉ số tăng khác 1. Sử dụng con trỏ hàm Mục tiêu Gây khó khăn cho các công cụ disassembler trong việc phân tích lời gọi hàm Kỹ thuật Không thực hiện lời gọi hàm trực tiếp trong chương trình mà sử dụng các con trỏ hàm. VD void my_func() { } typedef void (*FUNC)0; int _tmain(int argc, _TCHAR* argv[]) { FUNC ptr; ptr = my_func; printf("ptr address:%p",ptr); ptr(); /* make the function call */ return 0; } Giấu xâu Mục tiêu Gây khó khăn cho các công cụ disassembler trong việc phân tích các xâu nhạy cảm trong chương trình.VD Invalid cd-key Registration successful ... Kỹ thuật Mã hóa các xâu trong chương trình Base64 RC4 Giải thuật tự chọn Giấu xâu Ví dụ: dịch mã các ký tự trong xâu đi 0x19 #include #define A(c) (c) - 0x19 #define UNHIDE_STR(str) do { char *p = str; while (*p) *p++ += 0x19; } while (0) #define HIDE_STR(str) do { char *p = str; while (*p) *p++ -= 0x19; } while (0) int main(int argc, char *argv[ ]) { char str[ ] = { AC/’), A('e'), A('t'), A('c'), A('/'), A('p'), A('a'), A('s'), A('s'), A('w'), A('d'), 0 }; UNHIDE_STR(str); printf("%s\n", str); HIDE_STR(str); return 0; } Phát hiện debugger Mục đích: Phát hiện sự tồn tại của debugger Kỹ thuật: rất nhiều (google : anti-debugger) Kernel32!IsDebuggerPresent PEB!IsDebugged PEB!NtGlobaiFlags Self-debugging Ví dụ #include int _tmain(int argc, _TCHAR* argv[]) { if(IsDebuggerPresent()) { printf("Program is being debugged"); } return 0; } Self-modifying code Mục đích: Mã hóa lệnh quan trọng, chỉ giải mã khi cần thực hiện Kỹ thuật Không có sự trợ giúp của trình biên dịch. Gần như không thể thực hiện bằng C/C++ Cần hiểu rất sâu về hệ điều hành + hợp ngữ Googe: shellcode Ưu điểm Không thể’ dissassembler nếu chưa giải mã. Không dành cho amater cracker. Nhược điểm Rất khó bảo trì Vẫn có thể crack được nếu đặt đúng breakpoint tại điểm decrypt Xung đột với DEP (Data Execution Preventation) Giải pháp tổng thể Các kỹ thuật trên nếu kết hợp lại có thể có kết quả rất tốt. Trên Windows: Sử dụng các chương trình all-in-one: “Packer” ASPack ASProtect PECompact PECrypt Themida ... Code-sign ứng dụng bằng chữ ký số Trên các hệ điều hành khác Đang tiến dần đến xu hướng code-sign: VD iOS, MacOS... Giải pháp tổng thể Các kỹ thuật trên nếu kết hợp lại có thể có kết quả rất tốt. Trên Windows: Sử dụng các chương trình all-in-one: “Packer” ASPack ASProtect PECompact PECrypt Themida ... Code-sign ứng dụng bằng chữ ký số Trên các hệ điều hành khác Đang tiến dần đến xu hướng code-sign: VD iOS, MacOS... Các đề tài tìm hiểu Tìm hiểu và minh hoạ các kỹ thuật SQL Injection hiện nay (đặc biệt là blind sql injection).(Tuần 14 - Thuý) Tìm hiểu và minh hoạ kỹ thuật tấn công tràn bộ đệm buffer overflow và khai thác qua shellcode. Có thể dùng Metasploit để thử nghiệm.(Tuần 15- Xuan Hiep) Tìm hiểu cơ chế leo thang đặc quyền trên một thiết bị chạy hệ điều hành Android (rooting, tìm cái dễ root nhất).(Tuần 15 - Phi Hiệp) Sử dụng một trong các kỹ thuật đồng bộ để thực hiện thuật toán quicksort trên bộ vi xử lý đa nhân. Yêu cầu tốc độ sắp xếp phải đạt được tuyến tính với số nhân của bộ vi xử lý.(Tuần 12 - Ngọc Anh) Sử dụng thuật toán HMAC để phát hiện thay đổi trong mã lệnh của chương trình. Với key và giá trị băm được tải về từ internet trong mỗi lần kiểm tra. (Tuần 12 - Linh) Sử dụng chữ ký số để phát hiện thay đổi trong mã lệnh của chương trình. Với public key được tải về từ internet trong mỗi lần kiểm tra.(Tuần 13 - Quynh, Thành) Tìm hiểu các kỹ thuật phát hiện debugger (anti-debugger) và các kỹ thuật chống phát hiện debugger (anti-anti-debugger).(Tuần 13 - Hoa, Tùng) Xây dựng hệ thống cấp phát chứng thực số dựa trên openssl với CA sinh sẵn Chỉ yêu cầu viết bằng php/html để nhận tham số của chứng thực qua form, sau đó sinh ngay cặp chứng thực/key cho client và biểu diễn dưới dạng
File đính kèm:
- bai_giang_lap_trinh_an_toan_chuong_7_anti_tampering_luong_an.docx
- secureprogramming_7_7105_505048.pdf