- Блог начинающего Android developera
- суббота, 4 мая 2013 г.
- Взаимодействие с API и как правильно разбирать JSON в Android
- Анализ взаимодействия мобильных Android-приложений с API социальных сетей Facebook, Instagram, ВКонтакте
- Как это звучало на NeoQUEST?
- Зачем определять API?
- Как изучать API?
- Примеры и демонстрации
- ВАЖНО!
- ВКонтакте и незащищенный протокол HTTP
- Instagram и HTTPS
- Facebook и SSL Pinning
- В заключение
- Простой клиент-сервер на Android (интернет-мессенджер)
- Делаем сервер
- Клиентская часть
Блог начинающего Android developera
Именно здесь вы найдете самую интересную информацию о разработке на платформе Android , обзоры интересных гаджетов и просто новостей из мира IT.
суббота, 4 мая 2013 г.
Взаимодействие с API и как правильно разбирать JSON в Android
Вообще этот проект я делал для диплома , который еще кстати не защитил 🙂 Так для начала опишу серверную часть .
Имеем БД MySQL с таблицей categories внутри , чтобы получить содержимое таблицы и закодировать в JSON выполним следующее
function getCategories() <
if(isset($_GET[‘format’]) && intval($_GET[‘num’])) <
$format = strtolower($_GET[‘format’]);
$num = intval($_GET[‘num’]);
mysql_query(‘SET NAMES \’UTF8\»);
$result = mysql_query(‘SELECT * FROM categories ORDER BY `category_id` DESC LIMIT ‘ . $num) or die(‘MySQL Error.’);
if($format == ‘json’) <
$сategories = array();
while($category = mysql_fetch_array($result, MYSQL_ASSOC)) <
$categories[] = array(‘category’=>$category); >
$output = json_encode($categories); echo $output;
>
>
>
if($_REQUEST[‘function’]==’getCategories’)
getCategories();
То есть чтобы сделать запрос и получить ответ в JSON в браузере делаем следующее :
http://superquiz.zz.mu/api.php?format=json&num=10&function=getCategories
Так теперь перейдем к клиентской части. Я делал общий класс API у которого будут методы для получения категорий , списка тестов , статистики и т.д . Опишу метод получения категорий.
public class API <
private HttpClient client;
private HttpGet httpGet;
private BufferedReader in;
private JSONObject mainJsonObject, innerJsonObject;
private ArrayList categoriesArr = new ArrayList ();
private static final String TAG_CATEGORY = «category»;
private static final String TAG_CATEGORY_ID = «category_id»;
private static final String TAG_CATEGORY_NAME = «category_name»;
public API() <
client = new DefaultHttpClient();
>
public ArrayList getCategoryQuiz() <
httpGet = new HttpGet( «http://superquiz.zz.mu/api.php? format=json&num=10&function=getCategories»);
try <
HttpResponse response = client.execute(httpGet);
in = new BufferedReader(new InputStreamReader(response.getEntity() .getContent()));
StringBuffer sb = new StringBuffer(«»);
String line = «»;
while ((line = in.readLine()) != null) <
sb.append(line + «\n»);
>
in.close();
String result = sb.toString();
JSONArray jsonMainArr = new JSONArray(result);
for (int i = 0; i
mainJsonObject = jsonMainArr.getJSONObject(i);
innerJsonObject = mainJsonObject.getJSONObject(TAG_CATEGORY);
int String name = innerJsonObject.getString(TAG_CATEGORY_NAME);
categoriesArr.add(new Categories(id, name)); >
> catch (Exception e) <
e.printStackTrace();
> return categoriesArr;
>
Теперь разберем что мы здесь наделали. Делаем GET запрос и получаем JSON ответ записывая его в StringBuilder. Затем формируем JSONArray из нашего ответа. После этого «растаскиваем» наш JSONArray на объекты и добавляем его в ArrayList из категорий. Кому не понятно как создать класс категорий выкладываю.
Источник
Анализ взаимодействия мобильных Android-приложений с API социальных сетей Facebook, Instagram, ВКонтакте
Не секрет, что большинство крупных сервисов на серверной стороне используют какой-либо API (Application Programming Interface) для взаимодействия с различными клиентами.
На «очной ставке» NeoQUEST-2016 Максим Хазов рассказал о различных подходах к определению и использованию скрытого серверного API-функционала на примере таких популярных сервисов, как ВКонтакте, Instagram, Facebook.
В данной статье остановимся на основных моментах доклада и поделимся всеми электронными материалами: видеозаписью выступления, презентацией, а также демонстрациями атак для каждой рассматриваемой социальной сети (всё под катом).
Намекнём: «прогулки» по социальным сетям ещё предстоят участникам NeoQUEST-2017, регистрация на online-этап которого идет полным ходом!
Как это звучало на NeoQUEST?
Сразу же, как и обещали, делимся презентацией (тык) и докладом:
Зачем определять API?
Основных цели в данном случае две:
- Искать уязвимости (на серверной стороне или в протоколе взаимодействия).
- Автоматизировать действия в социальных сетях (всеми любимые “боты”).
Подобных ботов можно назвать “хамелеонами”, так как они будут мимикрировать под официальное мобильное приложение сервиса, выполняя такие же запросы с такой же структурой. На серверной стороне будет непросто отличить такого бота от настоящего пользователя мобильного приложения.
Как изучать API?
Есть 3 главных направления:
- Изучение документации (хорошо, если она есть!);
- Анализ сетевого трафика (наиболее простой способ, далее выбран в качестве основного);
- Реверс-инжиниринг мобильного приложения (наиболее “хардкорный” способ, но иногда без него не обойтись).
Примеры и демонстрации
Для демонстраций была использована контролируемая Wi-Fi точка, а также прокси для HTTP-запросов Burp Suite. В данном случае все тестируемые приложения взаимодействовали с API с помощью протокола HTTP и его модификаций.
ВАЖНО!
Исследование проводилось весной-летом 2016 года, на данный момент в архитектуре приложений и протоколов взаимодействия могут быть изменения (например, с ноября 2016 приложение ВКонтакте для Android больше не поддерживает протокол HTTP).
ВКонтакте и незащищенный протокол HTTP
Мобильное приложение ВКонтакте под Android по умолчанию использует протокол HTTP, а значит (как было показано в первой части доклада, видеозапись которого в конце статьи):
- Приложение уязвимо для атак типа Man in the Middle (MITM). Тем не менее, API предусматривает некоторые меры защиты от модификации и повторения запросов.
- Не составляет никакого труда проанализировать API, используемое приложением (хотя к нему и так существует открытая документация).
В демонстрации показан перехват незашифрованного трафика и нахождение в нем запроса к API, отвечающего за отправку сообщения.
Instagram и HTTPS
Во второй части доклада было рассмотрено приложение Instagram под Android, для взаимодействия с API оно использует защищенный протокол HTTPS (HTTP + SSL). Это значит, что в общем случае (при отсутствии доступа к устройству у исследователя и достаточно современной версии TLS) протокол взаимодействия не уязвим к атакам MITM.
Но, имея доступ к телефону, можно установить на него свой корневой сертификат и легко расшифровывать трафик, подменяя сертификаты для HTTPS соединений (BurpSuite умеет это делать в автоматическом режиме). В демонстрации показаны перехват шифрованного трафика после установки на телефон контролируемого корневого сертификата и нахождение в нем запроса к API, отвечающего за лайк к фотографии.
У Instagram существует публичное документированное API для разработчиков. В нем заданы достаточно строгие лимиты для ключевых функций (лайки, подписки, постинг и т.д.). Как выяснилось, приложение Instagram использует другое, приватное API, в котором, разумеется, подобных лимитов нет.
Чем интересно это приватное API в плане “ботоведения”? Главное отличие приватного API: подпись всех важных запросов секретным ключом (уникальным для версии приложения). Так как ключ хранится внутри приложения, можно достать его с помощью реверс-инжиниринга приложения.
Facebook и SSL Pinning
В третьей части доклада было рассмотрено приложение Facebook под Android. Данное приложение для взаимодействия с API использует защищенный протокол HTTPS + надстройку под названием SSL Pinning.
SSL Pinning – внедрение в код мобильного приложения SSL-сертификата сервера API. Эта технология предназначена для защиты от перехвата трафика путем установки корневого сертификата на устройство и подмены сертификатов.
Тем не менее, SSL Pinning можно отключить (и даже разными способами):
- С помощью декомпиляции и модификации приложения (сложный способ).
- Модифицируя низкоуровневые SSL функции на устройстве (требует root-доступ, не всегда работает стабильно). Программы Android SSL Bypass, iOS SSL KillSwitch работают именно по этому принципу.
В докладе был продемонстрирован способ отключения SSL Pinning в мобильном приложении Facebook под Android (с помощью удаления одной из библиотек, используемых приложением – libsslx.so) и последующий успешный перехват трафика.
Как выяснилось при анализе трафика, мобильное приложение Facebook использует некоторые недокументированные методы API (в том числе, для регистрации аккаунтов и входа в систему).
Также был найден недокументированный метод API, позволяющий получить ID пользователя Facebook по номеру телефона. Вот как выглядит демонстрация возможного автоматизированного использования полученных недокументированных методов:
В заключение
При должном желании всегда можно проанализировать протокол взаимодействия между мобильным приложением и сервером. Использование дополнительных средств защиты (таких, как SSL Pinning) может лишь несколько затруднить работу исследователю. Поэтому разработчикам следует избегать использования привилегированных недокументированных методов API в приложении (особенно если есть публичное и документированное API).
Кроме того, есть возможность сделать бота, который будет отправлять точно такие же запросы, как официальное мобильное приложение. Для борьбы с подобными ботами можно порекомендовать усложнять структуру запросов к API и тщательно анализировать все параметры запросов на серверной стороне.
На «очной ставке» NeoQUEST-2017, которая пройдет 29 июня в Питере, как и всегда, будут классные доклады о самых актуальных тенденциях кибербезопасности, современных механизмах защиты и способах их обхода.
Если ты не из Питера, смело планируй свой отпуск на июнь и приезжай! Белые ночи, разводные мосты, бесконечные дожди и NeoQUEST-2017 космической тематики с докладами, демонстрациями, конкурсами и призами — все это ждет тебя. Также ты можешь посетить «очную ставку» как участник hackquest и сразиться за главный приз — поездку на одну из международных конференций по информационной безопасности! Для этого — регистрируйся тут и с 1 по 10 марта проходи задания online-этапа. Возможно, именно ты окажешься лучшим? Узнаем 10 марта…
Источник
Простой клиент-сервер на Android (интернет-мессенджер)
Важно. Все написанное ниже не представляет собой какой либо ценности для профессионалов, но может служит полезным примером для начинающих Android разработчиков! В коде старался все действия комментировать и логировать.
Поехали. Многие мобильные приложения (и не только) используют архитектуру клиент-сервер. Общая схема, думаю, понятна.
Уделим внимание каждому элементу и отметим:
- сервер — представляет собой некую программу, работающую на удаленном компьютере, и реализующую функционал «общения» с приложениями-клиентами (слушает запросы, распознает переданные параметры и значения, корректно отвечает на них);
- клиент — в нашем случае, программа на мобильном устройстве, которая умеет формировать понятный серверу запрос и читать полученный ответ;
- интерфейс взаимодействия — некий формат и способ передачи/получения запросов/ответов обеими сторонами.
Неважно, как реализован любой из этих элементов, все они в любом случае присутствуют. Давайте реализуем примитивный сервер и Android клиент, работающий с ним. Как пример, будем использовать любой популярный мобильный интернет-мессенджер (Viber, ICQ), а приложение условно назовем «интернет-чат».
Схема взаимодействия следующая:
Клиент, установленный на устройстве А, посылает сообщение для клиента, установленного на устройстве Б. И наоборот. Сервер играет роль связующего звена между устройством А и Б… С, Д… и т.д. Также он играет роль «накопителя» сообщений, для их восстановления, на случай удаления на одном из клиентских устройств.
Для хранения сообщений используем SQL БД как на сервере, так и на устройствах-клиентах (в принципе, вся работа клиентов интернет-мессенджеров и сводится к постоянной синхронизации локальной и удаленной БД с сообщениями). Дополнительно, наш интернет-чат будет уметь стартовать вместе с запуском устройства и работать в фоне. Взаимодействие будет происходить путем HTTP запросов и JSON ответов.
Более логично, если синхронизация происходит через порт/сокет, это с одной стороны упрощает задачу (не нужно циклично слать HTTP запросы на проверку новых сообщений, достаточно проверять состояние прослушиваемого сокета), но с другой стороны, это усложняет создание серверной части приложения.
Делаем сервер
Для реализации «сервера», нам нужно зарегистрироваться на любом хостинге, который дает возможность работы с SQL и PHP.
Создаем пустую SQL БД, в ней создаем таблицу.
- author — автор сообщения;
- client — получатель сообщения;
- data — время и дата получения сообщения на сервере;
- text — сообщение.
В двух следующих файлах необходимо изменить переменные, содержащие данные для доступа к БД, на свои, полученные Вами при регистрации Вашего«сервера».
Структура запросов к api:
- обязательный атрибут action — может быть равен select (сервер ответит списком записей из своей БД), insert (сервер добавить новую запись в свою БД), delete (сервер очистит свою БД)
- если action=insert, нам нужно будет передать дополнительные параметры: author (кто написал сообщение), client (кому адресовано сообщение), text (сообщение)
- action=select может содержать дополнительный параметр data, в этом случае ответ сервера содержит не все сообщения из БД, а только те, у которых время создания позднее переданного
Примеры:
- chat.php?action=delete – удалит все записи на сервере
- chat.php?action=insert&author=Jon&client=Smith&text=Hello — добавит на сервере новую запись: автор Jon, получатель Smith, содержание Hello
- chat.php?action=select&data=151351333 — вернет все записи, полученные после переданного времени в long формате
Клиентская часть
Теперь структура Android приложения:
В фоне работает FoneService.java, который, в отдельном потоке, каждые 15 секунд делает запрос на сервер. Если ответ сервера содержит новые сообщения, FoneService.java записывает их в локальную БД и отправляет сообщение ChatActivity.java о необходимости обновить ListView, с сообщениями. ChatActivity.java (если она в этот момент открыта) получает сообщение и обновляет содержимое ListView из локальной БД.
Отправка нового сообщения из ChatActivity.java происходит сразу на сервер, минуя FoneService.java. При этом наше сообщение НЕ записывается в локальную БД! Там оно появится только после получения его назад в виде ответа сервера. Такую реализацию я использовал в связи с важным нюансом работы любого интернет-чата — обязательной группировкой сообщений по времени. Если не использовать группировку по времени, будет нарушена последовательность сообщений. Учитывая, что клиентские приложения просто физически не могут быть синхронизированы с точностью до миллисекунд, а возможно будут работать даже в разных часовых поясах, логичнее всего будет использовать время сервера. Так мы и делаем.
Создавая новое сообщение, мы передаем запросом на сервер: имя автора сообщения, имя получателя сообщения, текст сообщения. Получая эту запись назад, в виде ответа сервера, мы получаем то, что отправляли + четвертый параметр: время получения сообщения сервером.
Источник