2023 | WolvCTF | Crypto
TealyMan
题目¶
Use the TestNet. Submit by sending enough testnet algos to cover the current transaction fee to the CTF_Address.
CTF_Address | OH4YZ4QXWOWLHIUKPQAOMPBZBELCANRPRX3NI7SQFL2OFASHLBW5DTLDZQ |
AppID | 163726037 |
解题思路¶
- 看地址首先排除 Ethereum uwu 根据
TestNet
和algos
锁定 Algorand 生态 owo - OH4YZ4QXWOWLHIUKPQAOMPBZBELCANRPRX3NI7SQFL2OFASHLBW5DTLDZQ 为普通账户,163726037 对应需要交互的智能合约账户
- Algorand 智能合约包含两部分,
ApprovalProgram
和ClearStateProgram
。ApprovalProgram
负责处理主应用逻辑,ClearStateProgram
负责将对应智能合约从账户记录中移除,执行成功返回 \(1\)
the flag will be sent to u once ur done with the app and provide the address enough to cover current transaction fees
- 目标是与应用进行完整交互。与合约交互的方法包括 Opt-in、Call(NoOp)、Read state、Update、Close out、Delete 以及 Clear state
- 在开始与使用本地状态的应用交互前,账户需要 Opt in
-
分析
ApprovalProgram
,根据OnCompletion
的类型执行相关操作,重点关注OnCompletion == 0
,即 NoOp。目标应用支持setup
和buy
- 首先通过
setup
向应用注册 asset,并向应用转移一部分 asset 以便后续购买操作 - 再进行
buy
,需要发送一个交易组,其中第一个交易为 Payment(向应用支付购买 asset 的 algo),第二个是 Application Call
Approval Program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
#pragma version 5 intcblock 1 0 4 9223372036854775808 // prepare block of uint64 constants for use by intc bytecblock 0x7374617274 0x656e64 0x61646d696e5f6b6579 0x6e66745f6964 // prepare block of byte-array constants for use by bytec // Deploy or Call? txn ApplicationID intc_1 // 0 == bnz label1 txn OnCompletion intc_1 // 0, NoOp, only execute the ApprovalProgram associated with this application ID, with no additional effects. == bnz label2 txn OnCompletion intc_0 // 1, OptIn, before executing the ApprovalProgram, allocate local state for this application into the sender's account data == bnz label3 txn OnCompletion pushint 2 // CloseOut, after executing the ApprovalProgram, clear any local state for this application out of the sender's account data. == bnz label4 txn OnCompletion pushint 5 // DeleteApplication == bnz label5 txn OnCompletion intc_2 // 4, UpdateApplication == bnz label6 err label6: intc_1 // 0 return label5: txn Sender global CreatorAddress == assert bytec_2 // "admin_key" app_global_get callsub label7 intc_0 // 1 return label4: intc_0 // 1 return label3: intc_0 // 1 return label2: txna ApplicationArgs 0 // 0-th value of the ApplicationArgs array of the current transaction pushbytes 0x7365747570 // "setup" == bnz label8 txna ApplicationArgs 0 pushbytes 0x627579 // "buy" == bnz label9 err label9: global CurrentApplicationAddress // Address that the current application controls txna Assets 0 // Foreign Assets listed in the ApplicationCall transaction asset_holding_get AssetBalance store 1 // store is_opted_in to the 1-th scratch space store 0 // store asset balance to the 0-th scratch space load 1 // load is_opted_in from the 1-th scratch space intc_1 // 0 load 0 callsub label10 && // if is_opted_in and asset balance > 0 txn Sender bytec_0 // "start" app_local_get global LatestTimestamp callsub label10 && global LatestTimestamp txn Sender bytec_1 // "end" app_local_get callsub label10 && txn GroupIndex // index=1 intc_0 // 1 - // GroupIndex - 1 gtxns TypeEnum // field F of the (GroupIndex - 1)-th transaction in the current group intc_0 // 1 == && txn GroupIndex // index=1 intc_0 // 1 - gtxns Sender txn Sender == && txn GroupIndex // index=1 intc_0 // 1 - gtxns Receiver global CurrentApplicationAddress == && global MinTxnFee txn GroupIndex // index=1 intc_0 // 1 - gtxns Amount callsub label10 && assert txna ApplicationArgs 1 btoi global LatestTimestamp + txn Sender bytec_0 // "start" app_local_get callsub label10 bnz label11 intc_1 // 0 return label11: txn Sender bytec_3 // "nft_id" app_local_get txn Sender callsub label12 intc_0 // 1 return label8: itxn_begin // begin preparation of a new inner transaction in a new transaction group intc_2 // 4 itxn_field TypeEnum // set field of the current inner transaction to AssetTransfer txna Assets 0 itxn_field XferAsset global CurrentApplicationAddress itxn_field AssetReceiver itxn_submit // execute the current inner transaction group txn Sender bytec_3 // "nft_id" txna Assets 0 app_local_put // store the nft_id in the sender's local state txn Sender pushbytes 0x73656c6c6572 // "seller" txn Sender app_local_put // store the seller address in the sender's local state txn Sender bytec_0 // "start" global LatestTimestamp app_local_put txn Sender bytec_1 // "end" txna ApplicationArgs 1 btoi app_local_put txn Sender bytec_0 // "start" app_local_get txn Sender bytec_1 // "end" app_local_get < assert // require start < end intc_0 // 1, approval return label1: bytec_2 // "admin_key" txn Sender app_global_put intc_0 // 1 return label12: store 3 store 2 global CurrentApplicationAddress load 2 asset_holding_get AssetBalance store 5 store 4 load 5 bz label13 itxn_begin intc_2 // 4 itxn_field TypeEnum load 2 itxn_field XferAsset load 3 itxn_field AssetCloseTo itxn_submit label13: retsub label7: store 6 global CurrentApplicationAddress balance intc_1 // 0 != bz label14 itxn_begin intc_0 // 1 itxn_field TypeEnum load 6 itxn_field CloseRemainderTo itxn_submit label14: retsub label10: store 8 store 7 intc_3 // 9223372036854775808 load 7 & bnz label15 intc_3 // 9223372036854775808, 0x8000000000000000 load 8 & bnz label16 load 7 load 8 < bnz label17 intc_1 // 0 retsub label17: intc_0 // 1 retsub label16: intc_1 // 0 retsub label15: intc_3 // 9223372036854775808 load 8 & bnz label18 intc_0 // 1 retsub label18: load 7 load 8 > bnz label19 intc_1 // 0 retsub label19: intc_0 // 1 retsub
- 首先通过
-
CTF_Address 会向完成交易的账户发起 Transfer 交易,其中包含使用 AlgoSMS 加密的 Flag
Exploit¶
Flag¶
wctf{1_h0p3_y0u_d0nt_4cc1dent4lly_4get_t0_r3m0ve_th3_4pp}
参考资料¶
- Interact with smart contracts - Algorand Developer Portal
- Opcodes - Algorand Developer Portal
- PureStake Developer Portal
- algosms - npm
最后更新:
2023年3月21日 20:33:27
Contributors: