Wie verwende ich ein C-Programm, um einen Befehl auf dem Terminal auszuführen?


10

Ich möchte ein Programm in C-Sprache erstellen, mit dem ich einen Befehl im Terminal ausführen kann.

Ich habe ein Programm in Shell-Skript erstellt, das mir die IP-Adresse jeder Website gibt, die in meinem Browser geöffnet ist. Dieses Shell-Skript wird ausgeführt, indem Sie diesen Befehl in das Terminal eingeben:

sudo tcpdump -n dst port 80 -i eth

Mein Professor sagte mir, ich solle ein Programm in C-Sprache erstellen, das das Terminal öffnet und diesen Befehl eingibt, und dann würde mein Shell-Skript funktionieren.

Bitte sagen Sie mir, wie man ein solches Programm erstellt.

Antworten:


8

Sie können die in stdlib.h verfügbare Funktion system () verwenden , um Befehle auszuführen.

BESCHREIBUNG

system () führt einen in string angegebenen Befehl durch Aufrufen von / bin / sh -c string aus und kehrt nach Abschluss des Befehls zurück. Während der Ausführung des Befehls wird SIGCHLD blockiert und SIGINT und SIGQUIT werden ignoriert.

Weitere Informationen finden Sie hier http://linux.about.com/library/cmd/blcmdl3_system.htm


Dies ist sicherlich eine Möglichkeit, aber Sie möchten wahrscheinlich keine Befehle von einem AC-Programm ausführen. Stattdessen verfügen die meisten Linux-Programme über eine Bibliothek, die nur den Code der Programme direkt kann. Zum Beispiel kann ssh libssh verwenden . Es gibt normalerweise einen SEHR begrenzten Grund, Systembefehle aus Code auszuführen. Wenn du viel machst, machst du mit ziemlicher Sicherheit etwas falsch.
Coteyr

Ich habe ein Programm in C wie dieses gemacht
Tehseen Malik

4

Hallo, ich werde für Sie einen Beispielcode schreiben, ihn Ihnen erklären und hoffe, dass dies Ihnen hilft. Der Prototyp der Funktion ist ungefähr so:

int system (const char * cmd);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CMN_LEN 100

int main(int argc, char *argv[])
{
    char cmd[MAX_CMN_LEN] = "", **p;

    if (argc < 2) /*no command specified*/
    {
        fprintf(stderr, "Usage: ./program_name terminal_command ...");
        exit(EXIT_FAILURE);
    }
    else
    {
        strcat(cmd, argv[1]);
        for (p = &argv[2]; *p; p++)
        {
            strcat(cmd, " ");
            strcat(cmd, *p);
        }
        system(cmd);
    }

    return 0;
}

1). Öffnen Sie ein Terminal und kompilieren Sie das Programm

2). Führen Sie es aus (zum Beispiel in Ubuntu) ./program_name comman_name -anything - irgendetwas

Beispiel: ./a.out locale -a

In diesem Beispiel werden alle von meinem Compiler unterstützten Gebietsschemas gcc gedruckt.

Mehr Info:

p ist ein Poniter, der auf char zeigt (wie argv ist) p = & argv [2], zeigt auf -jegliche Zeichenfolge, die ich alle -jedes auf meine cmd-Zeichenfolge katze, ich verlasse die Schleife, wenn * p auf NULL zeigt Ich werde dieses Symbol verwenden, um Punkte zu sagen (verwechseln Sie es nicht mit dem Rechtspfeil-Auswahloperator).

argv [0] -> Programmname

argv [1] -> Befehlsname (in diesem Beispiel ist der Befehlsname das Gebietsschema, aber geben Sie stattdessen den Befehl ein, den Sie überprüfen möchten)

argv [2] -> -anything (in diesem Beispiel -a, das sind alle Gebietsschemas)

argv [3] -> NULL (in diesem Beispiel wird die Schleife verlassen)

ok das ist es, denke ich.


Stellen Sie sicher, dass Sie dies nicht als ausführbare Setuid-Datei verwenden, da dies einen offensichtlichen Pufferüberlauf-Exploit aufweist.
Martin

0

Ich gehe davon aus, dass es darum geht, eine setuid-root-Binärdatei als Ersatz für sudo zu verwenden, anstatt nur eine willkürliche Befehlsausführung, also werde ich die anderen Teile der Lösung einbeziehen.

Aus Sicherheitsgründen vermeiden wir system (), da es entführt werden kann.

Installieren Sie nach dem Kompilieren die resultierende Binärdatei als setuid-root.

#include <unistd.h>
#include <stdio.h>
#include <sysexits.h>

int main (int argc, char ** argv) {
    if (argc> 2) {fputs ("zu viele Argumente \ n", stderr); return EX_USAGE; }}
    if (argc> 1 && argv [1] [0] == '-') {fputs ("keine Optionen erlaubt \ n", stderr); return EX_USAGE; }}
    if (geteuid ()! = 0) {fputs ("nicht korrekt als setuid-root installiert \ n", stderr); return EX_UNAVAILABLE; }}
    if (setuid (0) 1) p [6] = argv [1];

    / * Wenn alles gut geht, wird execv nicht zurückkehren
     * (weil dieses Programm durch tcpdump ersetzt wurde) * /
    execv (p0, p);
    / * Wenn wir hier ankommen, muss execv fehlgeschlagen sein * /

    Perror (p0);
    return EX_OSFILE;
}}

Wenn Sie dies als gespeichert haben foo.cund es als installieren möchten, führen Sie Folgendes /usr/local/sbin/fooaus:

mache foo && installiere -o root -m 4511 foo / usr / local / sbin / foo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.