Hackowanie Tenda CP7

Cześć,
Może kogoś to zainteresuje: iot-vul/README.md at efe24fd88d7f594cdd2f714d3f0741f939924d70 · fxc233/iot-vul · GitHub
Sprawdziłem na CP7 z najnowszym firmware i bez problemu można uzyskać telnet. Hash właśnie leci i się “łamie” więc niedługo pewnie jakiś update z oficjalnym hasłem do roota. W telnecie jest dostępnych dużo skryptów, m. in. idump.sh, który służy do zrobienia dumpu całego systemu i wszystkich partycji (opcjonalnie na kartę sd - zaraz będę robił, tak na wszelki wypadek). Dalsza analiza w trakcie - jak ktoś chce się pobawić i podzielić odkryciami to zapraszam :wink:

Sposoby na update:

  • z palca przez telnet
  • z karty SD
  • ota przez aplikacje (prawdopodobnie tftp?)
  • tftp

Telnet - port 23:

Shadow: root:7h2yflPlPVV5.:0:0:root:/root:/bin/sh
Login: root
Hasło: tdrootfs

uname -a

Linux (none) 4.9.129 2022-08-18 11:50:53 armv6l

mount

rootfs on / type rootfs (rw,size=16212k,nr_inodes=4053)
proc on /proc type proc (rw,relatime)
none on /sys type sysfs (rw,relatime)
ramfs on /home type ramfs (rw,relatime)
udev on /dev type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/mtdblock5 on /app type squashfs (ro,relatime)
/dev/mtdblock4 on /app/userdata type jffs2 (rw,relatime)
/dev/mmcblk0p1 on /mnt/sd type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

Porty

netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:6688            0.0.0.0:*               LISTEN      564/apollo
tcp        0      0 0.0.0.0:8554            0.0.0.0:*               LISTEN      564/apollo
tcp        0      0 0.0.0.0:843             0.0.0.0:*               LISTEN      584/noodles
tcp        0      0 0.0.0.0:9876            0.0.0.0:*               LISTEN      564/apollo
tcp        0      0 0.0.0.0:1300            0.0.0.0:*               LISTEN      584/noodles
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN      585/inetd
tcp        0      0 0.0.0.0:8699            0.0.0.0:*               LISTEN      564/apollo
udp        0      0 0.0.0.0:5683            0.0.0.0:*                           564/apollo
udp        0      0 0.0.0.0:3702            0.0.0.0:*                           564/apollo
udp        0      0 0.0.0.0:5012            0.0.0.0:*                           584/noodles
udp        0      0 0.0.0.0:19966           0.0.0.0:*                           564/apollo

Proces apollo to główna aplikacja odpowiadająca za komunikację z chmurą. Można ją spokojnie wyłączyć poprzez skrypt kill_app.sh . Aplikacja noodles służy do komunikacji z GPIO. Obie są spakowane przy pomocy upx. apollo posiada trochę więcej funkcji (m. in. panel WWW + aktualizacje OTA) i na nim się skupię później.

Część odpowiedzialna za SD Update

...
###########################################################################################
# sd upgrade                                                                               
###########################################################################################
if [ -d /mnt/sd/upgrade ] ; then                                                           
    if [ -f /mnt/sd/upgrade/img_up ] ; then                                                
        cp /mnt/sd/upgrade/img_up /home/                                                   
        chmod +x /home/img_up                                                              
    fi                                                                                     
    if [ -f /mnt/sd/upgrade/iu.sh ] ; then                                                 
        cp /mnt/sd/upgrade/iu.sh /home/                                                    
    elif [ -f $cur_dir/iu.sh ] ; then                                                      
        cp $cur_dir/iu.sh /home/                                                           
    elif [ -f /usr/bin/iu.sh ] ; then                                                      
        cp /usr/bin/iu.sh /home/                                                           
    fi                                                                                     
    if [ -f /home/iu.sh ] ; then                                                           
        chmod +x /home/iu.sh                                                               
        /home/iu.sh -s                                                                     
    fi                                                                                     
    rm -f /home/iu.sh                                                                      
fi 
...                                                                                        

W tym momencie można prosto zauważyć w jaki sposób z karty SD można uruchomić sobie dowolny plik sh. w iu.sh parametr -s odpowiada za update z karty SD. Wygląda on tak:

...
if [ "$sd_upgrade" = "y" ] ; then
  if [ -f $sd_img_dir/Flash.img ] ; then
    flash_img=$sd_img_dir/Flash.img
        if [ -f $sd_img_dir/Flash.md5 ] ; then
            flash_md5=$sd_img_dir/Flash.md5
            img_md5=$(cat $flash_md5)
        else
            flash_md5=
            img_md5=$($local_img_up_tool -f $flash_md5 -5)
        fi
  elif [ -f $sd_img_dir/Flash.bin ] ; then
    flash_img=$sd_img_dir/Flash.bin
        if [ -f $sd_img_dir/Flash.md5 ] ; then
            flash_md5=$sd_img_dir/Flash.md5
            img_md5=$(cat $flash_md5)
        else
            flash_md5=
            img_md5=$($local_img_up_tool -f $flash_md5 -5)
        fi
  elif [ -f $sd_img_dir/Flash_d.img ] ; then
    flash_img=$sd_img_dir/Flash_d.img
        if [ -f $sd_img_dir/Flash_d.md5 ] ; then
            flash_md5=$sd_img_dir/Flash_d.md5
            img_md5=$(cat $flash_md5)
        else
            flash_md5=
            img_md5=$($local_img_up_tool -f $flash_img -5)
        fi
  elif [ -f $sd_img_dir/Flash_d.bin ] ; then
    flash_img=$sd_img_dir/Flash_d.bin
        if [ -f $sd_img_dir/Flash_d.md5 ] ; then
            flash_md5=$sd_img_dir/Flash_d.md5
            img_md5=$(cat $flash_md5)
        else
            flash_md5=
            img_md5=$($local_img_up_tool -f $flash_img -5)
        fi
  elif [ -f $sd_img_dir/Flash.pmg ] ; then
    flash_img=$sd_img_dir/Flash.pmg
    flash_md5=
      img_md5=$($local_img_up_tool -f $flash_img -5)
  elif [ -f $sd_img_dir/Flash_d.pmg ] ; then
    flash_img=$sd_img_dir/Flash_d.pmg
    flash_md5=
      img_md5=$($local_img_up_tool -f $flash_img -5)
  elif [ -f $sd_img_dir/Flash.zmg ] ; then
    flash_img=$sd_img_dir/Flash.zmg
    flash_md5=
      img_md5=$($local_img_up_tool -f $flash_img -5)
  elif [ -f $sd_img_dir/Flash_d.zmg ] ; then
    flash_img=$sd_img_dir/Flash_d.zmg
    flash_md5=
      img_md5=$($local_img_up_tool -f $flash_img -5)
  else
    iu_ret
  fi

  opt=
  opt_md5=
  if [ -f $img_up_operate_file ] ; then
    opt=$(get_cfg -f $img_up_operate_file -L1)
    opt_md5=$(get_cfg -f $img_up_operate_file -L2)
  fi

  if [ "$opt_md5" = "$img_md5" ] ; then
    if [ "$opt" = "done" ] || [ "$opt" = "invalid" ] ; then
      iu_ret
    fi
  fi

  if [ -f $sd_img_dir/force ] || [ -f $sd_img_dir/enforce ]; then
    force_up=y
    tmp_force_opt=
    if [ -f $sd_img_dir/force ] ; then
      tmp_force_opt=$(cat $sd_img_dir/force)
    else
      tmp_force_opt=$(cat $sd_img_dir/enforce)
    fi
    
    if [ "$tmp_force_opt" = "keep_apenv" ] ; then
      keep_apenv=y
    elif [ "$tmp_force_opt" = "keep_env" ] ; then
      keep_env=y
    fi
  fi
  if [ -f $sd_img_dir/uboot_en ] ; then
    enable_uboot_up=y
  fi
  if [ -f $sd_img_dir/downgrade_en ] ; then
    downgrade=y
  fi
  if [ "$always_up" != "y" ] && [ "$data_up" != "y" ] && [ "$res_up" != "y" ] ; then
    do_img_check
  fi

  #cp -f $flash_img /home/Flash.img
  #cp -f $flash_md5 /home/Flash.md5
  #flash_img=/home/Flash.img
  #flash_md5=/home/Flash.md5

    if [ "$image_same" != "y" ] ; then
        do_img_upgrade
    fi

  if [ "$opt" != "anyway" ] ; then
    echo "done" > $img_up_operate_file
    echo "$img_md5" >> $img_up_operate_file
    sync
  fi

    if [ "$image_same" != "y" ] ; then
        echo "Burn SD flash finished, reboot" >&2
        reboot -f
    fi
    exit 0
fi
...

Konfiguracja trybu AP:

interface=wlan1
ssid_type=td_alilv
ssid_prefix=TendaIPC
channel=5
auth=none
key=ygtekadmin123456
ip=192.168.55.1
dhcpd_start=192.168.55.100
dhcpd_end=192.168.55.199

Zawartość /app - extract z SquashFS:

TODO

  • sterowanie kamerą w pełni bez chmury
  • uruchomienie panelu WWW

Przydał by się pełny update, więc jeśli ktoś ma oczekującą aktualizację to chętnie pomogę go zgrać - niestety ja zrobiłem update odrazu i teraz czekam aż nowy się pojawi.

1 Like

Witam potrzebuje pomocy mam tenda CP6 i nie wiem jak ją otworzyć, brak śrubek.

Sprawdzałeś czy są śrubki po oderwaniu gumowych nóżek?
(takie przypuszczenie na podstawie zdjęć obudowy w sieci)

tak, każdą gumową nóżkę odkleiłem brak śrubek. Odkleiłem również śrubkę z kodem qr brak śrubki. głowica też nie posiada śrubki

W takim razie obudowa klejona ultradźwiękowo (skreślenie, bo to nie była prawidłowa nazwa) zgrzewana ultradźwiękowo = nierozbieralna (tzn. każda jest rozbieralna, ale takie tylko jeden raz).
Technika rozbierania to okręcić szmatką czy ręcznikiem i obtłuc młotkiem wzdłuż szwu obudowy, ale czy skutecznie to potem skleisz trudno zgadnąć.

Możesz to wszystko ogarnąć po konsoli - powyższy opis powinien pasować. Jak chcesz to napisz do mnie na PW to Ci pomogę.

Kamerke skanowałem przez nmap, brak otwartego portu od telneta. Chciałem się podpiąć po UART jeśłi ma

Pochwal się wynikami z nmap bo to takie wróżenie z fusów co tam można zrobić.

nmap:

Starting Nmap 7.94 ( https://nmap.org ) at 2024-01-13 19:04 Środkowoeuropejski czas stand.
NSE: Loaded 156 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 19:04
Completed NSE at 19:04, 0.00s elapsed
Initiating NSE at 19:04
Completed NSE at 19:04, 0.00s elapsed
Initiating NSE at 19:04
Completed NSE at 19:04, 0.00s elapsed
Initiating ARP Ping Scan at 19:04
Scanning 192.168.2.110 [1 port]
Completed ARP Ping Scan at 19:04, 0.42s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 19:04
Completed Parallel DNS resolution of 1 host. at 19:04, 0.03s elapsed
Initiating SYN Stealth Scan at 19:04
Scanning 192.168.2.110 [65535 ports]
**Discovered open port 554/tcp on 192.168.2.110**
**Discovered open port 8888/tcp on 192.168.2.110**
**Discovered open port 6688/tcp on 192.168.2.110**
Completed SYN Stealth Scan at 19:04, 15.49s elapsed (65535 total ports)
Initiating Service scan at 19:04
Scanning 3 services on 192.168.2.110
Completed Service scan at 19:07, 161.28s elapsed (3 services on 1 host)
Initiating OS detection (try #1) against 192.168.2.110
Retrying OS detection (try #2) against 192.168.2.110
Retrying OS detection (try #3) against 192.168.2.110
Retrying OS detection (try #4) against 192.168.2.110
Retrying OS detection (try #5) against 192.168.2.110
NSE: Script scanning 192.168.2.110.
Initiating NSE at 19:07
Completed NSE at 19:07, 14.33s elapsed
Initiating NSE at 19:07
Completed NSE at 19:07, 1.06s elapsed
Initiating NSE at 19:07
Completed NSE at 19:07, 0.00s elapsed
Nmap scan report for 192.168.2.110
Host is up (0.0031s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE         VERSION
**554/tcp**  open  rtsp            D-Link DCS-2130 or Pelco IDE10DN webcam rtspd
|_rtsp-methods: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER
**6688/tcp** open  soap            gSOAP 2.8
|_http-cors: HEAD PUT OPTIONS PATCH
|_http-title: Site doesn't have a title (application/soap+xml; charset=utf-8).
| http-methods: 
|_  Supported Methods: HEAD POST OPTIONS
|_http-server-header: gSOAP/2.8
**8888/tcp** open  sun-answerbook?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8888-TCP:V=7.94%I=7%D=1/13%Time=65A2D0B1%P=i686-pc-windows-windows%
SF:r(GetRequest,1,"\xee")%r(HTTPOptions,1,"\xee")%r(FourOhFourRequest,2,"\
SF:xee\xff");
MAC Address: C8:3A:xxxxxx (Tenda Technology)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94%E=4%D=1/13%OT=554%CT=1%CU=33341%PV=Y%DS=1%DC=D%G=Y%M=C83A35%
OS:TM=65A2D163%P=i686-pc-windows-windows)SEQ(CI=Z%II=I)SEQ(SP=102%GCD=1%ISR
OS:=109%TI=Z%CI=Z%TS=A)SEQ(SP=102%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)OPS(O1=
OS:M5B4ST11NW3%O2=M5B4ST11NW3%O3=M5B4NNT11NW3%O4=M5B4ST11NW3%O5=M5B4ST11NW3
OS:%O6=M5B4ST11)OPS(O1=NNT11%O2=NNT11%O3=NNT11%O4=NNT11%O5=M5B4ST11NW3%O6=M
OS:5B4ST11)OPS(O1=NNT11%O2=NNT11%O3=NNT11%O4=NNT11%O5=NNT11%O6=NNT11)WIN(W1
OS:=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)WIN(W1=E24%W2=E24%W3=E24%W
OS:4=E24%W5=7120%W6=7120)WIN(W1=E24%W2=E24%W3=E24%W4=E24%W5=E24%W6=7120)ECN
OS:(R=Y%DF=Y%T=40%W=7210%O=M5B4NNSNW3%CC=Y%Q=)ECN(R=Y%DF=Y%T=40%W=E42%O=%CC
OS:=N%Q=)T1(R=Y%DF=Y%T=40%S=O%A=O%F=A%RD=0%Q=)T1(R=Y%DF=Y%T=40%S=O%A=O%F=AS
OS:%RD=0%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=
OS:Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%
OS:RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0
OS:%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIP
OS:CK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 1 hop
Service Info: Device: webcam; CPE: cpe:/h:pelco:ide10dn

TRACEROUTE
HOP RTT     ADDRESS
1   3.12 ms 192.168.2.110

NSE: Script Post-scanning.
Initiating NSE at 19:07
Completed NSE at 19:07, 0.00s elapsed
Initiating NSE at 19:07
Completed NSE at 19:07, 0.00s elapsed
Initiating NSE at 19:07
Completed NSE at 19:07, 0.00s elapsed
Read data files from: D:\Program Files (x86)\Nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 208.89 seconds
           Raw packets sent: 65643 (2.892MB) | Rcvd: 65636 (2.629MB)

kamere chciałem otworzyć bo:
-zobaczyć jak wygląda w środku :wink: jestem nastolatkiem zainteresowany w kierunku monitoringu i mam kilka kamer i chcę brać z nich oprogramowanie i modyfikować narazie uart mam w domu a programator idzie mi
-uszkodziła mi się blokada obrotu w poziomej osi, chciałem naprawić plastik wystarczy przykleić na kropelke bo słyszę że coś tam się ułamało
-diody IR nie działają od początku kamery - może kabel w produkcji nie zostal dobrze podłączony.
w kamerze też onvif jakoś nie działa, rtsp działa. Onvif device manager wykrywa ale nic nie idzie odczytać użyłem admin admin123456 jak producent kazał.

OK pod portem 8888 z tego co widzę masz otwarty serwer HTTP - możesz spróbować coś wyciągnąc z kamerki “od tej strony” - być może jakiś błąd LFI or RCE się znajdzie.

6688 - w teorii SOAP pod onvif - więc onvif powinien działać - stawiam dolary przeciw orzechom, że coś tu źle skonfigurowałeś. Trzeba by było przyjrzeć się po SOAP co zwraca kamera za odpowiedzi dla konkretnych zapytań - tu SoapUI powinien pomóc Ci zbadać wszystkie dostępne endpointy.

554 to stream RTSP.

Co do modyfikacji oprogramowania to ja bym zaczął od najważniejszej rzeczy, od których zaczyna się każdy reverse engineering (a raczej powinno - o ile masz takie możliwości) a mianowicie od pobrania ostatniej wersji oprogramowania dla danego sprzętu. W nim znajdziesz wiedzę od czego zacząć exploitowanie urządzenia. Jako, że CP7 jest podobnym urządzeniem to można przyjąć za pewnik, że soft Twojej kamery pod względem budowy nie będzie znacznie odbiegał od mojej. Możesz spróbować uruchomić iu.sh z karty SD i np. przy jego pomocy możesz spróbować np. zrobić mniej więcej coś takiego:

mount -uw /mnt/sd || true
ls -laRp > /mnt/sd/output.txt || true

Oczywiście uważaj z takim wykonywaniem skryptów bo jak możesz wywnioskować z kodu, który wkleiłem to plik jest kopiowany, wykonywany i usuwany po poprawnym wykonaniu. Jak wrzucisz do niego coś, co się nie wykona bądź przerwie proces, np. reboot to możesz skończyć z bootloopem w urządzeniu.

PS. Proszę staraj się używać markdown wklejając jakikolwiek output z konsoli bo to co wkleiłeś daje mocno po oczach.

Dobrze sorki mój błąd :wink: dziękuje za wyjaśnienie wszystkiego. Właśnie chcę zacząć zabawę nad reverse engineering, moimi ulubionymi są kamery chińskie na aplikacji icsee - czipie xiongmai. Udało mi się do niej podłączyyć przez uart ale wyłączenie auto boota zakończyło się niepowodzeniem ponieważ ma hasło. Oprogramowanie mam do każdej kamery na icsee - producent daje na swojej stronie, ale to nie mój level żeby otworzyć i zobaczyć co jest w uboot.img - co jeszcze bardziej dla mnie będzie trudne a chce zrobić to zmiana komunikatów głosowych, znalazłem folder z nimi.
Co do tendy będę próbować dzięki, oto zrzuty z ODM:


Niby błąd użytkownika, dałem to co producent napisał w mailu. PTZ sterowanie działa.

Zacznij od zapoznania się z linux :slight_smile: albo chociaż z WSL na Windows. Jako “podstawę” do rozpoczecia jakiejkolwiek analizy polecam binwalk, file, dd i fdisk by móc rozebrać firmware pod kamerę. Niepotrzebnie próbujesz zacząć od “boota” bo być może (z dużym prawdopodobieństwem bo to chińskie zabawki) nie ma tam żadnej procedury autoryzacji odpalanych image - np. AHAB czy innych takich rzeczy. Wiele z tych sprzętów operuje na tzw. RTOS - w bardziej zaawansowanych systemach podstawką nie będzie linux a qnx. Ogólnie dużo nauki przed Tobą, ale polecam bo jest to dość fajne hobby - choć bardzo często niewdzięczne :wink:

2 Likes

Dzięki, linuxa mam binwalkiem narazie tylko udało mi się wypakować {nazwafirmware_icsee}.bin na:
-custom-x.cramfs.img
-InstallDesc
-romfs-x.cramfs.img
-u-boot.bin.img
-u-boot.env.img
-uImage.img
-user-x.cramfs.img
A przy użyciu 7zip’a już na windowsie otwierałem je dalej oprócz u-boot…img bo są to pliki binarne.
Znam 2 specjalistów którzy specjalizują się w reverse engineering w temacie kamer, jakoś mi pomagają :wink: Jeden na szybko próbwał znaleźć hasło do uboot ale nie działało. Będę sam próbować, bo bardzo mnie to interesuje i chcę rozwinąć bardziej swoje doświadczenie w kierunku monitoringu ucząc się reverse engineering. Dzięki

Trochę późno, ale zawsze :wink:
uBoot rozpakujesz na skrypt bootujący (parametry boota) + binarkę z kodem do PBL więc też coś tam możesz się dowiedzieć. Reszta plików spokojnie do rozpakowania, więc pewnie już dałeś radę :slight_smile:

Dzięki, tak bez problemu wszystko rozpakowałem, uboota będę próbował. Moim celem jest otworzenie user-x.cramfs.img (zrobione), zmienienie dźwiękow (zrobione), i zbudowanie pliku .bin (też zrobiłem, ale kamera się zbrickowała :wink: będę programatorem ratować firmware)
Użyłem takich komend do zbudowania firmware’u:
mkcramfs user user-x.cramfs.img - buduje obraz .img user-x.cramfs.img

mkimage -A arm -O linux -T ramdisk -n "linux" -e 0x00580000 -a 0x00080000 -d user-x.cramfs user-x.cramfs.img

zip -D -X firmware.bin * - buduje plik oprogramowania .bin

W środku oprócz samego, user-x.cramfs.img był też plik InstallDesc, który informował kamerkę, żeby zainstalowała sam user-x.cramfs.img, bez ruszania innych plików. Czytałem z tej stronki, jak “unbrickne” kamerkę, będę próbował na nowo :slight_smile: Распаковка, редактирование и упаковка прошивок видеорегистраторов и IP камер от Xiong Mai / Хабр