It’s a binary protocol, ´MSG_PUNCH_PKT´ doesn’t literally appear in the conversation, it’s just a name for 0x41 in the protocol description that Thulinma linked (here).
You’re not going to get readable text by decoding the wireshark dump, you’ll just get something that can be interpreted with the above protocol description.
I can’t really help either, but my camera contains a BK7252
chip, for which there appears to be a RT-Thread SDK with Audio / Video support here: GitHub - bekencorp/bk7251_rtt_audio_sdk: bk7251_rtt_audio_sdk (according to that, this chip might have bluetooth low energy as well ??)
might be fun trying to flash some random example firmware that starts a normal webserver instead of weird shittyly encrypted p2p protocol things, there’s some tutorials to be found e.g. [live today] how to play the bk7252 Wireless SoC supporting audio and image with RT thread - 文章整合
I had a very similar camera, I’m not sure the firmware is the same. It also died pretty quickly, so I won’t be able to do anything on it now.
But I was able to enable the RTSP access, using the micro-sd slot : in the root folder, create a ceshi.ini file containing :
[CONST_PARAM]
rtsp = 1 ; RTSP on
I could make it work locally, cameras are totally blocked from accessing Internet. Then it died, I opened it and it seems the connection from lens to main board wasn’t properly connected.
I tried this with rtsp://IPADRESS:554/live/ch00_1
but I can’t get it to work with VLC.
The SD slot is functional because I see avi files dropping in.
nmap
returns no open port (first 1000).
Has anybody tried to contact the manufacturer and ask for the device’s source code?
I wouldn’t know where to begin, but surely someone here would know.
Hey @combe15. I managed to fix the issues with your decrypt function.
Try creating a byte array by using the bytearray.fromhex method. Example:
key = bytearray.fromhex("B8489000")
InputValue = bytearray.fromhex("5d099800ed958ebe07b243c05d48c937dda5df984ed0c57b")
Also it seemed like the buff array in the decrypt function was getting misaligned. I created a new buffer and stored the results in the new buffer. I modified your decrypt function. It should return the correct results now in an int array.
def decrypt(buff, key):
newbuff = []
previousByte = 0
for position, _ in enumerate(buff):
index = (key[previousByte & 3] + previousByte) & 255
previousByte = buff[position]
r = buff[position] ^KEY_TABLE[index]
newbuff.append(r)
return newbuff
Edit:
my camera uses the HDWIFICAM pro app, and uses the key: 6900cc19
I’m sorry for not coming back here sooner: the camera that uses WIFICAM PRO and that I indicated (aliExpress link) no longer allows a direct connection!!! I think this is due to an automatic update (OTA) and the functionality has disappeared… my apologies. on the other hand I see at the end of the forum that great progress has been made and I will dive back into the subject to create a windows application (with VS2019) which simulates the littleStar or WificamPro application and finally allows to recover the video stream. I’ll let you know dear friends!
Just for fun here is how I blocked my 3 cameras: I made an AP (wifi station) with an ESP8266 and I put in a DHCP with a scope corresponding to my local network + a DNS which responds with the same address to all requests: the IP address of my PC. I then put a web server on my PC that shares the rtthread.rbl file. I of course configured my cameras to connect to my ESP8266: finally I recovered lots of RBL files on an FTP server dedicated to the A9s (I can’t find the URL anymore, sorry…) and I put them in my web server one by one. after some adjustments the cameras started to update via MY OTA :-). each time I tested the camera to see how it reacted. in the end I had to put my 3 cameras in the trash. they have become pieces of wood! end of the story. I’m really too dumb…
How did you obtain the key?
Also, did you check to make sure the output is correct? That was what made me delay the fixes, I had no idea if what the program’s output was correct. Other than looking at each step by hand to validate.
I ended up hand validating your code that you posted. All of it was correct, except at the very end when writing to the buffer. Below are my changes to your code.
def encrypt(buff,key):
newbuff=[]
previousByte = 0
for position, _ in enumerate(buff):
index = (key[previousByte & 0x03] + previousByte) & 0xFF
r = buff[position] ^KEY_TABLE[index]
newbuff.append(r)
previousByte = r
return newbuff
def decrypt(buff, key):
newbuff = []
previousByte = 0
for position, _ in enumerate(buff):
index = (key[previousByte & 3] + previousByte) & 255
previousByte = buff[position]
r = buff[position] ^KEY_TABLE[index]
newbuff.append(r)
return newbuff
InputValue = bytearray.fromhex("2cba5f5d")
key = [0x69,0x00,0xcc,0x19]
decrypted = decrypt(InputValue, key)
I found the key to my camera by bruteforce. I had a packet capture from my phone communicating to the camera. The phone application will broadcast a hello message F1 30 00 00. I had the encrypted string from the packet capture: 2c ba 5f 5d
. From there I iterated through the keyspace until I found the correct key.
Also to verify my results, I used your post earlier quote:
with your input of:
5d099800ed958ebe07b243c05d48c937dda5df984ed0c57b
converted into bytes
the decript resulted with:fffffff1 41 0 14 41 43 43 51 0 0 0 0 0 0 ffffffb5 3c 4e 4e 4d 50 5a 0 0 0
Except the key is different for that specific string, since it uses the stars app. The key is 0xB8489000
(Thanks Thulinma).
I see…
As I do not know if my results were correct, we still do not know for certain that any of this is correct. At the very least, you were able to recreate what I was building in C lang.
Maybe @Tamadite will be able to confirm for us that the program operates with a useable output.
Any update on this?
I would love to test any prototype code.
Come on guys, the camera can not win!
There are some of us still working on it. I was able to use Thulinma’s insights to initiate communication with my camera, though it uses a slightly different protocol (it only listens for initiation packets to its address on port 8070, not broadcast packets to port 32108). The next step is to decrypt/decode the UDP stream packets to get image data. I reached out to Thulinma via email to see if his software was ready to be released publicly soon. I didn’t get an answer, it appears he must be busy. Once I can decode the streaming response packets from my camera I will try to release the Python code I wrote. I’m not sure it will work for everyone, my cameras seem to use a strange modification of the protocol, but if the data packets are the same then it should be easy to support different initiation protocols in the python script
Here’s what I have so far I haven’t had too much time to work on it recently and I won’t until next month, but I wanted to get something out there in case its useful to others. My camera seems to use a slightly different discovery protocol than what has been described above in this thread. It requires I send packets directly to the camera IP (not broadcast address) and that I send them to specific ports (8070, 8080) in a specific order instead of 32108 or 32100. I discovered this by using an emulator through android studio with little stars app installed and running a wireshark session with my computer connected to the cameras Wifi AP. There’s more details in the repo’s README:
From your Wireshark capture #6 to #31 look to be a JPEG image, you can tell #6 is a JPEG header from the ‘JFIF’ in the payload.
You need to remove the first 8 bytes from each UDP payload and join them all together and hopefully you should get a complete JPEG image.
The next JPEG image starts at #33, leaving #32 which is sent to port 8070 rather than 8080 , I’m guessing is part of an audio stream.