尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Hikvision 考勤机数据提取(2)

Hikvision 考勤机数据提取(2)
📅 发布时间:2026/6/20 17:26:08
import xml.etree.ElementTree as ET
import requests
from requests.auth import HTTPDigestAuth
import json 
import sys import hashlib
import base64 
import timedef get_random():timestamp = str(int(time.time() * 1e3 ))md5_hash = hashlib.md5(timestamp.encode()).hexdigest()e = md5_hash[:8]e = str(int(e.replace("#", ""), 16))[:8]return e ip='192.168.1.100'
port=80
username='admin'
password='admin'
session_url=f'http://{ip}:{port}/ISAPI/Security/sessionLogin/capabilities?username={username}&random={get_random()}'xml_string=requests.get(session_url).text
# xml_string = '<?xml version="1.0" encoding="UTF-8"?>\n<SessionLoginCap version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">\n  <sessionID>b81319692d0d270187bd71246c096131eae6f465243b565368e4c6e2f37aa59a</sessionID>\n  <challenge>07bf94e08f004c30736eb0835270393e</challenge>\n  <iterations>100</iterations>\n  <isIrreversible>true</isIrreversible>\n  <salt>WTV7Y1NXX57TXW4V0N4LS3OYFRHOPUML4Y8IFVVDGIMDEQOFUS0MV40QBXV0SHLC</salt>\n  <sessionIDVersion>2</sessionIDVersion>\n</SessionLoginCap>\n'root = ET.fromstring(xml_string)# 定义命名空间
ns = {'ns': 'http://www.isapi.org/ver20/XMLSchema'}# 使用命名空间查找元素
session_id = root.find('ns:sessionID', ns)
salt=root.find('ns:salt', ns)
challenge=root.find('ns:challenge', ns)
iterations=root.find('ns:iterations', ns)
print(session_id.text, salt.text, challenge.text, iterations.text)  # 现在应该能正确输出 sessionID 的值def get_security_capabilities(ip, username,password, port=80):"""Retrieves the solid salt to generate aes keyArgs:ip: IP address of the A10 Plususername: Username for authenticationpassword: Password for authenticationport: HTTP port (default 80)Returns:Dictionary with device information or an error message"""url = f"http://{ip}:{port}/ISAPI/Security/capabilities?username={username}"auth = HTTPDigestAuth(username, password)print(f"Querying device salt value at: {url}")try:response = requests.get(url, auth=auth, timeout=10, verify=False)print(f"Response code: {response.status_code}")if response.status_code == 200:# Parse the XML responsetry:root = ET.fromstring(response.content)security_cap = parse_security_capabilities(root)return {'status': 'success','security_cap': security_cap,'raw_response': response.text}except ET.ParseError as e:return {'status': 'error','message': f'Error parsing XML: {str(e)}','raw_response': response.text}else:return {'status': 'error','message': f"HTTP Error: {response.status_code}",'details': response.text if hasattr(response, 'text') else 'No details available'}except requests.exceptions.RequestException as e:return {'status': 'error','message': f'Connection Error: {str(e)}'}
def parse_security_capabilities(root):"""Extracts device SecurityCap include salt information from the XML response"""fields = ['supportUserNums','userBondIpNums','userBondMacNums','isSupCertificate','issupIllegalLoginLock','isSupportOnlineUser','isSupportAnonymous','isSupportStreamEncryption','securityVersion','keyIterateNum','isSupportUserCheck','SecurityLimits','WebCertificateCap','RSAKeyLength']security_cap = {}# Handle namespace if it existsnamespace = ''if '}' in root.tag:namespace = root.tag.split('}', 1)[0] + '}'if hasattr(root, 'attrib') and root.attrib:for attr_name, attr_value in root.attrib.items():security_cap[attr_name] = attr_value# Extract all available fieldsfor field in fields:# Search with namespace if it existselement = root.find(f'.//{namespace}{field}') if namespace else root.find(f'.//{field}')if element is not None:if len(element) > 0:security_cap[field] = extract_nested_element(element)elif element.attrib:attr_info = []for attr_name, attr_value in element.attrib.items():attr_info.append(f"{attr_name}={attr_value}")security_cap[field] = f"[{', '.join(attr_info)}]"elif element.text and element.text.strip():security_cap[field] = element.text.strip()else:security_cap[field] = "[Empty]"for child in root:tag = child.tag# Remove namespace if it existsif '}' in tag:tag=tag.split('}', 1)[1]if tag not in security_cap:if len(child) > 0:security_cap[tag] = extract_nested_element(child)elif child.attrib:attr_info = []for attr_name, attr_value in child.attrib.items():attr_info.append(f"{attr_name}={attr_value}")security_cap[tag] = f"[{', '.join(attr_info)}]"elif child.text and child.text.strip():security_cap[tag]=child.text.strip()   root_attrs = extract_element_attributes(root)security_cap.update(root_attrs)return security_capdef extract_nested_element(element):"""递归提取嵌套XML元素的信息"""result = []if element.attrib:attrs = []for key, value in element.attrib.items():attrs.append(f"{key}={value}")if attrs:result.append(f"{[', '.join(attrs)]}")if element.text and element.text.strip():result.append(element.text.strip())for child in element:child_info = extract_nested_element(child)if child_info:if child.tag !=element.tag:result.append(f"{child.tag}: {child_info}")else:result.append(child_info)return "; ".join(result) if result else "[No content]"def extract_element_attributes(element, field_name=""):"""提取元素的属性信息,格式化为更易读的形式"""if not element.attrib:return Noneresult = []# 提取所有属性for attr_name, attr_value in element.attrib.items():result.append(f"{attr_name}={attr_value}")# 特殊处理某些字段if field_name == 'securityVersion' and 'opt' in element.attrib:return f"option={element.attrib['opt']}"elif field_name == 'RSAKeyLength':info = []if 'opt' in element.attrib:info.append(f"option={element.attrib['opt']}")if 'def' in element.attrib:info.append(f"default={element.attrib['def']}")return "; ".join(info) if info else Nonereturn "; ".join(result) if result else Nonedef extract_element_attributes(element, prefix=""):"""extract element attributes"""attributes = {}if hasattr(element, 'attrib') and element.attrib:for attr_name, attr_value in element.attrib.items():key = f"{prefix}{attr_name}" if prefix else attr_nameattributes[key] = attr_valuereturn attributesdef format_security_cap(security_cap):"""Formats the security capacities information for legible presentation"""if not security_cap:return 'No security cap information found'# # all_fields = [#      # 基础配置#   "version",#   "supportUserNums",#   "userBondIpNums",#   "userBondMacNums",#   # 用户认证与管理#   "isSupCertificate",#   "isSupportAnonymous",#   "isSupportUserCheck",#   "isSupportONVIFUserManagement",#   # 安全策略#   "issupIllegalLoginLock",#   "isSupportOnlineUser",#   "isSupportStreamEncryption",#   # 密码安全#   "keyIterateNum",#   "SecurityLimits",#   "LoginPasswordLenLimit",#   # 加密算法#   "securityVersion",#   "RSAKeyLength",#   "WebCertificateCap",#   "CertificateType",#   "SecurityAlgorithm",#   "algorithmType"# ]priority_fields = ['version',                    # 版本号 ✓'supportUserNums',           # 支持用户数量 ✓'isSupCertificate',          # 支持证书认证 ✓'isSupportAnonymous',        # 支持匿名访问 ✓'isSupportUserCheck',        # 支持用户检查 ✓'isSupportStreamEncryption', # 支持流加密 ✓'issupIllegalLoginLock',     # 支持非法登录锁定 ✓'isSupportOnlineUser',       # 支持在线用户管理 ✓'keyIterateNum',             # 密钥迭代次数 ✓'securityVersion',           # 安全版本 ✓'RSAKeyLength'               # RSA密钥长度 ✓]output = ["=== SECURITIES CAPACITIES INFORMATION ==="]# First display priority fields (only if they exist)for field in priority_fields:if field in security_cap:output.append(f"{field}: {security_cap[field]}")# Group  informationoutput.append("\n=== Firmware INFORMATION ===")firmware_fields = ['securityVersion',           # 安全版本 (已在priority_fields中)'RSAKeyLength'               # RSA密钥长度 (已在priority_fields中)]for field in firmware_fields:if field in security_cap and field !='securityVersion':output.append(f"{field}: {security_cap[field]}")# Then display the rest of the fieldsoutput.append("\n===ADDITIONAL INFORMATION ===")for key, value in sorted(security_cap.items()):if key not in priority_fields and key not in firmware_fields:output.append(f"{key}: {value}")return "\n".join(output)def save_results_to_file(result, filename="security_cap.json"):"""Saves the results to a JSON file"""with open(filename, "w", encoding="utf-8") as f:json.dump(result, f, indent=2, ensure_ascii=False)print(f"Results saved to '{filename}")
result=get_security_capabilities(ip,username,password,port)if result['status'] == 'success':print("\n" +format_security_cap(result['security_cap']))save_results_to_file(result)
else:print(f"\nError: {result['message']}")if 'details' in result:print(f'Details: {result['details']}')print("\nSuggestions:")print("1. Verify that the IP and port are correct")print("2. Check the user credentials (username and password)")print("3. Ensure the device is accessible on the network")print("4. Try with different ports (80, 8000)")print("5. Check if the device requires HTTPS instead of HTTP")

参考:
https://github.com/reiarseni/hikvision-device-info/blob/main/hikvision_device_info.py

相关新闻

  • 2025-11-28 如何更换power shell背景颜色(deepseek)
  • XYD11.27模拟赛
  • P10704

最新新闻

  • 毕业季论文必备!专业AI论文平台,成稿速度破纪录
  • 江苏南京10大叛逆/网瘾/厌学孩子全封闭学校推荐|2026家长必看,别再走弯路! - 辛云教育资讯
  • 嵌入式GUI多语言支持:从UTF-8编码到复杂脚本的实战解析
  • BeautifulSoup实战:从豆瓣TOP250到构建个人电影数据库
  • 深圳代理记账避坑指南:99元/月的账,你敢用吗? - 小征每日分享
  • OpenCore Legacy Patcher完整指南:3个步骤让老旧Mac重获新生

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号