这道题的ssh密码是上一道题的flag,mommy now I get what PATH environment is for :) ,我这里给出一下,省的还得再去找。
看一下源码
#include <stdio.h>
#include <string.h>
int filter(char* cmd){
int r=0;
r += strstr(cmd, "=")!=0;
r += strstr(cmd, "PATH")!=0;
r += strstr(cmd, "export")!=0;
r += strstr(cmd, "/")!=0;
r += strstr(cmd, "`")!=0;
r += strstr(cmd, "flag")!=0;
return r;
}
extern char** environ;
void delete_env(){
char** p;
for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
}
int main(int argc, char* argv[], char** envp){
delete_env();
putenv("PATH=/no_command_execution_until_you_become_a_hacker");
if(filter(argv[1])) return 0;
printf("%s\n", argv[1]);
system( argv[1] );
return 0;
}
这个题和之前的cmd1那道题很像,也是将环境变量给更改了,然后将你传进去的参数当成命令执行,不过这次好像过滤更加严格了,参数中不能包含"="、 “PATH”、 “export”、 “/” 、 “`” 、 “flag”。
没有PATH变量,所以我们的命令必须绝对路径,而filter函数过滤了“/”,所以需要想办法绕过他。
我们尝试用echo去绕过‘/’,下图是echo函数的说明,加上“-e” 能够启用反斜杠转义的解释作用。

再查看ascii码,“/”的ascii码用16进制表示是2F

我们利用echo -e "\X2f"输出”/“

但是利用cmd2的程序测试,发现并没有得到想要的效果

源码中利用的是system()函数执行你传入的命令,我们看一下system函数的说明

system()会调用fork()产生子进程,由子进程来调用/bin/sh -c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。
我们利用man sh查看一下,然后利用/echo搜索关于echo的说明,如果以\0digits的形式,则输出值由0到3位八进制数字给出的字符。从上面ascii码上可以看到”/“的八进制为057。

可以看到得到了想要的结果,"/"。

然后继续尝试

反馈结果的第一行是传进去的参数,第二行是通过system执行参数命令返回的结果。第二个为什么会出现传进去的是\057bin\057cat cmd2.c?
在bash中,$( )与` `(反引号)都是用来作命令替换的。所以$()里面的命令先得到了执行,输出\057bin\057cat,这里没有转换为"/"的原因是,此处执行的是程序库中的函数echo,而不是sh中的echo,二者是有差别的,前面已经有关于两个函数说明的截图了。
在$()前面加个转义符号"\",表示输入的是一个字符串,然后再让system执行这个字符串。
测试成功后,就可以去解题了,创建一个目录,创建一个软连接,执行刚才测试好的结果。

本文介绍如何在特定的SSH环境中,通过巧妙利用echo命令的转义特性及system函数,绕过严格的参数过滤,实现对命令的精确执行。在无PATH变量的情况下,采用特殊字符编码方式绕过‘/’的过滤,最终成功执行目标命令。
587

被折叠的 条评论
为什么被折叠?



