mini blockchain
題目 :
某銀行利用區塊鏈技術,發明了DiDiCoins記賬系統。某寶石商店采用了這一方式來完成鉆石的銷售與清算過程。不幸的是,該銀行被黑客入侵,私鑰被竊取,維持區塊鏈正常運轉的礦機也全部宕機。現在,你能追回所有DDCoins,并且從商店購買2顆鉆石么? 注意事項:區塊鏈是存在cookie里的,可能會因為區塊鏈太長,瀏覽器不接受服務器返回的set-cookie字段而導致區塊鏈無法更新,因此強烈推薦寫腳本發請求 題目入口:
http://116.85.48.107:5000/b942f830cf97e
解答 :
拿到題目,內心是拒絕的。因為雖然說區塊鏈這么火,但是自己還是沒怎么了解過。
第一反應是。藥丸,沒戲了。但是,搞信息安全的孩子怎么可以輕言放棄呢!
時間辣么長,還不信看不明白個區塊鏈。最后肛了兩天多,才大概明白了題目
首先,題目給了源碼,這個很棒棒。
建議大家分析題目時將代碼也多讀幾遍,然后再結合參考資料進行理解。
在這里不做太多的理解源碼的講解。
最初我是將重心代碼的一些邏輯上,以及加密是否可逆。(發現自己太年輕,看不懂)
然后慢慢的開始了解區塊鏈,最后發現這種手段。
這道題目中,利用了區塊鏈一個很神奇的東西。
因為區塊鏈是一個鏈表,而且還是一個誰都可以增加的,此時,人們達成了一種默認,以最長的那條鏈為主鏈(正版),其他的分支都是盜版。
如下圖,就是此時該題目的區塊鏈。

那么我們可以再構造一條鏈,只要比主鏈長,那這條鏈就是我們說了算。
此時雖然說區塊鏈1是正規的鏈,但是區塊鏈2要比1長,此時區塊鏈2即為正規鏈。
但是,說的輕巧,我們該如何構造呢?
首先,我們分析路由可以發現,題目預留了一個創建交易的接口。此時可以生成新塊。
只要我們可以挖到一個DDcoin,就可以創建一次新塊,然后會判斷商店的余額。最終給予磚石獎勵。
然而DDcoin是什么呢。
在這道題里,其實就是這個東西,這就是一個區塊。對他進行分析一下。

nonce:自定義字符串prev:上一個區塊的地址hash:這個區塊的hashheight:當前處于第幾個節點transactions:交易信息
再分析transactions
input與signature好像是一個憑證,驗證這個區塊主人身份。
output,收款人信息
amount,收款數額
addr,收款地址
hash這里的話,不是太明白。
但是看代碼。發現都有現成的可以生成。只要利用這三個函數,即可創建一個新的區塊。
create_output_utxo(addr_to, amount) // 新建一個output信息create_tx(input_utxo_ids, output_utxo, privkey_from=None) // 新建一個transactions信息create_block(prev_block_hash, nonce_str, transactions) // 新建一個區塊
首先新建output,此時參數很簡單,收貨人地址(商店),數量(全款)
然后創建tx,此時output_utxo就是剛剛咱創建好的那個。然而問題來了,私鑰和id咱是沒有的。此時分析代碼可以發現,這一步做的主要就是創建一個sig簽名。還有就是生成一個hash

此時,邪惡的想到,既然是要創建第二條鏈,那么可不可以借用一下第一條鏈的第一塊的信息。
也就是直接忽略掉sig的生成,偽造tx,直接重寫一下create_tx

然后此時tx也有了,進行下一步create_block
此時他的三個參數也好寫,上一個區塊的hash,自定義字符串,剛剛做好的tx
此時,我們要通過爆破nonce的方式,來使create_block生成的塊的hash為00000開頭,
這樣,我們才能添加。
然后向那個添加塊的地址post由create_block即可成功添加第一個塊。
記得改請求頭中的content-type為json。還有就是cookie自己手動更新
第二個塊的時候,問題又來了。
這條鏈中,我們之前的tx已經使用過一次,無法使用了。怎么辦?
此時可以注意到題目中init中給的hint。

憑啥他可以不寫tx就生成塊!不開心,你都能那樣,我也要!
于是。。。。。通過這個方式,在后面添加幾個空區塊就好。
成功偽造主鏈!獲取一顆磚石。
再次重復以上做法,完成第三條鏈即可獲取到flag
切記,手動更新cookie……
2018DDCTF-Writeup