WWW.YOUINFO.SITE
标签聚合 pwn

/tag/pwn

LinuxDo 最新话题 · 2026-06-10 12:26:38+08:00 · tech

本人之前从事二进制方向,PWN和逆向的研究,从一个月前开始SRC的研究。正好赶上了这波AI挖掘SRC的浪潮,各路培训机构层出不穷,本人也在可以算是第一家有成熟套路的机构报了名,上了几天课,但是一直有几个无法解决的问题,在此分享一些目前的一些收获和测试情况(后面我会附上我想到的问题,有些问题没有实践只是猜想)以及向各位佬友交流一下有没有更好的解决方案。 各类堆skill大法 在这个方法下又诞生了几种方法论: 把SRC报告喂给ai,让ai总结成skill 问题:src报告通常都是复现过程,缺少了漏洞发现的过程,以及一些排查思路。 让ai打靶场,总结成skill 问题:实测dp无法很好地写这个skill,打到有价值的地方也不进行总结,gpt5.5稍微好一点,但是效果也不尽人意 蒸馏各类网安skill 问题:显而易见,听说这种skill很难出货,因为信息杂乱,通常是由ai总结,依然脱离实战 另外,实测发现随着上下文变长,AI会慢慢不听skill的话 记忆系统 这种方法我觉得不仅适用于网安,也适用其他领域。 就是将上下文、技巧、经验不仅存储在skill里,也存储在数据库中 问题:ai不知道什么时候把当前的重复错误行为和有价值的经验存入数据库,也不知道什么时候从数据库中提取什么经验。且选型我目前很纠结,这个东西类似本地知识库,但是用RAG又很臃肿,用jsonl又过于轻量且只能用关键词一比一搜索,不能模糊搜索,那还有什么意义呢,比如xss一搜,可能出来很多很多,即便解决了这个问题,也面临ai不会用的问题。 我想到的解决办法: 针对记忆系统,使用传统skill的方式去写,但是由人工审核干预,还是很累做不到自动化,比如看到AI重复犯错,就触发写记忆skill,写到对应领域的技巧的skill里 轻量skill,skill只做角色定位+写记忆skill+记忆 实测还是有问题 ,不约束流程,ai会漏掉很多接口,功能点,还是不听skill的话,上下文问题还是无法解决。以下是测试情况,测试目标是我徒弟测试过的一个edu站点。 第一版重流程skill(从国外大佬提取+打靶场强制他优化)无记忆系统: deepseek v4 pro可以挖到edu站点中手挖几小时出来的同样的身份证信息泄露,又多挖出来四个csrf 第二版加记忆系统,轻skill: dp直接蒙圈,困在主站页面,浪费大量token后没有任何发现(开始不用mcp工具一直用curl) gpt5.5竟然更严重,从头到尾不调用mcp工具 第三版最轻量skill: gpt5.5同样的问题,并且会胆子很小,各种功能点全部避开,甚至js都不看 目前也是徘徊,我觉得记忆系统有必要,但是不知道怎样落地,ai挖洞的意义难道不是覆盖手工无法覆盖的地方,提高手工的效率吗,如果他学不会手工的技巧,漏掉功能点,哪还有什么意义呢,初入此站,望各位佬友能一起交流,寻找灵感。 5 个帖子 - 2 位参与者 阅读完整话题

v2ex · 2026-05-19 05:14:03+08:00 · tech

https://haveibeenpwned.com/Breach/Addi 今年 3 月,哥伦比亚金融科技公司 Addi 在其平台上发现了未经授权的活动,并告知客户“您的个人信息可能已被泄露”。“不付钱就泄密”敲诈勒索组织 ShinyHunters 随后声称对此负责,并公布了大量据称从阿迪获得的个人数据。数据包括信用评分请求、信用局记录、客户身份记录和电子邮件验证日志的 3400 万个唯一电子邮件地址,还包含政府颁发的身份证件、估计收入、经济水平、支付情况和其他与信贷相关的数据。 泄露情况概述:影响数量:3450 万,发生时间:2026 年 3 月,添加到 HIBP 的日期:2026 年 5 月 18 日 泄露的数据:年龄组/信用评分/设备信息/电子邮件地址/政府颁发的身份证件/收入水平/IP 地址/纬度和经度/姓名/电话号码/地址/支付情况/经济水平

IT之家 · 2026-05-16 09:47:12+08:00 · tech

