给开源编译器插入后门

VOLT开源GPU编译器:SIMT控制流优化技术解析 GPU编译器技术是提升并行计算性能的核心环节,其核心挑战在于处理控制流分歧(Control Flow Divergence)导致的线程执行效率下降。通过LLVM中间表示扩展和分歧感知优化策略,现代GPU编译器能够显著提升硬件资源利用率。VOLT作为开源解决方案,创新性地引入SIMT控制流优化技术,包括CFG结构化、线程掩码跟踪和分歧管理函数插入等关键技术。这些方法在RISC-V GPU架构上实现了平均1.15倍的性能加速,特别适用于计算密集型和高控制流复杂度的应用场景。工程实践中,开发者可通过uniform 阅读详情

原文地址:https://ring0.me/2014/11/insert-backdoor-into-compiler/

说起 Ken Thompson,我们首先想到的是他发明的 UNIX 操作系统。他因此获得 1984 年的图灵奖。在图灵奖演讲上,Ken Thompson 提出了一个深刻的问题:看到了软件的源码,就意味着没有后门吗?编译器是否可能存在能自我复制的后门?

KenThompson

这篇发表在《ACM 通讯》上的论文只有短短三页,省略了很多细节。原理上有点像输出自身代码的 C 程序,但又比它难很多。我追随先哲的脚步,给一个开源 C 编译器——tcc 插入了能自我复制的后门,这个插入了后门的编译器在编译 Linux 登录程序 sulogin 的源码时,会自动插入一个后门。

什么是 sulogin

当文件系统挂载失败或者启动过程中出现其他故障时,Linux 往往会进入一个如下图所示的界面,要求输入 root 密码进入恢复控制台。这个请求输入 root 密码的程序就是 /sbin/sulogin。

sulogin 界面

sulogin 界面

这个程序本身是以 root 身份运行的,去系统用户数据库检查用户输入的 root 密码是否正确,如果正确的话就进入一个 root shell。我使用了 sulogin 做例子,只是因为它比标准的命令行登录程序 /bin/login 代码行数更少。如果让 sulogin 程序在接受正确密码之余,还能够悄悄接受 bojieli 这个密码……

让我们从 sulogin 的源码开始。(sulogin 在 util-linux 这个软件包里,Debian 系可以用 dpkg -S 搜索到)其中负责验证密码的部分如下图所示。

Untitled

只要增加一个条件判断,就可以畅通无阻啦!

Untitled

当然,在 sulogin 中插入一段如此明显的后门代码,实在是太拙劣了。为何不让编译器完成这个光荣而伟大的使命?

让编译器给 sulogin 插入后门

简单来说,编译器的输入是程序源码,输出是二进制机器码。只要编译器发现正在编译的是 sulogin,就替换源码的特定部分,插入后门。

Untitled

如何 “发现” 正在编译的是 sulogin 呢?编译器很复杂,在 AST(抽象代码树)层次上做替换,固然比较隐蔽,对 sulogin 代码修改的鲁棒性也比较强,但难度比较大。既然是演示,我们就做简单的源代码文本匹配和替换。

由于 gcc(GNU C compiler)太复杂了,编译一遍很耗时,就用小巧而简单的 tcc(tiny C compiler)编译器吧。我们从读取源代码的缓冲区下手,一旦读到的部分匹配上 sulogin 的比较密码部分,就替换成带有后门的源代码字符串。

Untitled

上面的代码扼住了 tcc 读入源代码的 “咽喉”,当匹配到 login_pattern 时(红色箭头),就在它后面添加 login_append(绿色箭头),真是简单粗暴。这段代码里也有明显的 bug,当待匹配代码跨越了缓冲区边界时,就匹配不上了,不过不要在意这些细节……

加入后门的 C 编译器中有一段明显的后门代码,作为开源代码发布出去显然会被发现。我们要让编译器把后门 “隐藏” 起来。

编译器后门的自我复制

在 gcc 的编译过程中,为了避免潜在的问题,需要用 gcc 编译 gcc 自身的源码得到一个可执行文件 A,再用 A 编译 gcc 源码得到可执行文件 B,只有 A 和 B 相同的时候才认为编译成功。也就是说,编译器必须能够编译自身。

我们的后门显然也要有自我复制的能力。有后门的 tcc 可执行文件在编译正常的 tcc 源代码时,生成的 tcc 可执行文件也要包含相同的后门。

初看,这个过程并不复杂。如下面的伪代码所述,当匹配到 sulogin 源码的时候就插入登录后门;当匹配到 tcc 自身的源码时就插入 tcc 后门。

