| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/safe_browsing/zip_analyzer.h" | 5 #include "chrome/common/safe_browsing/zip_analyzer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <set> | 11 #include <set> |
| 12 | 12 |
| 13 #if defined(OS_MACOSX) |
| 14 #include <mach-o/fat.h> |
| 15 #include <mach-o/loader.h> |
| 16 #endif // OS_MACOSX |
| 17 |
| 13 #include "base/i18n/streaming_utf8_validator.h" | 18 #include "base/i18n/streaming_utf8_validator.h" |
| 14 #include "base/logging.h" | 19 #include "base/logging.h" |
| 15 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "build/build_config.h" |
| 16 #include "chrome/common/safe_browsing/archive_analyzer_results.h" | 22 #include "chrome/common/safe_browsing/archive_analyzer_results.h" |
| 17 #include "chrome/common/safe_browsing/binary_feature_extractor.h" | 23 #include "chrome/common/safe_browsing/binary_feature_extractor.h" |
| 18 #include "chrome/common/safe_browsing/download_protection_util.h" | 24 #include "chrome/common/safe_browsing/download_protection_util.h" |
| 19 #include "chrome/common/safe_browsing/file_type_policies.h" | 25 #include "chrome/common/safe_browsing/file_type_policies.h" |
| 20 #include "components/safe_browsing/csd.pb.h" | 26 #include "components/safe_browsing/csd.pb.h" |
| 21 #include "crypto/secure_hash.h" | 27 #include "crypto/secure_hash.h" |
| 22 #include "crypto/sha2.h" | 28 #include "crypto/sha2.h" |
| 23 #include "third_party/zlib/google/zip_reader.h" | 29 #include "third_party/zlib/google/zip_reader.h" |
| 24 | 30 |
| 25 namespace safe_browsing { | 31 namespace safe_browsing { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 53 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) | 59 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) |
| 54 return false; | 60 return false; |
| 55 sha256_->Update(data, num_bytes); | 61 sha256_->Update(data, num_bytes); |
| 56 return true; | 62 return true; |
| 57 } | 63 } |
| 58 | 64 |
| 59 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { | 65 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { |
| 60 sha256_->Finish(digest, digest_length); | 66 sha256_->Finish(digest, digest_length); |
| 61 } | 67 } |
| 62 | 68 |
| 69 #if defined(OS_MACOSX) |
| 70 bool StringIsMachOMagic(std::string bytes) { |
| 71 if (bytes.length() < sizeof(uint32_t)) |
| 72 return false; |
| 73 |
| 74 uint32_t magic; |
| 75 memcpy(&magic, bytes.c_str(), sizeof(uint32_t)); |
| 76 |
| 77 return magic == FAT_MAGIC || magic == FAT_CIGAM || magic == MH_MAGIC || |
| 78 magic == MH_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64; |
| 79 } |
| 80 #endif // OS_MACOSX |
| 81 |
| 63 void AnalyzeContainedFile( | 82 void AnalyzeContainedFile( |
| 64 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor, | 83 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor, |
| 65 const base::FilePath& file_path, | 84 const base::FilePath& file_path, |
| 66 zip::ZipReader* reader, | 85 zip::ZipReader* reader, |
| 67 base::File* temp_file, | 86 base::File* temp_file, |
| 68 ClientDownloadRequest::ArchivedBinary* archived_binary) { | 87 ClientDownloadRequest::ArchivedBinary* archived_binary) { |
| 69 std::string file_basename(file_path.BaseName().AsUTF8Unsafe()); | 88 std::string file_basename(file_path.BaseName().AsUTF8Unsafe()); |
| 70 if (base::StreamingUtf8Validator::Validate(file_basename)) | 89 if (base::StreamingUtf8Validator::Validate(file_basename)) |
| 71 archived_binary->set_file_basename(file_basename); | 90 archived_binary->set_file_basename(file_basename); |
| 72 archived_binary->set_download_type( | 91 archived_binary->set_download_type( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 bool advanced = true; | 128 bool advanced = true; |
| 110 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { | 129 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { |
| 111 if (!advanced) { | 130 if (!advanced) { |
| 112 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; | 131 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; |
| 113 return; | 132 return; |
| 114 } | 133 } |
| 115 if (!reader.OpenCurrentEntryInZip()) { | 134 if (!reader.OpenCurrentEntryInZip()) { |
| 116 DVLOG(1) << "Failed to open current entry in zip file"; | 135 DVLOG(1) << "Failed to open current entry in zip file"; |
| 117 continue; | 136 continue; |
| 118 } | 137 } |
| 138 |
| 119 const base::FilePath& file = reader.current_entry_info()->file_path(); | 139 const base::FilePath& file = reader.current_entry_info()->file_path(); |
| 140 bool current_entry_is_executable; |
| 141 #if defined(OS_MACOSX) |
| 142 std::string magic; |
| 143 reader.ExtractPartOfCurrentEntryToString(sizeof(uint32_t), &magic); |
| 144 current_entry_is_executable = |
| 145 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file) || |
| 146 StringIsMachOMagic(magic); |
| 147 #else |
| 148 current_entry_is_executable = |
| 149 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file); |
| 150 #endif // OS_MACOSX |
| 151 |
| 120 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { | 152 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { |
| 121 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); | 153 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); |
| 122 results->has_archive = true; | 154 results->has_archive = true; |
| 123 archived_archive_filenames.insert(file.BaseName()); | 155 archived_archive_filenames.insert(file.BaseName()); |
| 124 ClientDownloadRequest::ArchivedBinary* archived_archive = | 156 ClientDownloadRequest::ArchivedBinary* archived_archive = |
| 125 results->archived_binary.Add(); | 157 results->archived_binary.Add(); |
| 126 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); | 158 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); |
| 127 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) | 159 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) |
| 128 archived_archive->set_file_basename(file_basename_utf8); | 160 archived_archive->set_file_basename(file_basename_utf8); |
| 129 archived_archive->set_download_type( | 161 archived_archive->set_download_type( |
| 130 ClientDownloadRequest::ZIPPED_ARCHIVE); | 162 ClientDownloadRequest::ZIPPED_ARCHIVE); |
| 131 } else if (FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file)) { | 163 } else if (current_entry_is_executable) { |
| 132 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); | 164 #if defined(OS_MACOSX) |
| 133 results->has_executable = true; | 165 // This check prevents running analysis on .app files since they are |
| 134 AnalyzeContainedFile(binary_feature_extractor, file, &reader, &temp_file, | 166 // really just directories and will cause binary feature extraction |
| 135 results->archived_binary.Add()); | 167 // to fail. |
| 168 if (file.Extension().compare(".app") == 0) { |
| 169 DVLOG(2) << "Downloaded a zipped .app directory: " << file.value(); |
| 170 } else { |
| 171 #endif // OS_MACOSX |
| 172 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); |
| 173 results->has_executable = true; |
| 174 AnalyzeContainedFile(binary_feature_extractor, file, &reader, |
| 175 &temp_file, results->archived_binary.Add()); |
| 176 #if defined(OS_MACOSX) |
| 177 } |
| 178 #endif // OS_MACOSX |
| 136 } else { | 179 } else { |
| 137 DVLOG(3) << "Ignoring non-binary file: " << file.value(); | 180 DVLOG(3) << "Ignoring non-binary file: " << file.value(); |
| 138 } | 181 } |
| 139 } | 182 } |
| 140 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), | 183 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), |
| 141 archived_archive_filenames.end()); | 184 archived_archive_filenames.end()); |
| 142 results->success = true; | 185 results->success = true; |
| 143 } | 186 } |
| 144 | 187 |
| 145 } // namespace zip_analyzer | 188 } // namespace zip_analyzer |
| 146 } // namespace safe_browsing | 189 } // namespace safe_browsing |
| OLD | NEW |