IT之家 5 月 16 日消息,科技媒体 bleepingcomputer 昨日(5 月 15 日)发布博文,报道称在 Pwn2Own Berlin 2026 活动第 2 天,Windows 11 系统再次被攻破。 在 2026 年柏林 Pwn2Own 开赛首日,来自全球各地的安全研究员挖掘报告 24 个零日漏洞,成功拿到 523000 美元(现汇率约合 355.7 万元人民币)奖金。 在开赛第二日,参赛研究员共拿下 15 个零日漏洞,累计获得 385750 美元奖金,涉及 Windows 11、微软 Exchange、Red Hat Enterprise Linux for Workstations 和多款 AI 编码工具。 在第二日最受关注的案例,来自 DEVCORE Research Team 的 Cheng-Da Tsai,他串联 3 个漏洞,成功攻破微软 Exchange,拿到远程代码执行能力,并直接提升到 SYSTEM 权限。 他凭借这项漏洞攻击链,获得 20 万美元奖金,也是第 2 天金额最高的单项奖励。 Windows 11 依然是本届活动的重点攻击目标,在首日被攻破 3 次后,在第 2 天也再次失守,Siyeon Wi 利用整数溢出漏洞成功攻破系统,获得 7500 美元奖金。 Team DDOS 的 Ben Koo 在 Red Hat Enterprise Linux for Workstations 上完成本地提权,拿到 root 权限,奖金 10000 美元。 0xDACA 和 Noam Trobishi 则利用释放后使用漏洞,成功利用 NVIDIA Container Toolkit,说明容器相关组件仍是企业环境的重要攻击面。 AI 赛道同样有多起成功案例。Viettel Cyber Security 的 Le Duc Anh Vu 攻破 Cursor AI coding agent,获得 30000 美元。 Summoning Team 的 Sina Kheirkhah 演示了 OpenAI Codex 的零日漏洞,奖金 20000 美元;Compass Security 也成功利用 Cursor,获得 15000 美元。

IT之家 · 2026-05-15 11:27:21+08:00 · tech

IT之家 5 月 15 日消息,2026 年柏林 Pwn2Own 开赛首日,来自全球各地的安全研究员挖掘报告 24 个零日漏洞, 成功拿到 523000 美元(现汇率约合 355.7 万元人民币)奖金。 其中 Orange Tsai 通过串联 4 个逻辑漏洞,在 Microsoft Edge 浏览器上完成沙箱逃逸,单项奖金达到 175000 美元。 Windows 11 成为本次活动首日重点目标之一,Angelboy 和 TwinkleStar03、Marcin Wiązowski、以及 GMO Cybersecurity 的 Kentaro Kawane 都演示了新的提权零日。 针对企业和 AI 相关产品,Valentina Palmiotti 在拿下 Red Hat Linux for Workstations 的 root 权限后,又发现 NVIDIA Container Toolkit 零日,分别获得 20,000 美元和 50,000 美元。 k3vg3n 通过 3 个漏洞让 LiteLLM 失效,Satoki Tsuji 和 haehae 则利用 NVIDIA Megatron Bridge 零日拿到奖金。 OpenAI Codex 也被纳入攻击范围。Compass Security 和 Doyensec 的 maitai 都成功攻破这一编码智能体,各自获得 40,000 美元。haehae 还提交了 Chroma 零日,STARLabs SG 则攻破 LM Studio,分别拿到 20000 美元和 40000 美元。 IT之家注:Pwn2Own Berlin 2026 是全球最负盛名的黑客竞赛之一,于 2026 年 5 月 14 日在德国柏林的 OffensiveCon 安全会议上正式拉开帷幕。 该赛事由趋势科技旗下的零日漏洞计划(Zero Day Initiative)主办,旨在通过实时实机攻防,发掘主流软件、云基础设施及前沿 AI 平台的零日(0-Day)漏洞。

LinuxDo 最新话题 · 2026-05-11 20:12:22+08:00 · tech

