• SSL在线生成系统更新支持通配符申请,更新证书有效时长延迟至半年时长

    SSL在线生成系统更新支持通配符申请,更新证书有效时长延迟至半年时长 此次主要更新的功能支持统配符跟,半年,3个月的区分 控制台也增加了功能   下载地址:https://wwpr.lanzout.com/iP5Hb1bffx5g ...

    2023-10-12 171
  • Linux运维常用帮助命令详解

    1.1 命令类型 命令类型有:alias(别名)、keyword(关键字,shell保留字)、function(函数,shell函数)、builtin(内部命令,shell内部命令)、file(文件,磁盘文件,外部命令)、unfound(没有找到) 1.1.1 type命令 #语法格式:type [-afptP] name [name ...] # 选项: -t 根据name的类型返回一个单词(别名,关键字,函数,内建,文件),否则返回空值 -p 如果给出的指令为外部指令,则显示其绝对路径 -a 在环境变量“PATH”指定的路径中,显示给定指令的信息,包括命令别名 #作用:用来显示指定命令的类型,判断给出的指令是内部指令还是外部指令 #示例: # type -t cd # 判断cd指令是内部指令还是外部指令 # type -t sh # 判断sh指令是内部指令还是外部指令 1.2 命令帮助 help命令只能显示shell内部命令的帮助信息,对于外部命令的帮助信息可以使用man命令或info命令或命令 –help方式 1.2.1 help命令 #语法格式:help [-dms] [pattern ...] # 选项: -d 输出每个主题的简短描述 -m 以 man 手册的格式显示使用方法 -s 为每一个匹配 PATTERN 模式的主题仅显示一个用法 #作用:用于显示shell内部命令的帮助信息 #示例: # help -m help # 显示help命令帮助信息 # help -m cd # 显示cd命令帮助信息 1.2.2 –help参数 #语法格式:<command> --help #作用:显示外部命令帮助信息 # 示例: # sh --help # 显示sh命令帮助信息 1.2.3 man命令 #语法格式:man [option] <command> #选项: -a 在所有的man帮助手册中搜索 -f 显示给定关键字的简短描述信息 -p 指定内容时使用分页程序 -w 显示文件所在位置 #作用:查看Linux中的指令帮助、配置文件帮助和编程帮助等信息 #示例: # man mv # 查看mv命令帮助信息 1.2.4 info命令 #语法格式:info [option] <command> #作用:查看Linux指令帮助信息 #示例: # info mv # 查看mv命令帮助信息 1.2.5 whatis命令 #语法格式:whatis [option] <command> #作用:查看常用命令简介信息 #示例: # whatis pwd # 查看pwd命令简介信息 </div> ...

    2023-10-10 190
  • Linux运维常用关机重启命令详解

    1、关机命令 1.1 halt/poweroff命令 #语法格式:halt/poweroff [option] #选项: -p 在关闭系统之后,自动将计算机电源关闭 -f 强制关闭系统,无需确认 -d 仅关闭系统,不断电 #作用:用于关闭系统并停止所有进程,将计算机完全关闭 #示例: # halt -p # 关闭系统后关闭电源 # halt -d # 关闭系统但不断电   2、重启命令 2.1 reboot命令 #语法格式:reboot [option] #选项: -d 重新开机时不把数据写入记录文件/var/tmp/wtmp -f 强制重新开机,不调用shutdown指令的功能 -i 在重开机之前,先关闭所有网络界面 -n 重开机之前不检查是否有未结束的程序 -w 仅做测试,并不真正将系统重新开机,只会把重开机的数据写入/var/log目录下的wtmp记录文件 #作用:用于关闭系统并停止所有进程,将计算机完全关闭 #示例: # reboot # 重开机 # reboot -w # 做个重开机的模拟   3、关机重启 3.1 shutdown命令 #语法格式:shutdown [option] #选项: -c 取消即将执行的关机程序 -k 仅仅向每个登录用户发出警告信息,并不真正关机 -h 关机(halt) -H 关机(halt) -P 关机(poweroff) -r 重启(reboot) #作用:用来重启、关闭服务器 #示例: # shutdown –h now # 立刻关机 # shutdown –h +10 # 10分钟后关机 # shutdown -h 21:30 # 21点30分关机 # shutdown -c # 取消关机 # shutdown -r now # 立刻重启 # shutdown -r +10 # 10分钟后重启   3.2 init命令 #语法格式:init [option] #选项: 0 关闭计算机系统 1 切换单用户模式 3 切换完全多用户模式 6 重启计算机系统 #作用:用来重启、关闭服务器 #示例: # init 0 # 关闭计算机系统 # init 6 # 重启计算机系统   4、退出命令 4.1 logout命令 #语法格式:logout #作用:退出当前登录的shell命令 #示例: # logout # 退出当前登录   4.2 exit命令 #语法格式:exit #作用:退出当前登录的shell命令并退出执行的shell脚本 #示例: # exit # 退出当前登录的shell命令并退出执行的shell脚本   </div> ...

    2023-10-10 165
  • Linux如何设置ssh密钥(免密)登录

    我们在使用ssh客户端远程连接Linux服务器时,为了考虑安全方面的因素,通常使用密钥的方式来登录。 密钥分为公钥和私钥,这两把密钥可以互为加解密。 公钥是公开的,私钥是由个人自己持有,并且必须妥善保管和注意保密。 Linux设置密钥登录的步骤 一、生成密钥(公钥与私钥) 执行ssh-keygen命令,生成id_rsa和id_rsa.pub两个文件,id_rsa是私钥(重要,需安全保管),id_rsa.pub是公钥,密钥生成过程中可根据提示对密钥设置密码,也可留空直接回车。 解释: -t 选项指定要使用的加密算法,“rsa”表示使用RSA算法; -b 选项指定密钥的长度; -C 选项是可选的,用于添加注释。 二、创建authorized_keys文件并设置权限 1.查看密钥认证文件authorized_keys是否存在,若不存在则创建并授权,命令如下: [root@server1 ~]# touch ~/.ssh/authorized_keys [root@server1 ~]# chmod 600 ~/.ssh/authorized_keys 2.将公钥内容追加到authorized_keys文件中 [root@server1 ~]# cd ~/.ssh [root@server1 .ssh]# cat id_rsa.pub >> authorized_keys 三、设置sshd配置文件允许使用密钥登录 修改sshd_config文件,启用以下参数: RSAAuthentication yes PubkeyAuthentication yes PermitRootLogin yes AuthorizedKeysFile .ssh/authorized_keys 修改完配置文件,重启sshd服务 [root@server1 ~]# systemctl restart sshd 四、使用私钥登录验证 在Linux主机上登录验证 [root@server1 .ssh]# ssh root@localhost -i id_rsa Last login: Wed Sep 13 17:13:28 2023 from 192.168.15.1 在Win下使用ssh客户端导入私钥登录验证 五、禁用密码登录 修改sshd_config文件,启用以下参数: PasswordAuthentication no 重启sshd服务 [root@server1 ~]# systemctl restart sshd 至此,Linux已经设置为密钥登录,相对于使用密码认证登录的方式更为安全,前提是私钥要安全保管。 ...

    2023-10-10 171
  • 实战经验 | 企业安全运营如何做好数据接入?

    1 项目背景 1.1 整体安全观 网络安全管理平台作为企业安全的大脑,也就是整个企业的安全运营中心,其数据接入的多少、好坏直接影响到安全运营的效果,如果以汽车来比喻的话,数据就是汽车的油箱或者电瓶,是保障汽车启动的动力。 1.2 安全现状 (一)数据接入不全面,告警结果不准确 企业IT资产的日志包括系统日志、中间件日志、数据库日志,安全设备日志、网络设备日志,其涉及的日志类型多、规模庞大,企业大部分未完成全部接入,存在监控死角; (二)数据量呈现过多,重要信息难发现 以10Gbps流量的举例,大概每天会产生50000条左右的日志,但是真正有效的日志只有100条以内,想要在几万条的数据中发现几十条有用的数据,无异于是大海捞针; (三)数据存在孤岛,数据无法串联 由于企业建设的阶段不同、要求不同,安全设备存在不同的安全厂商、安全设备之间能力未打通,因此无法进行关联分析,根据洛克希德马丁的杀伤链模型,攻击并不是凭空出现,安全设备的日志与系统的日志之间都是有关联的; (四)能力建设缺失,未有统一规划 安全作为业务的附属,大多数企业在投资还是管理上都存在严重不足的情况,脑海中对安全的要求是不出事就可以,但是安全不同于业务,安全平常是不可见的,只有在被攻击的时候才会体现效果; 1.3 建设依据 ...

    2023-10-10 220
  • 以“溯源”为诱饵反钓鱼蓝队,攻击队这波上大分

    2023年攻防演练活动圆满收官,各位七夕节还在疯狂打HW的红蓝队师傅们辛苦了。上次分享了一些蓝队方面的想法,“攻防演练之给蓝队防守方的11个忠告”,感兴趣的师傅们可以在FreeBuf网站查看。这篇文章分享一下2023年攻防演练中红队的一些个人想法,希望和大家一起交流交流。如有不对之处,还请师傅们多多指教。 回顾2023年攻防演练行动,发生了很多非常有意思的事情,攻击队的整体表现令业界眼前一亮,给不少蓝队成员上了难忘的一课。例如在攻防演练行动刚刚开始时,就传出某某通信领域的单位被攻击队直接打穿;某某攻击队已经杀疯了等多种版本的传闻。由于事件的敏感性和保密性,导致很多消息难以百分百实锤,但也从侧面反映出2023年攻击队之强悍,战法之新颖,武器之犀利等。 最最令人感到不可思议的是,某个攻击队竟然想出一个“以溯源反制”为诱饵,引诱蓝队防守成员进入恶意环境,成功钓鱼蓝队的方法,在网络安全领域展示了一波什么才是真正的对抗,以及孙子兵法如何活灵活现应用至攻防演练行动中。 正是因为有如此出人意料的攻击方式的存在,才让攻防演练行动变得更加有意义。在攻防演练中发现问题,解决问题,真正提升企业安全防护能力,从而提升我国网络空间整体安全等级,才是攻防演练的最终目的和真正意义。 为2023年攻防演练行动中攻击队的优异表现点赞。但在攻防演练圆满收官的时候,攻击队这边也曝出舞蹈生滥竽充数的案例,其令网安行业震惊的程度不亚于上述新颖的攻击战法,甚至是有过之而无不及,可以预见,在2024年的攻防演练行动中,新人面试攻击成员将会遭遇前所未有的难度。 接下来,我会一一分享个人总结的2023年攻防演练观点,欢迎评论区留言讨论。 签了保密协议就认真履行 2023年攻防演练行动最后一天最大的瓜莫过于“苕皮哥了”。这位“苕皮哥”是某蓝队防守方成员,攻防演练的最后一天在红书发文:“暑假12天挣了3万多,奖励自己吃苕皮”,一时间引起轩然大波,迅速在整个网安圈子里流传,更是震惊了一众圈外打工人,纷纷在社交平台上惊呼“网安人搞钱太容易了。” 据说“苕皮哥”并非专业的网安人,而是一名在校舞蹈生,经过三个月的学习后以在校生的身份参加了2023年攻防演练行动,单日收入2700元。说实话这个工资已经吊打许多网安毕业生了。 不知道是觉得钱拿的过于容易,还是为了炫耀,“苕皮哥”干了一件很无脑的事情——直接公布了攻防演练进场合同,上面明确写了进场工资1800元,工作12小时以上工资上浮1.5倍,也就是2700元。 打过HW的师傅们都知道,一般这类合同都有保密协议,就这样不打码直接将进场合同发在社交平台上,对于厂商、甲方、第三方来说都是一种巨大的伤害。传闻“苕皮哥”事件传开后,厂商已经在琢磨起诉事宜,后续等待“苕皮哥”的也是会是更重的处罚。 最最糟糕的是这件事情将会给攻防演练行动的外聘人员带来严重的负面影响,很有可能以后在校大学生在面试hw时会面临更严格的要求,价格肯定也会迎来一波跳水,甚至有可能引发相关部门对于攻防演练外聘人员的整顿。“苕皮哥”行为出发点也许就是单纯的炫一波,但是最终的结果却是把网安吃饭的桌子都给掀了。 当然,从长远来看,这件事情也许会让攻防演练行动变得越来越规范,一些行业乱象将会被整改。这里强调一下,签了保密合同就要认真履行保密协议,真的别不当回事,当法院传票发来的那一刻,对于个人来说将会面临非常严重的后果。 攻击队上演“三十六计” 2023年另外一件令我大开眼界的事情,就是攻击队在攻防演练中上演了一波精彩的网安三十六计。整个攻击过程异常丝滑犹如行云流水,攻击方心思缜密层层设局,洞悉防守方的内心,一步步将防守方成员引入陷阱之中,将三十六计是玩的明明白白,实在是令人拍案叫绝,该狠狠上一波大分。 通常来说,蓝队防守方利用蜜罐来钓鱼攻击方是非常常见的手法,也是蓝队溯源反制必不可少的措施,蜜罐用的好,攻防演练的成绩基本也不会差到哪里去。但是红队以“溯源反制”为诱饵,反过来钓鱼蓝队这就不常见了。事实上这一次反钓鱼的效果非常好,蓝队成员大多中了圈套,后面结果如何已经不需要多说。 具体操作思路如下:红队故意发起攻击是蓝队进行溯源反制,在这个过程中诱导蓝队访问器搭建的恶意服务,钓鱼公告后红队再次对蓝队主机进行攻击反制,从而顺利获得防守方的内网权限。整个攻击方法不仅仅体现在技术高超,更多的是利用了规则——即没有多少蓝队能够抵得住“溯源反制”的诱惑,从而反钓鱼蓝队拿下权限。 2023年的这个案例充分说明了,网络攻防演练不是套路化的演习,而是实打实的攻守双方的激烈对抗,真正的攻击方不会和你讲任何的经验与套路,只会不断掏出新的攻击方法持续碾压你们。该案例也从侧面说明了攻防演练的实质,演习即实战,在攻防演练行动中,防守方必须时刻牢记,自己面对的是一群不论技术还是理念都十分先进的对手,千万不可放松警惕。如果我是本次攻防演练的裁判,那么我会给攻击方更多的分数,正是因为有这样持续进化的攻击方,我们的网络安全防护体系才能持续不断发展、优化。 旧的攻击方法依旧很好用 他山之石可以攻玉。在攻防演练行动开始之前,攻击队应该提前收集各类优秀的攻击方法和案例,总结学习其中的优秀思路和手法, 在攻防演练中,攻击方会利用各种技术手段和方法,如网络渗透、漏洞利用等,来尝试入侵防守方的系统或获取敏感信息。他们的目标是发现潜在的漏洞和弱点,并评估防守方对这些攻击的应对能力。红队常见的攻击方法可以分为以下八类: 互联网边界渗透。几乎所有企业都有部分开放于互联网的设备或系统,比如邮件、官网等。红队会以这些设备或系统的开放性特点,将其作为入侵的切入点。 通用产品组件漏洞利用。信息化产品虽然提高了企业的运行效率,但其自身的安全漏洞也给企业带来了很多潜在隐患。红队在攻防演练中就经常通过利用产品组件的漏洞来达成攻击目标,比如:OA漏洞、中间件漏洞、数据库漏洞等。 0day攻击。在攻防演练中,0day攻击已成为常态,由于0day漏洞能够穿透现有基于 ...

    2023-10-09 170
  • 记一次众测的两个洞

    这两个洞是公众号的,以下是我利用Charles+burp进行抓包,Charles的配置。 测公众号的话,可以用浏览器打开,以下主要是可以进行微信小程序的测试。不用下载什么模拟器,pc端完全可以。但是找小程序包的逆向看源码,我发现有一个相同的小程序,模拟器里面的包有主包和分包。PC端的只有一个主包。进行查看,分包里面的内容也没有什么可用的,但是有的小程序PC端也会发现分包。真机的话,已经在root的手机没有在小程序包的目录发现。 还有小程序在模拟器找小程序包的话,要root,用雷神的话,文件管理器会赋予root权限,可以进行根目录的查看。要是真机或者mumu的话需要下载一个Root Explorer,才可以查看根目录。当然可以用adb进入shell,在导出wxapkg包也完全可以。 首先安装证书 之后跟着走就安装好了 接着需要配置https。 最后配置连接到bu ...

    2023-10-08 171
  • 如何使用Redeye在渗透测试活动中更好地管理你的数据

    关于Redeye Redeye是一款功能强大的渗透测试数据管理辅助工具,该工具专为渗透测试人员设计和开发,旨在帮助广大渗透测试专家以一种高效的形式管理渗透测试活动中的各种数据信息。 工具概览 服务器端面板将显示所有添加的服务器基础信息,其中包括所有者用户、打开的端口和是否已被入侵: 进入服务器之后,将显示一个编辑面板,你可以在其中添加目标服务器上发现的新用户、安全漏洞和相关的文件数据等: 用户面板包含了从所有服务器上发现的全部用户,用户信息通过权限等级和类型进行分类,用户的详细信息可以通过将鼠标悬停在用户名上以进行修改: 文件面板将显示当前渗透测试活动中相关的全部文件,团队成员可以上传或下载这些文件: 攻击向量面板将显示所有已发现的攻击向量,并提供严重性、合理性和安全风险图: 预报告面板中包含了当前渗透测试活动中的所有屏幕截图: 图表面板中包含了渗透测试过程中涉及到的全部用户和服务器,以及它们之间的关系信息: API允许用户通过简单的API请求来轻松获取数据: curl redeye.local:8443/api/servers --silent -H "Token: redeye_61a8fc25-105e-4e70-9bc3-58ca75e228ca" | jq curl redeye.local:8443/api/users --silent -H "Token: redeye_61a8fc25-105e-4e70-9bc3-58ca75e228ca" | jq   curl redeye.local:8443/api/exploits --silent -H "Token: redeye_61a8fc25-105e-4e70-9bc3-58ca75e228ca" | jq 漏洞利用: 任务查看: 工具安装 Docker安装 首先,我们需要从该项目的GitHub代码库上拉取项目代码: git clone https://github.com/redeye-framework/Redeye.git 然后切换到项目目录中,并运行docker-compose: cd Redeye     docker-compose up -d 接下来,我们需要启动或关闭容器: sudo docker-compose start/stop 最后存储并加载Redeye即可: docker save ghcr.io/redeye-framework/redeye:latest neo4j:4.4.9 > Redeye.tar     docker load < Redeye.tar 源代码安装 由于该工具需要使用到Python 3环境,因此我们首先需要在本地设备上安装并配置好Python 3。接下来,广大研究人员可以使用下列命令将该项目源码克隆至本地: git clone https://github.com/redeye-framework/Redeye.git 然后切换到项目目录中,激活虚拟环境,并使用pip3工具和项目提供的requirements.txt文件安装该工具所需的其他依赖组件: cd Redeye     sudo apt install python3.8-venv   python3 -m venv RedeyeVirtualEnv   source RedeyeVirtualEnv/bin/activate   pip3 install -r requirements.txt 最后,执行数据库脚本和工具脚本即可: python3 RedDB/db.py     python3 redeye.py --safe 工具使用 工具运行后,将开始监听下列地址: http://0.0.0.0:8443 默认用户凭证如下: 用户名:redeye 密码:redeye Neo4j将监听下列地址: http://0.0.0.0:7474 默认登录凭证如下: 用户名:neo4j 密码:redeye 许可证协议 本项目的开发与发布遵循BSD-3-Clause开源许可证协议。 项目地址 Redeye:【GitHub传送门】 参考资料 https://github.com/azouaoui-med/pro-sidebar-template https://bootsnipp.com/snippets/Q0dAX https://www.jqueryscript.net/chart-graph/Drag-drop-Flow-Chart-Plugin-With-jQuery-jQuery-UI-flowchart-js.html http://danml.com/download.html http://www.dropzonejs.com https://www.iconfinder.com http://www.freepik.com https://codepen.io/jo_Geek/pen/NLoGZZ  ...

    2023-10-08 158
  • 如何在Linux上用Doxygen生成源代码文档

    在试着熟悉别人的代码时,你总希望他们留下的代码注释能对你理解代码有所帮助。同理,无论为了自己还是其他人,编写代码时写注释是好习惯。所有编程语言都有专门的注释语法,注释可以是一个单词、一行文字、甚至是一整段话。编译器或解释器处理源代码时会忽略注释。 注释不能完全取代文档,但是有方法可以使用注释来生成文档。Doxygen是一个开源的文档生成工具,它能够根据代码注释生成 HTML 或 LaTeX 格式的文档。Doxygen 让你在不用额外操作的情况下创建代码结构概览。尽管 Doxygen 主要是用来给 C++ 生成文档的,它对其它语言同样适用,比如 C、Objective-C、 C#、 PHP、Java 和 Python 等。 要使用 Doxygen,你只需要在源代码中使用 Doxygen 能够识别的语法来写注释。Doxygen 会扫描源码文件,然后根据这些特殊注释生成 HTML 或 LaTeX 文档。下面的示例项目会演示如何使用 Doxygen 注释,以及文档是如通过注释生成出来的。示例代码可从 GitHub上获得,本文中也将引用Doxygen 手册及文档的相关章节。 在 Linux 上安装 Doxygen 在 Fedora 上可以通过软件包的形式安装 Doxygen。打开终端运行命令: sudo dnf install doxygen 在基于 Debian 的操作系统上,可以通过以下命令来安装: sudo apt-get install doxygen 使用 安装完 Doxygen 后,你需要在项目中按 Doxygen 可以识别的格式来注释代码,还要提供一个 Doxyfile 配置文件来控制 Doxygen 的一些行为。 注意:如果你用的是 GitHub 上的示例项目,你可以忽略下面一步。 如果 Doxyfile 文件不存在,你可以用 Doxygen 生成一个标准 Doxyfile 模板文件。切换到项目根目录下,运行: doxygen -g 参数 -g表示 生成generate。现在应该会出现一个名为Doxyfile的新文件。通过命令调用 Doxygen: doxygen 现在应该能会有两个新文件夹: html/ latex/ 默认情况下,Doxygen 会同时输出 LaTeX 和 HTML 格式的文档。本文主要关注 HTML 文档。你可以在 Doxygen 官方文档的入门小节中找到关于 LaTeX 格式输出的更多信息。 双击 html/index.html打开 HTML 文件。用空的配置文件生成的文档如下图: 现在我们试着修改 Doxyfile文件,并在源代码中添加特殊注释。 Doxyfile 文件 在 Doxyfile文件中可以定义大量的可调选项,本文通过介绍示例项目的Doxyfile文件我只能覆盖其中很小的子集。 第 35 行:项目名称 你可以在这里指定项目名称,它最终会显示在页眉header和浏览器标签上。 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "My Project" 第 47 行:项目简介 项目简介会以略小的字号显示在页眉上。 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "An example of using Doxygen in C++" 第 926 行:包含子目录 允许 Doxygen 查找源代码和文档文件时递归遍历子目录。 # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES 第 1769 行:禁用 LaTeX 输出 如果你只想生成 HTML 文档,可以通过这个开关禁用 LaTeX 输出。 # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO 修改完成后,你可以再次运行 Doxygen 来检验修改是否生效了。可以在调用 Doxygen 时使用 -x选项来查看Doxyfile文件的变更项: 通过调用 diff命令,Doxygen 仅显示当前 Doxyfile 文件和模板文件的差异。 特殊注释 Doxygen 通过扫描源代码文件中的特殊注释和关键字来生成 HTML 文档。示例项目中的 ByteStream 类的头文件可以很好地解释特殊注释的用法。 下面用构造函数和析构函数作为示例: /*! @brief Constructor which takes an external buffer to operate on * * The specified buffer already exist. * Memory and size can be accessed by buffer and size. * * @param[in] pBuf Pointer to existing buffer * @param[in] size Size of the existing buffer */ ByteStream(char* pBuf, size_t size) noexcept; 特殊注释块有不同的格式风格。我倾向于使用 /*!开头(Qt 风格),每行前添加*,以*/结束注释块。你可以参考 Doxygen 手册的文档化代码小节,以大致了解不同的风格选项。 Doxygen 注释分两个部分:简要描述和详细描述。它们都是可选的。在上面的例子中的注释块是对紧跟其后的构造函数声明的描述。在 @brief之后的文本会显示在类概览小节中: 在空行(空行是段落分隔符)之后是构造函数的实际文档。用 @param[in/out]关键字标注传递给构造函数的参数,Doxygen 基于此生成参数列表: 值得注意的是 Doxygen 为 buffer和size方法自动生成了链接。相反,Doxygen 忽略了析构函数前的注释,因为它并没有使用特殊注释: // Destructor ~ByteStream; 现在你已经看到 Doxygen 的绝大部分功能了。通过使用一种稍微改良的注释格式,让 Doxygen 能够识别它们。通过使用一些关键字,你甚至可以进一步控制格式化。在下一节中,我会进一步介绍 Doxygen 的其它特性。 其它特性 现在几乎所有的工作都可以通过对源代码注释的方式完成。通过一些微调,你可以轻松地优化 Doxygen 的输出。 Markdown 格式 为了进阶的格式化,Doxygen 支持 Markdown 和 HTML 命令。Markdown 速查表可以在 这里下载到。 项目主页 除了自定义页眉之外,html/index.html几乎没有其它内容了。你可以通过使用关键字向其中添加一些有意义的内容。因为主页通常不是针对某个源代码文件的,你可以将要显示在主页的内容放到项目根目录下的一个单独文件中。示例项目中就是这样做的,其输出效果如下: 自动链接生成 上面已将提到了,当你引用代码的其它部分时,Doxygen 会自动识别并生成相应链接。但要注意,这要求被引用部分也有文档才行。 更多信息可以在官方文档的自动链接生成中找到。 分组 ByteStream类重载overload 了的读写流操作符 ( 和 >>)。在类的概览中可以发现操作符被分为读和写两组。分组是在ByteStream的头文件中定义的。 分组的语法以标记 @{开始,以}@结束。在标记范围中的内容都属于这个分组。在ByteStream.h中的实现如下: /** @name Writing * Operators for writing to the stream * @{ */ (...) /** @} * @name Reading * Operators for reading from the stream * @{ */ (...) /** @} */ 你可以在官方文档的分组中找到更多相关信息。 LLVM 支持 如果你用 Clang构建项目的话,可以通过使用-Wdocumentation选项让 Clang 对特殊注释进行检查。想了解该特性的更多信息,可以参考 LLVM 用户手册和 Dmitri Gribenko 的展示报告,它们可以在 Clang 网站上找到。 谁在用 Doxygen Doxygen 是在 1997 年首次发布的。尽管有些年头了,现在仍然有很多项目在使用 Doxygen。比如 NASA 的飞行软件框架 F Prime、图像处理库OpenCV、包管理器RPM。你还可以在其它领域发现 Doxygen 语法标记的身影,比如内容管理平台Drupal的文档标准中。 注意:Doxygen 输出的 HTML 文档风格类似于九十年代网页。并且它也难以描绘元编程和模板编程架构。在这些情况下,你应该选择 Sphinx而不是 Doxygen。 ...

    2023-09-26 234
  • 注册获得一个备案域名教程

    一个未注册备案域名扫描教程,文字教程。我花钱购买了这份教程,并认为操作非常简单,几乎没有成本。相信大部分站长都看到过,有人售卖未注册中文备案域名,今天我花钱买了一份教程,操作非常简单,几乎无成本,现在免费分享给大家!首先先去淘宝或者闲鱼买个站长工具的会员,大概1-5元然后访问站长工具 (chinaz.com)按照我下图进行配置  图一 判断有没有注册,点进你想看的哪个域名进去就有显示,如果显示没有哪大概率就是没有注册的之后在到腾讯云域名注册进行查询域名注册购买_域名注册选购 – 腾讯云 (tencent.com)说明:自定义时间尽量设置在17年以前,单位性质可以为企业或者个人,网站状态必须为未开通在找域名时最好只看中文备案域名,英文很少有,没有太多技术,如果会写脚本,可以直接进行爬,然后判断 ...

    2023-09-25 207
  • 为什么Java中字符串是不可变的

    文章目录 1. 什么是不可变类? 2.字符串的运作方式 3.不可变字符串的优点 3.1. 应用程序和数据安全性 3.2. 提高性能 3.3. 线程安全性 3.4. 缓存 结论 默认情况下,Java 字符串是不可变的。字符串的不变性有助于提供缓存、安全性、快速性能和更好的内存利用率等功能。本教程讨论字符串的不可变性如何帮助实现这些功能。 1. 什么是不可变类? 什么是不可变类? 让我们从不可变性本身开始。一个不可变对象是一个其状态在其整个生命周期内都保证不会发生改变的对象。这意味着一旦初始化了对象的状态,它就无法在任何情况下被改变。 Java也有不可变类,主要包括String和包装类。 2.字符串的运作方式 在Java中,内存被分为三个部分,即堆(Heap)、栈(Stack)和字符串常量池(String Pool)。字符串常量池是专门用于存储字符串字面值的特殊区域。 当我们创建一个字符串时,会在字符串常量池中搜索具有完全相同内容的String对象。如果找到一个现有的String对象,那么它的引用就会指向新变量,因此,实际上,现有对象也会被重用于新的字符串声明。这有助于减小因为存在多个具有相同内容的字符串而导致的内存使用量。 String str1 = "value"; String str2 = "value"; String str3 = "value"; 上述程序创建了三个String类型的变量,它们都指向字符串常量池区域中的同一个对象。将来所有具有内容“value”的字符串都会指向堆中的同一对象,从而节省内存。 当我们修改一个字符串时,会在字符串常量池中创建一个新的带有修改内容的字符串。现有的对象永远不会被改变。 str3 = "test"; 当没有引用变量指向字符串常量池中的字符串对象时,该对象将被垃圾回收。通过这种方式,一旦创建了一个字符串,它就永远不会被更改。 3.不可变字符串的优点 现在让我们了解一下上面讨论的不可变性如何在运行时有所帮助。 3.1. 应用程序和数据安全性 首先,毫无疑问最重要的原因是安全性。这不仅适用于我们的应用程序,甚至适用于JDK本身。Java类加载机制是根据传递的类名参数来工作的,然后在类路径中搜索这些类。 在以下程序中,我们通过类名加载SQL服务器驱动程序。想象一下,如果字符串是可变的,那么恶意操作者可以更改驱动程序名称,在运行时加载恶意驱动程序类,并几乎不费力地入侵应用程序。 public static final String DRIVER_CLASS = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; Class.forName(DRIVER_CLASS); 类似地,恶意操作者可以更改SQL语句并在运行时执行SQL注入攻击。不可变性确保不会发生此类修改。 3.2. 提高性能 String类的不可变性是字符串常量池的基础。如果没有不可变性,普通堆内存和字符串常量池之间就没有区别。 正如在前面的部分中讨论的那样,字符串常量池有助于实现更好的内存利用率,从而提高性能。 3.3. 线程安全性 不可变对象在多线程应用程序中自动具备线程安全性。如果某物无法更改,那么即使线程也无法更改它。非常简单! 由于String类在Java编程语言中是主要的构建块,因为它用于类加载机制,因此在多线程情况下,必须防止String类被污染。不可变性在这里起到了魔法作用。 3.4. 缓存 缓存通常是作为键-值对实现的,类似于Java中的Map实现。缓存键通常存储为字符串,以便快速查找。 考虑一下,如果我们可以在与其关联的值存储在缓存中之后更改键,那么在我们意外构建相同键之前,将不可能再检索该值。 字符串的不可变性保证了缓存键永远不会被更改。这就是为什么在Java中字符串是缓存和映射中最常用的键的原因。 结论 从以上讨论可以得出结论,字符串的不可变性有助于实现Java应用程序所需的安全性和性能。 ...

    2023-09-16 217
  • Java 字符串常量池

    文章目录 1.Java中的不可变字符串 2.Java中的String常量池是什么? 3.字符串文字和字符串对象的区别 4.String.intern() API 5.优点 5.1. 增强的安全性 5.2. 线程安全性 6.缺点 6.1. 无法扩展String类 6.2. 长时间内存中的敏感数据 6.3. 可能的OutOfMemoryError 了解Java中的String类,创建它的不可变性背后的动机,以及String常量池的概念。我们将看到当我们通过String文字或String构造函数创建String实例时,内存是如何被操作的。最后,我们将讨论String类的不可变性引起的主要优点和缺点。 1.Java中的不可变字符串 字符串是字符序列。在Java中,与其他编程语言类似,字符串是预定义类型的一部分。Java有java.lang.String类,其实例表示字符串。 String类是一个不可变类。不可变意味着一旦创建了String实例,就无法更改它。 通常,许多敏感信息(用户名、密码、URL、端口、数据库、套接字连接)被表示并传递为字符串。通过使这些信息不可变,代码就能够免受各种安全威胁的影响。 字符串的不可变性还允许缓存字符串文字,这允许应用程序在堆内存和垃圾收集器上产生最小的影响的情况下使用大量的字符串文字。 在可变的上下文中,修改字符串文字可能导致变量损坏。 2.Java中的String常量池是什么? 在Java中,内存被分为三个部分,即堆、栈和字符串池。字符串常量池是用于存储字符串文字的特殊区域。 请注意,在Java 7之前,字符串池是永久代内存区的一部分。 从Java 7开始,字符串与应用程序创建的其他对象一起分配在Java堆区域中。 随后,在Java 8中,永久代已完全删除。 因此,在最新的JVM中,字符串池是堆内存中的一个特殊区域,用于存储字符串文字。 尽管字符串池已从永久代空间移动到堆内存区域,但围绕字符串的创建、文字、对象和内部化的所有概念都没有改变。   3.字符串文字和字符串对象的区别 在Java中,字符串文字是使用双引号创建的字符串,而字符串对象是使用new()运算符创建的字符串。 需要注意的是,字符串文字是在字符串池区域创建的,而字符串对象是在堆内存区域创建的。 String strLiteral = "Hello World"; String strObj = new String("Hello World"); 假设我们想创建两个具有相同内容“panziye.com”的字符串。如果已经存在一个内容为“panziye.com”的字符串,那么新的文字将指向已经存在的文字。而对于字符串对象,每次都会在堆内存中创建一个新的字符串对象。 让我们看一个示例: String a = "panziye.com"; String b = "panziye.com"; System.out.println(a == b); //true 在上面的程序中,我们创建了两个具有相同内容的字符串文字。在字符串池中创建了’a’之后,下一个字符串文字’b’指向了内存中的同一个对象,所以’a == b’是true。这是因为Java中的字符串文字会被重用,以节省内存空间。 String a = "panziye.com"; String b = "panziye.com"; System.out.println(a == b); String c = new String("panziye.com"); System.out.println(a == b); //true System.out.println(b == c); //false 在上面的程序中,我们创建了一个具有类似内容的新字符串对象。当我们检查对象引用是否相等时,我们看到’b’和’c’指向不同的对象。这意味着当我们创建字符串对象’c’时,在内存中创建了一个新的对象。这是因为每次使用new关键字创建字符串对象时,都会在堆内存中分配一个新的对象。这与字符串文字不同,字符串文字在字符串池中被重用。 4.String.intern() API 我们知道字符串文字是在字符串池中创建的,而字符串对象是在堆内存区域中创建的。 我们可以使用String.intern()方法为字符串对象创建字符串文字。当在字符串对象上调用intern()方法时,它会在堆内存中创建一个String对象的精确副本,并将其存储在字符串常量池中。 String a = "panziye"; String b = "panziye"; String c = new String("panziye"); String d = c.intern(); 在上面的例子中,字符串a、b和d将引用SCP中相同的字符串文字。而字符串c将继续指向堆内的对象。 5.优点 5.1. 增强的安全性 正如前面所述,字符串池允许字符串不可变。不可变对象有助于使应用程序更安全,因为它们可能存储敏感信息。 由于我们无法更改不可变对象,这有助于提高安全性。 5.2. 线程安全性 字符串可能是Java应用程序中最常用的对象。想象一下,如果字符串是可变的。在这种情况下,在应用程序中管理线程安全将会成为一场噩梦。 任何不可变对象都具有天生的线程安全性。这意味着多个线程可以共享和操作字符串,而无需担心损坏和不一致性。 6.缺点 6.1. 无法扩展String类 如果我们想扩展String类以添加更多功能,那是不可能的。不可变类被声明为final以防止扩展。 但幸运的是,我们有许多第三方库(如Apache Commons Lang、Spring Framework、Guava),它们为几乎所有种类的用途提供了出色的实用程序类。 6.2. 长时间内存中的敏感数据 字符串中的敏感数据(例如密码)可能会在内存中(在字符串常量池中)驻留更长时间,因为字符串常量池受到垃圾收集器的特殊处理。垃圾收集器不会像访问其他内存区域那样频繁(周期性)访问字符串常量池。 由于这种特殊处理,敏感数据会在字符串常量池中保存很长时间,可能会容易受到不希望的使用。 为了避免这种潜在的缺点,建议将敏感数据(例如密码)存储在char[]中,而不是String中。 6.3. 可能的OutOfMemoryError 字符串常量池与其他内存区域相比是一个小内存区域,可能会很快填满。将太多字符串文字存储在字符串常量池中会导致OutOfMemoryError。 ...

    2023-09-16 160
  • Java String面试题汇总

    文章目录 Java中String是关键字吗? 为什么String是不可变的? 什么是字符串常量池? 什么是String intern()? 如何使用正则表达式查找匹配的字符串? 如何比较两个字符串? Java中的字符串是如何工作的? 如何检查回文字符串? 如何在字符串中删除或替换字符? 如何将字符串转换为小写或大写? 我们可以在’ switch ‘语句中使用String吗? 如何打印一个字符串的所有排列组合? 如何翻转字符串中的每个单词? 如何分割一个字符串? 为什么不应该使用字符串来存储密码? 字符串是线程安全的吗? 为什么String是HashMap键的最佳选择? String、StringBuffer和StringBuilder之间有什么区别? 如何连接多个字符串? 统计给定程序中的字符串对象数量 统计字符串中每个字符的出现次数? 在不使用 StringBuilder 或 StringBuffer 的情况下反转字符串? 总结 给定的Java String面试问题涵盖了字符串方法、字符串不可变性和内存泄漏问题,以及简单的示例和用例。我将尽力涵盖Java面试中最常问的String类相关问题。 Java中String是关键字吗? 不是的。String不是Java中的保留关键字。它是一种派生数据类型,也就是一个类。 public class StringExample { public static void main(String[] args) { Integer String = 10; System.out.println(String); //输出 10 } } 为什么String是不可变的? 第一个原因是性能改进。Java语言的开发旨在加快应用程序的开发速度,因为在之前的语言中它的速度不是那么快。JVM的设计者必须足够聪明,能够识别到实际应用程序将主要由字符串组成,这些字符串是标签、消息、配置、输出和其他形式的数据。看到这种过度使用,他们想象了字符串的不当使用可能有多危险。因此,他们提出了字符串池的概念。字符串池实际上是一组大部分是唯一的字符串。字符串池背后的基本思想是一旦创建了字符串,就可以重用它。这样,如果在代码中创建了一个特定的字符串20次,应用程序只有一个实例。 我认为第二个原因是安全性考虑。字符串是Java编程的各个方面中最常用的参数类型。无论是加载驱动程序还是打开URL连接,都需要将信息作为字符串参数传递。如果字符串不是不可变的,就会引发一系列安全性问题。 什么是字符串常量池? 字符串常量池是常规堆内存中的一块特定内存区域,用于存储这些字符串常量。在应用程序的生命周期中,字符串变量引用这些常量。 在Java中,我们可以通过多种方式创建字符串。例如,使用字符串字面值和使用new关键字。 String str1 = "abc"; String str2 = new String("abc"); 使用字符串字面值会导致JVM验证是否已经存在一个与字符串”abc”(相同的字符序列)。如果存在这样的字符串,JVM会将现有对象的引用赋给变量str;否则,将创建一个新的对象”abc”,并将其引用赋给变量str1。 当使用new关键字时,Java会在正常的堆内存中创建一个新的String对象。我们必须使用intern方法将字符串从堆内存移到字符串池中。 为了更好地利用内存并提高性能,建议使用字符串字面值来创建字符串。除非需要显式复制原始字符串,否则不需要使用构造函数,因为字符串是不可变的。 什么是String intern()? 当调用String的intern()方法时,如果字符串池已经包含与此字符串相同内容的字符串(由equals()方法确定),则返回池中的引用。否则,将此String对象添加到池中,并返回池中此新String对象的引用。 简单来说,字符串池化是将一个String对象从常规堆内存移动到字符串常量池中,并使用池中的对象引用的过程。 String str = new String("abc"); str.intern(); 对于intern()方法,对于任何两个字符串s1和s2,只有当s1.equals(s2)为true时,s1.intern() == s2.intern()才为true。 这意味着如果s1和s2是不同的字符串对象,并且具有相同的字符序列,那么在两者上调用intern()将导致由两个变量引用的单个字符串池字面值。 默认情况下,请记住所有字面字符串和具有字符串值的常量表达式都会被池化。 如何使用正则表达式查找匹配的字符串? 我们可以使用Pattern和Matcher API进行正则表达式匹配。String类提供了自己的matches()方法。我们应该直接使用matches()方法。该方法在函数定义内部也使用Pattern.matches()。 String str = new String("Welcome to panziye.com"); System.out.println(str.matches("(.*)ziye(.*)")); //Prints true System.out.println(Str.matches("(.*)www(.*)")); //Print false 如何比较两个字符串? 面试中的另一个受欢迎的领域。通常有两种比较对象的方法: 使用==运算符 使用equals()方法 ==运算符用于比较对象引用。因此,如果两个字符串对象引用字符串池中的相同字面值或堆中的相同字符串对象,则’s == t’将返回true,否则返回false。 equals()方法在String类中被重写,并验证String对象所持有的字符序列。换句话说,equals()方法比较字符串对象的值。如果它们存储相同的字符序列,’s.equals(t)’将返回true,否则返回false。 Java中的字符串是如何工作的? 与其他编程语言一样,Java中的字符串是字符序列。这更像是一个用于处理该字符序列的实用类。这个字符序列以char数组类型的以下变量维护: /** 值使用char 数组存储 */ private final char value[]; 各种字符串方法在不同的情况下使用以下变量来维护数组中的位置: /** 偏移量(offset)是存储中首个被使用的索引。*/ private final int offset; /** 计数(count)是字符串中字符的数量。 */ private final int count; 如何检查回文字符串? 如果一个字符串的值在反转后仍然相同,那么它就是回文字符串。要检查回文字符串,可以将字符串反转,然后将其与原始字符串进行比较。 如果原始字符串和反转后的字符串相同,那么给定的字符串就是回文字符串。 String originalString = "abcdcba"; StringBuilder strBuilder = new StringBuilder(originalString); String reverseString = strBuilder.reverse().toString(); boolean isPalindrame = originalString.equals(reverseString); System.out.println(isPalindrame); //true 如何在字符串中删除或替换字符? 要替换或删除字符,可以使用String.replace()或String.replaceAll()方法。 这两种方法都接受两个参数。第一个参数是要替换的字符,第二个参数是要放入字符串中的新字符。 如果想删除字符,可以在第二个参数中传递空字符。 String originalString = "howtodoinjava"; //Replace one character System.out.println( originalString.replace("h", "H") ); //Howtodoinjava //Replace all matching characters System.out.println( originalString.replaceAll("o", "O") ); //hOwtOdOinjava //Remove one character System.out.println( originalString.replace("h", "") ); //owtodoinjava //Remove all matching characters System.out.println( originalString.replace("o", "") ); //hwtdinjava 如何将字符串转换为小写或大写? 要将字符串转换为小写或大写,可以使用String.toLowerCase()和String.toUpperCase()方法。 String blogName = "PanZiYe.com"; System.out.println(blogName.toLowerCase()); //panziye.com System.out.println(blogName.toUpperCase()); //PANZIYE.COM 我们可以在’ switch ‘语句中使用String吗? 可以,自Java 7以来,我们可以在switch语句中使用String类。在Java 7之前,这是不可以的,我们必须使用if-else语句来实现类似的功能。 如何打印一个字符串的所有排列组合? 排列是将字符元素重新排列,以使每个排列在其他排列方面都是唯一的。例如,下面是字符串“ABC”的排列 – ABC、ACB、BAC、BCA、CBA 和 CAB。 长度为N的字符串有N!(N阶乘)个排列。 import java.util.HashSet; import java.util.Set; public class StringExample { public static void main(String[] args) { System.out.println(getPermutations("ABC")); //Prints //[ACB, BCA, ABC, CBA, BAC, CAB] } public static Set<String> getPermutations(String string) { //All permutations Set<String> permutationsSet = new HashSet<String>(); // invalid strings if (string == null || string.length() == 0) { permutationsSet.add(""); } else { //First character in String char initial = string.charAt(0); //Full string without first character String rem = string.substring(1); //Recursive call Set<String> wordSet = getPermutations(rem); for (String word : wordSet) { for (int i = 0; i <= word.length(); i++) { permutationsSet.add(charInsertAt(word, initial, i)); } } } return permutationsSet; } public static String charInsertAt(String str, char c, int position) { String begin = str.substring(0, position); String end = str.substring(position); return begin + c + end; } } 如何翻转字符串中的每个单词? 要分别翻转每个单词,首先要对字符串进行分词,将所有单词分隔成一个数组。然后,对每个单词应用翻转单词的逻辑,最后将所有单词连接起来。具体代码可以参考:反转字符串中的单词 如何分割一个字符串? 使用String.split()方法,该方法会根据给定的正则表达式来分割字符串。它也被称为根据分隔符获取字符串标记。 split()方法返回一个字符串数组,数组中的每个字符串都是一个独立的标记。 为什么不应该使用字符串来存储密码? 我们知道在Java中,字符串存储在常量池中。一旦一个字符串被创建在字符串池中,它会一直在池中存在,除非被垃圾回收。在这段时间内,任何恶意程序都可以访问物理内存中的内存区域并访问字符串数据。 如果我们将密码存储为一个字符串,它将在内存中保留的时间比所需的时间长,因为垃圾收集周期是不可预测的。这会使敏感的密码字符串容易受到黑客攻击和数据盗窃的威胁。 有人可能会提出一个观点,即在使用后将字符串设置为空。但是,这是不可行的,因为我们知道一旦一个字符串被创建,就无法操纵它,例如无法更改它的内容。字符串是不可变的。 但是,字符数组是可变的,我们可以在使用后覆盖它们的内容。因此,我们的应用程序应该使用char[]来存储密码文本,并在使用密码后替换数组内容为空白。 总之,使用char[]而不是字符串来存储密码是更安全的做法,因为它可以在使用后覆盖密码,减少了敏感信息被恶意访问的风险。这是更好的密码安全实践。 String password = "123456"; //不能使用字符串 char[] passwordChars = new char[4]; //从数据库等系统中获取密码。 //使用密码 for(char c : passwordChars) { c = ' '; } 字符串是线程安全的吗? 是的,字符串是线程安全的,因为它们是不可变的。 请记住,所有不可变的实例都是线程安全的,这是它们的设计特点。 为什么String是HashMap键的最佳选择? 在Java中,Map的键必须是不可变的,并且应该遵守equals()和hashCode()方法之间的约定。String类满足这两个条件。 此外,String类提供了许多有用的方法,用于比较、排序、分词或大小写转换。在对Map执行CRUD操作时,可以使用这些方法。 所有这些特点使得String类非常适合用作Map中的键,而不是创建我们自己的类。 String、StringBuffer和StringBuilder之间有什么区别? String类表示字符序列,并提供了处理字符的有用方法。String类的实例是不可变的。因此,每次我们使用String类进行字符串连接时,都会创建一个新对象,其中包含连接后的字符串。 StringBuilder类用于以更节省内存的方式执行字符串连接操作。它在内部维护char[],只在这个数组中操作内容。当我们在执行所有操作后需要获取完整的连接字符串时,它会使用存储的字符数组创建一个新的String。 StringBuffer与StringBuilder类非常相似,唯一的区别是它是线程安全的,它的所有方法都是同步的。 如何连接多个字符串? 根据是否需要线程安全,使用StringBuffer或StringBuilder类。在这两个类中,使用append()方法来连接字符串。 统计给定程序中的字符串对象数量 String s1 = "panziye.com"; String s2 = "panziye.com"; String s3 = new String("panziye.com"); 上面的代码将创建2个对象。 第一条语句将在字符串池中创建第一个字符串字面量。 第二条语句不会创建任何新对象,s2将引用与s1相同的字符串常量。 第三条语句将在堆内存中创建一个新的字符串对象。 统计字符串中每个字符的出现次数? 要找出给定字符串中每个字符的出现次数,我们使用了HashMap,其中字符作为键,其出现次数作为值。 每次字符出现新的次数时,我们将增加该字符的计数值。代码实现可以参考《Java中查找字符串中的重复字符》 在不使用 StringBuilder 或 StringBuffer 的情况下反转字符串? 反转字符串的最佳方法是使用 StringBuffer.reverse() 和 StringBuilder.reverse() 方法。尽管如此,面试官可能会要求您编写自己的程序,以检查您的技能水平。 请使用下面给出的基于递归的示例来反转字符串。 该程序从字符串中取出第一个字符,并将其放置在字符串的最后位置。它使用这种替换方式来反转字符串中的所有字符,直到整个字符串被反转。 具体代码实现可以参考:《基于递归的示例来反转字符串》 总结 以上就是我认为面试时经常被问到的关于String类问题,希望对你的面试有帮助。如果你知道更多关于Java String面试题问题,可以留言。 ...

    2023-09-16 150
  • 如何使用hBlock提升你的网络和隐私安全

    关于hBlock hBlock是一款针对用户网络安全和隐私安全的保护工具,该工具可以通过屏蔽广告、屏蔽应用程序跟踪和恶意软件域名来保护你的信息安全。 hBlock是一个符合POSIX的Shell脚本,它可以从多个来源获取提供广告、跟踪脚本和恶意软件的域名列表,并创建一个hosts文件和其他格式,以防止你的系统跟它们建立连接。 需要注意的是,hBlock在默认情况下会替换系统的hosts文件,如果有要保留的条目,请考虑先进行备份。 支持的源 数据源 主地址 镜像 adaway.org URL URL AdBlock NoCoin List URL URL AdGuard - Simplified URL URL disconnect.me - Ad URL URL disconnect.me - Malvertising URL URL disconnect.me - Malware URL URL disconnect.me - Tracking URL URL ETH PhishingDetect URL URL FadeMind - add.2o7Net URL URL FadeMind - add.Dead URL URL FadeMind - add.Risk URL URL FadeMind - add.Spam URL URL KADhosts URL URL malwaredomainlist.com URL URL malwaredomains.com - Immortal domains URL URL malwaredomains.com - Just domains URL URL matomo.org - Spammers URL URL mitchellkrogza - Badd-Boyz-Hosts URL URL pgl.yoyo.org URL URL ransomwaretracker.abuse.ch URL URL someonewhocares.org URL URL spam404.com URL URL StevenBlack URL URL winhelp2002.mvps.org URL URL ZeroDot1 - CoinBlockerLists URL URL zeustracker.abuse.ch URL URL   工具安装 hBlock支持在各种软件包管理器中安装和使用,具体请查看【最新列表】。除此之外,广大研究人员也可以通过执行下列命令将该项目最新版本的代码克隆至本地: git clone https://github.com/hectorm/hblock.git 如果你想手动执行工具安装的话,也可以执行下列命令: curl -o /tmp/hblock 'https://raw.githubusercontent.com/hectorm/hblock/v3.4.2/hblock' \   && echo 'a7d748b69db9f94932333a5b5f0c986dd60a39fdf4fe675ad58364fea59c74b4  /tmp/hblock' | shasum -c \     && sudo mv /tmp/hblock /usr/local/bin/hblock \     && sudo chown 0:0 /usr/local/bin/hblock \     && sudo chmod 755 /usr/local/bin/hblock 我们也可以直接使用NPX在不需要安装的情况下运行hBlock: npx hblock 工具使用 脚本参数 工具支持使用各种选项参数来控制工具的任务执行: Usage: hblock [options...]      -O, --output FILE            Hosts 文件路径(默认:/etc/hosts)    -R, --redirection IP           屏蔽了列表中所有条目的目的IP地址                                (默认:0.0.0.0)    -H, --header HEADER          Hosts文件头部需要引入的内容,你可以使用其他命令的输出作为该参数的数据,例如"$(cat header.txt)"    -S, --sources URLS           用于生成屏蔽列表的数据源,每个URL用空格分隔    -W, --whitelist ENTRIES       需要从屏蔽列表中移除的条目    -B, --blacklist ENTRIES        需要添加到屏蔽列表中的条目,每个域名用空格分隔    -b, --backup [DIRECTORY]     设置时间戳备份 (默认:输出文件目录)    -l, --lenient                   针对数据源进行IP地址匹配                                (默认: 0.0.0.0, 127.0.0.1 或none)    -i, --ignore-download-error   发生下载错误时继续执行任务    -c, --color auto|true|false     颜色高亮输出(默认:auto)    -q, --quiet                   禁用非错误消息    -v, --version                 显示工具版本信息和退出    -h, --help                   显示工具帮助信息和退出 保留内容 该脚本会替换掉你系统中的hosts文件,如果你想要恢复其中的部分内容,可以直接使用下列数据结构对要恢复的内容进行“封装”: # <custom>     ...   </custom> 临时禁用hBlock 有的时候你可能需要临时禁用hBlock,最简单的方式就是快速生成一个不包含任何屏蔽域名的hosts文件,命令如下: hblock -S none -D none 工具使用演示 演示视频:【点我观看】 许可证协议 本项目的开发与发布遵循MIT开源许可证协议。 项目地址 hBlock:【GitHub传送门】 参考资料 https://en.wikipedia.org/wiki/Hosts_(file) https://hblock.molinero.dev/ https://github.com/hectorm/hmirror ...

    2023-09-08 196
  • 绕过检测将恶意Word文件嵌入到PDF文件中

    日本的计算机应急响应团队JPCERT分享了其检测到的一种新的攻击技术。2023年7月,JPCERT观察到该攻击技术并将之命名为“MalDoc in PDF”,该技术通过将恶意Word文件嵌入到PDF文件中来绕过检测。         JPCERT采样的恶意文件是一个多语言文件,多语言文件指包含多种不同文件格式的文件,可以根据打开它们的应用程序解释和执行多种文件类型。在本例中,大多数扫描引擎和工具会将其识别为PDF,但办公应用程序可以将其作为常规的Word文档(.doc)打开。           多语言文件在一种格式中可能看似无害,而在另一种格式中则可能隐藏了恶意代码,因此黑客通常使用这类文件来逃避检测或混淆分析工具。在这种情况下,该PDF文档包含一个带有VBS宏的Word文档,如果在Microsoft Office中将之作为.doc文件打开,则会下载并安装一个MSI恶意软件文件。         “MalDoc in PDF”作为攻击手段的主要优势是能够逃避传统PDF分析工具(如“pdfid”)或其他只检查文件外层(即合法的PDF结构)的自动化分析工具的检测。但另外一些分析工具(如“OLEVBA”)仍然可以检测到多语言文件中隐藏的恶意内容。JPCERT指出,多层次的防御和丰富的检测集能够有效对抗这种威胁。           JPCERT提醒道,虽说本文描述的技术无法绕过禁用Word宏自动执行的设置,但由于这些文件被识别为PDF文件,现有的沙箱或杀毒软件可能无法检测到它。所以假如正在使用一些沙箱、工具等进行自动化恶意软件分析,需要特别注意这一点。   </p> 原文出自:https://zhuanlan.kanxue.com/article-24259.htm 发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担! 如侵权请私聊我们删文...

    2023-09-03 338
  • 断剑重铸?Kaiji僵尸网络正在重新构建

    概述 近日深信服威胁情报研究团队捕获到Kaiji僵尸网络的最新变种。该病毒最早在2020年出现,使用多种危害较高的漏洞发起攻击,试图感染服务器和物联网设备,能够发起分布式拒绝服务(DDoS)攻击。与其他IoT僵尸网络不同的是,Kaiji并没有从其他(开源或黑市论坛获取)成熟的恶意软件家族中直接套用攻击代码。 Kaiji僵尸网络病毒在最新的版本中发生了非常大的改动,采用最新的Golang1.18版本进行病毒程序编写(老版本采用Golang1.15版本),大大增加了安全人员分析和调试该病毒的难度,同时也进一步证实了越来越多的病毒开发者使用Golang语言的趋势。 Kaiji僵尸网络相对老版本代码被重构,函数功能更加聚焦,函数名不再采用中式拼音命名。最新的版本驻留功能非常强大,增加了多种持久化手段,但是传播模块相对较弱,这里猜测一下,作者正在逐渐更新功能模块,该病毒很可能会随着时间的推移进一步变得更加复杂,未来Kaiji或许会成为一款强大的僵尸网络。 Kaiji僵尸网络的整体攻击流程如下   情报分析 捕获的Kaiji僵尸网络主要使用多种高危RCE漏洞(GitLab未授权访问漏洞(CVE-2021-22205)和Atlassian Confluence OGNL注入漏洞(CVE-2021-26084))利用作为初始攻击。一旦病毒入侵了服务器或物联网设备,Kaiji僵尸网络就可以在其团伙的指挥下发动DDoS攻击。 当前版本的Kaiji持久化模块非常强大,使用超过8种驻留手段进行持久化。Kaiji僵尸网络还会窃取本地SSH密钥,并进一步发起SSH爆破攻击以感染互联网上其他暴露的设备。 Kaiji运行后,若检测自身文件名为dir、find、ls、lsof、netstat、ps、ss之一,则会伪装执行相应命令,复制自身到/tmp/seeintlog后运行。随后会将自身复制到/etc/id.services.conf: 生成shell脚本/etc/32678(传播模块为32679),定时执行/etc/id.services.conf: /etc/id.services.conf运行后,会创建协程,执行main_Link、main_Watchdog、main_Initetc、main_addtime、main_Killcpu。 通信模块[main_Link函数] 通信模块执行时,与C2服务器103.138.80.90:1111、dark1998.f3322.org:8080、156.96.156.105:8080进行通信,发送上线信息后,由main_receive函数等待接收并执行ipbegin、ipend、finish、unload、shell、reverse、remarks、http、ipspoof、tcp、udp、syn、tap等命令,包含执行shell命令、卸载自身、发动DDoS攻击等功能。 传播模块[main_Sshboom函数] 在老版本的Kaiji僵尸网络会窃取本地SSH密钥,进一步发起SSH爆破攻击,爆破成功后会下载执行相应CPU架构的驻留模块,例如:103.138.80.90:808/808/linux_amd64、linux_arm64、linux_mips。最新版本的Kaiji僵尸网络缺少传播模块功能,这里猜测作者正在逐一优化功能模块。 持久化模块[main_Initetc函数] 通过修改/etc/rc.local、/etc/rc.d/rc.local、/etc/init.d/boot.local文件实现自启动 利用chkconfig工具添加linux_kill服务,实现自启动 注册linux.service 安装SELinux策略模块 修改/etc/profile.d/bash_config.sh复制自身到/usr/lib/libdlrpcld.so添加定时任务,每隔一分钟执行/.img 替换dir、find、ls、lsof、netstat、ps、ss七个工具 尝试将自身进程名伪装为ksoftirqd/0   小结 Kaiji僵尸网络作者采用最新的Golang1.18版本重构,大幅更新持久化模块,整体复杂度也相比老版本明显增加。可以发现Kaiji正处于前中期发展的僵尸网络,未来作者可能在攻击模块和横向传播模块上进行更新迭代,从而导致Kaiji进一步变得复杂。 此外,鉴于Golang语言的跨平台等特点,近年来将其作为编程语言编码的恶意软件数量急剧增加,Kaiji僵尸网络也进一步证实了使用Golang语言开发恶意软件已成为一种趋势。 参考链接 https://www.intezer.com/blog/research/kaiji-new-chinese-linux-malware-turning-to-golang/ ...

    2023-09-03 303
  • 网站快速提升百度权重的4个方法

    在互联网上,网站的权重和排名很大程度上决定了它的曝光率和流量。如果你是一个新手站长,或者你的网站权重不高,那么接下来的这篇文章将会为你提供一些实用的技巧,帮助你在三个月内提升网站权重到5。 1. 优化关键词 首先,你需要找到一些与你网站内容相关的高搜索量、低竞争的关键词。你可以使用一些关键词研究工具,如Google关键词规划师,来帮助你找到这些关键词。然后,你需要在你的网站上合理地布局这些关键词,包括在标题、描述、URL和内容中。但是,一定要注意避免过度优化,否则可能会被搜索引擎视为作弊。 2. 提高网站质量 除了关键词之外,网站的质量也是影响权重的一个重要因素。这包括网站的加载速度、用户体验、移动友好性等。你可以通过使用CDN、优化图片大小、减少HTTP请求等方式来提高网站的加载速度。同时,你也需要确保你的网站易于导航,无论用户使用的是电脑还是手机。 3. 建立高质量的外部链接 外链是另一个影响网站权重的重要因素。你可以通过写高质量的原创内容来吸引其他网站的链接。同时,你也可以参与一些行业论坛或社交媒体平台,分享你的知识和观点,从而吸引更多的外链。但是,记住不要过度追求外链的数量,质量才是最重要的。 4. 持续更新和优化 最后,持续更新和优化你的网站是非常重要的。你需要定期发布新的内容,以保持用户的访问量和搜索引擎的索引。同时,你也需要根据用户的反馈和搜索引擎的算法变化,不断调整和优化你的网站。...

    2023-09-02 329
  • Linux系统如何创建用户并为其设置密码

    根据下列要求创建用户及组账号: 1、名为admins的组 2、用户harry,其附属组为admins 3、用户natasha,其附属组还属于admins 4、用户alice,没有可交互的登录Shell,且不属于admins组 5、harry、natasha、alice的密码都应该是redhat [root@bunian ~]# groupadd admins #创建admins组 [root@bunian ~]# useradd -G admins harry #创建用户harry并设置其附属组为admins [root@bunian ~]# useradd -G admins natasha #创建用户natasha并设置其附属组为admins [root@bunian ~]# useradd -s /sbin/nologin alice #创建用户alice,设置不可交互的登录shell,不为其指定admins组 要求5的命令如下 [root@bunian ~]# echo redhat |passwd --stdin harry #为harry设置密码为redhat Changing password for user harry. passwd: all authentication tokens updated successfully. [root@bunian ~]# echo redhat |passwd --stdin natasha #为natasha设置密码为redhat Changing password for user natasha. passwd: all authentication tokens updated successfully. [root@bunian ~]# echo redhat |passwd --stdin alice #为alice设置密码为redhat Changing password for user alice. passwd: all authentication tokens updated successfully. </div> ...

    2023-09-02 293
  • 在Linux中如何将cURL输出保存到文件?

    当你需要将cURL的输出保存到文件时,Linux提供了几种不同的方法。 cURL是一个功能强大的命令行工具,用于在网络上传输数据,通常用于HTTP请求。 在本文中,我们将探讨如何使用cURL将其输出保存到文件,以及一些附加的选项和技巧。 安装cURL 在介绍如何使用cURL将输出保存到文件之前,确保已安装cURL是非常关键的。下面是如何安装cURL的指南,具体取决于您所使用的Linux发行版: Ubuntu/Debian sudo apt install curl Fedora/RHEL sudo dnf install curl Arch Linux sudo pacman -S curl 使用重定向操作符 最简单的方法是使用重定向操作符>或>>来将cURL的输出保存到文件中。>将覆盖文件内容,而>>将追加到文件末尾。 curl -o output.txt URL 这将下载URL的内容并将其保存到名为output.txt的文件中。如果output.txt不存在,它将被创建;如果已经存在,它将被覆盖。 curl -o output.txt URL 这将下载URL的内容并将其追加到名为output.txt的文件末尾。 例如,我们将访问百度的域名: curl -o output.txt https://www.baidu.com 使用-c选项保存Cookie 有时,你可能需要保存cURL请求的Cookie信息。你可以使用-c选项将Cookie保存到一个文件中,然后使用-b选项加载Cookie信息。 curl -c cookies.txt URL 这将保存从URL获取的Cookie信息到名为cookies.txt的文件中。然后,你可以使用-b选项来加载Cookie信息: curl -b cookies.txt URL 例如,我们将访问百度的域名: curl -b cookies.txt https://www.baidu.com 保存HTTP头信息 如果你想保存HTTP响应头信息,可以使用-i选项将它们保存到文件中: curl -i -o output.txt URL 这将把HTTP响应头信息保存到output.txt中。 例如,我们将访问百度的域名: curl -i -o output.txt https://www.baidu.com 同时保存输出和错误信息 有时,你可能希望将cURL的输出和错误信息保存到不同的文件中。你可以使用2>操作符来将错误信息重定向到一个文件: curl -o output.txt URL 2> error.txt 这将下载URL的内容并将正常输出保存到output.txt,将错误信息保存到error.txt。 保存到特定目录 如果你想将文件保存到特定目录,可以在文件名中包含目录路径: curl -o /path/to/directory/output.txt URL 这将下载URL的内容并将其保存到/path/to/directory/目录下的output.txt文件中。 例如,我们将访问百度的域名,并将结果保存至/tmp/test/baidu/output.txt: curl -o /tmp/test/baidu/output.txt https://www.baidu.com 注意:在保存至特定目录,一定要先保证该目录存在! 使用-w选项自定义输出格式 使用-w选项,你可以自定义cURL的输出格式。例如,你可以只保存响应的HTTP状态码: curl -o output.txt -w "%{http_code}" URL 这将下载URL的内容并将HTTP状态码保存到output.txt中。 例如,我们将访问百度的域名: curl -o output.txt -w "%{http_code}" https://www.baidu.com 使用 cURL 命令保存多个文件 -o选项可以用于为每个链接指定一个输出文件名,这对于批量下载文件非常方便。 以下是示例用法: curl https://link-1.com https://link-2.com https://link-3.com -o File1 -o File2 -o File3 在这个示例中,cURL会从三个不同的链接下载文件,并将它们分别保存为File1、File2和File3。 这对于下载多个文件非常有用,特别是在需要自动化下载任务时。 例如: curl https://www.baidu.com https://www.baidu.com https://www.baidu.com -o File1 -o File2 -o File3 总结 这些是在Linux中使用cURL将输出保存到文件的一些常见方法和技巧。 你可以根据你的需求选择最合适的方法,希望这篇文章对你有所帮助! 如果你有任何问题或需要更多信息,请随时提问。 ...

    2023-09-02 294
  • 记一次从xss到任意文件读取

    0x00 前言 xss一直是一种非常常见且具有威胁性的攻击方式。然而,除了可能导致用户受到恶意脚本的攻击外,xss在特定条件下还会造成ssrf和文件读取。 本文主要讲述在一次漏洞挖掘过程中从xss到文件读取的过程,以及其造成的成因。   0x01 漏洞详细 1. XSS 漏洞所在的是一个可以在线编辑简历并导出的一个网站。 首先注册账号后进去,任意选一个模板在线编辑,在编辑简历时插入payload测试 发现被转义了,我们手动修改回去 刷新简历可以看到成功弹窗,证明存在存储型xss 然后使用<h1>标签测试,可以发现h1标签也会被解析 然后我们发现,网站有一个功能可以把简历转成pdf并下载,而在线编辑的是html格式,而且这一转换过程是在后端完成,并且导出的pdf中标签依然是被解析的,如下图所示,导出的pdf中上方的字体也明显变大,说明h1标签被解析 2. SSRF 通过过滤网络请求我们发现这样一个数据包,它将html及里面包含的js代码会发送给后端,后端可能通过渲染html代码从而生成pdf供用户下载   </p> 那后端是如何将html渲染成pdf,执行html中的js呢?   一般可以通过获取后端解析的组件及版本来获取更多信息,从下载的pdf中,可以文件的头部信息可以获取创建者或者pdf文件信息   </p> 可以发现后端使用的wkhtmltopdf组件   wkhtmltopdf官方文档: https://wkhtmltopdf.org/index.html 在他的使用文档中发现其使用 Qt WebKit 浏览器引擎将html渲染成pdf,既然是通过浏览器渲染的,那html中的所有标签也会被浏览器所执行。   所以我们使用 iframe 标签尝试读取内网资源   <iframe src="http://127.0.0.1" width="500" height="100">   </p> 可以看到虽然是403,但是确实是能读取成功的。   </p>   3. 任意文件读取 我们尝试是否能通过请求file协议读取文件   javascript 将在服务器端执行,让我们尝试通过注入以下 javascript 从文件系统中获取文件,然后构造payload进行文件的读取:                 <script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open('GET','file:///etc/passwd');x.send();</script> 通过XMLHttpRequest发起请求,使用file协议读取本地文件,然后document.write将请求的结果覆盖原来html的内容。   </p> 访问pdf,成功读取到文件   </p> 0x03 漏洞成因及修复 所里这里有一个疑问,为什么js会导致本地任意文件读取,如果真是这样的话那我们每个用户在浏览有js的网页时都会造成本地信息泄露?   </p> 其实我们在使用浏览器访问网页并加载js时,浏览器有一套安全机制,使用XMLHttpRequest对象读取本地文件在Web浏览器中是受限的,因为出于安全考虑,浏览器限制了通过XMLHttpRequest对象直接访问本地文件系统。   </p> 如上图所致直接在浏览器执行这段payload会被提示 Not allowed to load local resource   </p>   </p> 前面我们提到后端将html转换为pdf的组件是 wkhtmltopdf,他使用无头运行的Qt WebKit浏览器引擎,但是浏览器默认参数是使用 --enable-local-file-access,即允许访问本地文件,这就是导致可以使用 file 协议进行任意文件的问题。       --disable-local-file-access 不允许一个本地文件加载其他的本地文件,使用命令行参数 --allow 指定的目录除外。--enable-local-file-access 与--disable-local-file-access相反(这是默认设置)--allow 允许加载指定文件夹中的一个或多个文件 同时wkhtmltopdf官方文档中也说明了不要将 wkhtmltopdf 与任何不受信任的 HTML 一起使用   </p> 即使使用了 --disable-local-file-access,攻击者也可以利用预构建二进制文件中的 CVE 的攻击者可能能够绕过此设置。     文章来源:奇安信攻防社区(Duck)原文地址:https://forum.butian.net/share/2409...

    2023-09-01 186

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:8:00-23:00,节假日休息

扫码关注