Untitled

实际实现的时候,却会发现一个困难:后门代码自身是一个字符串,它自己又要在 “tcc-backdoor” 部分出现……有点自我指涉的感觉了。

输出自身的 C 程序

很多小伙伴也许听说过能输出自身代码的 C 程序。Google 一下也能找到,但程序作者往往把程序写得很短很精炼,因而不易看懂。事实上这并不是什么 rocket science。

如何输出自身呢?源代码一定要被放在二进制文件的数据段中。最简单的自我输出代码片段就像这样:

Untitled

上面的 printf 代码重复了两次,第一次是作为字符串常量的一部分,第二次是作为源代码被编译。而这个字符串也被输出了两次,因为 printf 里有两个 %s。

给不熟悉 C 语言的朋友解释一下:char *s 定义了一个字符串,并以后面紫色和红色部分的字符串常量作为初值。其中 \ 是字符串常量 s 中的转义字符,表示紧随其后的引号或 \ 不是表示字符串结尾的引号,而是字符串中的一个普通字符。s 这段字符串与其后的完整代码完全相同。而其后的代码把 s 之前的代码抄过来,再输出两遍 s。

这段代码的强大之处在于:它可以包含任意的其他代码,因此任意程序都可以包装成自输出的形式。例如我们在程序最后增加一条输出 Hello World 的语句,只需要把它在字符串 s 中原样抄一遍(除了要注意转义字符)。

Untitled

细心的读者也许已经发现了其中换行符、转义字符的细微区别,因此真正的自输出代码不能简单地把字符串输出两次,第一次输出的时候要添加上转义字符和每行末尾的字符串跨行连接符 \,而第二次输出就是原样输出了。各位看官不要着急 OCR,文末有代码的下载链接。

Untitled

给编译器插入自我复制的后门

有了 “输出自身代码” 的理论基础,就可以把它应用于 tcc 了。输出两遍的代码字符串 s,在这里的名字是 tcc_replace。编译器读入一段代码后,一旦发现它是 tcc 的代码,就把这段代码替换成后门代码:转义后的 tcc_replace 连接上 tcc_replace。伪代码如下:

Untitled

当然,C 语言是一门比较底层、表现力比较低的语言,因此实现出来的代码就很冗长了。

full

这个带有后门的编译器是这么玩的:

  1. 编译已经插入后门的 tcc-new,用什么编译器都行;
  2. 用带后门的 tcc-new 编译正版 tcc 源码 tcc-orig,生成仍然带后门的可执行文件 tcc-orig。这称为自举(bootstrap)过程;
  3. 用 tcc-orig 编译 sulogin,得到带后门的 sulogin。
  4. 如果用 tcc-orig 再次编译干净的 tcc 源码,得到的编译器仍然是带后门的。这次生成的编译器将被作为发布版本。

下载恶意版本 tcc 的用户,编译看起来正常的 tcc 源码,得到的仍然是恶意版本的 tcc,而且二进制文件完全相同。也就是除非反汇编二进制文件,是无法发现该 tcc 编译版本的恶意行为的。

当然,在被插入后门的编译器的数据段(.data section)中,能够看到一大段源代码,这肯定是令人生疑的,用 strings 命令就能发现。应该用类似软件保护的方法,对这段数据进行加密,运行时再解密。此外,可以编写一个通用的框架来自动插入后门,免得手工构造 tcc_replace 这段字符串。本文只是给出了一个 proof of concept,后门要留得不露痕迹的话,还是要费很多心思的。

有人会说,使用其他编译器(如 gcc)编译干净的 tcc,得到的不就是不带后门的 tcc 了吗?可惜现在编译器越来越复杂,添加了各种独有的扩展语法,因此很多编译器只能用自己 bootstrap,例如 gcc 源码就只能用 gcc 编译。谁知道 gcc 数以百万行计的代码里,会不会隐藏着一个自我复制的后门呢?

越底层的漏洞越危险

Ken Thompson 说,如果被插入后门的不是编译器,而是汇编器、链接器,甚至硬件微码呢?层次越低,后门就越难被发现。

Ken Thompson 的预言应验了。Intel x86_64 SYSRET 本地提权漏洞就是一个臭名昭著的例子。这严格意义上应该算是 Intel 手册没写清楚。SYSRET 是 AMD 率先在 64 位系统上实现的,返回时如果 RIP 触发了通用保护错误,这个错误是触发在 ring 3。Intel x86_64 后来实现 SYSRET 指令时,RIP 触发通用保护错误却是在 ring 0,但手册里并没有指出这处不同。然后问题就来了。