身份如题 是个二本院校的计算机学生,刚大一下的的时候学过一段时间pwn,到大二下开始到期中后就没学下去,跟着一个看得上我的老师,帮他干开发了,这个老师是个领导想做个考试系统碰巧vibecoding起来了。老师教我规范性开发用openspec什么的负责vibecoding开发。期间还接了外面认识的一个研究生的动物识别项目,赚了点毛毛钱,同时因为我是大三的老登了,网络安全断代了,我这个润人带着大二大一去打比赛,混了了两个线下赛三等奖然后老师通过人脉给我内推了网络安全龙头公司的面试,好久没干网安了,面试3天前告诉我的,我背了背面经,结果也没过。说我没实战经验,挺受打击的,然后就看渗透最近,五一期间,在团队里面人带动下,用cc去挖了挖洞利用ai,虽然没深度学过对web的学习也就是学过owasptop10但是ai真是太好用了,掏了两个高危一些中低危。但是大三下去网上boos直聘上去找实习和护网,根本没啥人要,(护网现在都不要学生了或者说不能写自己是学生也是学习到一点写简历的技巧),感觉找工作好难。和老师聊是说 实习就是不好找因为人家觉得你干2 ,3月就走了不想白培养,然后我老师就是让我考研,他自己的地位已经挺高的了,可是他给我说要是年轻的时候读个全日制研究生,自己就能副厅级了(学习里面的那种和政府还是区别挺大),告诉我年轻应该多提升自己的平台和见识,然后就告诉我学历对后续发展很关键 我听的云里雾语,lz本身家里面的大学生很多只有我自己一个是二本( ) 我的老哥二战考研没考上心仪学校去就业,因为自身情商比较高,在职场如鱼得水混的也挺好,他告诉我能就业就就业不要考研,就业也没有网上说的那么糟糕(他是疫情后1年去工作的),因为他也才工作3年还没有说能看到上面我老师说的学历对后续的影响;然后姐管科做产品经理前几年的时候也是她工作2,3年的时候也是说让我去南方找工作,机会多有能力就不太看重学历。但是到今年她又说自己想跳槽时多么希望自己大学时能考个雅思这样外企待遇好,多么希望自己当时考个研究生,人生那么长研究生也就是那么几年,现在劝我考个研究生,同时相信我现在能找到工作只是时机没到。 lz也是很焦虑 现在投实习护网找不到(但是前几天老学长(之前内推面试的也是他,是个管理层)给我找了个暑假实习医院的网络安全方面工作,没有工资管住就是让我兜底边干边找同时在真实环境中去学习,要是想干到时候就给我转正),是在北方县里面的医院 没具体了解应该就是外包那种工作。lz还是想去南方杭州深圳什么的看看,如果找不到暑假就去这了先。我老师也是说 工作没有那么好,到时候干的不顺心就回来准备下半年考研考上就上考不上不想二战就就业。 当我把这种焦虑和身边同学说的时候,他们也不能理解,因为表面看来我已经比他们(刚上大学因为他们都没怎么用过电脑,电脑调试或者有一些电脑问题,清灰换内存固态刷系统什么都是我帮他们,所以觉得我比他们会的多)好太多了,做过实际的项目,开发安全运维都做过有经验,有比赛得奖,还有老师的关系之类的。就觉得我在杞人忧天但是lz真的好焦虑,现在大三下自己找不到实习,问我老哥就说正常,找到工作的瞬间焦虑自然也就没了,但是毕竟他是一本的院校我就是二本,感觉变量还是有的而且年份也变了,互联网上也是充斥着计算机就业不好,我也知道大部分大学生都是不学的上大学什么都不会,所以才有这个情况 但是现在我的情况也是找不到 会不会我也是这种下场。 请各个领域的佬们点拨点拨 5 个帖子 - 5 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-08 22:39:25+08:00 · tech

