1
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int good(int addr) {
    printf("Address of hmm: %p\n", addr);
}

int hmm() {
    printf("Win.\n");
    execl("/bin/sh", "sh", NULL);
}

extern char **environ;

int main(int argc, char **argv) {

    int i, limit;

    for(i = 0; environ[i] != NULL; i++) 
        memset(environ[i], 0x00, strlen(environ[i]));

    int (*fptr)(int) = good;
    char buf[32];

    if(strlen(argv[1]) <= 40) limit = strlen(argv[1]);

    for(i = 0; i <= limit; i++) {
        buf[i] = argv[1][i];
        if(i < 36) buf[i] = 0x41;
    }

    int (*hmmptr)(int) = hmm;

    (*fptr)((int)hmmptr);

    return 0;

}

上記のCプログラムを、スタック保護(gcc -fno-stack-protector -o out test.c)を使用せずにrootとしてコンパイルし、通常のユーザーとして利用しました。ルートシェルを取得できませんでした。

これは、「smashthestack」から利用したものと同じコードです。

4

2 に答える 2

1

バイナリsuidを作成しましたか?

ルートとしての作業:

# cd /your/working/directory/
# chmod +s ./out

すべてのスタックスマッシング保護がオフになっていて、コードが正しい場合は、ルートシェルを取得します。それ以外の場合(保護がオフでコードが正しい場合)、ユーザーシェルのみを取得します。

于 2011-12-28T13:53:42.580 に答える
0

プログラムを使用してシェルに到達するために必要なのは、次のことだけですc

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

int main(int argc, char *argv[]) 
{
    execl("/bin/sh", "sh", NULL);
    return 0;
}

上記のコードをルートシェルで実行します。

新しいシェルの環境変数をクリアするために、次のコードを引き続き使用できます。

for(i = 0; environ[i] != NULL; i++) 
    memset(environ[i], 0x00, strlen(environ[i]));

ただし、コードを実行するには、変更する必要があります

printf("Address of hmm: %p\n", addr);

printf("Address of hmm: %p\n", &addr);

その関数に変数のアドレスを出力したい理由がわかりません。OTOH、関数自体には目的がありません。

于 2011-12-28T12:32:03.960 に答える