Ngôn ngữ lập trình hacker. Nguyên tắc cơ bản của hack. Kiểm tra xác thực và hack bảo mật cơ bản. Tìm một công việc phù hợp

Mười lăm năm trước, cuốn sách Nguyên tắc cơ bản về hack của Chris Kaspersky là cuốn sách đáng tham khảo dành cho mọi nhà nghiên cứu bảo mật máy tính đầy tham vọng. Tuy nhiên, thời gian trôi qua, kiến ​​thức do Chris công bố không còn phù hợp nữa. Các biên tập viên của Hacker đã cố gắng cập nhật tác phẩm đồ sộ này và chuyển nó từ thời Windows 2000 và Visual Studio 6.0 sang thời Windows 10 và Visual Studio 2017.

Kiểm tra xác thực

Xác minh tính xác thực (từ tiếng Hy Lạp authentikos - chính hãng) là “trái tim” của đại đa số các cơ chế bảo vệ. Chúng ta phải đảm bảo rằng người mà anh ta tuyên bố là đang làm việc với chương trình và liệu người này có được phép làm việc với chương trình hay không!

“Người” không chỉ có thể là người dùng mà còn có thể là máy tính hoặc phương tiện lưu trữ của người đó lưu trữ bản sao được cấp phép của chương trình. Vì vậy, tất cả các cơ chế bảo vệ có thể được chia thành hai loại chính:

  • bảo vệ dựa trên kiến ​​thức (mật khẩu, số sê-ri);
  • bảo vệ dựa trên quyền sở hữu (đĩa khóa, tài liệu).

Nếu việc phòng thủ chỉ dựa trên giả định rằng mã của nó sẽ không được kiểm tra và/hoặc thay đổi thì đó là cách phòng thủ kém. Việc thiếu mã nguồn hoàn toàn không phải là trở ngại không thể vượt qua đối với việc nghiên cứu và sửa đổi ứng dụng. Các công nghệ kỹ thuật đảo ngược hiện đại cho phép bạn tự động nhận dạng các hàm thư viện, biến cục bộ, đối số ngăn xếp, kiểu dữ liệu, nhánh, vòng lặp, v.v. Và trong tương lai gần, những người dịch ngược có thể sẽ học cách tạo các danh sách có hình thức tương tự như các ngôn ngữ cấp cao.

Nhưng ngay cả ngày nay, việc phân tích mã nhị phân cũng không đủ tốn nhiều công sức để ngăn chặn những kẻ tấn công lâu dài. Số lượng lớn các vụ hack liên tục xảy ra là minh chứng rõ nhất cho điều này. Lý tưởng nhất là kiến ​​thức về thuật toán bảo vệ không ảnh hưởng đến điện trở của nó, nhưng điều này không phải lúc nào cũng đạt được. Ví dụ: nếu nhà phát triển chương trình máy chủ quyết định đặt giới hạn về số lượng kết nối đồng thời được xử lý trong phiên bản demo (như thường lệ), kẻ tấn công chỉ cần tìm hướng dẫn bộ xử lý thực hiện kiểm tra đó và xóa nó. Việc sửa đổi một chương trình có thể được ngăn chặn bằng cách liên tục kiểm tra tính toàn vẹn của nó, nhưng một lần nữa, mã kiểm tra tính toàn vẹn có thể được tìm thấy và xóa.


Bước một. Ấm lên

Thuật toán của cơ chế xác thực đơn giản nhất bao gồm so sánh từng ký tự của mật khẩu do người dùng nhập với giá trị tham chiếu được lưu trữ trong chính chương trình (như thường lệ) hoặc bên ngoài nó, ví dụ như trong tệp cấu hình hoặc sổ đăng ký (ít phổ biến hơn).

Ưu điểm của việc bảo vệ như vậy là việc triển khai phần mềm cực kỳ đơn giản. Cốt lõi của nó thực sự bao gồm một dòng, trong C có thể được viết như thế này:

Nếu (strcmp(mật khẩu đã nhập, mật khẩu tham chiếu)) (/* Mật khẩu không chính xác */) else (/* Mật khẩu OK*/)

Hãy bổ sung mã này bằng các quy trình yêu cầu mật khẩu và hiển thị kết quả so sánh, sau đó kiểm tra độ mạnh của chương trình kết quả, nghĩa là khả năng chống hack:

Liệt kê 1. Một ví dụ về một hệ thống xác thực đơn giản

#include "stdafx.h" // Hệ thống xác thực đơn giản nhất - // so sánh mật khẩu từng ký tự #include #bao gồm #define PASSWORD_SIZE 100 #define PASSWORD "myGOODpassword\n" // Dấu gạch nối này là cần thiết để // không lấy dấu gạch nối từ chuỗi // được nhập bởi người dùng int main() ( // Bộ đếm số lần xác thực thất bại int count =0; // Bộ đệm cho mật khẩu được nhập bởi người dùng char buff; // Vòng lặp xác thực chính for(;;) ( // Yêu cầu và đọc người dùng // mật khẩu printf("Nhập mật khẩu:"); fgets(&buff, PASSWORD_SIZE,stdin); // So sánh mật khẩu ban đầu và mật khẩu đã nhập if (strcmp(&buff,PASSWORD)) // Nếu mật khẩu không khớp, chúng tôi sẽ “cãi nhau” printf("Sai mật khẩu\n"); // Ngược lại (nếu mật khẩu giống hệt nhau) // thoát khỏi chu kỳ xác thực nếu không sẽ bị hỏng; // Tăng bộ đếm xác thực thất bại // lần thử và, nếu tất cả // lần thử đã hết, hãy thoát khỏi chương trình nếu (++count>3) return -1; ) // Vì chúng tôi ở đây nên người dùng đã nhập đúng // mật khẩu printf("Password OK\n"); )

Trong các bộ phim nổi tiếng, những hacker khó tính dễ dàng xâm nhập vào bất kỳ hệ thống được bảo vệ khủng khiếp nào, bằng cách nào đó đoán được mật khẩu cần thiết sau nhiều lần thử một cách khó hiểu. Tại sao không thử đi theo con đường của họ?