好久不见佬友们,最近一个月忙着各种各样的事情,歇逼了一阵子,终于又来更新了。今天终于要正式进入Pwn用户态栈利用的部分了。章节1我们将从最基础的栈溢出漏洞开始,介绍这一元老级漏洞所造成的巨大危害,以及五花八门的利用手法。 Stack Buffer 我们即将学习你的第一个二进制漏洞—— 栈溢出 Stack Overflow 。或许一个更专业学术的名称是 栈缓冲区溢出 Stack Buffer Overflow 。那么,我们首先来简单介绍一下缓冲区的概念。 缓冲区 是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为 输入缓冲区 和 输出缓冲区 。 Wiki上叫作 缓冲器 ,以下是摘自其上的描述 缓冲器(英语:buffer),又称缓冲器,是暂时置放输出或输入数据的存储器区域。通常,自输入设备(例如麦克风)访问数据后,数据在输出至另一设备(例如扬声器)前,会暂存在缓冲器中。但此外,电脑内部的不同进程间传输数据也会用到缓冲器。这与电信中的缓冲器相当。缓冲器可以在硬件中的固定存储器位置中实现,也可以在软件中使用指向物理内存中的某个位置的虚拟数据缓冲器来实现。但无论如何,缓冲器中的数据都存储于某个实体的存储介质。多数缓冲器都是在软件层面实现的,它们一般会使用RAM来存储临时数据,因为RAM比硬盘的访问速度快得多。当接收数据的速率和处理数据的速率之间存在差异时,或者这些速率有波动的情况下,例如在打印机假离线程式或在线视频流中,通常也会使用缓冲器。在分布式计算环境中,数据缓冲器通常以突发缓冲器的形式实现,以提供分布式缓冲服务。 简单来说,这其实是一块 人为分配的大小有限的内存 ,它被用来暂时储存外部输入或将要输出到外部的数据,直到程序处理掉这块数据为止。如果这块内存被分配到栈上,那么就是 栈缓冲区 ;如果分配到堆上,那么就是 堆缓冲区 。 那么, 溢出 这个概念就自然好懂了,实际上就是 放入缓冲区的数据大小超过了缓冲区本身的大小 。如果该缓冲区是栈缓冲区,那么多出来的数据就会从那一片栈空间中 溢出 , 覆盖到栈上的其他数据 ,这就是 栈缓冲区溢出 。 Experiment - 分配一个用户输入栈缓冲区 我们由一个实验来直观地呈现栈缓冲区这个概念,同时熟悉pwndbg下栈的数据观察。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { char buffer[0x20]; read(0, buffer, 0x20); printf("Your Input is %s", buffer); return 0; } //gcc exper1111.c -o exper 简单解读一下程序,首先声明一个0x20大小的char数组,这就是我们所说的 缓冲区 。在0-1-3我们介绍过, 栈中存储着局部变量和函数调用信息 ,所以我们的 buffer 就是一个 栈缓冲区 。这个缓冲区用于储存后续 read 从 标准输入 读入的0x20个字节大小的数据,然后通过 printf 以 字符串 形式解析并打印到屏幕上。 关于文件描述符 Linux系统将每个对象当作文件处理。这包括输入和输出进程。Linux用文件描述符(file descriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0、1和2) 标准输入 STDIN fd=0 STDIN文件描述符代表shell的标准输入。对终端界面来说,标准输入是键盘。shell从STDIN文件描述符对应的键盘获得输入,在用户输入时处理每个字符。 编译后,我们运行一下。 程序正常执行,我们通过pwndbg调试一下试试 这里是main函数起始位置。可以看到之前介绍的程序序言部分开辟了一个栈帧。然后 sub rsp, 0x30 抬栈,这里就是程序预留出的栈缓冲区了。 简单说一下 A -> B -> C <- D 这个很常见的表示方法 比如 0x7fffffffe0a0 -> 0x7fffffffe150 -> 0x7fffffffe1b0 <- 0 首先第一个是栈地址,然后这个栈地址上的空间存储 0x7fffffffe150 这个栈 指针 ,这个指针又指向 0x7fffffffe1b0 这个栈地址,然后 0x7fffffffe1b0 中存储着 0 这个数据。 然后我们单步到 read 函数。 可以看到这里的 rsi 存储着栈顶的地址,说明 read 函数将要从栈顶开始向栈中读入来自标准输入的0x20字节大小的数据。 这里我们会发现缓冲区似乎比预想的更大一些,有0x30字节大小,并且在 rbp+8 的位置我们发现了一串神秘的数据。这其实是程序开启了 Canary 产生的现象,这里我们先按下不表,只需了解这是一种缓解栈溢出攻击的措施。 总之,这里我们继续读入数据 在这里我们一共读入了11个字节,可以在栈视图中直观地看出。我们的数据已经从用户标准输入读入到了程序的栈缓冲区当中。 Stack Overflow 我们已经知道,栈缓冲区实际上就是一块可以由 用户控制其内容的栈空间 。那么设想这样一种情况:如果程序允许用户输入的数据大小超过了缓冲区的大小,理所应当地,就发生了栈缓冲区溢出。 char buffer[0x20]; read(0, buffer, 0x100); 由于栈上存储着局部变量和函数调用信息,因此,溢出的数据最终会 覆盖 掉这些信息,导致程序运行 出错 或者被 劫持 。 所以,发生栈溢出的基本前提是: 程序必须向 栈上写入 ,也就是说有一块 可控的栈缓冲区 写入的大小未被很好地控制 导致输入大小可以超过缓冲区的大小 一个十分简单的例子:如果我有一个 gets(buf) 原语,由于 gets 无限制地向 buf 缓冲区从标准输入读入数据,但是 buf 并不是无限大的 ,这就会导致栈溢出的发生。读入的数据大小超过了缓冲区的大小。 历史上的第一个蠕虫病毒 莫里斯蠕虫 就是利用了危险函数 gets 实现了栈溢出。由于该函数广为人知的不安全性,在2011年12月发布的标准中, gets 函数被移除 Experiment - Stack Overflow to Overwrite 接下来,我们由一个实验来体会栈溢出所能造成的严重后果。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int vuln() { char buffer[0x10]; int flag = 0; scanf("%s", &buffer); if(flag != 0) { return 1; } else { return 0; } } int main(){ int check = vuln(); if (check == 1) { printf("Congratulations!\n"); system("/bin/sh"); } else { printf("End of the line.\n"); } return 0; } //gcc exper1112.c -fno-protector -O0 -o exper 这是一个简单的 Proof of Concept ,在 vuln 中存在一个栈溢出漏洞,可导致程序输入 覆盖到其他变量 : vuln 申请了一片缓冲区和一个状态变量,用户输入使用 scanf("%s", &buffer) 向缓冲区读取数据并按照字符串形式进行解析。在此过程中, scanf("%s", &buffer) 是一个危险原语。由于 scanf("%s") 不检查输入长度 ,所以这里存在栈溢出漏洞。后续在返回前,函数检查了 flag 的值,然后返回不同的值 在 main 中,首先检查了 vuln 的返回值是否为1, 如果是,那么直接 GetShell ,如果不是,打印信息后返回。 直接运行程序输入abc试试 程序的缓冲区大小在编译后可能会发生变化,不过没关系,我们直接用gdb进行调试。 我们直接进入 vuln 函数, 单步到 scanf 的位置看看 再想想刚才的分析,如果我们想要 让 vuln 返回1的话,就必须让 flag 变量有值 。但是 flag 全程没有被调用,所以我们只能通过非正常手段让 flag 被 覆盖 为1. 显然是用我们刚刚提到的栈溢出漏洞了。我们尝试一下。 确认一下当前的栈情况 如何定位 flag 呢,在汇编中是没有局部变量符号的,我们只能从源码开始分析 scanf("%s", &buffer); if(flag != 0) 在 scanf 之后就是if判断块,那么下一条指令应该就是对 flag 的操作。 0x555555555183 <vuln+42> cmp dword ptr [rbp - 4], 0 那么 rbp - 0x4 的位置就是 flag 变量。我们通过 x/20gx 命令查看 由于我们的 flag 是 int 只有四个字节,那么在图上就在这里 现在的flag为0 我们先输入0x18个字符,测试下缓冲区边界。 这里输入了24个字符a,对应的十六进制就是0x61,可以看到刚刚好覆盖到 flag 的前面。那么我们直接重启程序,尝试将 flag 全部覆盖。 我们需要输入 0x20 个字符。 重新定位到 scanf 这里通过 cyclic 命令生成了0x20长度的字符串。直接复制即可。 这里我们实际上输入了0x21个字符,因为回车是最后一个换行符 \n 。但是在 scanf 解析后被替换为了 \x00 ,所以实际上还是 0x20 个字符读入。 C语言以 \x00 作为字符串结尾。 我们的 flag 被覆盖为了 aaaa , 成功了 !这里出现了栈溢出, 覆写 Overwrite 了 flag 的内容。根据函数逻辑,我们的 vuln 会返回1 RAX 为1, 成功了!当我们返回到 main 函数,我们将会获得 Shell 现在我们退出调试,直接运行程序,然后输入 0x20 长度字符串触发栈溢出,同样会得到Shell,试试看。 总结一下。我们利用 vuln 函数的栈溢出漏洞,成功覆盖了栈上的关键变量 flag ,导致绕过了if检查获取到了Shell。 这其实是缓冲区溢出漏洞利用中特别重要的 覆写思想 overwrite ,利用溢出漏洞,我们可以修改在内存中的敏感信息,例如 指针,变量,返回地址 等。通过覆写,我们可以劫持程序执行流,从而达到Getshell的目的。 Pwntools 脚本交互 刚才我们是通过终端直接和程序交互,但是很多时候,我们需要发送一些键盘不能直接打出的特殊字符,或者需要很快的交互光手打无法达成的时候,我们就需要使用 pwntools 这个Python库来和程序进程进行交互。 新建一个py文件,导入 pwntools 。 from pwn import * 然后通过创建一个IO对象来使用pwntools封装的方法 # 使用路径 filepath = "" # 从本地启动一个进程,建立socket连接 io = process(filepath) # 如果需要远程连接,使用remote io = remote('IP/domain name', Port) 比如我要发送一些数据,就使用 # 字符串前面加b表示以字节流形式发送,这是个好习惯。 io.send(b'Hello World') 要接收数据,使用 # 接收到最近的换行符 io.recvline() 也就是说,我们完全使用Python脚本进行数据收发,这极大方便了我们对程序进行测试和利用。只需要在这个脚本中写入我们需要的一切操作,运行就能达成我们想要的效果。这就是 Exploit利用脚本 刚刚的实验,我们完全可以通过python脚本的形式进行交互和利用。 from pwn import * # 新建io对象,从本地启动程序exper io = process("./exper") # 构建GetShell的Payload payload = cyclic(0x20) #生成0x20大小有序的字符串 # 在payload后加一个换行符发过去 io.sendline(payload) # 启动交互模式,可以直接在Python脚本运行环境下和程序交互,这里就用于和Shell进行交互 io.interactive() 跑一下试试。 Experiment - 通过栈溢出绕过随机数检查 在CTF中我们常见这样一类题目,需要你输入一串密码,但是这个密码是随机生成的。你虽然能通过调试拿到这个密码,但是每次启动程序这个密码都是不一样的。CTF Pwn中,我们需要获取的flag都在服务器上,本地只会给你一个测试用的程序。所以当我们 本地利用成功后,还需要连接到服务器上进行远程利用 ,远程利用和本地利用是同样的程序。在远程利用中,我们当然就不能直接通过gdb调试直接拿到密码了。 我们由一个实验来体会CTF Pwn的题目模型。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> char TOKEN[0x10]; void initpasswd() { setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); setvbuf(stderr, 0, 2, 0); //设置缓冲区,让输入输出即时显示 FILE* stream = fopen("/dev/urandom", "r"); fgets(TOKEN, 0x10, stream); } int vertify() { char PASSWORD[0x10]; char password[0x10]; memcpy(PASSWORD, TOKEN, 0x10); printf("Give me your passwd:"); read(0, password, 0x18); if (!strcmp(password, PASSWORD)) return 1; else return 0; } void main() { initpasswd(); if ( vertify() ) { printf("Welcome to the system!\n"); system("/bin/sh"); } else { printf("Invalid password!\n"); } } //gcc exper1113.c -fno-stack-protector -O0 -o exper 程序实现了一个验证功能。每次启动时在 initpasswd 去生成一串随机数,这个随机数从 /dev/urandom 读取。urandom通过当前设备的运行熵生成随机数。所以想要直接预测这个随机数是非常困难的,可以姑且看作是真随机。 发生器有一个容纳噪声数据的[熵池],在读取时, /dev/random 设备会返回小于熵池噪声总数的随机字节。 /dev/random 可生成高随机性的[公钥]或[一次性密码本]。若熵池空了,对 /dev/random 的读操作将会被[阻塞],直到收集到了足够的环境噪声为止。这样的设计使得 /dev/random 是真正的[随机数发生器] ,提供了最大可能的随机数据熵,建议在需要生成高强度的密钥时使用。 /dev/random 的一个副本是 /dev/urandom (“unblocked”,非阻塞的随机数发生器,它会重复使用熵池中的数据以产生伪随机数据。这表示对 /dev/urandom 的读取操作不会产生阻塞,但其输出的熵可能小于 /dev/random 的。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。 然后通过 vertify 去做身份验证。如果通过的话就开一个Shell给你。这里 vertify 中存在一个栈溢出。 char PASSWORD[0x10]; char password[0x10]; read(0, password, 0x18); 栈在申请局部变量时是先申请的在下方,后申请的在上方。 这个栈溢出非常小,只有8字节,并且不足以完全覆写 PASSWORD 原密码缓冲区,只能覆写密码的前8字节。 怎么办呢?注意到比较是通过 strcmp 实现的。这里我们需要先考查一下 strcmp 函数的性质。 简单的比较字符串是吧。但是我们在上一个实验曾经提到过 C语言的字符串以 \x00 结尾 那么 strcmp 是否遵循这个规则呢?我们可以写一个简单的PoC验证一下 #include <string.h> #include <stdio.h> int main() { char str1[] = "abc\x00def"; char str2[] = "abc\x00xyz"; if (strcmp(str1, str2)) printf("Same Strings!"); else printf("NO!"); return 0; } 程序很简单,定义两个字符串,它们的前三个字符和 \x00 相等,后三个字符不同。通过 strcmp 进行比较,如果相同就打印相同。我们编译运行一下。 我们的猜想是正确的!在比较的过程中, strcmp 发生了 零截断 。这导致字符串没有被完整比较。事实上,它只比较了 \x00 前面的部分。 于是,我们的思路就呼之欲出了: 通过栈溢出覆写PASSWORD前字节为 \x00 ,截断字符串,使之与我们输入的 password 相同。 所以我们可以构建这样的Payload payload = b'\x00' * 0x18 脑测一下: 程序从 password 起始位置开始读入数据,整个 password 被读入为0x10个 \x00 缓冲区溢出到 PASSWORD , PASSWORD 的前8个字节被覆盖为 \x00 来到 strcmp ,由于零截断,只会比较 password 的第一个 \x00 和 PASSWORD 的第一个 \x00 通过验证,GetShell 所以我们的Exp如下 from pwn import * io = process("./exper") # 准备payload payload = b'\x00' * 0x18 # 在提示之后发送 io.sendlineafter(b'Give me your passwd:', payload) # 开Shell io.interactive() 试试看 没问题成功了。 实际上,由于 /dev/urandom 生成的随机数是完全随机,所以我们可以采用爆破的形式。当我们随机到 TOKEN 的第一个字节为 \x00 时,同样在 strcmp 时会发生零截断。 EXP如下 from pwn import * while True: io = process('./exper') io.sendlineafter(b'Give me your passwd:', b'\x00') # 缓存接收信息 result = io.recvline() if b'Welcome' not in result: io.close() else: break io.interactive() 可以看到同样成功了。 Summries 本节我们学习了第一个二进制漏洞:栈溢出。这是相当基础,相当重要的漏洞。栈溢出可以造成严重的后果,本节我们主要探讨了Pwn利用的一个重要思想: 覆写 Overwrite 。覆写是一切篡改的基础。后续的学习我们将和栈帧的相关知识结合起来,学习栈溢出基本的利用手法。后续的Pwntools教程也会跟进补上。 Have Fun!我们下个帖子再见! 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-06 21:53:55+08:00 · tech

