Приключения в S3 Scraping — часть 1
Вы не поверите, какими странными файлами люди делятся в корзинах S3. Вещи, которые они, вероятно, не должны. Вещи, которые они определенно не должны.

Только в этом месяце я видел такие файлы, как:
- Лицензионные ключи к программному обеспечению компании.
- Документ Excel с конференции по СМИ, содержащий имена, адреса электронной почты и номера телефонов сотрудников местных СМИ в 9 разных штатах.
- Документ Powerpoint для латиноамериканского подразделения крупной технологической компании с пометкой «Проприетарно и конфиденциально» (мой испанский немного заржавел), в котором, как я полагаю, указаны затраты/сборы/доходы за предлагаемые услуги.
- 45 000–50 000 документов в формате PDF, содержащих персональные данные клиентов (полные имена, адреса электронной почты, номера телефонов и местонахождение) для компании, которая прекратила свою деятельность за последние 2 года. (Я сообщил о корзине в службу поддержки AWS и обсудим проблему более подробно, ЕСЛИ они примут меры и защитят данные в ближайшем будущем.)
- Скан в высоком разрешении чьих-то водительских прав, страховой карты и регистрации транспортного средства за 2015–2016 годы. (В попытке приличия я попытался связаться с этим человеком, найдя его в LinkedIn и Google, только чтобы найти человека с таким же именем, датой рождения и адресом, который был осужден в 2021 году за довольно серьезное преступление и сейчас отбывает срок, таким образом Я не потеряю сон из-за того, что его документы 7-летней давности находятся в Интернете).
В течение последних 10 лет я предполагал, что люди будут лучше оснащены и будут иметь лучшие инструменты, чтобы заблокировать свой контент и делиться только тем, чем следует делиться. Я был неправ. Так зачем через 10 лет повторять эту деятельность? Для развлечения и осознания. Также прошло несколько лет с тех пор, как я написал сколько-нибудь существенное количество кода, поэтому я хотел вернуться и отточить некоторые навыки.
Как просмотреть файлы корзины?
Во-первых, я хотел идентифицировать существующие корзины S3, которые могут быть в определенном регионе AWS (us-east, us-west и т. д.). Если бы у меня было действительное имя для корзины, я мог бы затем попробовать его в веб-браузере и посмотрите, указано ли в нем содержимое ведра. Это не означает, что сами файлы можно просмотреть, но, по крайней мере, позвольте мне увидеть пути к файлам для дальнейшего изучения этих файлов.
Например, если имя корзины «MyObviciousFakeBucket» было общедоступным и находилось в регионе AWS «Восток США 1», вы потенциально могли бы увидеть содержимое в своем веб-браузере, посетив https://myobviciousfakebucket.s3.us-east-1. amazonaws.com/
Это вернет список, аналогичный следующему частично отредактированному изображению.

В XML-документе, который отображается в результате, вы можете увидеть записи файлов под каждым тегом «Содержание». Для каждого узла «Содержание» есть узел
«Ключ», который отображает путь к файлу и имя каждого файла. Таким образом, для файла «interesting-text-file.txt» вы потенциально можете проверить доступ к файлу, добавив путь в конец URL-адреса корзины, например:
https://myobviciousfakebucket.s3.us-east-1.amazonaws.com/interesting-text-file.txt
Если файл можно было просмотреть, он откроется в браузере или запустит автоматическую загрузку (в зависимости от типа файла и вашего браузера). Если бы у вас не было доступа, вы бы увидели результат XML, по существу отображающий сообщение «Отказано в доступе».
Несмотря на все усилия AWS, все еще есть люди, которые делают контент общедоступным, когда этого делать не следует. Я не работал с S3 несколько лет, поэтому, возможно, я что-то упускаю, но, похоже, требуется НЕСКОЛЬКО шагов, прежде чем ваш сегмент можно будет легко перечислить и просмотреть в веб-браузере.
При создании новой корзины по умолчанию установлен флажок «Блокировать весь публичный доступ». Вы должны снять флажок, а затем установить флажок «Я подтверждаю» ниже. Смотри ниже.