Không có gì lạ khi mật khẩu là những từ có ý nghĩa như Ferrari, QWERTY, tên những chú chuột hamster yêu thích của bạn hoặc tên các vị trí địa lý. Đoán mật khẩu cũng giống như đoán bằng lá trà - không có gì đảm bảo thành công, bạn chỉ có thể trông cậy vào may mắn. Và may mắn, như bạn biết, là một con chim kiêu hãnh - đừng cho ngón tay vào miệng nó. Có phương pháp hack nào đáng tin cậy hơn không?

Chúng ta hãy suy nghĩ về nó. Vì mật khẩu tham chiếu được lưu trữ trong phần nội dung của chương trình, nên trừ khi nó được mã hóa theo cách thông minh nào đó, nó có thể bị phát hiện bằng cách kiểm tra đơn giản mã nhị phân của chương trình. Bằng cách xem qua tất cả các dòng văn bản được tìm thấy trong đó, bắt đầu với những dòng gần giống với mật khẩu nhất, chúng tôi sẽ nhanh chóng chọn khóa cần thiết và mở chương trình bằng nó! Hơn nữa, khu vực xem có thể được thu hẹp đáng kể - trong phần lớn các trường hợp, trình biên dịch đặt tất cả các biến được khởi tạo trong phân đoạn dữ liệu (trong tệp PE, nó được đặt trong phần .data hoặc .rdata). Có lẽ, ngoại lệ là những người biên dịch Baghdad (Borland) thời kỳ đầu với sở thích chèn các chuỗi văn bản vào một đoạn mã - ngay tại nơi chúng được gọi. Điều này làm đơn giản hóa trình biên dịch nhưng tạo ra nhiều vấn đề. Các hệ điều hành hiện đại, không giống như MS-DOS cũ, cấm sửa đổi đoạn mã và tất cả các biến được đặt trong đó đều ở dạng chỉ đọc. Ngoài ra, trên các bộ xử lý có hệ thống bộ đệm riêng biệt, chúng “làm tắc nghẽn” bộ đệm mã, đến đó trong quá trình đọc trước, nhưng trong lần truy cập đầu tiên, chúng sẽ được tải lại từ RAM chậm (bộ đệm cấp hai) vào bộ đệm dữ liệu. . Kết quả là sự chậm lại và giảm hiệu suất.

Vâng, hãy biến nó thành phần dữ liệu! Tất cả những gì còn lại là tìm một công cụ thuận tiện để xem tệp nhị phân. Tất nhiên, bạn có thể nhấn phím F3 trong shell yêu thích của mình (ví dụ FAR) và nhấn phím Page Down bằng một viên gạch, chiêm ngưỡng những con số đang chạy cho đến khi bạn chán.

Bạn có thể sử dụng bất kỳ trình soạn thảo hex nào (QView, Hiew...) - bất cứ điều gì bạn thích - nhưng trong bài viết, vì lý do rõ ràng, kết quả của tiện ích DUMPBIN từ gói Microsoft Visual Studio tiêu chuẩn đã được trình bày. DUMPBIN được chạy từ Dấu nhắc lệnh của nhà phát triển.

Hãy đặt tiện ích thành tệp thực thi của chương trình của chúng tôi, chứa mật khẩu và yêu cầu nó in phần rdata chứa dữ liệu chỉ đọc được khởi tạo (khóa /SECTION:.rdata) ở dạng "thô" (khóa /RAWDATA: BYTES), chỉ định biểu tượng > để chuyển hướng đầu ra sang một tệp (phản hồi của chương trình chiếm nhiều dung lượng và chỉ có “đuôi” vừa với màn hình).

Liệt kê 2

> dumpbin /RAWDATA:BYTES /SECTION:.rdata passCompare1.exe > rdata.txt 004020E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...... .. 004020F0: 18 30 40 00 68 30 40 00 45 6E 74 65 72 20 70 61 [email được bảo vệ]@.Nhập pa 00402100: 73 73 77 6F 72 64 3A 00 6D 79 47 4F 4F 44 70 61 ssword:.myGOODpa 00402110: 73 73 77 6F 72 64 0A 00 57 72 6F 6E 67 2 0 70 61 ssword..Sai rồi 00402120 : 73 73 77 6F 72 64 0A 00 50 61 73 73 77 6F 72 64 ssword..Mật khẩu 00402130: 20 4F 4B 0A 00 00 00 00 00 00 00 00 00 00 00 00 được rồi......... ... 00402140: 00 00 00 00 90 0A C1 5B 00 00 00 00 02 00 00 00 ......A[........ 00402150: 48 00 00 00 24 22 00 00 24 14 00 00 00 00 00 00 H....$"..$......

Trong số những thứ khác, có một dòng rất giống với mật khẩu tiêu chuẩn (nó được in đậm trong văn bản). Chúng ta sẽ kiểm tra cô ấy nhé? Tuy nhiên, vấn đề là gì - xét theo văn bản nguồn của chương trình, đây thực sự là mật khẩu mong muốn, mở ra cơ chế bảo vệ, giống như một chiếc chìa khóa vàng. Trình biên dịch đã chọn một nơi quá nổi bật để lưu trữ nó - sẽ không có hại gì nếu giấu mật khẩu tốt hơn.

Một cách để làm điều này là buộc mật khẩu tham chiếu vào một phần do chúng ta chọn. Khả năng này không được tiêu chuẩn cung cấp và do đó mỗi nhà phát triển trình biên dịch (nói đúng ra, không phải trình biên dịch, mà là trình liên kết, nhưng điều này không quan trọng) có quyền tự do triển khai nó theo cách riêng của mình hoặc không triển khai nó tại tất cả. Microsoft Visual C++ cung cấp một pragma data_seg đặc biệt cho mục đích này, cho biết phần nào sẽ đặt các biến khởi tạo sau đây. Các biến chưa được khởi tạo được đặt trong phần .bss theo mặc định và được kiểm soát bởi bss_seg pragma tương ứng.

Trong Liệt kê 1, trước hàm main, chúng ta sẽ thêm một phần mới trong đó chúng ta sẽ lưu trữ mật khẩu của mình:

// Từ giờ trở đi, tất cả các biến khởi tạo sẽ // được đặt trong phần.kpnc #pragma data_seg(".kpnc") #define PASSWORD_SIZE 100 #define PASSWORD "myGOODpassword\n" char passwd = PASSWORD; #dữ liệu pragma_seg()

Bên trong hàm main, chúng ta khởi tạo mảng:

// Bây giờ tất cả các biến khởi tạo sẽ lại // được đặt trong phần mặc định, đó là.rdata char buff="";

Điều kiện so sánh các chuỗi trong vòng lặp đã thay đổi một chút:

Nếu (strcmp(&buff,&passwd))

Hãy chạy tiện ích DUMPBIN trên tệp thực thi mới:

> dumpbin /RAWDATA:BYTES /SECTION:.rdata passCompare2.exe > rdata.txt 004020C0: D3 17 40 00 00 00 00 00 D8 11 40 00 00 00 00 00 [email được bảo vệ].@..... 004020D0: 00 00 00 00 2C 11 40 00 D0 11 40 00 00 00 00 00 ....,.@.?.@..... 004020E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...... 004020F0: 18 30 40 00 68 30 40 00 45 6E 74 65 72 20 70 61 [email được bảo vệ]@.Nhập pa 00402100: 73 73 77 6F 72 64 3A 00 57 72 6F 6E 67 20 70 61 ssword:.Sai pa 00402110: 73 73 77 6F 72 64 0A 00 50 61 73 73 77 6 F 72 64 ssword..Mật khẩu 00402120 : 20 4F 4B 0A 00 00 00 00 00 00 00 00 00 00 00 00 OK............ 00402130: 00 00 00 00 6F CB C4 5B 00 00 00 00 02 00 00 00 . ...oEA[........ 00402140: 48 00 00 00 14 22 00 00 14 14 00 00 00 00 00 00 H............... 00402150: 6F CB C4 5B 00 00 00 00 0C 00 00 00 14 00 00 00 oEA[............

Vâng, hiện tại phần dữ liệu không có mật khẩu và hacker đang “nghỉ ngơi”! Nhưng đừng vội kết luận. Trước tiên hãy hiển thị danh sách tất cả các phần có trong tệp:

> dumpbin passCompare2.exe Tóm tắt 1000 .data 1000 .kpnc 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text

Phần không chuẩn.kpnc ngay lập tức thu hút sự chú ý. Nào, hãy xem trong đó có gì?

> dumpbin /SECTION:.kpnc /RAWDATA passCompare2.exe RAW DATA #4 00404000: 6D 79 47 4F 4F 44 70 61 73 73 77 6F 72 64 0A 00 myGOODpassword..

Đây rồi, mật khẩu! Ẩn, nó được gọi là... Tất nhiên, bạn có thể bị biến thái và đưa dữ liệu bí mật vào phần dữ liệu chưa được khởi tạo (.bss) hoặc thậm chí là phần mã (.text) - không phải ai cũng nghĩ đến việc nhìn vào đó, nhưng vị trí như vậy sẽ không làm gián đoạn chức năng của chương trình. Nhưng đừng quên khả năng tìm kiếm tự động các chuỗi văn bản trong tệp nhị phân. Bất cứ phần nào chứa mật khẩu tham chiếu, bộ lọc sẽ dễ dàng tìm thấy nó (vấn đề duy nhất là xác định chuỗi văn bản nào trong số nhiều chuỗi văn bản đại diện cho khóa mong muốn; bạn có thể cần phải sắp xếp qua hàng tá hoặc hai “ứng cử viên” tiềm năng).

Bước hai. Giới thiệu Trình tháo rời

Được rồi, chúng tôi đã tìm ra mật khẩu. Nhưng thật tẻ nhạt biết bao khi phải nhập nó từ bàn phím mỗi lần trước khi bắt đầu chương trình! Sẽ rất tốt nếu hack nó để không yêu cầu mật khẩu nào cả hoặc chương trình coi bất kỳ mật khẩu nào đã nhập là chính xác.

Hack, bạn nói gì? Chà, nó không khó đâu! Việc quyết định chính xác những gì cần hack sẽ khó khăn hơn nhiều. Bộ công cụ của hacker cực kỳ đa dạng và có rất nhiều thứ được tìm thấy ở đây: trình dịch ngược, trình gỡ lỗi, gián điệp API và tin nhắn, màn hình truy cập vào các tệp (cổng, sổ đăng ký) và trình giải nén các tệp thực thi, và... Chỉ một chút thôi. phức tạp đối với một người mới đào mã với tất cả các thiết bị này, hãy tìm ra!

Tuy nhiên, gián điệp, giám sát, giải nén chỉ là những tiện ích nền phụ và vũ khí chính của hacker là trình gỡ lỗi và trình dịch ngược.

Vì vậy, trình dịch ngược có thể áp dụng để nghiên cứu các chương trình được biên dịch và một phần phù hợp để phân tích mã được biên dịch giả. Nếu vậy, nó sẽ phù hợp để phá vỡ mật khẩu bảo vệ của passCompare1.exe. Toàn bộ câu hỏi là nên chọn trình phân tách nào.

Không phải tất cả các trình tháo rời đều giống nhau. Trong số họ cũng có những “trí thức” tự động nhận ra nhiều cấu trúc, chẳng hạn như phần mở đầu và phần kết của hàm, biến cục bộ, tham chiếu chéo, và cũng có những “người đơn giản” có khả năng bị giới hạn trong việc dịch các lệnh máy thành hướng dẫn lắp ráp.

Điều hợp lý nhất cần làm là sử dụng các dịch vụ của trình phân tách thông minh (nếu bạn có), nhưng... đừng vội mà hãy thử thực hiện toàn bộ phân tích theo cách thủ công. Tất nhiên, công nghệ là một điều tốt, nhưng không phải lúc nào nó cũng có sẵn và sẽ rất tốt nếu bạn học trước cách làm việc trong lĩnh vực này. Ngoài ra, việc giao tiếp với một trình phân tách kém sẽ nhấn mạnh một cách hoàn hảo những “điểm tốt” của một trình phân tách tốt.

Hãy sử dụng tiện ích DUMPBIN vốn đã quen thuộc, một “con dao quân đội Thụy Sĩ” thực sự với nhiều chức năng hữu ích, trong đó có chức năng tháo rời. Hãy tháo rời phần mã (như chúng ta nhớ, được gọi là .text), chuyển hướng đầu ra sang một tệp, vì rõ ràng nó sẽ không vừa với màn hình:

> dumpbin /SECTION:.text /DISASM passCompare1.exe > code-text.txt

Chúng ta hãy xem lại phần dữ liệu (hoặc phần khác, tùy thuộc vào nơi lưu trữ mật khẩu): xem Liệt kê 2.

Hãy nhớ lại mật khẩu chúng ta đã tìm được: myGOODpassword. Không giống như Visual C++ 6.0 mà Chris đã sử dụng, Visual C++ 2017 không truy cập các biến được khởi tạo bằng offset hex mà thay thế giá trị trực tiếp vào phần mã. Vì vậy, chúng ta hãy thử tìm mật khẩu đã được xác định trước đó trong danh sách đã được phân tách bằng cách sử dụng tìm kiếm theo ngữ cảnh thông thường bằng bất kỳ trình soạn thảo văn bản nào.

0040107D: B9 08 21 40 00 mov ecx,offset ??_C@_0BA@PCMCJPMK@myGOODpassword?6?$AA@ 00401082: 8A 10 mov dl,byte ptr 00401084: 3A 11 cmp dl,byte ptr 00401086: 75 1 Ajne 004010A2 00401088: 84 D2 test dl,dl 0040108A: 74 12 je 0040109E

Hãy xem, phần trung tâm của danh sách này chịu trách nhiệm so sánh các giá trị của thanh ghi EAX và ECX. Ở phần sau, như chúng ta thấy, mật khẩu tham chiếu được viết ở dòng đầu tiên của danh sách, do đó, ở dòng đầu tiên - do người dùng nhập. Sau đó, một sự so sánh xảy ra và các bước nhảy được thực hiện gần như giống nhau: 0x4010A2 và 0x40109E. Chúng ta hãy xem những gì ở đó:

0040109E: 33 C0 xor eax,eax 004010A0: EB 05 jmp 004010A7 004010A2: 1B C0 sbb eax,eax 004010A4: 83 C8 01 hoặc eax,1 004010A7: 85 C0 kiểm tra eax,eax 004010A9 : 74 63 je 0040110E 004010AB: 0F 1F 44 00 00 nop dword ptr 004010B0: 68 18 21 40 00 đẩy offset ??_C@_0BA@EHHIHKNJ@Wrong?5password?6?$AA@ 004010B5: E8 56 FF FF FF gọi _printf

Vai trò trung tâm ở đây được thực hiện bởi lệnh kiểm tra eax,eax, nằm ở offset 0x4010A7. Nếu eax bằng 0, lệnh JE tiếp theo sẽ nhảy tới 0x40110E. Ngược lại, dòng Sai mật khẩu sẽ được đẩy lên đầu ngăn xếp:

Đẩy phần bù ??_C@_0BA@EHHIHKNJ@Wrong?5password?6?$AA@

và sau đó là một lệnh gọi hàm với một tên tự giải thích:

Gọi_printf

Điều này có nghĩa là giá trị EAX khác 0 biểu thị mật khẩu sai và số 0 biểu thị mật khẩu đúng.

Được rồi, hãy chuyển sang phân tích nhánh hợp lệ của chương trình, việc này được thực hiện sau khi chuyển sang 0x40110E. Và ẩn giấu ở đây là một hướng dẫn đặt chuỗi Mật khẩu OK lên đầu ngăn xếp, sau đó thủ tục _printf được gọi, thủ tục này rõ ràng sẽ in chuỗi đó ra màn hình:

0040110E: 68 28 21 40 00 bù đẩy ??_C@_0N@MBEFNJID@Password?5OK?6?$AA@ 00401113: E8 F8 FE FF FF gọi _printf

Các cân nhắc vận hành như sau: nếu bạn thay thế lệnh JE bằng JNE, chương trình sẽ từ chối mật khẩu thực là không chính xác và chấp nhận mọi mật khẩu không chính xác là đúng. Và nếu bạn thay thế TEST EAX,EAX bằng XOR EAX,EAX thì sau khi thực hiện lệnh này, thanh ghi EAX sẽ luôn bằng 0, bất kể mật khẩu được nhập là gì.

Tất cả những gì còn lại cần làm là tìm những byte tương tự trong tệp thực thi và sửa chúng một chút.

Bước thứ ba. Phẫu thuật

Thực hiện các thay đổi trực tiếp đối với tệp thực thi là một công việc nghiêm túc. Bị nén bởi mã đã có sẵn, chúng tôi phải hài lòng với những gì chúng tôi có và sẽ không thể tách các đội ra xa nhau, hoặc thậm chí di chuyển họ, loại bỏ “phụ tùng thay thế” khỏi bộ phận bảo vệ. Rốt cuộc, điều này sẽ dẫn đến sự thay đổi về độ lệch của tất cả các lệnh khác, trong khi giá trị của con trỏ và địa chỉ bước nhảy sẽ không thay đổi và sẽ bắt đầu trỏ đến những nơi hoàn toàn khác nhau!

Chà, khá dễ dàng để giải quyết việc "vứt bỏ các phụ tùng thay thế" - chỉ cần điền mã bằng các lệnh NOP (mã opcode là 0x90 chứ không phải 0x0, như nhiều người mới đào mã vì lý do nào đó nghĩ), tức là trống (trên thực tế, NOP chỉ là một dạng viết lệnh XCHG EAX,EAX - nếu quan tâm). Với việc “trượt” thì khó khăn hơn nhiều! May mắn thay, các tệp PE luôn chứa rất nhiều “lỗ hổng” còn sót lại trong quá trình căn chỉnh và bạn có thể đặt mã hoặc dữ liệu của mình vào đó.

Nhưng chẳng phải việc biên dịch tệp đã tập hợp sẽ dễ dàng hơn sau khi đã thực hiện các thay đổi cần thiết đối với nó sao? Không, nó không đơn giản hơn, và đây là lý do: nếu trình hợp dịch không nhận ra các con trỏ được truyền tới các hàm (và như chúng ta đã thấy, trình dịch ngược của chúng ta không thể phân biệt chúng với các hằng số), do đó, nó sẽ không thèm sửa chúng một cách chính xác, và, tất nhiên, chương trình sẽ không hoạt động.

Chúng ta phải cắt chương trình trực tiếp. Cách dễ nhất để thực hiện việc này là sử dụng tiện ích Hiew, tiện ích này “tiêu hóa” định dạng tệp PE và do đó đơn giản hóa việc tìm kiếm đoạn mong muốn. Bất kỳ phiên bản nào của trình soạn thảo hex này sẽ làm được. Ví dụ: tôi đã sử dụng phiên bản 6.86 mới nhất, tương thích tốt với Windows 10. Hãy khởi chạy nó bằng cách chỉ định tên tệp trong dòng lệnh hiew32 passCompare1.exe, nhấn đúp phím Enter, chuyển sang chế độ trình biên dịch mã và sử dụng lệnh Phím F5 để đến địa chỉ cần tìm. Như chúng ta nhớ, lệnh TEST, lệnh kiểm tra kết quả bằng 0, được đặt tại địa chỉ 0x4010A7.

Để Hiew có thể phân biệt địa chỉ với offset trong chính tập tin, chúng ta đặt trước nó một ký tự dấu chấm: .4010A7.

004010A7: 85 C0 kiểm tra eax,eax 004010A9: 74 63 je 0040110E

Đúng, đúng thứ chúng ta cần! Nhấn phím F3 để đưa Hiew vào chế độ chỉnh sửa, di chuyển con trỏ đến lệnh TEST EAX,EAX và nhấn phím Enter, thay thế bằng XOR EAX,EAX.

004010A7: 33 C0 xor eax,eax 004010A9: 74 63 je 0040110E

Hài lòng nhận thấy lệnh mới khớp hoàn toàn với lệnh trước, nhấn phím F9 để lưu các thay đổi vào đĩa, sau đó thoát Hiew và thử chạy chương trình, nhập mật khẩu đầu tiên xuất hiện trong đầu:

>passCompare1 Nhập mật khẩu:Xin chào, hat! Mật khẩu được

Đã xảy ra! Hàng phòng ngự đã thất thủ! Được rồi, nhưng chúng ta sẽ hành động thế nào nếu Hiew không biết cách “tiêu hóa” các tập tin PE? Sau đó, chúng ta sẽ phải dùng đến tìm kiếm theo ngữ cảnh. Chúng ta hãy chuyển sự chú ý của chúng ta sang kết xuất thập lục phân được đặt bởi trình dịch ngược ở bên trái các lệnh của trình biên dịch mã. Tất nhiên, nếu bạn cố gắng tìm chuỗi 85 C0 - mã lệnh TEST EAX,EAX, sẽ không có kết quả gì tốt - có thể có hàng trăm KIỂM TRA này trong chương trình, hoặc thậm chí nhiều hơn. Nhưng địa chỉ nhảy rất có thể khác nhau trong tất cả các nhánh của chương trình và chuỗi con TEST EAX,EAX/JE 0040110E rất có thể là duy nhất. Các bạn thử tìm đoạn code tương ứng trong file: 85 C0 74 63 (ở Hiew chỉ cần nhấn phím F7).

Ối! Chỉ có một mục được tìm thấy, đó là những gì chúng tôi thực sự cần. Bây giờ chúng ta hãy thử sửa đổi tệp trực tiếp ở chế độ hex mà không cần vào trình biên dịch mã. Chúng ta hãy lưu ý trong quá trình thực hiện - việc đảo ngược bit ít quan trọng nhất của mã lệnh dẫn đến thay đổi điều kiện chuyển sang ngược lại, tức là 74 JE -> 75 JNE.



Làm? Theo một nghĩa nào đó, lực lượng phòng thủ đã hoàn toàn phát điên - nó không nhận ra mật khẩu thực sự nhưng vui vẻ chào đón những mật khẩu khác. Tuyệt vời!


Còn tiếp?

Vậy là bạn đã đọc (bạn đã đọc chưa?) đoạn mở đầu trong cuốn sách kinh điển của Chris Kaspersky, Nguyên tắc cơ bản về hack, với hơi hướng hiện đại. Chúng ta đã có thể cập nhật kiến ​​thức này lên trình độ hiện tại chưa? Có đáng để tiếp tục không? Chia sẻ ý kiến ​​của bạn về

Nhưng còn lời khuyên của Spolsky là học 1 ngôn ngữ mỗi năm để phát triển tầm nhìn của bạn thì sao? :)

Mikhail Flenov

Tôi không biết lời khuyên như vậy và tôi không khuyên bạn nên làm điều đó. Điều này làm cho tầm nhìn của bạn tốt hơn, nhưng không tốt hơn. Khi bạn biết 3-4 ngôn ngữ, tốt hơn hết bạn nên học từng thuật toán mới để phát triển tầm nhìn của mình. Ngay cả khi bạn không bao giờ sử dụng thuật toán này.

Igor

Câu hỏi trong loạt bài “Làm gì để trở thành hacker”
Để trở thành hacker bạn cần:
1. Học hợp ngữ. Các ngôn ngữ khác không cần thiết, cái chính là phải biết trình biên dịch chương trình.
2. Mặc áo len và để râu. Việc bạn là con gái không quan trọng.
3. Cài đặt Linux. Không quan trọng tại sao. Mọi hacker đều nên có Linux.
Về nguyên tắc, danh sách có thể được tiếp tục vô thời hạn. Hacker trước hết phải là một chuyên gia chứ không phải là bản sao của những lời sáo rỗng trên phim ảnh và báo chí. Đạt được thành công trong một lĩnh vực và bạn sẽ hạnh phúc :).

Zhenya

Tôi nghĩ các thuật toán cần được hiểu chứ không phải ghi nhớ. Về ngôn ngữ, bạn có thể đọc một cuốn sách về 1 ngôn ngữ mỗi năm để hình dung về khả năng của nó. Và sau đó, nếu cần, hãy sử dụng nó

Serge

Có những ngôn ngữ mà bạn có thể viết “mọi thứ tôi cần” như Mikhail đã nói. Và có những ngôn ngữ mà về nguyên tắc bạn có thể viết bất cứ điều gì. Tôi nghĩ loại thứ hai bao gồm trình biên dịch mã, C và C++. Phần còn lại dành cho các tác vụ có tính chuyên môn cao (php, v.v.) hoặc kém hơn về tốc độ (c#, java, v.v.). Chọn cái gì thì mỗi người tự quyết định, tùy theo nhiệm vụ của mình. Mọi người nên làm quen với các nguyên tắc toán học của lập trình - đây là những điều cơ bản.

tiếng kêu

Bây giờ, còn Python thì sao)

Theo mình thì không phải hacker đâu, cú pháp rất đơn giản, đơn giản hơn cả C#. Nếu chúng ta cho rằng ngôn ngữ C# và Java là ngôn ngữ cấp cao thì Python là ngôn ngữ cấp siêu cao, vì nó hoàn toàn dành cho lập trình ứng dụng; khi viết chương trình trong đó, điều chính yếu là có thể sử dụng thư viện.

Và mọi thứ không thể viết bằng Python đều được viết bằng C và được gọi từ chương trình Python.

tiếng kêu

Về cách trở thành hacker,

catb. org/~esr/faqs/hacker-howto. html

alex

Một hacker (từ tiếng Anh hack - to cut) là một chuyên gia CNTT cực kỳ có trình độ, một người hiểu biết sâu sắc về công việc của hệ thống máy tính.
Gần đây, khái niệm hacker đã được nâng lên gần như khái niệm của người dùng cao cấp. Theo tôi, hacker là người có kiến ​​​​thức hoàn hảo về trình biên dịch mã và C, đồng thời có khả năng viết, nếu không phải là hệ điều hành thì cũng là ngôn ngữ thuật toán, đó là những gì họ đã làm với những thành công khác nhau trong quá trình học tại viện. Một hacker chỉ biết php hay html thì nghe buồn cười quá.

Nick

2alex, tôi nghĩ nếu bạn biết PHP, thực sự biết PHP thì ngoài ra bạn sẽ học được js bằng cách nào đó, chưa kể đến việc hiểu cách phá vỡ và vượt qua bảo mật trang web...

Ancort

Asm, C++ và Lisp (bằng cách nào đó họ đã quên) - đây là những ngôn ngữ “hacker”, IMHO

Vladimir

Bằng cách nào đó, tôi cũng thích C# hơn, theo kiểu OOP, mã bằng cách nào đó dễ nhận biết hơn hoặc điều gì đó

Ruslan Dauthadzhiev

Có một cuộc tranh luận khác về ngôn ngữ nào ngầu hơn?? Một cuộc tranh luận vĩnh cửu về chủ đề này. Về Python, nó là ngôn ngữ kịch bản thuần túy dành cho nền tảng di động và web. Hỗ trợ trình tạo GUI của bên thứ ba, chẳng hạn như QT. Tôi không thấy bất kỳ sự thú vị đặc biệt nào trong ngôn ngữ này. Bạn có thể lập trình hoàn hảo ngay cả trong QBasic - tất cả phụ thuộc vào trí tưởng tượng và kinh nghiệm của người lập trình. Chỉ vì một ngôn ngữ đã lỗi thời không có nghĩa là nó "chết".

Ruslan Dauthadzhiev

Alex, ngày nay lập trình viên là những người có thể làm việc đơn giản trên MS Word :). Bạn muốn gì? Để một người sinh ra có cơ hội viết hệ điều hành của riêng mình? Mọi người đều bắt đầu nhỏ. Tất cả phụ thuộc vào mong muốn học hỏi và học hỏi điều gì đó mới của một người.

Chúng tôi đã hiểu rằng bạn là một “Hacker” và đã viết ngôn ngữ của riêng bạn tại trường đại học. Cảm ơn..

Những tin tặc đầu tiên có thể được coi là một nhóm nhỏ bao gồm các lập trình viên và chuyên gia mạng giàu kinh nghiệm, những người cách đây vài thập kỷ đã đứng đầu việc tạo ra các máy vi tính đời đầu và tham gia vào các thí nghiệm ARPAnet. Việc hack máy tính và mạng điện thoại đã trở thành một triệu chứng của văn hóa hacker, nó thực sự phức tạp hơn nhiều và không chỉ giới hạn ở việc hack. Bạn sẽ học được cách tham gia cộng đồng này, có được những kỹ năng cần thiết, học cách suy nghĩ như một hacker và nhận được sự tôn trọng cũng như danh tiếng trong môi trường này.

bước

Phần 1

Tiếp thu các kỹ năng cơ bản

    Chuyển sang hệ điều hành giống Unix, chẳng hạn như Linux. Unix là một hệ điều hành phổ biến, thường được sử dụng cho các máy chủ và đã tạo động lực cho sự phát triển của Internet. Mặc dù bạn có thể sử dụng Internet mà không cần biết Unix, nhưng bạn không thể trở thành hacker Internet nếu không hiểu Unix. Vì lý do này mà văn hóa hacker ngày nay lấy Unix làm trung tâm. Unix, giống như Linux, có thể được sử dụng cùng với Windows trên cùng một máy tính. Tải xuống Linux hoặc yêu cầu người dùng Linux giúp bạn cài đặt hệ thống.

    Giúp kiểm tra và gỡ lỗi các chương trình nguồn mở. Những người kiểm tra và gỡ lỗi các chương trình nguồn mở cũng được tôn kính. Trong thế giới không hoàn hảo này, chúng ta chắc chắn phải dành phần lớn thời gian phát triển chương trình cho giai đoạn gỡ lỗi. Đây là lý do tại sao bất kỳ tác giả nguồn mở chu đáo nào cũng sẽ nói với bạn rằng những người thử nghiệm beta giỏi (những người biết cách mô tả rõ ràng các triệu chứng, giỏi xác định các vấn đề, có thể sửa lỗi chính tả và sử dụng một số quy trình chẩn đoán đơn giản) đều đáng giá như vàng.

    • Nếu bạn là người mới bắt đầu, hãy cố gắng tìm một chương trình đang phát triển mà bạn quan tâm và trở thành người thử nghiệm beta giỏi. Có một tiến trình rất tự nhiên từ việc giúp kiểm tra các chương trình đến giúp gỡ lỗi và sau đó giúp sửa đổi chúng. Bạn sẽ học được rất nhiều điều theo cách này và tạo nghiệp tốt trong mối quan hệ với những người sẽ giúp đỡ bạn sau này.
  1. Đăng thông tin hữu ích. Một điều tốt nữa là chọn lọc và tích lũy thông tin hữu ích và thú vị trên các trang web hoặc tài liệu như Câu hỏi thường gặp (câu hỏi và câu trả lời thường gặp) và công khai chúng. Người tổ chức các Câu hỏi thường gặp về kỹ thuật chính gần như được tôn trọng như các tác giả của phần mềm nguồn mở.

    Giúp duy trì hoạt động của cơ sở hạ tầng. Văn hóa hacker (và kỹ thuật Internet) dựa trên tình nguyện viên. Có rất nhiều công việc cần thiết nhưng không đặc biệt hiệu quả cần được thực hiện để duy trì quy trình: quản lý danh sách gửi thư, kiểm duyệt các nhóm tin tức, quản lý kho lưu trữ phần mềm lớn, phát triển RFC và các tiêu chuẩn kỹ thuật khác. Những người làm tốt công việc này rất được kính trọng, bởi vì mọi người đều biết rằng loại công việc này tốn rất nhiều thời gian và không thú vị bằng việc chơi mã. Công việc này thể hiện sự cống hiến.

  2. Phục vụ chính văn hóa hacker. Cuối cùng, bạn có thể phục vụ và truyền bá văn hóa. Nhưng bạn không nên làm điều này cho đến khi bạn đã làm việc đó một thời gian dài và trở nên nổi tiếng nhờ một trong bốn điều đầu tiên. Không có những nhà lãnh đạo rõ ràng trong văn hóa hacker, nhưng có những “anh hùng văn hóa”, “trưởng lão bộ lạc”, các nhà sử học và diễn giả. Khi bạn sống trong những chiến hào này đủ lâu, bạn có thể phát triển thành một trong những người này.

    • Nhưng hãy cẩn thận: tin tặc cảnh giác với những trưởng lão bộ tộc to mồm của họ, vì vậy việc đạt được vinh quang rõ ràng như vậy là đầy nguy hiểm. Thay vì phấn đấu vì điều này, tốt hơn hết bạn đừng quan tâm đến nó và khi đó mọi thứ sẽ tự đến, chỉ khi đó bạn mới có thể trở nên khiêm tốn và nhân từ trong địa vị của mình.
  • Một số công ty thuê tin tặc để kiểm tra mức độ an toàn của hệ thống của họ. Vì vậy, bạn có thể kiếm tiền tốt từ việc này!
  • Cố gắng không để bị bắt và Không thực hiện một số hack.
  • Viết tốt bằng ngôn ngữ mẹ đẻ của bạn. Theo quan niệm chung, lập trình viên không phải là người biết chữ nhưng trên thực tế, nhiều hacker rất giỏi nói ngôn ngữ này.
  • Lisp rất đáng để học vì bạn sẽ có được sự giác ngộ sâu sắc khi cuối cùng bạn thành thạo nó. Kiến thức này sẽ giúp bạn trở thành một lập trình viên xuất sắc trong suốt quãng đời còn lại, ngay cả khi bạn chưa bao giờ thực sự sử dụng Lisp. Bạn có thể có trải nghiệm ban đầu với Lisp ở chế độ chỉnh sửa mã của trình soạn thảo văn bản Emacs hoặc plugin Script-Fu cho trình chỉnh sửa đồ họa GIMP.
  • Học Perl rất hợp lý vì những lý do thực tế: nó được sử dụng rất rộng rãi cho các trang web đang hoạt động và quản trị hệ thống, vì vậy ngay cả khi bạn không bao giờ phải viết Perl, bạn cũng nên học cách đọc nó. Nhiều người sử dụng Perl để tránh lập trình bằng C, vốn tiêu tốn nhiều tài nguyên.
  • Kiểm tra kiến ​​thức của bạn trên các trang web bạn tạo.
  • Hãy sử dụng kiến ​​thức và kỹ năng của bạn cho mục đích tốt. Trở thành một hacker giỏi sẽ an toàn hơn và mang lại nhiều lợi ích hơn cho mọi người so với việc trở thành một hacker tồi. Những hacker xấu có cuộc sống không mấy tốt đẹp - họ phải lẩn trốn để tránh rắc rối với pháp luật.
  • Luôn luôn cẩn thận. Các hoạt động bất hợp pháp có thể gây ra hậu quả rất nghiêm trọng và không có gì trên Internet thực sự ẩn danh.
  • Đừng tham gia vào bất cứ điều gì có thể dẫn đến rắc rối.
  • Hỏi các công ty địa phương xem họ có cần kiểm tra hệ thống an ninh không.

