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) | |
Robert Sesek
2017/08/03 15:43:36
Platform-specific includes usually come after the
mortonm
2017/08/03 17:09:12
Done.
| |
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" | |
Robert Sesek
2017/08/03 15:43:36
note: build_config.h is probably required for the
mortonm
2017/08/03 17:09:12
Acknowledged.
| |
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 || | |
Robert Sesek
2017/08/03 15:43:36
Rather than duplicating this, can you use MachOIma
mortonm
2017/08/03 17:09:12
Good call, thanks.
| |
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( |
73 download_protection_util::GetDownloadType(file_path)); | 92 download_protection_util::GetDownloadType(file_path)); |
74 archived_binary->set_length(reader->current_entry_info()->original_size()); | 93 archived_binary->set_length(reader->current_entry_info()->original_size()); |
75 HashingFileWriter writer(temp_file); | 94 HashingFileWriter writer(temp_file); |
76 if (reader->ExtractCurrentEntry(&writer)) { | 95 if (reader->ExtractCurrentEntry(&writer, |
96 std::numeric_limits<uint64_t>::max())) { | |
77 uint8_t digest[crypto::kSHA256Length]; | 97 uint8_t digest[crypto::kSHA256Length]; |
78 writer.ComputeDigest(&digest[0], arraysize(digest)); | 98 writer.ComputeDigest(&digest[0], arraysize(digest)); |
79 archived_binary->mutable_digests()->set_sha256(&digest[0], | 99 archived_binary->mutable_digests()->set_sha256(&digest[0], |
80 arraysize(digest)); | 100 arraysize(digest)); |
81 if (!binary_feature_extractor->ExtractImageFeaturesFromFile( | 101 if (!binary_feature_extractor->ExtractImageFeaturesFromFile( |
82 temp_file->Duplicate(), | 102 temp_file->Duplicate(), |
83 BinaryFeatureExtractor::kDefaultOptions, | 103 BinaryFeatureExtractor::kDefaultOptions, |
84 archived_binary->mutable_image_headers(), | 104 archived_binary->mutable_image_headers(), |
85 archived_binary->mutable_signature()->mutable_signed_data())) { | 105 archived_binary->mutable_signature()->mutable_signed_data())) { |
86 archived_binary->clear_image_headers(); | 106 archived_binary->clear_image_headers(); |
(...skipping 23 matching lines...) Expand all Loading... | |
110 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { | 130 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { |
111 if (!advanced) { | 131 if (!advanced) { |
112 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; | 132 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; |
113 return; | 133 return; |
114 } | 134 } |
115 if (!reader.OpenCurrentEntryInZip()) { | 135 if (!reader.OpenCurrentEntryInZip()) { |
116 DVLOG(1) << "Failed to open current entry in zip file"; | 136 DVLOG(1) << "Failed to open current entry in zip file"; |
117 continue; | 137 continue; |
118 } | 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.ExtractCurrentEntryToString(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 |