奇奇怪怪的编程语言:Malbolge

Malbolge

除了我们日常使用的Python、Java、C等主流编程语言外,还存在这么一类极为晦涩难懂的编程语言,被称为深奥的编程语言Esoteric programming language,简称Esolang)。它们被设计用于测试计算机语言表达的极限,所以不会考虑它们的实用性。今天我们来看其中一个非常典型的例子:Malbolge。

Malbolge由Ben Olmstead 在1998年发明,其名字来自于但丁的《神曲》中的第八层地狱“Malebolge”,意大利语中意为“邪恶的沟渠”(male bolge)。

1610007501597.jpg

Hello World

下面这段Malbolge代码会输出“Hello, World.”

(=<`#9]~6ZY327Uv4-QsqpMn&+Ij"'E%e{Ab~w=_:]Kw%o44Uqp0/Q?xNvL:`H%c#DD2^WV>gY;dts76qKJImZkj

而这段代码则会输出“Hello, World!”

('&%:9]!~}|z2Vxwv-,POqponl$Hjihf|B@@>,=<M:9&7Y#VV2TSn.Oe*c;(I&%$#"mCBA?zxxv*Pb8`qo42mZF.{Iy*@dD'<;_?!\}}|z2VxSSQ

我们可以看到,光是一个标点符号的改变,就导致代码发生了天翻地覆的变化。

CTF

大多数涉及 Malbolge 的基础 CTF 题目会提供一段看似乱码的内容。此时,需要识别出这实际上是 Malbolge 代码,并通过编译器将其编译出来。

比如说这段代码会输出“flag{this_is_a_flag}”

D'`;qLo=I;|XyhCwStcr=NL-,I$)"XW21A/c>,v_)\xqYonsrqj0hPlkdcb(`Hd]#a`_A@VzZY;QuUTSRQJImGLEJIBAeED&B;_9>7<;:921U54ts10)M'&Jkj"F&%|#z@~}vu;y[Zvo5Vlkjongf,Miha'Hd]\[ZY}W?UZYRQuU7SLp]

2024-12-10-23-00-32.png
有些题目可能需要对编译后的结果再进行一次处理,比如使用 base64 解码等。
但是这些内容都不需要了解任何 Malbolge 语言的特性,只需要找到一个编译器即可。因此,接下来我会介绍一些 Malbolge 的特点,并分享一道较难的 CTF 比赛真题。

Malbolge的特点

首先,Malbolge会使用 三个寄存器(register),分别是 acd
a:Accumulator,主要用于存储计算结果和输入/输出数据。
c:Code Pointer / Instruction Pointer,用于指向当前正在执行的代码的位置(即指令指针)。
d:Data Pointer,用于指向内存中的数据位置。

其次,基于这些寄存器,Malbolge提供了八条指令,分别为:jmpoutinrotrmovcrznopend。我们可以利用某些在线编译网站提供的规范化(Normalization)功能,将代码转换为由一组固定字符组成的指令字符集,从而更方便地进行调试(debug)。

更多详细信息可以参考
https://en.wikipedia.org/wiki/Malbolge

例题

题目来源:Platypwn 2024 CTF
链接:https://platypwn.ctf.platypwnies.de/
题面:
2024-12-08-13-44-48.png
下载下来的文件内容为:

D'`__LK!mY:jiy6Be3cPa)onKI[#j4&DUBzcx>_;):'Zputml21onPlkd*hJIedcb[!YXW{[TYXWVUNrRQPImGFEDIBfFED=<;:?8\<;432V65ut,P*/('&J*j(!~}C#cy~}v<tsxwvon4Ukji/Plejc)gIedcb[!_^]\U=SwWVONMqQPONMFjJIHGF(>b<$:?876ZG

这段内容看似是乱码,但根据题面的提示“the worst of esoteric programming languages” (正如前文所提到的),我们可以判断出它实际上是一段Malbolge的代码。
直接编译这段代码无法得到任何结果,因此我们可以选择使用某个在线编译工具对其进行规范化处理,使代码转换为更标准的指令字符集,从而便于调试(debug):
2024-12-11-00-19-26.png

2024-12-11-00-19-36.png

normalized 之后的结果为:

ojii<vvj/io//jov/o/</p**<i/pjvo</<pjp<*iv<v*poopp<<oo*oop<o**oooop<ppp<opooooop<ooop<ppppop<oooppppop<ooppp<oo**p<poppp<o*oppp<o*poop<ppooopp<*ppp<*opop<o*oooop<oooop*p<ooppp<ooooop<ooooo*p<p*poppp<v

当我们运行这段代码时,会发现它在执行到中间某处时意外停止了:

2024-12-11-00-20-30.png

大概是在这个位置:
2024-12-11-00-19-36.png
所以我们猜测(尝试)需要将这一项改成其他的命令。
而在将其改正为p了之后会得到:
2024-12-11-00-28-18.png

订正后的内容

ojii<vvj/io//jov/o/</p**<i/pjvo</<pjp<*iv<p*poopp<<oo*oop<o**oooop<ppp<opooooop<ooop<ppppop<oooppppop<ooppp<oo**p<poppp<o*oppp<o*poop<ppooopp<*ppp<*opop<o*oooop<oooop*p<ooppp<ooooop<ooooo*p<p*poppp<v
D'`__LK!mY:jiy6Be3cPa)onKI[#j4&DUBzcx>_;):'Zputml21onPlkd*hJIedcb[!YXW{[TYXWVUNrRQPImGFEDIBfFED=<;:?8\<;432V65ut,P*/('&J*j(!~}C#cy~}v<tsxwvon4Ukji/Plejc)gIedcb[!_^]\U=SwWVONMqQPONMFjJIHGF(>b<$:?876ZG

具体改动:
2024-12-10-13-49-22.png
这样一来我们就成功获取到了flag。

其他办法

1. 暴力破解

当然,如果我们知道(或猜测)这段代码中只有一个地方存在问题,可以尝试使用暴力破解(brute force)的方法进行修正。这种方法的核心是将每条指令逐一修改为其他可能的指令,并观察编译结果。由于不需要理解 Malbolge 的具体特性,因此这种方法非常简单。

为实现这一目标,我们可以利用支持在线编译 Malbolge 的网站,以及 Python 中的 Selenium 库。Selenium 提供了浏览器自动化操作功能,能够帮助我们完成网页上的勾选、输入操作,并提取输出内容,从而实现自动化调试。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time# 初始化浏览器(确保你有对应的浏览器驱动)
# driver = webdriver.Chrome()  # Chrome
driver = webdriver.Firefox()  # Firefox
try:# 打开目标网页driver.get("https://lutter.cc/malbolge/debugger.html")# 等待页面加载wait = WebDriverWait(driver, 30)# 勾选所有复选框checkboxes_ids = ['until_in', 'until_out', 'until_crz', 'until_rotr', 'until_jmp', 'until_mov', 'until_nop']for checkbox_id in checkboxes_ids:checkbox = wait.until(EC.element_to_be_clickable((By.ID, checkbox_id)))if not checkbox.is_selected():checkbox.click()# 勾选Normalizednormalized_checkbox = wait.until(EC.element_to_be_clickable((By.ID, 'normalizedcode')))if not normalized_checkbox.is_selected():normalized_checkbox.click()# 原始Malbolge代码original_code = "ojii<vvj/io//jov/o/</p**<i/pjvo</<pjp<*iv<v*poopp<<oo*oop<o**oooop<ppp<opooooop<ooop<ppppop<oooppppop<ooppp<oo**p<poppp<o*oppp<o*poop<ppooopp<*ppp<*opop<o*oooop<oooop*p<ooppp<ooooop<ooooo*p<p*poppp<v"# 替换的字符列表replace_chars = ['i', 'j', 'o', 'p', '/', '*']# 标志变量,用于退出循环found_flag = False# 循环替换并执行代码for i in range(1, len(original_code)):if found_flag:  # 如果找到结果,退出外层循环breakfor char in replace_chars:modified_code = list(original_code)modified_code[i] = char  # 替换第i个字符modified_code = ''.join(modified_code)# 输入修改后的Malbolge代码program_textarea = driver.find_element(By.ID, "program")program_textarea.clear()program_textarea.send_keys(modified_code)# 点击Load/Reset按钮load_button = driver.find_element(By.ID, "load")load_button.click()# 点击Execute按钮execute_button = wait.until(EC.element_to_be_clickable((By.ID, "run")))execute_button.click()# 等待执行完成并获取Output内容time.sleep(1)  # 根据需要调整等待时间output_div = driver.find_element(By.ID, "output")output_content = output_div.text# 仅当output内容包含"flag"时打印结果if "pp{" in output_content.lower():print(f"将第 {i + 1} 位修改成 '{char}' 后成功编译出flag。")print(f"编译成功的代码: {modified_code}")found_flag = True  # 设置标志变量,标记已找到结果break  # 退出内层循环finally:# 关闭浏览器driver.quit()# 运行成功后会得到:
"""将第 43 位修改成 'p' 后成功编译出flag。
编译成功的代码: ojii<vvj/io//jov/o/</p**<i/pjvo</<pjp<*iv<p*poopp<<oo*oop<o**oooop<ppp<opooooop<ooop<ppppop<oooppppop<ooppp<oo**p<poppp<o*oppp<o*poop<ppooopp<*ppp<*opop<o*oooop<oooop*p<ooppp<ooooop<ooooo*p<p*poppp<v
"""

2. 修改解释器源代码

有一位参赛选手分享了一个非常巧妙的解法,具体如下:
首先他找到了一个用 C 语言编写的原始 Malbolge 解释器(https://github.com/bipinu/malbolge)。接着,他将第 131 行的return 改为 break,以避免 exec() 函数提前结束。
最后,他使用修改后的解释器运行题目中提供的 Malbolge 代码,成功得到了 flag。

工具(网站)

最后附上一些网页,可以用来生成,编译,或者debug。

https://lutter.cc/malbolge/debugger.html
2024-12-09-18-26-41.png

https://tio.run/##y03MScrPSU/9/19DXU3VyjJWsa62psoorKK8TFcnwL@wID8vR8UjKzMjrcbJwcFOx9bG18pSzTxSOSzMKCQ4T88/VSvZWsNTTVVFWSnX2cnRvqqiokwrIMkioTDfxCg3yk2v2rNSyyHFRd3GOt5eMaYWYnpwcOD//wA
2024-12-09-18-24-22.png

https://zb3.me/malbolge-tools/#generator
2024-12-09-18-23-33.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/850683.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识付费系统的资源

在当今信息快速迭代的时代,优质的教育资源不仅局限于线下教学,在线平台已成为教育的重要延伸。知识付费在线教育系统的兴起为企业及教师提供了更灵活高效的授课渠道。这些系统凭借自身强大的功能性和灵活性,能够支持不同形式的内容传播与交流互动,并辅以完善的运营支持策略…

一个使用 WPF 开发的管理系统

前言 最近发现有不少小伙伴在学习 WPF,今天大姚给大家分享一个使用 WPF 开发的管理系统,该项目包含了用户登录、人员管理、角色授权、插件管理、职位管理、主页功能(邮件、皮肤、设置)等功能,对于一个 WPF 初学者而言是一个值得参考和学习的项目。 WPF介绍 WPF 是一个强大…

读数据保护:工作负载的可恢复性10恢复方式

恢复方式1. 恢复 1.1. 不同的设计方案所提供的恢复能力不同1.1.1. 你必须先确定自己的恢复需求1.1.1.1. 你必须先知道自己需要什么样的恢复功能1.1.2. 然后才能选用可以满足该需求(也就是可以提供该功能)的方案来设计备份系统2. 镜像恢复 2.1. image backup 2.2. 镜像备份就是…

在线教育系统软件架构

@www.tuzhi.ltd 侵删近年来,在线教育行业发展迅速,尤其是在疫情期间,全球各地学校与机构不得不采用线上教学作为替代方案。在线教育系统的普及不仅是应对突发情况的重要手段,也是提升教育资源配置效率,推动教育现代化进程的关键技术之一。在此背景下,构建高性能且易于管理…

html中在span标签里面可以放那些标签?

在 HTML 中,span 标签被定义为“内联”元素。这意味着它主要用于对文本进行样式化或语义分组,并且它本身不会导致换行。 因此,你可以在 <span> 标签内放置其他内联元素,但不建议放置块级元素。 可以放在 <span> 标签内的元素:短语元素: <em>, <str…

温州在线教育系统官网

@www.tuzhi.ltd 侵删对于想要进军知识付费在线教育行业的从业者而言,了解最新的发展趋势和成功案例尤为重要。尤其是在当今社会,技术进步和人们对于高效教育方式的需求不断提高,如何利用在线教育系统和知识付费模式有效地传递知识成为关键议题。下面将对教育和技术结合带来的…

应用题2

这道题知识点参考树P101页广义表相关知识点; 知识点:什么是广义表,子表取表头G和取表尾G分别是什么操作如何获得广义表的链式存储结构图广义表和子表:所以用广义表表示表G:其中,我们可以知道表头是广义表中的第一个元素,表尾是除了第一个元素以外的其他元素组成的子表 (…

泷羽sec----burp抓取手机端数据包

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击下面…

泷羽sec----burp验证码识别爆破

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!有兴趣的小伙伴可以点击下面…

铜陵 知识付费源码_三分钟完成专属知识付费源码_口碑

近期,铜陵的一家教育科技公司推出了一套全新的一站式知识付费源码方案,使教师、培训机构和知识创作者在短时间内搭建起一个属于他们自己专业的在线教育网站。这个解决方案仅需花费三分钟左右,用户就能快速上线具有个性化功能的平台,从而实现内容收费的目的。值得一提的是,…

应用题1

这道题知识点参考书97页-100页稀疏矩阵的相关知识。 知识点:什么是稀疏矩阵,三元组线性表和十字链表。 什么是转置(运算)。如果一个矩阵中绝大多数元素数值为0,我们称其为稀疏矩阵 一般稀疏矩阵有两种表示方法,三元组线性表和十字链表三元组线性表: 我们先来讲讲三元组线…

API初探

一、API 侦察 要开始 API 测试,您首先需要尽可能多地了解有关 API 的信息,以发现其攻击面。 首先,您应该确定 API 端点。这些是 API 接收有关其服务器上特定资源的请求的位置。例如,请考虑以下请求:GET GET /api/books HTTP/1.1 Host: example.com 此请求的 API 端点是 。…