Cảnh báo

  • Hack là một hành vi bất hợp pháp có thể dẫn đến hình phạt nghiêm trọng. Hack là một tội ác và bị pháp luật trừng phạt.

Lập trình là công cụ chính của hacker. Nếu bạn chưa biết bất kỳ ngôn ngữ máy tính nào thì tôi khuyên bạn nên bắt đầu với Python. Nó được thiết kế rõ ràng, được ghi chép kỹ lưỡng và tương đối thân thiện với người mới bắt đầu. Mặc dù có thái độ thân thiện với người mới bắt đầu, nhưng nó không chỉ là một món đồ chơi mà còn là một công cụ rất mạnh mẽ và hữu ích. ngôn ngữ linh hoạt, rất phù hợp cho các dự án lớn. Tôi đã viết một bài đánh giá chi tiết hơn về Python. Có hướng dẫn xuất sắc dành cho người mới bắt đầu và hướng dẫn chính thức trên trang web Python và bạn cũng có thể tìm thấy các hướng dẫn xuất sắc ở nơi khác, một trong số đó là Vòng tròn Khoa học Máy tính.

Tôi đã từng khuyên dùng Java như một ngôn ngữ để học sớm, nhưng trước những lời chỉ trích này, tôi đã thay đổi quyết định (xem thêm: “Những cạm bẫy của Java như một ngôn ngữ lập trình đầu tiên”). Một hacker không thể tiếp cận vấn đề như thợ sửa ống nước trong cửa hàng giải quyết nó, anh ta phải biết chính xác điều gì làm mọi thành phần. Vì vậy, bây giờ tôi nghĩ rằng sẽ tốt hơn nếu học ngôn ngữ C và Lisp ngay từ đầu và chỉ sau chúng là Java.