glibc动态内存分配 写C语言时,如果想申请或释放内存,就需要 malloc 和 free 函数。从linux内核层面来看,往往会用到这两个系统调用: mmap brk 其中, brk 会将进程的heap段向内存高位扩充,可以理解为把堆顶抬高了。而 mmap 则在heap段和stack段之间申请匿名内存(不用担心这片区域被填满,64位系统下,你的电脑内存加起来都没它大)。 结合linux进程的简化内存分布,更加直观一些: 低地址 [text] [data] [bss] [heap] … [mmap region] … [stack] 高地址 释放内存的系统调用也有两个: munmap brk (没错, brk 也可以收缩堆空间) 这两种分配方式的区别在于, mmap 一般用来申请大块内存(默认值大约是128KB以上) 但是呢,问题出现了。每次进行系统调用时,都要从ring3态切换到ring0态,中间还要进行一堆安全检查,完事了还得再换回来,极其消耗系统资源。为此,glibc开局就申请了一大块内存,根据进程的需要来细细分割,管理这些内存的管理器就是ptmalloc2。接下来我们详细说说它。 结构初识 为了弄清楚这玩意,我查了不少资料。刚开始读源码不容易看懂;ctf wiki的内容全面,可是一上来就是一堆细节,看了头晕;相应的视频和书籍虽然权威,但基本都停留在2.29之前的版本。所以嘛…我想写一点新的东西,就比如这篇教程。 下面按照由浅入深的顺序,介绍一些概念: malloc : 申请内存 free : 释放内存 chunk : 申请的内存块,每次 malloc 都会申请到一个 chunk bin : 垃圾桶, chunk 被 free 释放后会进入 bin arena : 一个 arena 相当于一个堆,有自己的一套 bins main_arena : 主线程使用的 arena ,目前我们只研究单线程程序,也就是只有 main_arena 一个 arena malloc 分两种情况 申请大块内存:使用 mmap 系统调用 释放普通内存:正常流程(从 bin 获取,没有的话再进行分配) free 也分两种情况 释放 mmap 申请的内存:使用 munmap 系统调用 申请小块内存:正常流程(进 bin ) chunk 每一个 chunk 都是有自己的结构滴,这个结构的全称叫做 malloc_chunk ,好在不复杂。 // malloc/malloc.c:1153 struct malloc_chunk { INTERNAL_SIZE_T mchunk_prev_size; /* 前一个 chunk 大小 */ INTERNAL_SIZE_T mchunk_size; /* 当前 chunk 大小 */ struct malloc_chunk* fd; /* 前向指针 */ struct malloc_chunk* bk; /* 后向指针 */ struct malloc_chunk* fd_nextsize; /* large bin 专用 */ struct malloc_chunk* bk_nextsize; /* large bin 专用 */ }; 讲解一下字段的含义 INTERNAL_SIZE_T 就是 size_t ,前两个变量存放 chunk 大小,它们被称为 chunk 头部。因为 malloc 申请完内存之后,用户可以使用的部分是从第三个字段开始的,也就是说,后面的四个指针变量,正常情况下是没用的,会被用户写入的数据覆盖。 用户申请内存时,必须是16字节的整数倍(32位是8字节),就算你申请了1字节,ptmalloc2也会给你16字节。而 chunk 头部就占据了16字节(以后默认64位系统),所以一个 chunk 最小也有32字节。 这时,细心的你会发现,既然每个 chunk 都是16的倍数,那么 mchunk_size (简称 size )字段的低4位就处于未使用的状态,那就拿来当标志位吧: 位 宏 含义 bit 0 PREV_INUSE 前一个 chunk 是否被分配 bit 1 IS_MMAPPED 是否通过 mmap 分配 bit 2 NON_MAIN_ARENA 是否不属于 main arena 只用3个比特位,是为了兼容32位的版本。 chunk 进入 bin 后, fd 指针就指向前一个进入该 bin 的 chunk , bk 指针指向后一个进入该 bin 的 chunk 。这样的话,在 bin 中形成链表结构,方便存取。至于 fd_nextsize 和 bk_nextsize ,现在并不重要,待以后慢慢细讲。 先说这么多吧,多了不好消化。 知识库 how2heap :一个学习堆利用技术的绝佳资源库,包含了针对不同glibc版本的各种利用方法(如fastbin_dup, unsafe unlink, house of系列等)的教学代码。 CTF Wiki :由社区持续维护的CTF知识库,PWN部分涵盖了从入门基础到高级利用的系统性教程。 ctf pwn之glibc堆利用 : 我的教程(混进了什么奇怪的东西) 本人第一次写教程,求佬友批评指正,我会不断改进的。 1 个帖子 - 1 位参与者 阅读完整话题

