2013-02-10 40 views
7

Tôi có trường hợp sử dụng nơi chúng tôi cho phép người dùng tải tệp lên. Bây giờ trong java kết thúc trở lại (điều khiển mà trích xuất tập tin từ yêu cầu và kiểm tra http), tôi muốn phát hiện nếu người dùng tải lên bất kỳ tập tin thực thi. Nếu anh ấy tải lên, tôi phải loại bỏ tập tin đó. Tôi đã googled nó nhưng không thể tìm thấy một giải pháp tốt. Một số người đề nghị xác minh phần mở rộng (.exe). Nhưng tôi không chắc chắn nó sẽ lọc các tập tin exe đến mức nào. Tôi muốn chặn hoàn toàn các tệp thi hành được khi tải lên.Phát hiện tệp thi hành trong java

Nếu có ai trong số các bạn gặp phải tình huống này hoặc có giải pháp về vấn đề này, vui lòng cho tôi biết. Tôi sẽ biết ơn bạn.

Tôi sẽ vui hơn nếu bạn có thể chỉ cho tôi bất kỳ triển khai JAVA hoặc Java API hoặc thuật toán nào cam thực hiện công việc này.

+0

Bất kỳ đề xuất nào khác không? – Rajeev

Trả lời

9

tôi nghi ngờ rằng, ngoài phương pháp kiểm tra mở rộng mà bạn đã đề cập, sẽ không có cách nào để nắm bắt mọi trường hợp có thể xảy ra. Các tệp thực thi cuối cùng là chuỗi các lệnh máy khiến chúng không thể phân biệt được với bất kỳ dữ liệu nào khác.

Mặc dù vậy, có những thứ bạn có thể tìm kiếm trong một số loại nhất định có thể thực thi được. Ví dụ:

  • Windows sử dụng định dạng Portable Executable, mà phải luôn luôn bắt đầu với số 4d5a (ký tự ASCII MZ) ma thuật định dạng
  • ELF thực thi được sử dụng bởi Linux bắt đầu với 7f454c46
  • Java class files luôn bắt đầu với cafebabe (đó là hex, không phải ASCII!).
  • Theo như tôi thấy, Mach-O file được sử dụng bởi Mac OSX có sự kỳ diệu số feedface (hex nữa)

Tôi đề nghị bạn tạo một FileInputStream hoặc tương tự và đọc một vài byte đầu tiên của tập tin, kiểm tra các số ma thuật này. Nó không phát hiện bất kỳ tập tin nào có chứa mã thực thi, nhưng nó sẽ dừng các tệp trong các định dạng thực thi chuẩn này khỏi được cho phép, mà tôi nghĩ là những gì bạn mong muốn.

Vì vậy, ví dụ:

public static boolean isExecutable(File file) { 
    byte[] firstBytes = new byte[4]; 
    try { 
    FileInputStream input = new FileInputStream(file); 
    input.read(firstBytes); 

    // Check for Windows executable 
    if (firstBytes[0] == 0x4d && firstBytes[1] == 0x5a) { 
     return true; 
    } 
    return false; 
    } 
    catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 

Cũng hãy cẩn thận rằng có thể để có được một dương tính giả, nơi bạn từ chối một tập tin mà không phải thực thi. Tôi không biết loại tệp bạn định tải lên nên bạn nên xem xét khả năng xảy ra điều này.

+0

cảm ơn đề nghị của bạn. Tôi đã đi qua wiki và tìm thấy các loại giải pháp tương tự. Dưới đây là những wiki tôi nhận được: http://www.csn.ul.ie/~caolan/publink/winresdump/winresdump/doc/pefile2.html Tôi thực sự hạnh phúc hơn, nếu bạn có thể hướng dẫn tôi cách kiểm tra ba điều kiện trên bạn đã đề cập trong java – Rajeev

+0

Có, điều đó xác nhận những gì tôi đã tìm thấy: các tệp thực thi windows luôn bắt đầu bằng ASCII 'MZ' (hoặc hex' 4d5a'). Tôi đã cập nhật câu trả lời của mình để bao gồm Mac OSX cũng như – jazzbassrob

+0

Tôi đã cập nhật với một mẫu mã cho Windows. Tôi sẽ để nó cho bạn để tìm ra cách để kiểm tra những người khác. Hy vọng rằng sẽ giúp. – jazzbassrob

0

Thực thi Windows luôn bắt đầu bằng số ma thuật MZ. Có lẽ bạn có thể kiểm tra điều này.

+0

Tôi đã đi qua wiki và tìm thấy bên dưới hai wiki: http://www.delphidabbler.com/articles?article=8&part=1 http://stackoverflow.com/questions/2863683/how-to-find-if -a-file-is-an-exe Nhưng không quá rõ ràng. Họ đã đề xuất cho cheking PE..Nhưng cần thêm thông tin về điều đó giống như cách kiểm tra và thực hiện – Rajeev

0

Theo như tôi đã thấy, cách tiếp cận thông thường nhất là xác minh tiện ích. Ví dụ: tôi đã nhận thấy rằng ứng dụng thư khách thường chấp nhận gửi tệp thực thi nếu nó được đổi tên, ví dụ: để nén hoặc một số tiện ích mở rộng khác.
Tôi tin rằng điều này có vẻ phù hợp vì vấn đề bảo mật là nếu người dùng vô tình chạy tệp thực thi. Bằng cách đổi tên tệp thành một tiện ích mở rộng không xác định/khác, người dùng không thể vô tình làm điều đó và do đó nguy hiểm bằng cách nào đó "giảm nhẹ"
Nếu không, hãy tìm cách xem nội dung tệp để xác định xem bạn có thực thi hay không không biết khả thi như thế nào/xách tay/đáng tin cậy này là

0

có một cái nhìn ở đây:

Is there a good way to determine if a file is executable in Java

có vẻ như lệnh này có thể giúp: java.io.File.canExecute()

+1

Thật không may, điều đó chỉ xác định xem tệp có * quyền * thực thi hay không - không phải là tệp thực sự có chứa mã thực thi – jazzbassrob

+0

Như jazzbassrob nói, điều này sẽ không giúp được gì. Nó không thể phát hiện dữ liệu thực thi là có trong tập tin hay không – Rajeev

+0

tôi đã đi qua các liên kết bạn đã đề cập. Nó không liên quan đến câu hỏi tôi đang hỏi chính xác .... – Rajeev

0

Hãy nhận biết rằng cửa sổ thực thi không chỉ .exe tập tin để kiểm tra phần mở rộng sẽ không đủ

Nếu bạn muốn một cái gì đó cao cấp và khó khăn để đánh lừa, bạn có thể sử dụng một công cụ của bên thứ ba như File for Windows nó là một phổ biến công cụ dòng lệnh đã được chuyển từ Linux.

ví dụ, nếu bạn muốn kiểm tra một số tập tin program.exe

C:\file -b "program.exe" 

Kết quả sẽ được một cái gì đó giống như

PE32 executable for MS Windows <GUI> Intel 

Bạn có thể chạy công cụ này từ một chương trình Java sử dụng Runtime.getRuntime().exec()

Xem this question để tìm hiểu cách chạy chương trình dòng lệnh và nhận kết quả đầu ra trong Java

Bạn cũng có thể kiểm tra Apache Tika để nhận loại tệp từ nội dung của nó

+0

Làm thế nào tôi có thể làm điều này trong java? – Rajeev

+0

Sự phụ thuộc nào tôi cần thêm ... Sẽ hữu ích hơn nếu mọi người có thể cung cấp chương trình mẫu phát hiện tệp thực thi?Cũng biết ơn bạn nếu bạn có thể ném ánh sáng vào âm bản của việc sử dụng phương pháp này như trường hợp cạnh mà nó có thể bỏ lỡ hoặc nó có thể xử lý tập tin bình thường như là một thực thi. – Rajeev

+0

Bạn không cần phải thêm bất kỳ thứ gì trong Java (ví dụ: jars), nếu bạn có thể chạy lệnh từ 'cmd', bạn có thể gọi trực tiếp từ Java bằng cách sử dụng' getRuntime(). Exec() ' – iTech

Các vấn đề liên quan