BsEKniQCAAA994L

早在 2006 年,Linux 社区就发现了这个漏洞(CVE-2006-0744)并 patch 上了,但这个问题并没有引起其他操作系统注意。直到 2012 年,Xen 又发现了这个问题(CVE-2012-0217),顺便发现了 FreeBSD、Windows 7 都有这个漏洞,但误以为 Linux 的问题已不存在了。

2014 年,Linux 社区发现 ptrace 仍然可以触发这个漏洞(CVE-2014-4699),也就是说除非禁用了 ptrace,几乎每台 Linux 机器都有这个漏洞。但 CVE 只是轻描淡写地说是 “linux ptrace bug”,Debian oldstable 至今仍未修复(stable 主线已经修复)。

安全算法中的后门是很底层的,也是非常可怕的。2013 年,NSA 被怀疑选用随机性有缺陷的 Dual_EC_DRBG 算法作为 RSA 公司一个加密库的默认算法,并促使该算法成为 ANSI 标准(丁老怪还拿这个做期末考试题)。2014 年 9 月刚爆出的 SSL 3.0 POODLE 漏洞,是 SSL 3.0 协议设计的问题(当然,这不一定是后门)。这不同于今年上半年的心脏出血等漏洞,不是软件实现的问题,而是协议本身就不安全,因此除了禁用协议之外没有好的解决方法。

poodle

附记

在错综复杂的软件世界里,我们能够相信哪段源码呢?正如 Ken Thompson 所说,我们也许只能相信写代码的人了。

这是我大三《黑客反汇编入门》的课程作业,然后在 LUG 每周小聚上也讲过。

代码已经上传到 Github,戳这里。演示文稿 戳这里下载。

密码分析与加密后门:从攻防原理到安全实践 密码学是保障数据安全的基石,其核心在于通过数学算法实现信息的加密与解密。密码分析作为其对立面,旨在不掌握密钥的情况下破解密码系统,主要方法包括暴力破解、差分分析、线性分析以及侧信道攻击等。这些技术不仅揭示了算法层面的潜在弱点,也突显了工程实现中侧信道攻击等现实威胁。加密后门则是在密码系统中故意或无意留下的隐蔽通道,可能存在于算法设计、代码实现或协议层面,严重威胁系统整体安全。理解密码分析与后门机制,对于构建健壮的加密系统至关重要,能帮助开发者在算法选择、参数配置、随机数生成和代码审计等环节规避风险,确保数据 阅读详情

相关推荐

华为方舟编译器正式开源,采用自主平台托管

华为方舟编译器正式开源,采用自主平台托管 Kotlin 开发者社区 01 — 概述 “方舟编译器概述:方舟编译器是为支持多种编程语言、多种芯片平台的联合编译、运行而设计的统一编程平台,包含编译器、工具链、运行时等关键部件。方舟编译器还在持续演进中,陆续将上述能力实现和开源。” 面向多设备、支持多语言的统一编程平台。 OpenArkCompi...

AI天才研究院 1万+

sulogin命令手册

sulogin:单用户登录功能描述:使用sulogin命令可以进行单用户登录,在启动时Shell将不会读取/etc/profile或$HOME/.profile文件。语法格式:sulogi...

关注微信公众号【开源Linux】,后台回复『10T』,领取10T学习资源大放送,涵盖Linux、虚拟化、容器、云计算、网络、Python、Go等书籍和视频 1179

深入VIM编辑器与GCC编译器

本文深入探讨了VIM编辑器的基础模式与命令,以及GCC编译器的多语言支持和编译过程。通过对VIM模式、编辑命令、退出方法的介绍,以及GCC编译器家族的详细介绍,包括其支持的语言、预处理、编译、汇编、链接阶段,并提供了GCC编译器的使用示例。

weixin_42462474的博客 534

linux系统sulog,Linux 下 Login 和 Logout 详解

Login进程Login 是你用Linux系统工作时面对的第一个进程,这对于使用终端以及通过网络使用Linux都是正确的。但是login进程本身并不是你在终端上见到的,你见到的其实是getty (get TeleTYpe terminal ,早期电脑上的意思是获取纸带终端,现在可以直接理解成打开终端),它是由init(通过/etc/inittab)在启动login进程时添加而启动的。所以完整的启动...

weixin_34141225的博客 1648

给自己的软件添加后门

C#.NET给自己的软件添加后门

sulogin命令 单用户登录