linux.do · 2026-04-29 22:55:09+08:00 · tech

简单聊聊堆管理器 众所周知,内存分配方面的策略有很多。不同的操作系统、不同的C语言库甚至应用程序都有不同的堆管理器。就比如: 堆管理器 平台 ptmalloc2 现代Linux (glibc 2.3+) Windows Heap Windows (NT 内核) tcmalloc Google自研,多线程速度快 mallocng musl libc,轻量级 而我们主要研究的,就是linux下最常用C语言标准库glibc的堆管理器——ptmalloc2 在pwn区,glibc可谓是令人闻风丧胆,每隔几个版本就整波大的,机制还复杂得离谱。 linux环境下,我们可以运行 /lib/libc.so.6 查看当前系统的glibc版本。 glibc重大版本 2.23 及之前 除了 safe_unlink 之外,几乎没有值得一提的防护机制。可以理解机制,但过于古老,现在几乎见不到。 2.26 引入万恶之源 tcache ,虽说在多线程方面性能有所增加,但是安全防护堪称一坨shit。属于堆利用的事故多发地。 2.29 一个密集的“打补丁”版本。Unsorted Bin Attack、House of Force 等经典手法被集中修复, tcache 的 double‑free 检测也进一步增强,利用难度上了一个台阶。 2.32 PWN 选手的噩梦——Safe Linking 横空出世。tcache 和 fastbin 的 fd 指针现在会被加密存储,直接篡改变得非常困难,必须配合地址泄露才能绕过。同时,对齐检查的引入也让构造精密的假堆块变得更加容易失败。 2.34 移除了 __malloc_hook 和 __free_hook 。以前靠堆溢出覆盖这两个钩子就能轻松接管控制流,现在这条路被彻底堵死,攻击者被迫转向 _IO_FILE 结构的攻击。 2.36 运行时强制为 GOT 表施加只读保护(等效 Full RELRO)。直接在 GOT 里改写函数指针的方式彻底失效,篡改 _IO_FILE 虚表(如 House of Apple 系列)成为绝对主流。 2.40+ 开始重构核心函数,进入现代化阶段。单纯利用堆getshell已经不太可能。 何处启程 古代 : 学习无防护的经典利用——glibc 2.23; 学习tcache的经典利用——glibc 2.27。现代环境中,这些手段都有相应的防护措施。 近代 :glibc 2.35,Safe-Linking是一个难点,并尝试 tcache stashing unlink attack 等高阶技巧。 现代 :glibc 2.37 - 2.43,堆利用与glibc其他模块( IO_FILE 等)结合。 根据 how2heap 的利用教程,这次我们先从glibc2.35的基础环境开始,进行一些机制以及著名利用手段(off-by-one, house-of系列等)。 常用工具 Docker 环境 (如 pwndocker ) :强烈推荐用于搭建本地环境,可以轻松切换不同版本的glibc,确保与远程服务器环境完全一致。另外,虚拟环境也方便与主机隔离,防止自己给自己RCE了 。 pwndbg : 直观查看堆内存布局与各种结构,本地进行调试 pwntools : 每一个pwn大手子的专武,用于编写脚本(更多功能等待发现)。 知识库 how2heap :一个学习堆利用技术的绝佳资源库,包含了针对不同glibc版本的各种利用方法(如fastbin_dup, unsafe unlink, house of系列等)的教学代码。 CTF Wiki :由社区持续维护的CTF知识库,PWN部分涵盖了从入门基础到高级利用的系统性教程。 ctf pwn之glibc堆利用 : 我的教程(混进了什么奇怪的东西) 本人第一次写教程,求佬友批评指正,我会不断改进的。 2 个帖子 - 2 位参与者 阅读完整话题