给开源编译器插入后门

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

usb gadget uvc driver的code分析

uvc的linux driver分为host侧和gadget侧两个driver。host侧的driver在v4l2框架下,而设备侧的driver在usb/gadget文件夹下。gadget侧的uvc driver,利用v4l2框架去注册video_device,向应用层提供调用接口。同时,它完成v4l2 video buffer拷贝到usb request下的buffer下,然后利用uvc实现的协

lintwins的专栏 1万+

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

Cesium中GLB模型加载

Cesium中GLB模型加载全解析:Primitive与Entities方法详解

m0_72030584的博客 3472

Android开发者必看:5分钟搞定MQTT客户端连接EMQX服务器(附完整代码)

本文为Android开发者提供了一份快速实现MQTT客户端连接EMQX服务器的实战指南。通过引入Eclipse Paho SDK,详细讲解了从项目配置、权限申请到核心连接、主题订阅与消息发布的完整流程,并附有即拿即用的Kotlin代码,帮助开发者在物联网应用中高效集成轻量级实时通信功能。

weixin_29228781的博客 271

PAM后门从入门到应急响应

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

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

【ESP32接入国产大模型之豆包】

🥳🥳🥳现在,我们在本教程中,您学习了如何使用ESP32接入语言大模型之豆包。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境,后期会持续分享esp32跑freertos实用案列🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣如果你有任何问题,可以通过q group(945348278)加入鹏鹏小分队,期待与你思维的碰撞😘😘😘。

vor234的博客 1万+

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

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

优快云资讯 4913

(11)(2.2.2) BLHeli32,AM32, and BLHeli_S ESCs(一)

Ardupilot官网关于《Peripheral Hardware》的翻译 —《(2.2.2) BLHeli32,AM32, and BLHeli_S ESCs》。

无人机开发(开源Ardupilot) 2232

【Qt】解决 FTH: (11284): *** Fault tolerant heap shim applied to current process. (亲测有效)

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers。容错堆垫片应用到当前的过程。这通常是由于以前的崩溃。win + r,输入regedit。

Fanjufei的博客 830

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

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

码农翻身 1333

Android Input——输入事件ANR执行(十六)

上一篇文章我们介绍了输入事件 ANR 的触发流程,这里我们再来看一下输入事件 ANR的执行流程。

小旭的专栏 944

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

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

量子位 4875

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

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

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

smellycat000的专栏 994

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

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

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

闲谈 714

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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、付费专栏及课程。

余额充值