記一道有趣的“簽到”題

最近看完三體三部曲心潮澎湃,感嘆于宇宙的浩瀚,感慨于自己的渺小。大劉的世界,涵蓋了從奇點到宇宙邊際的所有尺度,跨越了從白堊紀到億萬光年的漫長時光。越往后翻,我甚至變得小心翼翼,只為了能在三體的世界多待一會兒。
而最終當我終于翻過最后一頁時,心跳很急促,可能是智子的干擾讓我并不能確定到底過了多少時間,客觀時間大約流逝了不到十秒鐘,主觀時間長得像一生。這時我看到世界在眼前分成了四份,一份是周圍的現(xiàn)實世界,另外三份是變形的映像。映像來自我眼前突然出現(xiàn)的三個球體,它們都有著全反射的鏡面,我不知道這是智子的幾維展開,那三個球體都很大,在我的前方遮住了半個天空,擋住了正在亮起來的東方天際,在球體映出的西方天空中我看到了幾顆殘星,球體下方映著變形的屏幕和自己。我很想知道的是為什么是三個,我首先想到的是三體世界的象征,就像葉文潔在最后一次ETO的聚會上看到的那個藝術(shù)品;但看到球體上所映照的雖然變形但異常清晰的現(xiàn)實圖像時,我又感覺那是三個平行世界的入口,暗示著三種可能的選擇;接下來看到的又否定了我的這種想法,因為三個球體上都出現(xiàn)了相同的字:
起床打CTF!


好了言歸正傳,最近在ctfshow平臺刷題時,遇到了一道比較有意思的題目,跟大家分享一下。
題目的名字叫l(wèi)uckybase


題目邏輯很簡單,就是用戶的輸入經(jīng)過utf-8編碼再經(jīng)base64編碼后,如果與一個隨機數(shù)相減的絕對值小于0.0000000001就顯示flag,其實就是基本等于這個隨機數(shù)了。
那么問題來了,base64編碼后的數(shù)據(jù)怎么eval后成為數(shù)字的形式又恰好“無限接近”這個隨機數(shù)呢?
題目名字luckybase也是想讓我們找到那個“幸運的”base64編碼數(shù)據(jù)。
所以解決這個問題的關(guān)鍵在于理解base64編碼的原理。
我們知道,base64編碼基于64個可打印字符來表示二進制數(shù)據(jù),也就是:

ABCDEFGHIJKLMNOPQRSVWXYZabcdeghiklmnopqrstuvxyz0123456789+/

而且對于解決本題來講,需要知道base64編碼是”3個字節(jié)變?yōu)?個字節(jié)“的過程
因此如果想要通過base64編碼生成這樣一個帶有小數(shù)的數(shù)字,需要用到+和/來實現(xiàn)

通過hint我們知道0.1是如何產(chǎn)生的了


而且通過爆破的方式,我們也能得到三個字符經(jīng)base64編碼變成e00+、e01+、e04+、e05+等等這種科學計數(shù)法方式表示的形式,再加上hint中的0.1/,我們就可以得到我們想要的任何小數(shù)了(只需再乘以相應的倍數(shù)就可以)


以剛才的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"(起補足作用,防止異常)
當然,也可以寫個自動生成腳本完成。
以下是腳本自動完成效果。