Có lẽ có một cách tiếp cận tổng quát hơn cho vấn đề này. Khi bạn có một công cụ tốt để tạo ra thứ gì đó, nhưng có quá nhiều ngôn ngữ cho nó và việc học nó rất khó khăn. Không chỉ các ngôn ngữ lập trình có thể xử lý nhiệm vụ mà nhiều framework web khác nhau như RubyOnRails, CakePHP, Django cũng có thể giải quyết nhiệm vụ một cách dễ dàng nhưng sẽ để lại cho bạn kiến ​​thức hời hợt và bạn sẽ không thể giải quyết một vấn đề phức tạp hơn hoặc hiểu rõ hơn. vấn đề nếu nó xảy ra nhanh chóng và giải pháp dễ dàng sẽ không hoạt động chính xác.

Nếu bạn quyết định đi sâu vào lập trình nghiêm túc, thì bạn phải học cốt lõi của hệ điều hành Unix - ngôn ngữ C (phát âm là ). C++ (phát âm là Nơi biển) liên quan rất chặt chẽ với C, nếu bạn biết cái này thì việc học cái kia sẽ không khó. Mặc dù chúng không phải là ngôn ngữ dành cho người mới bắt đầu. Và trên thực tế, bạn càng tránh lập trình C thì bạn sẽ càng làm việc hiệu quả hơn.