使用sulogin命令可以进行单用户登录,在启动时Shell将不会读取/etc/profile或$HOME/.profile文件。 语法格式:sulogin [参数] 常用参数: -p 单用户Shell调用一个破折号作为参数中的第一个字符 -t 程序只会等待用户输入指定秒数 参考实例 进行单用户的登录: [root@linuxcool ~]# sulogin 与该功能相关的Linux命令:rev命令 – 颠倒过来显示文件内容dpkg-preconfigure命令 – 软件包安装之前询问问题dpkg-deb命令 – Debian包管理器egrep命令 – 在文件内查找指定的字符

linux exit 源码,Linux命令——exit、sulogin、rlogin

1.exit功能描述:退出Shell命令语法:exit [选项]2.sulogin功能描述:可以进行单用户登录,在启动时Shell将不会读取/etc/profile或$HOME/.profile文件命令语法:sulogin [选项] [TTY]选项含义:-p:单用户Shell调用一个破折号作为参数中的第一个字符-t:程序只会等待用户输入指定秒数3.rlogin功能描述:可以在当前本地主机系统的终端...

weixin_34288514的博客 366

UE5抗锯齿实战:如何用TAA解决闪烁问题(附参数优化指南)

本文深入探讨了UE5中TAA(时间性抗锯齿)技术如何有效解决画面闪烁问题,并提供了详细的参数优化指南。通过基础参数配置、高级优化技巧以及材质层面的策略,帮助开发者显著提升视觉质量。文章还介绍了诊断工具链,助力快速定位并解决顽固闪烁问题。

solidity8miner的博客 428

gcc破损[已解决]

1.安装tcc 2.mv /usr/bin/gcc /usr/bin/gcc.bak ln -s /usr/local/bin/tcc /usr/bin/gcc 用tcc替换gcc. gcc的ld坏了,我也解决不了,索性换了。

u010563350的博客 1056

神州数码OSPF实战配置详解(手把手教学)

本文提供神州数码设备上OSPF基础配置的详细实战教程。通过搭建典型的两台三层交换机互联实验环境,手把手演示了VLAN创建、接口IP配置、OSPF进程启动、Router-ID设置及网络宣告等核心步骤,并分享了邻居状态验证、路由检查及常见排错方法,帮助网络工程师快速掌握神州数码OSPF的配置要点与操作技巧。

weixin_29210727的博客 79

AMBA-CHI协议详解(十)

该规范提供了一个Request Retry(请求重试)机制,确保当请求到达一个Completer 时,它要么被接受,要么被给予一个RetryAck响应,以防止阻塞REQ通道。

Crazzy_M的博客 987

PAM后门从入门到应急响应

PAM 可以说是一套应用程序编程接口 (Application Programming Interface, API),他提供了一连串的验证机制,只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)。由于 PAM 仅是一套验证的机制,又可以提供给其他程序所呼叫引用,因此不论你使用什么程序,都可以使用 PAM 来进行验证,如此一来,就能够让账号口令或者是其他方式的验证具有一致的结果!也让程序设计师方便处理验证的问题。

记录开发和安全学习过程中的点点滴滴 2390

Unity 面试篇⚠️ | Unity性能优化好,山寨机都能跑~

Unity 面试篇⚠️ | Unity性能优化好,山寨机都能跑~

m0_58523831的博客 1万+

方舟编译器开源技术沙龙北京站首秀:让开源激活软件开发的潜力

9月7日,首场方舟编译器开源技术沙龙在华为北京研究所举办。行业专家、高校学者、应用开发者和方舟编译器专家齐聚一堂,以方舟编译器开源为主题,围绕基础软件发展、开源社区构建、开源生态建设等方面进行了深入讨论。这也是8月31日方舟编译器正式开源后,首次面向行业组织的线下技术交流会议。 首场方舟编译器开源沙龙现场 华为消费者业务软件部开源项目主管做了开场致辞,介绍了开源目的、目前的进展以...

优快云资讯 4913

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

如何在 Ubuntu 22.04 上安装和配置 VNC 服务器?

VNC(Virtual Network Computing)是一种图形桌面共享系统,通过网络允许用户控制另一台计算机的桌面环境。无论你是系统管理员还是开发人员,VNC 都可以在远程访问桌面环境时提供极大的便利。在安装和配置 VNC 服务器之前,我们需要确保系统是最新的,并安装一些基本工具。这些命令将更新你的软件包列表并升级所有已安装的软件包,以确保你拥有最新的安全修复和功能更新。

网络技术联盟站 4003

如何在Linux中安插一个后门?

