During one of our investigations on the TP-Link Tapo C200 camera, we found two files that caught our attention: /etc/sys_conf_data and /etc/usr_conf_data.
Both of these files were not directly readable and appeared to be encrypted. However, after a reverse engineering process, we managed to decrypt their contents which revealed a lot of internal information.
Here’s how we did it:
Field reconnaissance
Let’s begin by examining two particularly interesting files located in the directory tree extracted using binwalk
:
└─$ find . | grep 'conf_data' ./extractions/flash_fixed.bin.extracted/5D800/squashfs-root/etc/usr_conf_data ./extractions/flash_fixed.bin.extracted/5D800/squashfs-root/etc/sys_conf_data
Our first step was to identify which system binaries were accessing these files. To do so, we initiated a reverse engineering analysis.
We used the following search command:
grep -ir 'conf_data'
This revealed a match in the binary file libuc_convert.so
:
grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/usr/lib/libuc_convert.so: binary file matches
libuc_convert.so and its roles
Next, we loaded the library into a disassembler and searched for references to the strings we had identified earlier: usr_conf_data
and sys_conf_data
.

The string usr_conf_data has an access reference and leads to the following point:

When examining references to FUN_0001301c
, we finally identified a function that makes use of cryptographic routines, exactly what we were looking for.

A preliminary analysis reveals the existence of a function named doUserConfigConvert
, which appears to be responsible for loading our configuration paths.

But which binary actually uses this library and calls the doUserConfigConvert
function? In other words, what is the main entry point?
We performed another search using grep
and found several references, including a directory named uc_convert
:
─$ grep -ir 'doUserConfigConvert' grep: libuc_convert.so: binary file matches grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/usr/lib/libuc_convert.so: binary file matches grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/lib/libuci.so: binary file matches grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/bin/uc_convert: binary file matches
This suggests that the uc_convert
binary is likely the main component responsible for invoking the doUserConfigConvert
function, either directly or via the linked library.

Everything is starting to make sense, so let’s move forward.
After reviewing some of the string messages—such as “get encrpt key failed!”, “make hash string failed!”, and “read flash failed!”—we were able to infer the following process:
-
Base Key Retrieval: The camera reads a string from a configuration partition within the firmware.
-
Hash Generation: This string is then processed using a hash function to derive the decryption key.
-
DES Decryption: The resulting hashed key is used to decrypt the files via the DES algorithm.

Looking for and putting the pieces together
Step 1: Get the key from the firmware.
Let’s see the following disassembly:
0000301c int32_t sub_301c(int32_t arg1) 00003050 int32_t var_14 = 0 00003054 int32_t var_20 = 0 00003058 int32_t var_1c = 0 0000305c char var_18 = 0 00003060 int32_t $v0 = sub_37e0(1, 2, &var_14) 00003070 int32_t $a1 = var_14 00003080 int32_t $v0_2 00003080 if ($v0 != 0 || ($v0 == 0 && $a1 s<= 0) || ($v0 == 0 && $a1 s> 0 && $a1 s>= 0xd)) 00003090 printf(0x5e38, $a1) {"get flash partition<firmware des…"} 0000309c $v0_2 = 0xffffffff 00003080 if ($v0 == 0 && $a1 s> 0 && $a1 s< 0xd) 000030a0 int32_t $v0_3 = malloc($a1, $a1) 000030ac if ($v0_3 == 0) 000030bc puts(0x5aa0) {"No enough memory!"} 000030c8 $v0_2 = 0xffffffff 000030cc else 000030cc int32_t $s1_1 = var_14 000030dc memset($v0_3, 0, $s1_1) 000030f0 int32_t $v0_5 000030f0 int32_t $a0_3 000030f0 int32_t $a0_4 000030f0 if (sx.d(data_2e06c0) == 0) 0000311c $v0_5 = sub_3a8c(1, $v0_3, 2) 00003124 if ($v0_5 != 0) 00003134 $a0_3 = 0x5e74 {"read flash failed!"} 00003164 label_3164: 00003164 puts($a0_3) 00003174 $a0_4 = $v0_3 000031a8 label_31a8: 000031a8 free($a0_4) 000031b0 $v0_2 = 0xffffffff 00003100 else 00003100 strncpy($v0_3, 0x16940, $s1_1) 00003124 if (sx.d(data_2e06c0) != 0 || (sx.d(data_2e06c0) == 0 && $v0_5 == 0)) 00003140 $a0_4 = $v0_3 0000313c if (sx.d(*$v0_3) == 0) 0000313c goto label_31a8 00003150 if (sub_2f64($a0_4, &var_20) != 0) 0000315c $a0_3 = 0x5e88 {"make hash string failed!"} 0000315c goto label_3164 00003184 memcpy(arg1, &var_20, 8) 00003194 free($v0_3) 000031a0 $v0_2 = 0 000031c4 return $v0_2
A crucial observation lies in the following snippet:
strncpy(dest, 0x16940, len); if (sx.d(0x2e06c0) != 0 || (sx.d(0x2e06c0) == 0 && some_flag == 0))
At offset 0x2E06C0
in the firmware, we found the hardcoded string "C200 3.0"
. This string is copied into a buffer and later used as the base value for generating the encryption key. A conditional check ensures the presence or validity of this string before the decryption routines proceed.
This confirms that the encryption key is not generated dynamically or derived from secure user input. Instead, it is based on a static, hardcoded value that can be easily extracted from the firmware, representing a significant security weakness.
└─$ xxd -s 0x2e06c0 -l 16 flash_fixed.bin 002e06c0: 4332 3030 2033 2e30 0000 0000 0000 0000 C200 3.0........
Let’s move to this part now.
00003124 if (sx.d(data_2e06c0) != 0 || (sx.d(data_2e06c0) == 0 && $v0_5 == 0)) 00003140 $a0_4 = $v0_3 0000313c if (sx.d(*$v0_3) == 0) 0000313c goto label_31a8 00003150 if (sub_2f64($a0_4, &var_20) != 0) 0000315c $a0_3 = 0x5e88 {"make hash string failed!"} 0000315c goto label_3164 00003184 memcpy(arg1, &var_20, 8) 00003194 free($v0_3) 000031a0 $v0_2 = 0
And let’s focus specifically on the following validation:
00003150 if (sub_2f64($a0_4, &var_20) != 0)
Step 2: The hash generation.
Here in sub_2ec0, we see that there is a hash generation.
00002f64 int32_t sub_2f64(int32_t arg1, int32_t arg2) 00002f8c int32_t $a0 00002f8c if (arg1 == 0 || (arg1 != 0 && arg2 == 0)) 00002f9c $a0 = 0x5dec {"NULL == srcStr || NULL == hashSt…"} 00002f8c uint32_t $v0_1 00002f8c int32_t $v0_2 00002f8c if (arg2 != 0 && arg1 != 0) 00002fa0 $v0_1 = sub_2ec0(arg1, arg2) 00002fac if ($v0_1 != 0) 00002fdc memset(arg2, 0, 8) 00002ffc snprintf(arg2, 9, 0x5e30, $v0_1, &data_1e750) {"%08x"} 00003004 $v0_2 = 0 00002fb8 else 00002fb8 $a0 = 0x5e10 {"calculate hash value failed!"} 00002fac if (arg1 == 0 || (arg1 != 0 && arg2 == 0) || (arg1 != 0 && arg2 != 0 && $v0_1 == 0)) 00002fc0 puts($a0) 00002fcc $v0_2 = 0xffffffff 00003014 return $v0_2
Let’s see this function to know how the hash is generated.
00002ec0 uint32_t sub_2ec0(int32_t arg1, int32_t arg2) 00002ecc if (arg1 == 0) 00002efc void* var_10 = &data_1e750 00002f04 puts(0x5ddc, arg2, 0x7fff0000) {"str is null ptr"} 00002f5c return 0 00002ed4 int32_t $a0 = arg1 + 1 00002ed8 uint32_t $v0 = 0 00002edc int32_t $v1 = 0 00002f30 int32_t $t0_1 00002f30 do 00002f38 int32_t $a1 = sx.d(*($a0 - 1)) 00002f40 $t0_1 = $a0 00002f3c if ($a1 == 0) 00002f3c break 00002f48 if ($v1 u>= 0xc) 00002f48 break 00002f18 int32_t $a3_1 = $v0 * 0x1f 00002f14 if ($a1 != 0x22) 00002f1c $v1 = $v1 + 1 00002f2c $v0 = modu.d($a3_1 + $a1, 0x7fffffff) 00002f34 $a0 = $a0 + 1 00002f34 while ($t0_1 != 0) 00002f54 $v0 = 0x7fffffff & $v0 << 0 00002f50 return $v0
The following is a pseudocode representation of the hash generation.
FUNCTION CalculateNumericHash(str_input):
IF str_input IS NULL THEN
PRINT "Error: str_input is a null pointer for CalculateNumericHash."
RETURN 0
END IF
hash_value = 0
char_count = 0
current_char_ptr = str_input
MODUL_VALUE = 0x7FFFFFFF // (2^31 - 1)
LOOP INDEFINITELY:
current_char = DEREFERENCE(current_char_ptr)
IF current_char IS NULL_CHARACTER THEN
BREAK
END IF
IF char_count IS GREATER_THAN 11 THEN
// Process a maximum of 12 relevant characters
BREAK
END IF
IF current_char IS NOT EQUAL_TO '"' THEN
// Ignore double quotes
char_count = char_count + 1
// Perform the multiplication and addition in a 32-bit context.
// Any overflow here would be implicitly handled.
intermediate_result = (hash_value * 0x1F) + current_char
hash_value = intermediate_result MODUL MODUL_VALUE
END IF
current_char_ptr = current_char_ptr + 1
END LOOP
RETURN hash_value
END FUNCTION
// Function: GenerateFinalHashString (Corresponds to sub_2f64)
// Purpose: Takes an input string, calculates its numeric hash, and formats it
// as an 8-character hexadecimal string.
//
// Parameters:
// src_string: The input string to hash.
// output_buffer: A pointer to the buffer where the final hash string will be stored.
// Must be at least 9 bytes (8 characters + null terminator).
//
// Returns:
// 0 on success.
// -1 (or 0xFFFFFFFF) on error (null input, hash calculation failure).
FUNCTION GenerateFinalHashString(src_string, output_buffer):
// 1. Validate inputs
IF src_string IS NULL OR output_buffer IS NULL THEN
PRINT "Error: src_string or output_buffer is null."
RETURN -1
END IF
// 2. Calculate the numeric hash
numeric_hash = CalculateNumericHash(src_string)
// 3. Check if the numeric hash calculation was successful (did not return 0 due to error)
IF numeric_hash IS EQUAL_TO 0 THEN
// If the numeric hash is 0, it could be a valid value or an error.
// The original pseudocode implied that a 0 return from sub_2ec0 indicated "str is null ptr" error.
// We assume here that any 0 from CalculateNumericHash is considered a failure.
PRINT "Error: Failed to calculate numeric hash value."
RETURN -1
END IF
// 4. Format the numeric hash into an 8-character hexadecimal string
// Clear the output buffer (first 8 bytes)
MEMSET(output_buffer, 0, 8)
// Format the numeric hash as a hexadecimal string with leading zeros into output_buffer,
// ensuring a maximum of 9 bytes (including the null terminator).
SNPRINTF(output_buffer, 9, "%08x", numeric_hash)
// 5. Return success
RETURN 0 // Success
END FUNCTION
Key Features:
-
Length Limitation: Only the first 12 characters of the input string are considered in the hash calculation. Any characters beyond this limit are ignored.
-
Character Filtering: Double quotation marks (
"
, ASCII 0x22) are explicitly skipped during the hash computation. They neither contribute to the final hash value nor count toward the character limit (char_count
). -
Hashing Formula: The algorithm applies the following iterative formula:
(previous_hash * 0x1F) + current_character
The result is then taken modulo0x7FFFFFFF
(2,147,483,647 or 2³¹−1), ensuring the final value stays within the range of a signed 31-bit integer. The multiplier0x1F
(31 in decimal) is a small prime commonly used in lightweight hash functions to minimize collisions. -
Output Format: The resulting numerical hash is formatted as an 8-character hexadecimal string, padded with leading zeros if necessary (e.g.,
0000ABCD
) to maintain a consistent length.
So the code to generate our hash from the key is as follows.
def hash_function_corrected(s: str) -> int: """ Calculates a hash value based on the provided C algorithm, emulating 32-bit unsigned integer overflow for exact match. Args: s: The input string. Returns: The calculated hash as an unsigned integer. """ if s is None: print("str is null ptr") return 0 hash_val = 0 char_count = 0 # Define the 32-bit unsigned integer maximum value for overflow simulation UINT_MAX_32_BIT = 2**32 MODULO_VALUE = 0x7fffffff # 2147483647 for char_code in map(ord, s): if char_count > 0xb: # 0xb is 11 in decimal break if char_code != ord('"'): char_count += 1 # Simulate C's intermediate 32-bit unsigned integer arithmetic # The calculation (char_code + hash_val * 0x1f) will first behave # as an unsigned 32-bit integer in C, which means it will wrap around # if it exceeds 2^32 - 1. We apply % UINT_MAX_32_BIT to simulate this. temp_val = (char_code + hash_val * 0x1f) % UINT_MAX_32_BIT # Then, apply the final modulo operation as in the C code hash_val = temp_val % MODULO_VALUE return hash_val def main_corrected(): buf = "C200 3.0" key = hash_function_corrected(buf) print(f"KEY: {key:08x}") if __name__ == "__main__": main_corrected()
Let’s see the result.
└─$ python3 key.py KEY: 5982a825
Step 3: The decryption mechanism.
To decrypt our information, we must pass the previous key in hexadecimal format, so our hash 5982a825 would be in hexadecimal 3539383261383235