C rất hiệu quả và rất tiết kiệm về tài nguyên máy. Tuy nhiên, sử dụng ngôn ngữ C sẽ có hiệu quả khi cần quản lý thủ công các tài nguyên cấp thấp như bộ nhớ. Tất cả các mã cấp thấp này đều phức tạp và dễ mắc lỗi, đồng thời cũng đòi hỏi bạn phải dành rất nhiều thời gian để gỡ lỗi (tìm và sửa lỗi). Khi tính đến sức mạnh của máy tính hiện đại, bạn có thể đưa ra quyết định thỏa hiệp - điều thông minh cần làm là chọn ngôn ngữ sử dụng tài nguyên máy tính kém hiệu quả hơn, nhưng hơn hiệu quả về mặt thời gian dành cho việc thực hiện. Sự đánh đổi đó là Python.

Các ngôn ngữ khác có tầm quan trọng hàng đầu đối với tin tặc là Perl và LISP. Học Perl rất hợp lý vì những lý do thực tế: nó được sử dụng rất rộng rãi cho các trang web đang hoạt động và quản trị hệ thống, vì vậy ngay cả khi bạn không bao giờ phải viết Perl, bạn cũng nên học cách đọc nó. Nhiều người sử dụng Perl cho mục đích này, nhưng tôi khuyên bạn nên sử dụng Python và tránh lập trình C trừ khi nhiệm vụ yêu cầu sử dụng tiết kiệm tài nguyên máy. Bạn cần phải hiểu mã như vậy.

