Terminalde komut çalıştırmak için bir C programı nasıl kullanılır?


11

Terminalde bir komut çalıştırmamı sağlayacak C dilinde bir program oluşturmak istiyorum.

Kabuk betiğinde, tarayıcımda açılan herhangi bir web sitesinin ipini verecek bir program yaptım. Bu kabuk betiği terminalde şu komut girilerek yürütülür:

sudo tcpdump -n dst port 80 -i eth

Profesörüm, C dilinde terminali açıp bu komutu girecek bir program oluşturmamı söyledi ve sonra kabuk betiğim çalışacaktı.

Lütfen böyle bir programı nasıl oluşturacağımı söyle.

Yanıtlar:


8

komutları çalıştırmak için stdlib.h dosyasında bulunan system () işlevini kullanabilirsiniz .

AÇIKLAMA

system (), / bin / sh -c dizesini çağırarak dizede belirtilen bir komutu yürütür ve komut tamamlandıktan sonra geri döner. Komutun yürütülmesi sırasında SIGCHLD engellenecek ve SIGINT ve SIGQUIT göz ardı edilecektir.

Bununla ilgili daha fazla bilgiyi buradan edinebilirsiniz http://linux.about.com/library/cmd/blcmdl3_system.htm


Bu kesinlikle bir yoldur, ancak muhtemelen ac programından komut çalıştırmak istemezsiniz, bunun yerine, çoğu Linux programının sadece programların kodunu doğrudan yapabilen bir lib'i vardır. Örneğin ssh libssh kullanabilir . Genellikle sistem komutlarını koddan çalıştırmak için ÇOK sınırlı bir neden vardır. Çok gidiyorsan neredeyse kesinlikle yanlış bir şey yapıyorsun.
coteyr

C'de böyle bir program yaptım
Tehseen Malik

4

Merhaba, sizin için bir örnek kod yazacağım, size açıklayacağım ve gerçekten size yardımcı olacağını umuyorum. işlevin prototipi şuna benzer:

int sistemi (sabit karakter * 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). bir terminal açın ve programı derleyin

2). çalıştırın (örneğin Ubuntu'da) ./program_name comman_name -her şey - her şey

örnek: ./a.out yerel ayarı -a

bu örnek derleyici tarafından desteklenen tüm yerel ayarları yazdırır.

Daha fazla bilgi:

p char için işaretçi için bir poniterdir (argv gibi) p = & argv [2], -dediğim dizeyi işaretler i cmd dizesine herşeyi kedi i * p NULL'a baktığında döngüden çıkarım: -> ben işaret etmek için bu sembolü kullanacağım (sağ ok seçim operatörü ile karıştırmayın).

argv [0] -> program_adı

argv [1] -> komut_adı (bu örnekte komut adı yerel olacaktır, ancak kontrol etmek istediğiniz komutu girin)

argv [2] -> -her şey (bu örnekte -a, tüm yerel ayarlardır)

argv [3] -> NULL (bu örnekte döngüden çıkar)

tamam bu bence.


Belirgin bir arabellek taşması istismarına sahip olduğundan bunu bir setuid yürütülebilir dosyası olarak kullanmadığınızdan emin olun.
Martin

0

Ben bu sadece keyfi komut yürütme yerine sudo yerine bir setuid-kök ikili kullanmakla ilgili olduğunu varsayacağım, bu yüzden çözümün diğer kısımlarını dahil edeceğim.

Bir güvenlik konusu olarak, ele geçirilebileceğinden system () yönteminden kaçınırız.

Bunu derledikten sonra, elde edilen ikili dosyayı setuid-root olarak kurun.

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

int main (int argc, char ** argv) {
    if (argc> 2) {fputs ("çok fazla argüman \ n", stderr); dönüş EX_USAGE; }
    if (argc> 1 && argv [1] [0] == '-') {fputs ("seçenek kullanılamaz \ n", stderr); dönüş EX_USAGE; }
    if (geteuid ()! = 0) {fputs ("setuid-root \ n olarak doğru kurulmamış \ n", stderr); dönüş EX_UNAVAILABLE; }
    if (setuid (0) 1) p [6] = argv [1];

    / * Her şey yolunda giderse execv geri dönmez
     * (bu programın yerini tcpdump alacaktır) * /
    execv (p0, p);
    / * buraya ulaşırsak execv başarısız olmuş olmalı * /

    perror (p0);
    dönüş EX_OSFILE;
}

bunu şu şekilde kaydettiyseniz foo.cve şu şekilde yüklenmesini istiyorsanız /usr/local/sbin/foo:

foo && install -o root -m 4511 foo / usr / local / sbin / foo yap
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.