Linux内核是开源的代码,能不能向其中安插一个后门呢?这是一件难度很高的操作,但是有人却差点儿成功了,我们来看看这是怎么回事。时间回到2003年,当时Linux内核的代...

码农翻身 1333

QT入门开发一个时钟

本文讲述了时钟开发的具体过程以及代码。 涉及到一下几个知识点: 1. 定时器使用 2. 本地时间获取 3. resource资源读取 4. 图片绘制 5. 图片按照中心旋转 6. sin或者cos角度计算。

啊渊的专栏 5148

华为终于放出方舟编译器源代码!开源平台同步亮相,网友:硬核项目

乾明 边策 发自 凹非寺量子位 报道 | 公众号 QbitAI华为方舟编译器终于正式开源,源代码放出,兑现了在8月开源的承诺。代码不在GitHub,而是在自家开源平台上...

量子位 4875

OpenClaw进阶实战(二十一):工作流6:跨平台舆情监控与自动响应

摘要: 本文介绍基于OpenClaw构建自动化舆情监控系统,实现多平台数据采集、AI情感分析与智能预警。系统架构包含数据采集(微博/小红书/抖音)、消息队列、情感分析(SnowNLP/大模型API)、分级预警和自动响应模块。通过技能化开发(如微博API采集、小红书模拟登录)实现7×24小时监控,结合情感强度与传播速度分级处理负面舆情,形成"采集-分析-预警-处置"闭环,适用于企业私有化部署。

PeterPan的博客 299

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

黑客在数十个 WordPress 插件和主题中插入秘密后门,可发动供应链攻击

聚焦源代码安全,网罗国内外最新资讯!编译:代码卫士专栏·供应链安全数字化时代,软件无处不在。软件如同社会中的“虚拟人”,已经成为支撑社会正常运转的最基本元素之一,软件的安全性问题也正在成...

smellycat000的专栏 994

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

VOLT开源GPU编译器架构与SIMT分歧管理技术解析

GPU编译器是连接高级编程语言与底层硬件架构的核心工具,其设计直接影响异构计算的性能表现。在SIMT(单指令多线程)执行模型下,控制流分歧管理成为关键挑战,涉及线程同步、寄存器分配和执行效率优化等技术难点。开源VOLT编译器通过三层架构设计(前端语言适配、LLVM中间层优化、RISC-V后端生成),创新性地解决了这些难题。该框架采用统一性分析、控制流重构和分歧指令插入等核心技术,显著提升了开源GPU的编译效率。特别是在Vortex架构上,VOLT实现了对OpenCL和CUDA的跨语言支持,为AI加速、科学计

闲谈 714

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

VOLT开源GPU编译器框架解析与SIMT优化实践

GPU编译器作为连接软件与硬件的核心组件,其设计直接影响计算性能。在SIMT(单指令多线程)架构下,编译器需要处理线程分歧、控制流重汇聚等独特挑战。开源GPU生态的崛起使得对透明化编译工具链的需求日益迫切,VOLT框架应运而生。该框架通过LLVM中间表示层实现跨平台优化,支持从OpenCL/CUDA到RISC-V指令集的高效转换,特别针对wavefront调度、内存访问合并等GPU关键性能瓶颈提供解决方案。在AI加速、图形渲染等高性能计算场景中,此类开源工具链显著降低了异构编程门槛,为研究者提供了可定制的编

weixin_33725515的博客 1120

推荐开源项目:LLVM 深度优化编译器框架

推荐开源项目:LLVM 深度优化编译器框架 1. 项目介绍 LLVM 是一个强大的开源编译器基础设施工具包,用于构建高性能的编译器、优化器和运行时环境。它不仅提供了底层虚拟机(Low Level Virtual Machine)的基础,还包含了对代码进行深度优化的各种工具。这个项目旨在帮助开发者创建更高效、更难逆向工程的软件,同时保持良好的可移植性。 2. 项目技术分析 LLVM 的核心是其模块...

gitblog_00074的博客 515

探索QTableView的无限可能:插入按钮及其他控件的完美解决方案

探索QTableView的无限可能:插入按钮及其他控件的完美解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在现代软件开发中,用户界面的交互性和功能性是至关重要的。QTableView作为Qt框架中的一个核心组件,广泛应用于数据展示和用户交互场景。然而,如何在QTableView中灵活地插入各种控件,如按钮、复选框、日期选择器等,一直是开发者面临的挑战。为了解...

gitblog_09776的博客 532
上一篇: iOS 如何设置子视图alpha不同于父视图
下一篇: 如何制造一个XcodeGhost ?
Man_OC
博客等级 码龄12年 0粉丝 0原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值