记一道有趣的“签到”题
最近看完三体三部曲心潮澎湃,感叹于宇宙的浩瀚,感慨于自己的渺小。大刘的世界,涵盖了从奇点到宇宙边际的所有尺度,跨越了从白垩纪到亿万光年的漫长时光。越往后翻,我甚至变得小心翼翼,只为了能在三体的世界多待一会儿。
而最终当我终于翻过最后一页时,心跳很急促,可能是智子的干扰让我并不能确定到底过了多少时间,客观时间大约流逝了不到十秒钟,主观时间长得像一生。这时我看到世界在眼前分成了四份,一份是周围的现实世界,另外三份是变形的映像。映像来自我眼前突然出现的三个球体,它们都有着全反射的镜面,我不知道这是智子的几维展开,那三个球体都很大,在我的前方遮住了半个天空,挡住了正在亮起来的东方天际,在球体映出的西方天空中我看到了几颗残星,球体下方映着变形的屏幕和自己。我很想知道的是为什么是三个,我首先想到的是三体世界的象征,就像叶文洁在最后一次ETO的聚会上看到的那个艺术品;但看到球体上所映照的虽然变形但异常清晰的现实图像时,我又感觉那是三个平行世界的入口,暗示着三种可能的选择;接下来看到的又否定了我的这种想法,因为三个球体上都出现了相同的字:
起床打CTF!
好了言归正传,最近在ctfshow平台刷题时,遇到了一道比较有意思的题目,跟大家分享一下。
题目的名字叫luckybase
题目逻辑很简单,就是用户的输入经过utf-8编码再经base64编码后,如果与一个随机数相减的绝对值小于0.0000000001就显示flag,其实就是基本等于这个随机数了。
那么问题来了,base64编码后的数据怎么eval后成为数字的形式又恰好“无限接近”这个随机数呢?
题目名字luckybase也是想让我们找到那个“幸运的”base64编码数据。
所以解决这个问题的关键在于理解base64编码的原理。
我们知道,base64编码基于64个可打印字符来表示二进制数据,也就是:
ABCDEFGHIJKLMNOPQRSVWXYZabcdeghiklmnopqrstuvxyz0123456789+/
而且对于解决本题来讲,需要知道base64编码是”3个字节变为4个字节“的过程
因此如果想要通过base64编码生成这样一个带有小数的数字,需要用到+和/来实现
通过hint我们知道0.1是如何产生的了
而且通过爆破的方式,我们也能得到三个字符经base64编码变成e00+、e01+、e04+、e05+等等这种科学计数法方式表示的形式,再加上hint中的0.1/,我们就可以得到我们想要的任何小数了(只需再乘以相应的倍数就可以)
以刚才的33.93139511573606为例。
payload = "0.1/e00+"*339
payload += "0.1/e01+"*3
payload += "0.1/e04+"*139
payload += "0.1/e05+"*5
payload += "0.1/e08+"*115
payload += "0.1/e09+"*7
payload += "0.1/e10+"*3
payload += "0.1/e11+"*6
payload += "0.1/e14+"*06
payload += "0.1/e013"(起补足作用,防止异常)
当然,也可以写个自动生成脚本完成。
以下是脚本自动完成效果。