LISP rất có giá trị để học vì một lý do khác - bạn sẽ có được kiến ​​thức sâu sắc khi học ngôn ngữ này đến cùng. Kiến thức này sẽ giúp bạn trở thành một lập trình viên xuất sắc trong suốt quãng đời còn lại, ngay cả khi bạn chưa bao giờ thực sự sử dụng LISP. (Bạn có thể học được các kỹ năng lập trình LISP ban đầu khá dễ dàng bằng cách tạo và sửa đổi các tiện ích mở rộng cho trình soạn thảo văn bản Emacs hoặc tạo plugin Script-Fu cho GIMP).

Trên thực tế, sẽ tốt hơn nếu bạn học cả 5 ngôn ngữ: Python, C/C++, Java, Perl và LISP. Ngoài việc là những ngôn ngữ hack quan trọng nhất, chúng còn thể hiện những cách tiếp cận lập trình rất khác nhau và mỗi ngôn ngữ sẽ dạy những cách tiếp cận có giá trị.

Nhưng hãy nhớ rằng bạn sẽ không đạt đến trình độ của một hacker hay thậm chí là một lập trình viên thông thường chỉ bằng cách thu thập ngôn ngữ - bạn phải học cách suy nghĩ về cách lập trình một cách tổng quát, bất kể ngôn ngữ nào. Để trở thành một hacker thực thụ, bạn phải đạt đến trình độ kiến ​​thức mà bạn có thể học một ngôn ngữ mới trong vài ngày, chỉ bằng cách xem hướng dẫn sử dụng ngôn ngữ đó và liên kết nó với kiến ​​thức hiện có của bạn. Và để trở nên như thế này, bạn cần phải biết một số ngôn ngữ có bản chất rất khác nhau.

Tôi không thể đưa ra hướng dẫn đầy đủ ở đây về cách học lập trình - đó là một nghệ thuật phức tạp. Nhưng tôi có thể nói với bạn rằng sách và khóa học cũng không làm được điều đó - nhiều cuốn có thể số đông Những hacker giỏi nhất là những người tự học. Bạn có thể học chức năng của ngôn ngữ (một phần nhỏ kiến ​​thức) từ sách vở, nhưng kiểu tư duy khiến kiến ​​thức này có thể áp dụng vào cuộc sống chỉ có thể có được thông qua thực hành và qua một thời gian học tập nhất định. Những gì chương trình thực sự có thể dạy là (a) đọc mã nguồn và B) viết mã nguồn .

Peter Norvig, một trong những hacker hàng đầu của Google và là đồng tác giả của cuốn sách giáo khoa nổi tiếng về AI (Trí tuệ nhân tạo), đã viết một bài báo tuyệt vời có tên Dạy bản thân lập trình trong mười năm. “Công thức lập trình thành công” của ông rất đáng được quan tâm đặc biệt.

Học lập trình cũng giống như học viết ngôn ngữ tự nhiên tốt. Cách tốt nhất để làm điều này là đọc một cái gì đó được viết bởi các bậc thầy văn học được công nhận, sau đó tự viết một chút; đọc thêm một chút, viết thêm một chút; đọc nhiều hơn - viết nhiều hơn... Và lặp lại điều này cho đến khi chương trình của bạn trông giống như một mô hình mạnh mẽ và có tổ chức.

Tôi đã nói nhiều hơn về quá trình này trong Cách học hack. Đây là một bộ hướng dẫn đơn giản và không dễ thực hiện.

Việc tìm kiếm mã nguồn tốt để nghiên cứu trước đây rất khó khăn vì có rất ít chương trình lớn về mã nguồn cho các hacker trẻ nghiên cứu và thử nghiệm. Giờ đây, tình hình đã thay đổi đáng kể: các chương trình mã nguồn, công cụ phát triển và toàn bộ hệ điều hành (tất cả đều do tin tặc tạo ra) hiện đã được phổ biến rộng rãi. Điều này đưa tôi đến thẳng phần tiếp theo...