With all this information, we will proceed to decrypt the files via the following command:
openssl enc -d -des-ecb -nopad -K 3539383261383235 -in usr_conf_data -out usr_conf_data_decrypt

Once decrypted, we identify a zlib-compressed data block.


After extraction with Binwalk, the information becomes visible:

Some configurations of interest.


The complete list:
usr_conf_data
timing_reboot people_detection system luci auto_reboot ptz_plan cloud_config motion_detection tp_manage target_track tapo_care smart_msg_push_capability pattern smart_detection function cover video_capability audio_capability multicast relayd_config playback video linecrossing_detection intrusion_detection dhcpc msg_alarm_plan video_message device_info msg_push_plan system_state_audio harddisk_manage ai_enhance_capability abnormal_events lens_mask unusual_detection audio_config plan_advance auto_upgrade msg_alarm ffs_dss_pubkey uhttpd smart_data sound_detection app_component record_control telemetry onvif linkage_capability preset dhcpd record_plan protocol wlan_runtime cloud_iot image OSD_capability tamper_detection network tour wlan msg_push motion_detection_cloud ucitrack user_management config on_off 'reboot' option enabled 'off' option day '0' option time '03:00:00' option random_range '30' option last_reboot_time '0' config on_off 'detection' option enabled 'off' config notify_list 'notify_list' option record_enabled 'on' option msg_push_enabled 'on' option light_alarm_enabled 'on' option sound_alarm_enabled 'on' config plan 'arming_schedule' option monday '["0000-2400"]' option tuesday '["0000-2400"]' option wednesday '["0000-2400"]' option thursday '["0000-2400"]' option friday '["0000-2400"]' option saturday '["0000-2400"]' option sunday '["0000-2400"]' config region_info 'region_info_1' option id '1' option pt1_x '0' option pt1_y '0' option pt2_x '10000' option pt2_y '0' option pt3_x '10000' option pt3_y '10000' option pt4_x '0' option pt4_y '10000' option sensitivity '50' option threshold '0' option percentage '1' config system 'sys' option is_factory '1' option diagnose_mode 'off' option dev_alias 'Tapo_Camera' option avatar 'room' option makeroom_status '0' option append_dns '0.0.0.0' option network_type 'none' config setting 'basic' option timezone 'UTC-00:00' option timing_mode 'ntp' option zone_id 'Europe/London' config timing 'ntp' option server '0.0.0.0' option ntp_port '999' option timing_interval '1440' config debug 'debug' option coredump_enabled '0' config dst 'dst' option enabled '1' option synced '0' option has_rule '0' option dst_start_1 '---' option dst_end_1 '---' option dst_savings_1 '---' option dst_start_2 '---' option dst_end_2 '---' option dst_savings_2 '---' option dst_local_start '---' option dst_local_end '---' option dst_offset '---' config core 'main' config extern 'flash_keep' config internal 'languages' config internal 'sauth' config internal 'ccache' config internal 'themes' config font_info 'font' option display 'ntnb' option size 'auto' option color_type 'auto' option color 'white' config date_info 'date' option enabled 'on' option x_coor '0' option y_coor '0' config date_info 'week' option enabled 'off' option x_coor '6000' option y_coor '500' config date_info 'logo' option enabled 'on' option x_coor '0' option y_coor '9150' config label_info 'label_info_1' option enabled 'off' option text 'TP IPC' option x_coor '0' option y_coor '700' config label_info 'label_info_2' option enabled 'off' option text ' option x_coor '1000' option y_coor '4000' config label_info 'label_info_3' option enabled 'off' option text ' option x_coor '1000' option y_coor '6000' config zoom 'zoom' option display '2' option x_coor '4000' option y_coor '9000' config azimuth 'azimuth' option display '2' option x_coor '1000' option y_coor '9000' config preset 'preset' option display '2' option x_coor '6000' option y_coor '9000' config on_off 'reboot' option enabled 'off' option day '7' option time '(03:00)' config config 'plan_config' option enabled '0' option resume_time '5' config router_post 'bind' option username '' option accountId '' option bindCode '' config cloud_reply 'device_status' option bind_status '0' option reset_status '1' config cloud_reply 'upgrade_info' option type '' option version '' option release_date '' option download_url '' option location '' option release_log '' option release_log_url '' config data_collect 'onboarding' option lastOnboardingTimestamp '0' config data_collect 'extra_bind' option need_bind '0' option username '' option password '' config data_collect 'upgrade_status' option state '0' option lastUpgradingSuccess '0' config on_off 'motion_det' option enabled 'on' option sensitivity 'medium' option digital_sensitivity '50' config notif_list 'motion_notif_list' option app_enabled 'off' option client_enabled 'off' option record_enabled 'on' option msg_push_enabled 'on' option light_alarm_enabled 'on' option sound_alarm_enabled 'on' config region_info 'region_info_1' option height '10000' option width '10000' option x_coor '0' option y_coor '0' config tp_manage 'factory_mode' option enabled '0' config tp_manage 'bind_info' option owner '' config on_off 'roi_enable' option main_enabled 'off' option minor_enabled 'off' config target_track_info 'target_track_info' option enabled 'off' config info 'tapo_care_state' config app_component_list 'service_list' config info 'tapo_care_info' option enabled '0' config capability 'capability' config smart_detection 'capability' config module-spec 'module_spec' config wait-time 'wait_time' config cover_info 'cover' option enabled 'off' config capability 'main' config capability 'minor' config capability 'mjpeg' config capability 'device_speaker' config capability 'device_microphone' config capability 'app_speaker' list sampling_rate '8' list sampling_rate '16' option channels '2' list decode_type 'G711' list decode_type 'AAC' config capability 'app_microphone' list sampling_rate '8' list sampling_rate '16' option channels '2' list encode_type 'G711' list encode_type 'AAC' config server 'main' option enabled 'off' option address '224.0.1.0' option port '10000' option random 'on' config server 'minor' option enabled 'off' option address '224.0.1.0' option port '10002' option random 'on' config server 'third' option enabled 'off' option address '224.0.1.0' option port '10004' option random 'on' config relay_server 'server' option host 'aps1-relay-dcipc.i.tplinknbu.com' option port '443' option use_https '1' config scale_capability 'scale_0' config scale_capability 'scale_1' config scale_capability 'scale_2' config scale_capability 'scale_3' config scale_capability 'scale_4' config scale_capability 'scale_5' config scale_capability 'scale_6' config scale_capability 'scale_7' config scale_capability 'scale_8' config stream 'main' option stream_type 'general' option resolution '1280*720' option bitrate_type 'vbr' option frame_rate '65551' option quality '3' option bitrate '1024' option encode_type 'H264' config stream 'minor' option resolution '640*360' option bitrate_type 'vbr' option frame_rate '65551' option quality '3' option bitrate '256' option encode_type 'H264' config stream 'mjpeg' option resolution '640*360' option bitrate_type 'vbr' option frame_rate '65541' option quality '3' option bitrate '2560' option encode_type 'MJPEG' config info 'main_conf' config info 'minor_conf' config info 'mjpeg_conf' config on_off 'detection' option enabled 'off' config notify_list 'notify_list' option record_enabled 'on' option msg_push_enabled 'on' option light_alarm_enabled 'off' option sound_alarm_enabled 'off' config plan 'arming_schedule' option monday '["0000-2400"]' option tuesday '["0000-2400"]' option wednesday '["0000-2400"]' option thursday '["0000-2400"]' option friday '["0000-2400"]' option saturday '["0000-2400"]' option sunday '["0000-2400"]' config on_off 'detection' option enabled 'off' config notify_list 'notify_list' option record_enabled 'on' option msg_push_enabled 'on' option light_alarm_enabled 'off' option sound_alarm_enabled 'off' config plan 'arming_schedule' option monday '["0000-2400"]' option tuesday '["0000-2400"]' option wednesday '["0000-2400"]' option thursday '["0000-2400"]' option friday '["0000-2400"]' option saturday '["0000-2400"]' option sunday '["0000-2400"]' config dhcpc 'udhcpc' option enable '1' option retry '0' option ip_requested '0' config plan 'chn1_msg_alarm_plan' option enabled 'off' option alarm_plan_1 '0000-0000,127' config plan 'arming_schedule_sound' option monday '["0000-2400"]' option tuesday '["0000-2400"]' option wednesday '["0000-2400"]' option thursday '["0000-2400"]' option friday '["0000-2400"]' option saturday '["0000-2400"]' option sunday '["0000-2400"]' config plan 'arming_schedule_light' option monday '["0000-2400"]' option tuesday '["0000-2400"]' option wednesday '["0000-2400"]' option thursday '["0000-2400"]' option friday '["0000-2400"]' option saturday '["0000-2400"]' option sunday '["0000-2400"]' config on_off 'video_message' config wtd 'config' option enabled 'on' config info 'info' option device_name 'C200' option device_info 'C200 IPC' option device_model 'C200' option hw_version '3.0' option fw_description 'C200 3.0' option product_id '00000000' option sw_version '1.3.0 Build 220909 Rel.43466n' config plan 'chn1_msg_push_plan' option enabled 'off' option push_plan_1 '0900-1700,127' config info 'info' option language 'other' config ptz 'capability' config ptz 'basic_config' option speed_pan_default '0.350000' option speed_tilt_default '0.350000' option timeout_default '180000' option proportional_pan_enabled '1' option reverse_mode 'off' option eflip_mode 'off' config ptz 'scan_config' option speed '0.7000' config ptz 'park_config' option enabled '0' option park_time '5' option action_mode 'auto_scan' option action_id '1' config ptz 'limit_config' option enabled '0' option key_position_pan_enabled '0' option key_position_pan_left '-1' option key_position_pan_right '1' option key_position_tilt_enabled '0' option key_position_tilt_down '-1' option key_position_tilt_up '1' option scan_position_pan_enabled '0' option scan_position_pan_left '-1' option scan_position_pan_right '1' option scan_position_tilt_enabled '0' option scan_position_tilt_down '-1' option scan_position_tilt_up '1' config ptz 'poweroff_save_config' option enabled '1' option save_time '10' config ptz 'manual_control_config' option speed_mode 'self_adaptive' option speed_level 'normal' config ptz 'poweroff_save' config home 'home' option position_pan '-1.000' option position_tilt '1.000' config storage 'harddisk' option loop 'on' config partition 'video' option ratio '100' option data_file_size '256M' config partition 'picture' option ratio '0' config partition 'crossline' config partition 'msg_push' config partition 'passenger_flow' config manage 'harddisk_1' config capability 'traditional_enhance' config capability 'face_enhance' config on_off 'login_err' option enabled 'on' option max_num_err '10' config notif_list 'login_err_notif_list' option app_enabled 'off' option client_enabled 'off' config on_off 'sd_missing' config lens_mask_info 'lens_mask_info' option enabled 'off' config on_off 'login_error' option enabled 'on' option max_num_err '10' option msg_push_enabled 'on' option light_alarm_enabled 'off' config on_off 'hd_lack' option enabled 'on' option msg_push_enabled 'on' config on_off 'hd_error' option enabled 'on' option msg_push_enabled 'on' config audio_config 'speaker' option volume '100' config audio_config 'microphone' option sampling_rate '8' option channels '1' option encode_type 'G711alaw' option volume '100' option mute 'off' option noise_cancelling 'on' config audio_config 'record_audio' option enabled 'on' config advance 'plan_advance' option record_time '120' option delay_record '60' config on_off 'common' option enabled 'on' option time '03:00' option random_range '120' config info 'chn1_msg_alarm_info' option enabled 'off' option alarm_type '0' option light_type '1' list alarm_mode 'sound' list alarm_mode 'light' option sound_alarm_enabled 'off' option light_alarm_enabled 'off' config led 'config' option enabled 'on' config led 'model' config ffs 'ffs_info' config uhttpd 'main' option listen_https '443' config cert 'px5g' config status 'status' option enabled 'on' config on_off 'bcd' option enabled 'off' option sensitivity 'medium' option digital_sensitivity '50' config notif_list 'bcd_notif_list' option app_enabled 'off' option client_enabled 'off' option record_enabled 'on' option msg_push_enabled 'on' option light_alarm_enabled 'off' option sound_alarm_enabled 'off' config app_component_list 'app_component_list' config control 'chn1_record' option mode 'auto' option stream_type 'main' config control 'chn2_record' config control 'chn3_record' config control 'chn4_record' config control 'chn5_record' config control 'chn6_record' config control 'chn7_record' config control 'chn8_record' config basic 'basic' option enabled 'off' config cloud 'cloud' option cloudUrl 'n-da.tplinkcloud.com' option accessKey '' option accessSecret '' config strategy 'strategy' option strategyID '' option collect_interval '15' option post_interval '180' config profile 'profile_1' config profile 'profile_2' config vsconf 'vsconf' config asconf 'asconf' config discovery_mode 'dis_mode' option mode '0' config scopes 'custom_scopes' config true_false 'ffs_bind' option ffs '0' option ffs_binding '0' config capability 'capability' option sound_alarm_capability '000000000000100000000000001111' option light_alarm_capability '000000000010100000000000001101' option record_capability '000000000000100000000000001101' option capture_capability '000000000000000000000000000000' option ftp_capability '000000000000000000000000000000' option msg_push_capability '000000001010100000000000001111' option email_capability '000000000000000000000000000000' option alarm_out_capability '000000000000000000000000000000' config config 'preset_config' option image_freeze_enabled '0' option speed '1.0' config dhcpd 'udhcpd' option enable '1' option pool_start '192.168.191.100' option pool_end '192.168.191.199' option lease_time '7200' option gateway '192.168.191.1' option pri_dns '192.168.191.1' option snd_dns '0.0.0.0' option auto '0' config plan 'chn1_channel' option enabled 'off' option monday '["0000-2400:2"]' option tuesday '["0000-2400:2"]' option wednesday '["0000-2400:2"]' option thursday '["0000-2400:2"]' option friday '["0000-2400:2"]' option saturday '["0000-2400:2"]' option sunday '["0000-2400:2"]' config interface 'wan' option wan_type 'static' option proto 'static' option auto '0' option wan_rate 'auto' option ifname 'br-wan' config proto 'dhcp' option ifname 'br-wan' option mtu '1480' option dns_mode 'dynamic' option pri_dns '' option snd_dns '' option hostname 'IPC' option enable_broadcast '1' config proto 'static' option ifname 'br-wan' option ipaddr '192.168.0.10' option netmask '255.255.255.0' option gateway '192.168.0.1' option pri_dns '114.114.114.114' option snd_dns '8.8.8.8' option mtu '1480' config proto 'pppoe' option ifname 'br-wan' option proto 'pppoe' option auto '0' option wan_type 'pppoe' option connect '1' option parent 'wan' option username '' option password '' option dial_mode 'auto' option conn_mode 'auto' option demand_idle '600' option manual_idle '' option mtu '1480' option access '' option server '' option ip_mode 'dynamic' option specific_ip '' option dns_mode 'dynamic' option pri_dns '' option snd_dns '' config wlan_runtime 'ap0' option status 'off' list sta_list '' config config 'cloud' option server_type 'prd' config config 'dev' config config 'uat' config config 'uat2' config config 'uat3' config config 'staging' config config 'prd' config switch_type 'switch' option switch_mode 'common' option schedule_start_time '21600' option schedule_end_time '64800' option flip_type 'off' option rotate_type 'off' option ldc 'off' config para 'common' option luma '50' option contrast '50' option chroma '50' option saturation '50' option sharpness '50' option exp_type 'auto' option shutter '1/25' option focus_type 'semi_auto' option focus_limited '600' option exp_gain '0' option inf_type 'auto' option inf_start_time '64800' option inf_end_time '21600' option inf_sensitivity '1' option wide_dynamic 'off' option light_freq_mode 'auto' option wd_gain '50' option wb_type 'auto' option wb_R_gain '50' option wb_G_gain '50' option wb_B_gain '50' option lock_red_gain '0' option lock_gr_gain '0' option lock_gb_gain '0' option lock_blue_gain '0' option lock_red_colton '0' option lock_green_colton '0' option lock_blue_colton '0' option lock_source 'local' option area_compensation 'default' option smartir 'off' option smartir_level '100' option high_light_compensation 'off' option dehaze 'off' config para 'shedday' option luma '50' option contrast '50' option chroma '50' option saturation '50' option sharpness '50' option exp_type 'auto' option shutter '1/25' option focus_type 'semi_auto' option focus_limited '600' option exp_gain '0' option inf_type 'off' option inf_sensitivity '1' option inf_delay '30' option wide_dynamic 'off' option wd_gain '50' option wb_type 'auto' option wb_R_gain '50' option wb_G_gain '50' option wb_B_gain '50' option lock_red_gain '0' option lock_gr_gain '0' option lock_gb_gain '0' option lock_blue_gain '0' option lock_red_colton '0' option lock_green_colton '0' option lock_blue_colton '0' option lock_source 'local' option area_compensation 'default' option smartir 'off' option smartir_level '100' option high_light_compensation 'off' option dehaze 'off' config para 'shednight' option luma '50' option contrast '50' option chroma '50' option saturation '50' option sharpness '50' option exp_type 'auto' option shutter '1/25' option focus_type 'semi_auto' option focus_limited '600' option exp_gain '0' option inf_type 'on' option inf_sensitivity '1' option inf_delay '30' option wide_dynamic 'off' option wd_gain '50' option wb_type 'auto' option wb_R_gain '50' option wb_G_gain '50' option wb_B_gain '50' option lock_red_gain '0' option lock_gr_gain '0' option lock_gb_gain '0' option lock_blue_gain '0' option lock_red_colton '0' option lock_green_colton '0' option lock_blue_colton '0' option lock_source 'local' option area_compensation 'default' option smartir 'off' option smartir_level '100' option high_light_compensation 'off' option dehaze 'off' config para 'autoday' option luma '50' option contrast '50' option chroma '50' option saturation '50' option sharpness '50' option exp_type 'auto' option shutter '1/25' option focus_type 'semi_auto' option focus_limited '600' option exp_gain '0' option inf_type 'auto' option inf_sensitivity '1' option inf_delay '5' option wide_dynamic 'off' option light_freq_mode 'auto' option wd_gain '50' option wb_type 'auto' option wb_R_gain '50' option wb_G_gain '50' option wb_B_gain '50' option lock_red_gain '0' option lock_gr_gain '0' option lock_gb_gain '0' option lock_blue_gain '0' option lock_red_colton '0' option lock_green_colton '0' option lock_blue_colton '0' option lock_source 'local' option area_compensation 'default' option smartir 'off' option smartir_level '100' option high_light_compensation 'off' option dehaze 'off' config para 'autonight' option luma '50' option contrast '50' option chroma '50' option saturation '50' option sharpness '50' option exp_type 'auto' option shutter '1/25' option focus_type 'semi_auto' option focus_limited '600' option exp_gain '0' option inf_type 'auto' option inf_sensitivity '1' option inf_delay '5' option wide_dynamic 'off' option light_freq_mode 'auto' option wd_gain '50' option wb_type 'auto' option wb_R_gain '50' option wb_G_gain '50' option wb_B_gain '50' option lock_red_gain '0' option lock_gr_gain '0' option lock_gb_gain '0' option lock_blue_gain '0' option lock_red_colton '0' option lock_green_colton '0' option lock_blue_colton '0' option lock_source 'local' option area_compensation 'default' option smartir 'off' option smartir_level '100' option high_light_compensation 'off' option dehaze 'off' config capability 'font_info' config capability 'label_info' config capability 'res_info' config on_off 'tamper_det' option enabled 'off' option sensitivity 'medium' option digital_sensitivity '50' config region_info 'region' config notif_list 'tamper_notif_list' option app_enabled 'off' option client_enabled 'off' option msg_push_enabled 'on' option sound_alarm_enabled 'off' config interface 'loopback' config interface 'wan' option ifname 'br-wan' option type 'bridge' option wan_type 'dhcp' option speed_duplex 'auto' option proto 'dhcp' option mtu '1480' option auto '1' option netmask '255.255.255.0' option ipaddr '192.168.0.10' option gateway '192.168.0.1' option dns '0.0.0.0' config configuration 'tour_config' option recurring_times_default '10' option recurring_duration_default '36000' option stay_time_default '15000' config wlan 'basic' option factory_flag 'on' config wlan 'ap0' option on_boot 'on' option ssid '' option broadcast_ssid 'on' option region 'CN' option band '2g' option channel '0' option hwmode 'bgn' option channel_width 'ht20' option security 'none' option encryption 'ccmp' option key '' option wps 'off' option auto_disable_time '0' option isolation 'off' option acl 'none' list acl_mac '' config wlan 'sta0' option on_boot 'on' option connect_onboot 'off' option network_id '0' config wlan 'default_ap' config on_off 'chn1_msg_push_info' option notification_enabled 'on' option rich_notification_enabled 'off' config on_off 'msg_push_event' option motion_detection 'on' option people_detection 'on' option sound_detection 'on' config on_off 'motion_det' option enabled 'on' option digital_sensitivity '50' config notif_list 'motion_notif_list' option app_enabled 'off' option client_enabled 'off' option record_enabled 'on' option msg_push_enabled 'off' config region_info 'region_info_1' option height '10000' option width '10000' option x_coor '0' option y_coor '0' config root 'root' option username 'admin' option passwd 'zMiVw8Kw0oxKXL0' option ciphertext 'dl5GoIRk+FMC/JgP5yLjA+r8PynYYSai8DSmdv1Xw7iALNEKxkE5UusQw6BMC4+FlcWv0bCPuw8DSlSk/vkmcTZ/BF/ZY1ENNJqo+uJtiGi2f1zJFjleYhPlDx4YXa3qp7oSNF8EU1BU4mOY9nEtUakFl4oVPsvlLGM3qE/zI2k=' option sharepwd '' option comment '' config third_account 'third_account' option username '---' option passwd '---' option ciphertext 'dl5GoIRk+FMC/JgP5yLjA+r8PynYYSai8DSmdv1Xw7iALNEKxkE5UusQw6BMC4+FlcWv0bCPuw8DSlSk/vkmcTZ/BF/ZY1ENNJqo+uJtiGi2f1zJFjleYhPlDx4YXa3qp7oSNF8EU1BU4mOY9nEtUakFl4oVPsvlLGM3qE/zI2k=' option comment '' config authentication 'authentication' option basic_enabled '0' config server 'vhttpd' option port '8800' config server 'rtsp' option port '554' config URL 'URL' config on_off 'media_encrypt' option enabled 'off'
The same amount of information can be obtained from the file sys_conf_data:



sys_conf_data
timing_reboot people_detection system luci auto_reboot ptz_plan cloud_config motion_detection tp_manage target_track tapo_care smart_msg_push_capability pattern smart_detection function cover video_capability audio_capability multicast relayd_config playback video linecrossing_detection intrusion_detection dhcpc msg_alarm_plan video_message device_info msg_push_plan system_state_audio harddisk_manage ai_enhance_capability abnormal_events lens_mask unusual_detection audio_config plan_advance auto_upgrade msg_alarm ffs_dss_pubkey uhttpd smart_data sound_detection app_component record_control telemetry onvif linkage_capability preset dhcpd record_plan protocol wlan_runtime cloud_iot image OSD_capability tamper_detection network tour wlan msg_push motion_detection_cloud ucitrack user_management config on_off 'reboot' config on_off 'detection' config notify_list 'notify_list' config plan 'arming_schedule' config region_info 'region_info_1' config system 'sys' option hostname 'C200' config setting 'basic' config timing 'ntp' list def_server 'time.nist.gov' list def_server '128.138.140.44' list def_server '192.36.144.22' list def_server 'time-a.nist.gov' list def_server 'time-b.nist.gov' list def_server 'time.windows.com' list def_server 'time-nw.nist.gov' list def_server 'au.pool.ntp.org' list def_server 'nz.pool.ntp.org' config debug 'debug' config dst 'dst' config core 'main' option lang 'auto' option mediaurlbase '/web-static' option resourcebase '/luci-static/resources' config extern 'flash_keep' option uci '/etc/config/' option dropbear '/etc/dropbear/' option openvpn '/etc/openvpn/' option passwd '/etc/passwd' option opkg '/etc/opkg.conf' option firewall '/etc/firewall/firewall.user' option uploads '/lib/uci/upload/' config internal 'languages' config internal 'sauth' option sessionpath '/tmp/luci-sessions' option sessiontime '3600' config internal 'ccache' option enable '1' config internal 'themes' option TORCHLIGHT '/luci-static/torchlight' config font_info 'font' config date_info 'date' config date_info 'week' config date_info 'logo' config label_info 'label_info_1' config label_info 'label_info_2' config label_info 'label_info_3' config zoom 'zoom' config azimuth 'azimuth' config preset 'preset' config on_off 'reboot' config config 'plan_config' config router_post 'bind' config cloud_reply 'device_status' config cloud_reply 'upgrade_info' config data_collect 'onboarding' config data_collect 'extra_bind' config data_collect 'upgrade_status' config on_off 'motion_det' config notif_list 'motion_notif_list' config region_info 'region_info_1' config tp_manage 'factory_mode' config tp_manage 'bind_info' config on_off 'roi_enable' config target_track_info 'target_track_info' config info 'tapo_care_state' option version '1.0.0' config app_component_list 'service_list' list component '{"name": "msgPush", "version": 3}' config info 'tapo_care_info' config capability 'capability' list support 'md' list support 'od' list support 'id' list support 'cd' list support 'login_error' list support 'hd_lack' list support 'hd_error' config smart_detection 'capability' option linecrossing_detection '1' option intrusion_detection '1' option people_detection '1' option smart_data '1' config module-spec 'module_spec' config wait-time 'wait_time' config cover_info 'cover' config capability 'main' list encode_types 'H264' list frame_rates '65537' list frame_rates '65546' list frame_rates '65551' list bitrates '256' list bitrates '512' list bitrates '1024' list bitrates '2048' list bitrate_types 'cbr' list bitrate_types 'vbr' list resolutions '1920*1080' list resolutions '1280*720' list resolutions '640*360' list qualitys '1' list qualitys '3' list qualitys '5' config capability 'minor' list encode_types 'H264' list frame_rates '65537' list frame_rates '65546' list frame_rates '65551' list bitrates '64' list bitrates '128' list bitrates '256' list bitrates '512' list bitrate_types 'cbr' list bitrate_types 'vbr' list resolutions '640*360' list qualitys '1' list qualitys '3' list qualitys '5' config capability 'mjpeg' list encode_types 'MJPEG' list frame_rates '65537' list frame_rates '65546' list frame_rates '65551' list bitrates '2560' list bitrate_types 'vbr' list resolutions '640*360' list qualitys '1' list qualitys '3' list qualitys '5' config capability 'device_speaker' list sampling_rate '8' option channels '1' list decode_type 'G711' option volume '1' option mute '0' config capability 'device_microphone' list sampling_rate '8' option channels '1' list encode_type 'G711alaw' option volume '1' option mute '1' option aec '1' option noise_cancelling '1' option echo_cancelling '0' option half_duplex '1' config capability 'app_speaker' config capability 'app_microphone' config server 'main' config server 'minor' config server 'third' config relay_server 'server' option is_tums_talk '0' config scale_capability 'scale_0' option value '1/16' option change_pts '0' config scale_capability 'scale_1' option value '1/8' option change_pts '0' config scale_capability 'scale_2' option value '1/4' option change_pts '0' config scale_capability 'scale_3' option value '1/2' option change_pts '0' config scale_capability 'scale_4' option value '1/1' option change_pts '0' config scale_capability 'scale_5' option value '2/1' option change_pts '1' config scale_capability 'scale_6' option value '4/1' option change_pts '1' config scale_capability 'scale_7' option value '8/1' option change_pts '1' config scale_capability 'scale_8' option value '16/1' option change_pts '1' config stream 'main' option name 'VideoEncoder_1' option gop_factor '2' config stream 'minor' option name 'VideoEncoder_2' option gop_factor '2' config stream 'mjpeg' option name 'VideoEncoder_3' option gop_factor '2' config info 'main_conf' option res_num '3' option res_1_w '1920' option res_1_h '1080' option res_2_w '1280' option res_2_h '720' option res_3_w '640' option res_3_h '360' option min_br '256' option max_br '2048' option min_fr '1' option max_fr '15' config info 'minor_conf' option res_num '1' option res_1_w '640' option res_1_h '360' option min_br '64' option max_br '512' option min_fr '1' option max_fr '15' config info 'mjpeg_conf' option res_num '1' option res_1_w '640' option res_1_h '368' option min_br '256' option max_br '2560' option min_fr '1' option max_fr '15' config on_off 'detection' config notify_list 'notify_list' config plan 'arming_schedule' config on_off 'detection' config notify_list 'notify_list' config plan 'arming_schedule' config dhcpc 'udhcpc' config plan 'chn1_msg_alarm_plan' config plan 'arming_schedule_sound' config plan 'arming_schedule_light' config on_off 'video_message' option enabled 'off' option duration '15' config wtd 'config' option init_delay '0' config info 'info' option sys_software_revision '0x500a0103' option sys_software_revision_minor '0x0000' option isp_version '2' option device_type 'SMART.IPCAMERA' option features '3' option domain_name 'tplogin.cn' option language 'EN' option enable_dns '1' option manufacturer_name 'TP-LINK' option friendly_name 'IPC' option model_description 'IPC' option manufacturer_url 'http://www.tp-link.com' option vendor_id '0x00000001' option zone_code '0x0' option roi_reg_num '1' option cover_reg_num '4' option md_reg_num '32' option td_reg_num '1' option id_reg_num '4' option cd_reg_num '4' option ac_reg_num '1' option plugin_obtain_way 'web' option product_type 'ipc' option fw_shared_prefix 'Tapo_C200v3' option ext_fw_upgrade '1' config plan 'chn1_msg_push_plan' config info 'info' config ptz 'capability' list position_pan_range '-1.000000' list position_pan_range '1.000000' list position_tilt_range '-1.000000' list position_tilt_range '1.000000' option speed_pan_max '1.00000' option speed_tilt_max '1.000000' option absolute_move_supported '1' option relative_move_supported '1' option continuous_move_supported '1' option preset_supported '1' option preset_number_max '8' option tour_supported '0' list eflip_mode 'off' list eflip_mode 'on' list reverse_mode 'off' list reverse_mode 'on' list reverse_mode 'auto' option scan_supported '0' option park_supported '0' option plan_supported '0' option poweroff_save_supported '1' list poweroff_save_time_range '10' list poweroff_save_time_range '600' option home_position_mode 'none' option pattern_supported '0' option limit_supported '0' list manual_control_mode 'compatible' list manual_control_mode 'pedestrian' list manual_control_mode 'motor_vehicle' list manual_control_mode 'non_motor_vehicle' list manual_control_mode 'self_adaptive' list manual_control_level 'low' list manual_control_level 'normal' list manual_control_level 'high' option calibrate_supported '1' config ptz 'basic_config' option elevation_min '0' option elevation_max '90' config ptz 'scan_config' config ptz 'park_config' config ptz 'limit_config' config ptz 'poweroff_save_config' config ptz 'manual_control_config' config ptz 'poweroff_save' config home 'home' config storage 'harddisk' config partition 'video' option min_event_size '1M' option event_overlay_factor '3' option event_cache_wr_intv '120' option event_min_duration '1' config partition 'picture' option data_file_size '1M' option min_event_size '80K' option event_overlay_factor '1' option event_cache_wr_intv '120' option event_min_duration '1' config partition 'crossline' option ratio '0' option data_file_size '256M' option min_event_size '512K' option event_overlay_factor '1' option event_cache_wr_intv '900' option event_min_duration '900' config partition 'msg_push' option ratio '0' option data_file_size '1M' option min_event_size '1M' option event_overlay_factor '1' option event_cache_wr_intv '120' option event_min_duration '1' config partition 'passenger_flow' option ratio '0' option data_file_size '2664960' option min_event_size '8B' option event_overlay_factor '1' option event_cache_wr_intv '900' option event_min_duration '900' config manage 'harddisk_1' option type 'sdcard' option path '/dev/mmcblk0' option mnt '/tmp/mnt/harddisk_1' config capability 'traditional_enhance' option people_enhance_ver '7' config capability 'face_enhance' config on_off 'login_err' config notif_list 'login_err_notif_list' config on_off 'sd_missing' option msg_push_enabled 'on' config lens_mask_info 'lens_mask_info' config on_off 'login_error' config on_off 'hd_lack' config on_off 'hd_error' config audio_config 'speaker' config audio_config 'microphone' config audio_config 'record_audio' config advance 'plan_advance' option pre_record '3' config on_off 'common' config info 'chn1_msg_alarm_info' config led 'config' config led 'model' option startup 'on' config ffs 'ffs_info' option dss_pubkey '-----BEGIN PUBLIC KEY-----nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE++2MMSe9kWF6mJPkgsGcrqTCk8gbnvTccKPGZDL5pZcmfW+2EzRjfXhx6clwg3Wl4ClFe8+37fLNgxPYodqGQgA==n-----END PUBLIC KEY-----n' config uhttpd 'main' option home '/www' option rfc1918_filter '1' option max_requests '8' option cert '/tmp/uhttpd.crt' option key '/tmp/uhttpd.key' option cgi_prefix '/cgi-bin' option lua_prefix '/luci' option lua_handler '/usr/lib/lua/luci/sgi/uhttpd.lua' option script_timeout '180' option network_timeout '180' option tcp_keepalive '0' config cert 'px5g' option days '3600' option bits '1024' option country 'CN' option state 'China' option location 'China' option commonname 'TP-Link' config status 'status' config on_off 'bcd' config notif_list 'bcd_notif_list' config app_component_list 'app_component_list' list component '{"name": "sdCard", "version": 1}' list component '{"name": "timezone", "version": 1}' list component '{"name": "system", "version": 3}' list component '{"name": "led", "version": 1}' list component '{"name": "playback", "version": 3}' list component '{"name": "detection", "version": 1}' list component '{"name": "alert", "version": 1}' list component '{"name": "firmware", "version": 2}' list component '{"name": "account", "version": 1}' list component '{"name": "quickSetup", "version": 1}' list component '{"name": "ptz", "version": 1}' list component '{"name": "video", "version": 2}' list component '{"name": "lensMask", "version": 2}' list component '{"name": "lightFrequency", "version": 1}' list component '{"name": "dayNightMode", "version": 1}' list component '{"name": "osd", "version": 2}' list component '{"name": "record", "version": 1}' list component '{"name": "videoRotation", "version": 1}' list component '{"name": "audio", "version": 2}' list component '{"name": "diagnose", "version": 1}' list component '{"name": "msgPush", "version": 3}' list component '{"name": "deviceShare", "version": 1}' list component '{"name": "tapoCare", "version": 1}' list component '{"name": "blockZone", "version": 1}' list component '{"name": "personDetection", "version": 1}' list component '{"name": "targetTrack", "version": 1}' list component '{"name": "babyCryDetection", "version": 1}' list component '{"name": "needSubscriptionServiceList", "version": 1}' list component '{"name": "iotCloud", "version": 1}' config control 'chn1_record' config control 'chn2_record' option mode 'auto' option stream_type 'main' config control 'chn3_record' option mode 'auto' option stream_type 'main' config control 'chn4_record' option mode 'auto' option stream_type 'main' config control 'chn5_record' option mode 'auto' option stream_type 'main' config control 'chn6_record' option mode 'auto' option stream_type 'main' config control 'chn7_record' option mode 'auto' option stream_type 'main' config control 'chn8_record' option mode 'auto' option stream_type 'main' config basic 'basic' config cloud 'cloud' config strategy 'strategy' config profile 'profile_1' option name 'mainStream' option token 'profile_1' option fixed '1' option vsconf 'vsconf' option veconf 'main' option asconf 'asconf' option aeconf 'microphone' config profile 'profile_2' option name 'minorStream' option token 'profile_2' option fixed '1' option vsconf 'vsconf' option veconf 'minor' option asconf 'asconf' option aeconf 'microphone' config vsconf 'vsconf' option name 'VideoSourceConfig' option token 'vsconf' option sToken 'raw_vs1' option uCount '2' option bX '0' option bY '0' option bW '1920' option bH '1080' config asconf 'asconf' option name 'AudioSourceConfig' option token 'asconf' option sToken 'raw_as1' option uCount '2' config discovery_mode 'dis_mode' config scopes 'custom_scopes' config true_false 'ffs_bind' config capability 'capability' config config 'preset_config' config dhcpd 'udhcpd' option interface 'wlan1' option lease_file '/tmp/dhcp.leases' option pid_file '/var/run/udhcpd.pid' option subnet '255.255.255.0' config plan 'chn1_channel' config interface 'wan' option type 'bridge' config proto 'dhcp' option proto 'dhcp' option auto '1' option wan_type 'dhcp' config proto 'static' option type 'bridge' option proto 'static' option auto '1' option wan_type 'static' option fac_ipaddr '192.168.0.10' config proto 'pppoe' option keepalive '3,10' config wlan_runtime 'ap0' config config 'cloud' config config 'dev' option cloud_gateway_domain 'device-cloudgateway-alpha.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security-alpha.iot.i.tplinknbu.com' option cloud_security_port '443' config config 'uat' option cloud_gateway_domain 'device-cloudgateway-beta.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security-beta.iot.i.tplinknbu.com' option cloud_security_port '443' config config 'uat2' option cloud_gateway_domain 'device-cloudgateway-beta2.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security-beta2.iot.i.tplinknbu.com' option cloud_security_port '443' config config 'uat3' option cloud_gateway_domain 'device-cloudgateway-beta3.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security-beta3.iot.i.tplinknbu.com' option cloud_security_port '443' config config 'staging' option cloud_gateway_domain 'device-cloudgateway-staging.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security-staging.iot.i.tplinknbu.com' option cloud_security_port '443' config config 'prd' option cloud_gateway_domain 'device-cloudgateway.iot.i.tplinknbu.com' option cloud_gateway_port '443' option cloud_security_domain 'security.iot.i.tplinknbu.com' option cloud_security_port '443' config switch_type 'switch' option night_vision_mode 'inf_night_vision' option wtl_intensity_level '5' config para 'common' option inf_delay '10' config para 'shedday' option light_freq_mode 'auto' config para 'shednight' option light_freq_mode 'auto' config para 'autoday' config para 'autonight' config capability 'font_info' list display 'ntnb' list display 'tnb' list display 'ntb' list display 'tb' list size 'auto' list color_type 'auto' list color_type 'user_defined' list color 'black' list color 'white' option max_size '64*64' config capability 'label_info' option num '3' config capability 'res_info' option max_res_w '2304' config on_off 'tamper_det' config region_info 'region' option height '10000' option width '10000' option x_coor '0' option y_coor '0' config notif_list 'tamper_notif_list' config interface 'loopback' option ifname 'lo' option proto 'static' option ipaddr '127.0.0.1' option netmask '255.0.0.0' config interface 'wan' config configuration 'tour_config' config wlan 'basic' config wlan 'ap0' config wlan 'sta0' config wlan 'default_ap' option ap 'ap0' config on_off 'chn1_msg_push_info' config on_off 'msg_push_event' config on_off 'motion_det' config notif_list 'motion_notif_list' config region_info 'region_info_1' config network option init 'network' list affects 'dhcpd' list affects 'radvd' list affects 'ddns' list affects 'firewall' config wireless option init 'wlan' list affects 'wlanwarn' config firewall option init 'firewall' list affects 'upnpd' list affects 'packet_capture' config olsr option init 'olsrd' config dhcpd option init 'udhcpd' config dropbear option init 'dropbear' config httpd option init 'httpd' config fstab option init 'fstab' config system option init 'led' list affects 'luci_statistics' config upnpd option init 'miniupnpd' config ntpclient option init 'ntpclient' config samba option init 'samba' config tinyproxy option init 'tinyproxy' config uhttpd option init 'uhttpd' config ddns option init 'ddns' config guest_network option init 'guest_network' list affects 'firewall' config wlanwarn option init 'wlanwarn' config packet_capture option init 'packet_capture' config root 'root' config third_account 'third_account' config authentication 'authentication' config server 'vhttpd' config server 'rtsp' config URL 'URL' option profile_1 'stream1' option profile_2 'stream2' option profile_3 'stream3' config on_off 'media_encrypt'
Ciphertext, what is it?
You may wonder what sits inside those ciphertext variables, however, the content is encrypted. Thus, we have to perform the same operation and search in sl sysroot with grep by filtering by the keyword ciphertext:
config root 'root' option username 'admin' option passwd 'zMiVw8Kw0oxKXL0' option ciphertext 'dl5GoIRk+FMC/JgP5yLjA+r8PynYYSai8DSmdv1Xw7iALNEKxkE5UusQw6BMC4+FlcWv0bCPuw8DSlSk/vkmcTZ/BF/ZY1ENNJqo+uJtiGi2f1zJFjleYhPlDx4YXa3qp7oSNF8EU1BU4mOY9nEtUakFl4oVPsvlLGM3qE/zI2k=' option sharepwd '' option comment '' config third_account 'third_account' option username '---' option passwd '---' option ciphertext 'dl5GoIRk+FMC/JgP5yLjA+r8PynYYSai8DSmdv1Xw7iALNEKxkE5UusQw6BMC4+FlcWv0bCPuw8DSlSk/vkmcTZ/BF/ZY1ENNJqo+uJtiGi2f1zJFjleYhPlDx4YXa3qp7oSNF8EU1BU4mOY9nEtUakFl4oVPsvlLGM3qE/zI2k=' option comment ''
grep -ir 'ciphertext' grep: dsd: binary file matches grep: libdecrypter.so: binary file matches grep: _usr_conf_data_decrypt.extracted/18: binary file matches grep: extractions/flash_fixed.bin.extracted/43DA00/squashfs-root/usr/sbin/uhttpd: binary file matches grep: extractions/flash_fixed.bin.extracted/43DA00/squashfs-root/usr/bin/dsd: binary file matches grep: extractions/flash_fixed.bin.extracted/43DA00/squashfs-root/bin/nvid: binary file matches grep: extractions/flash_fixed.bin.extracted/43DA00/squashfs-root/bin/cet: binary file matches grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/usr/sbin/wpa_supplicant: binary file matches grep: extractions/flash_fixed.bin.extracted/5D800/squashfs-root/usr/lib/libdecrypter.so: binary file matches
Several matches show up, so we will start to analyze the binaries libdecrypter.so and dsd.
In libdecrypter.so we see an interesting function.
000013e0 int32_t private_decrypt(char* arg1, int32_t arg2, void* arg3) 00001414 int32_t $s0_2 00001414 if (arg2 != 0xac || (arg2 == 0xac && arg1 == 0)) 00001430 msglog(6, 0x1a40, 0x1b24, arg2) {"DECRYPTER"} {"wrong input. ciphertext_len %d.n"} 00001484 label_1484: 00001484 $s0_2 = 0 00001414 if (arg2 == 0xac && arg1 != 0) 00001450 void var_918 00001450 int32_t $v0_1 = sub_fa0(1, arg3, &var_918, arg2) 00001458 int32_t $v0_2 00001458 int32_t $a2_1 00001458 if ($v0_1 s>= 0) 00001490 $v0_2 = BIO_new_mem_buf(&var_918, 0xffffffff) 0000149c if ($v0_2 == 0) 000014b8 $a2_1 = 0x1a90 {"Create BIO buffer for public key…"} 000014cc else 000014cc int32_t $v0_3 = PEM_read_bio_RSAPrivateKey($v0_2, 0, 0, 0) 000014d8 if ($v0_3 == 0) 000014f4 msglog(6, 0x1a40, 0x1a90) {"DECRYPTER"} {"Create BIO buffer for public key…"} 000014fc $s0_2 = 0 00001510 else 00001510 int32_t var_20 = 0x80 00001520 void var_118 00001520 int32_t $v0_4 = rsa_base64_decode(arg1, 0xac, &var_118, &var_20) 00001528 int32_t $v0_5 00001528 int32_t $a2_3 00001528 if ($v0_4 != 0) 00001560 void var_98 00001560 $v0_5 = RSA_private_decrypt(var_20, &var_118, &var_98, $v0_3, 1) 0000156c if ($v0_5 s< 0) 00001584 $a2_3 = 0x1abc {"call RSA_public_encrypt failed"} 000015a4 else 000015a4 int32_t $v0_6 = calloc(0x75, 1) 000015ac $s0_2 = $v0_6 000015b0 if ($v0_6 != 0) 000015ec memcpy($v0_6, &var_98, $v0_5) 000015f8 *($s0_2 + $v0_5) = 0 000015cc else 000015cc msglog(6, 0x1a40, 0x1b6c) {"DECRYPTER"} {"Calloc mem error.n"} 00001544 else 00001544 $a2_3 = 0x1b48 {"Base64 decode ciphtertext error.…"} 0000156c if ($v0_4 == 0 || ($v0_4 != 0 && $v0_5 s< 0)) 00001590 $s0_2 = 0 0000158c msglog(6, 0x1a40, $a2_3) {"DECRYPTER"} 00001600 RSA_free($v0_3) 00001610 BIO_free_all($v0_2) 00001470 else 00001470 $a2_1 = 0x1a6c {"Base64 decode public key error.n"} 0000149c if ($v0_1 s< 0 || ($v0_1 s>= 0 && $v0_2 == 0)) 00001478 msglog(6, 0x1a40, $a2_1) {"DECRYPTER"} 00001478 goto label_1484 00001630 return $s0_2
The following points summarize how the function seems to operate:
- Initially, it validates that the ciphertext is 172 bytes long.
- Decodes the private key from a given buffer (arg3).
- Uses OpenSSL internally (BIO, PEM_read_bio_RSAPrivateKey)
- Decodes base64 ciphertext
- Performs decryption with private RSA + PKCS#1 padding
- Returns a buffer with the decrypted result
A probable translation to pseudocode would be:
char* private_decrypt(char* ciphertext_b64, int len, void* rsa_key_data) { if (len != 0xac || ciphertext_b64 == NULL) return NULL; char decoded_key[...]; if (sub_fa0(1, rsa_key_data, &decoded_key, len) < 0) return NULL; BIO* bio = BIO_new_mem_buf(decoded_key, -1); if (!bio) return NULL; RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); if (!rsa) return NULL; uint8_t ciphertext_bin[128]; int bin_len = rsa_base64_decode(ciphertext_b64, len, ciphertext_bin, &ciphertext_len); if (bin_len == 0) return NULL; uint8_t plaintext[128]; int pt_len = RSA_private_decrypt(ciphertext_len, ciphertext_bin, plaintext, rsa, RSA_PKCS1_PADDING); if (pt_len < 0) return NULL; char* output = calloc(1, 0x75); memcpy(output, plaintext, pt_len); output[pt_len] = ' '; RSA_free(rsa); BIO_free_all(bio); return output; }
This function decrypts a 128-byte RSA block, which comes in base64, using a private key provided as arg3, also encrypted. It uses OpenSSL (or a similar implementation) internally and requires both the key and the message to be in the expected format (PEM + base64).
At this stage, we went hunting for the RSA private key which was found to be embedded inside the library:

-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQC4D6i0oD/Ga5qb//RfSe8MrPVIrMIGecCxkcGWGj9kxxk74qQNq8XUuXoy2PczQ30BpiRHrlkbtBEPeWLpq85tfubTUjhBz1NPNvWrC88uaYVGvzNpgzZOqDC35961uPTuvdUa8vztcUQjEZy16WbmetRjURFIiWJgFCmemyYVbQIDAQABAoGAZ7lLVR7JUcPpyOegiuJbOEVvpJjWblfGY0rEURZRizU33yuFT77xKUOsvWLPS7BIjdlWsJ5r0NTUmGfLees71DqxfedQb3kSamBMErHu/jXeRi7MaGCLTyO9Ae+0+PFAHUdld1QjX50mAZD/+fbDPv7zUebNrMkFzbl99ctYznECQQDwiHNBP51VOF2f8pRmncr5QpZmWZb3ZNPw9Qc/97kn7Xs8zGz1NBEUA9SLcF25KXv6GpVdr6X7BuhXeB9HZpNTAkEAw+WYCnB1KjYz68FiIYkA63lrvnN2IG9pllkt+az6XFdXgOdqodoi3pWvmhkU55Z2N0okuGjm93qO1pebC3JcPwJAOsn+8Yms2LFoILnXj6UtgPLHc8id32Wjb5dT6EyR0rJ2louYbe4F5pBxGIukPKdpB94Ld9SAivRLQWW4r2jgxQJBAJo1+D1nj+Rd7PuPLXfmyRGVcQrpC7m22vDfXUDqOeBNZXX1Ns0Y0lBUl3sAeaNhn8ggls2QzxlMonstt4EIUrMCQCgOhLJ1SoUw1RE+b3x5hpuibFpiknX9MAjNxMJ1vHQFgsYTIVlD9LdHc/+nGbeXhzi0BJ2h3R5tmQmIseOs9f0= -----END RSA PRIVATE KEY-----
On the other hand, if we analyze the dsd binary we can see the following private_decrypt function call:

Lastly, we only have to start putting these pieces of information together. Firstly, we took the ciphertext and decoded it to base64 and saved it in bin format:
echo "dl5GoIRk+FMC/JgP5yLjA+r8PynYYSai8DSmdv1Xw7iALNEKxkE5UusQw6BMC4+FlcWv0bCPuw8DSlSk/vkmcTZ/BF/ZY1ENNJqo+uJtiGi2f1zJFjleYhPlDx4YXa3qp7oSNF8EU1BU4mOY9nEtUakFl4oVPsvlLGM3qE/zI2k=" | base64 -d > encrypted.bin
Lastly, we executed the following command:
openssl rsautl -decrypt -inkey private.pem -in encrypted.bin

Conclusion
The analysis conducted on the TP-Link Tapo C200 camera (version 3.0) revealed the encryption mechanism used in certain internal system files. Through reverse engineering, it was discovered that the decryption key is derived from a fixed string linked to the device model and firmware version —in this case, “C200 3.0″— which is hashed and used as the key for the DES algorithm in ECB mode.
This reconstruction enabled successful decryption of the protected information, demonstrating that the implemented encryption scheme does not rely on a random or secret key, but rather on predictable data embedded within the firmware itself.
Furthermore, a second encryption layer based on RSA was identified, in which specific encrypted structures are decrypted using a private RSA key embedded or accessible from the system. The process involved base64 decoding, dynamic loading of the RSA key, and decryption using PKCS#1 padding. This discovery further exposed the device’s vulnerabilities, as understanding the logic allowed successful recovery of data protected by this additional mechanism.
While functional, these mechanisms reveal significant weaknesses in data protection—especially when cryptographic keys are derived from predictable information and the firmware can be freely analyzed.
Leave a Comment