Даже когда моя корзина настроена так, чтобы не «блокировать весь публичный доступ», когда я добавлял два образца текстовых файлов, я все еще не мог перечислить содержимое корзины в своем веб-браузере, пока не добавил политику корзины JSON, явно предоставляющую публичный доступ.
{
"Version": "2012-10-17",
"Id": "Policy1669653712601",
"Statement": [
{
"Sid": "Stmt1669653708988",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::myobviouslyfakebucket"
}
]
}
Общий подход
Итак, как составить список содержимого корзины, не угадывая случайным образом? Моими основными двумя вариантами достижения этого помимо одного имени корзины моего собственного изобретения было использование файла словаря в паре либо с AWS SDK, либо с простым HTTP GET.
Для первой версии я решил написать Java-код, используя простой HTTP GET. Это избавило от необходимости изучать обновленный AWS Java SDK v2. В последний раз, когда я использовал AWS Java SDK, это была версия 1, и в нем было достаточно изменений, поэтому я не хотел, чтобы кривая обучения задерживала мой прогресс. Я также мог избежать необходимости настраивать учетные данные AWS для использования SDK и любых ошибок или странностей, связанных с SDK, которые возникали во время тестирования. Будь проще.
Я начал с существующего файла словаря, который был у меня из предыдущего личного проекта. Это был простой текстовый файл с одним словом в строке. В какой-то момент я разбил его на 8 или 10 отдельных файлов, каждый из которых содержал записи для 1–3 букв в зависимости от количества записей. Это позволило мне легче обрабатывать меньшее количество записей за раз. Вы можете поискать файл словаря в Интернете, так как их много.
Я набросал шаги, необходимые для программирования, на двух стикерах. Они были следующими:
- Проанализируйте файл словаря, чтобы получить каждую запись слова.
- Для каждого слова в списке создайте URL-адрес для проверки, используя слово в качестве имени корзины и региона AWS (сейчас жестко запрограммировано на «Восток США 1»).
- Попробуйте подключиться к URL-адресу, чтобы выполнить операцию GET.
- Получите код ответа, отправленный с сервера.
- Если код ответа указывает на успех (ведро существует), добавьте слово в структуру данных.
- Сохраните успешные слова в структуре данных в простой текстовый файл для дальнейшего изучения.
Разобрать файл словаря
private void populateList(List<String> words, String dictionaryFile) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File(dictionaryFile)));
String line;
while ((line = br.readLine()) != null) {
words.add(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) { }
}
}
Создайте URL-адрес
String currentRegion = "us-east-1";
int wordSize = words.size();
for (int i = 0; i < wordSize; i++) {
String bucketName = words.get(i);
String sUrl = "https://" + bucketName + ".s3." + currentRegion + ".amazonaws.com";
URL url = new URL(sUrl);
// do something with the URL
}
Выполнить операцию ПОЛУЧИТЬ
String sUrl = "https://" + bucketName + ".s3." + currentRegion + ".amazonaws.com/";
URL url = new URL(sUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
Получить код ответа и сохранить его
int respCode = connection.getResponseCode();
if (respCode == 200) {
code200s.add(bucketName + "," + currentRegion);
}
Сохраните допустимые имена сегментов
private void writeCode200s(List<String> validBuckets, String parentDirectory) {
if(validBuckets == null || validBuckets.isEmpty()) {
return;
}
BufferedWriter bw = null;
try {
File parentDirectory = new File(parentDirectory);
if (!parentDirectory.exists()) {
parentDirectory.mkdirs();
}
FileWriter writer = new FileWriter(new File(parentDirectory, "valid_buckets_" + System.currentTimeMillis()+ ".txt"));
bw = new BufferedWriter(writer);
for (int i = 0; i < validBuckets.size(); i++) {
String bucketName = validBuckets.get(i);
bw.write(bucketName);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (Exception e) { }
}
}
Вот и все. Просто и понятно. Возможно, это было не самое элегантное решение, но оно сработало и послужило основой, позволившей мне расширить и улучшить его. Я идентифицировал тысячи действительных сегментов S3, просто соскребая несколько букв алфавита. Всего за несколько первых попыток я нашел каталоги файлов MP3, миллионы изображений, бесчисленное количество файлов журналов и многое другое.
С тех пор я удалил свою тестовую корзину «myobviiouslyfakebucket», так что не стесняйтесь претендовать на это имя, если хотите. В следующих нескольких частях этой серии статей я расскажу о дополнительных шагах по улучшению этого решения, таких как:
- Обработка и хранение кодов ответов для сегментов, кроме 200 (ОК), их значение и действия с этой информацией.
- Использование списка допустимых имен корзин, чтобы увидеть, можете ли вы перечислить список файлов в этой корзине.
- Разбор списка файлов корзины для захвата пути и имени отдельных файлов.
- Фильтруйте файлы по расширению файла, чтобы игнорировать нежелательный шум.
- Разбивка результатов файлов на страницы для корзин S3 с более чем 1000 файлов.
- Проверка списков файлов на предмет возможности загрузки отдельных файлов.