如何将 execlp 更改为 execv 和 运行 其他命令然后只是 'ls'
How change execlp to execv and run other commands then just 'ls'
目前我运行正在使用一个 HTML 网络服务器,它可以 运行 通过文本框和提交按钮向其发送命令,但我需要将 execlp
到 execv
,我不理解 execv
的数组部分。我试着让它成为 execv(command, command);
但它给了我一个不兼容的指针类型问题的传递参数。同样出于某种原因,我的执行只会 运行 一个单词命令,如 ls
并且不会接受任何标志,我不太确定为什么会这样。下面的代码执行和解析部分,如果需要可以提供完整代码。
Exection.c
char *parse(char *command){
char * newCommand = (char *) malloc(sizeof(char)*50);
int tgt = 0;
newCommand = strstr(command, "/run?command=");
newCommand = strtok(newCommand, " ");
newCommand = newCommand + 13;
for(int src = 0; src< strlen(newCommand); src++){
if(newCommand[src] == '+')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '%')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '7')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == 'C')
{
newCommand[src] = '|';
}
}
return newCommand;
}
char * execution(char *command){
int piper[2];
size_t len = 0;
pipe(piper);
char* output = malloc(1000 * sizeof(char));
memset(output, '[=12=]', 1000* sizeof(char));
pid_t pid = fork();
if(pid != 0)// parent
{
wait(NULL);
close(piper[1]);
int n = sizeof(output);
struct pollfd * poll_fd = malloc(sizeof(struct pollfd));
poll_fd->fd = piper[0];
poll_fd->events = POLLIN;
if(poll(poll_fd, 1, 0) == 1){ // pipe data check
read(piper[0], output, 1000);
}
}
else{
close(1);
dup(piper[1]);
execlp(command, command, NULL);
exit(1);
}
return output;
}
int main (void){
int sockfd;
int new_fd;
struct addrinfo hints;
struct addrinfo *serverinfo;
struct addrinfo *p;
struct sockaddr_storage client_addr;
socklen_t addrsize;
struct sigaction sa;
int yes = 1;
char s[INET6_ADDRSTRLEN];
int status;
memset(&hints, 0, sizeof hints); //makes struct empty
hints.ai_family = AF_UNSPEC; //IPv4 or v6
hints.ai_socktype = SOCK_STREAM; //TCP type need
hints.ai_flags = AI_PASSIVE; //Fill in IP for us
//if can't get address info print error
if((status = getaddrinfo(NULL, PORT, &hints, &serverinfo)) != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 1;
}
for(p = serverinfo; p != NULL; p = p->ai_next){
if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
perror("server: socket");
continue;
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
perror("setsockopt");
exit(1);
}
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(serverinfo);
if(p == NULL){
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1){
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections....\n");
while(1){
addrsize = sizeof client_addr;
new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addrsize);
if(new_fd == -1){
perror("Did not accept");
continue;
}
inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
if(!fork()){
close(sockfd);
int bufsize = 1024;
char *buffer = malloc(bufsize);
recv(new_fd, buffer, bufsize, 0);
send(new_fd, header, bufsize, 0);
if(send(new_fd, execution(parse(buffer)), 1000, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd);
}
return 0;
}
如果您希望 command
被 shell 解释,您需要将其作为参数传递,例如:
const char *args[] = {"/bin/sh", "-c", command};
execve("/bin/sh", args, NULL);
请注意,网络 shell 在很大程度上被视为恶意软件或未来的 CVE。
目前我运行正在使用一个 HTML 网络服务器,它可以 运行 通过文本框和提交按钮向其发送命令,但我需要将 execlp
到 execv
,我不理解 execv
的数组部分。我试着让它成为 execv(command, command);
但它给了我一个不兼容的指针类型问题的传递参数。同样出于某种原因,我的执行只会 运行 一个单词命令,如 ls
并且不会接受任何标志,我不太确定为什么会这样。下面的代码执行和解析部分,如果需要可以提供完整代码。
Exection.c
char *parse(char *command){
char * newCommand = (char *) malloc(sizeof(char)*50);
int tgt = 0;
newCommand = strstr(command, "/run?command=");
newCommand = strtok(newCommand, " ");
newCommand = newCommand + 13;
for(int src = 0; src< strlen(newCommand); src++){
if(newCommand[src] == '+')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '%')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '7')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == 'C')
{
newCommand[src] = '|';
}
}
return newCommand;
}
char * execution(char *command){
int piper[2];
size_t len = 0;
pipe(piper);
char* output = malloc(1000 * sizeof(char));
memset(output, '[=12=]', 1000* sizeof(char));
pid_t pid = fork();
if(pid != 0)// parent
{
wait(NULL);
close(piper[1]);
int n = sizeof(output);
struct pollfd * poll_fd = malloc(sizeof(struct pollfd));
poll_fd->fd = piper[0];
poll_fd->events = POLLIN;
if(poll(poll_fd, 1, 0) == 1){ // pipe data check
read(piper[0], output, 1000);
}
}
else{
close(1);
dup(piper[1]);
execlp(command, command, NULL);
exit(1);
}
return output;
}
int main (void){
int sockfd;
int new_fd;
struct addrinfo hints;
struct addrinfo *serverinfo;
struct addrinfo *p;
struct sockaddr_storage client_addr;
socklen_t addrsize;
struct sigaction sa;
int yes = 1;
char s[INET6_ADDRSTRLEN];
int status;
memset(&hints, 0, sizeof hints); //makes struct empty
hints.ai_family = AF_UNSPEC; //IPv4 or v6
hints.ai_socktype = SOCK_STREAM; //TCP type need
hints.ai_flags = AI_PASSIVE; //Fill in IP for us
//if can't get address info print error
if((status = getaddrinfo(NULL, PORT, &hints, &serverinfo)) != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 1;
}
for(p = serverinfo; p != NULL; p = p->ai_next){
if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
perror("server: socket");
continue;
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
perror("setsockopt");
exit(1);
}
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(serverinfo);
if(p == NULL){
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1){
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections....\n");
while(1){
addrsize = sizeof client_addr;
new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addrsize);
if(new_fd == -1){
perror("Did not accept");
continue;
}
inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
if(!fork()){
close(sockfd);
int bufsize = 1024;
char *buffer = malloc(bufsize);
recv(new_fd, buffer, bufsize, 0);
send(new_fd, header, bufsize, 0);
if(send(new_fd, execution(parse(buffer)), 1000, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd);
}
return 0;
}
如果您希望 command
被 shell 解释,您需要将其作为参数传递,例如:
const char *args[] = {"/bin/sh", "-c", command};
execve("/bin/sh", args, NULL);
请注意,网络 shell 在很大程度上被视为恶意软件或未来的 CVE。