Есть ли у GDB идентификатор пользователя? - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь отладить программу C, используя GDB. Но когда я пытаюсь запустить его изнутри GDB, я получаю следующую ошибку:

примечание: строка ошибки FATAL определяется пользователем

gdb-peda$ run 
Starting program: /home/masterdungeon/HTAOEBookPrograms/0x200/0x280/0x287/GameOfChance 


        **************** WELCOME to the GAME OF CHANCE *****************

    This game will essentially tell you how lucky you are today   ;)

---- New player ----
Please enter your name : user_gdb

[!!!] Fatal Error   in register_user() while opening  DATAFILE
: Permission denied
[Inferior 1 (process 10636) exited with code 0377]
Warning: not running
gdb-peda$ 

Эта программа на самом деле игра командной строки под названием «GameOfChance» (из книги HTAOE). Всякий раз, когда пользователь запускает программу, программа сначала проверяет свой UserID, чтобы увидеть, зарегистрирован ли пользователь как игрок в DATAFILE. Если в DATAFILE нет записи этого UID (т. Е. Игрок еще не зарегистрирован), тогда программа позволяет создать нового игрока и принять имя пользователя, таким образом регистрируясь как игрок с этим UID и принятым именем пользователя. Но я думаю, что GDB не имеет UID, так как в / etc / passwd нет записи о gdb. Как заставить программу работать во время отладки и зарегистрировать GDB как нового игрока? Это вообще возможно?

Код выглядит следующим образом:

12   #define DATAFILE "/var/gameofchance.data" // File to store user data

46   int main(){

//lines of code

 53         uid = getuid(); // get current user_id i.e player_id
 54         player_exists = get_player_data(uid); // returns -1 if player does not exist 
 55                 //otherwise returns 0 and puts all player data into struct player
 56 
 57         if(player_exists == -1) {
 58                 register_player(uid);
 59         }

//lines of code

148         return 0;
149   } //end main()

314   void register_player(int uid){

//lines of code

327         fd = open(DATAFILE, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
329 
330         if(fd==-1){
331                 fatal("  in register_user() while opening  DATAFILE\n");
332         }

//lines of code

344 } //end register_player

разрешения для DATAFILE:

-rw------- 1 root masterdungeon 240 Apr 19 13:54 gameofchance.data

разрешения для исполняемой игры GameOfChance:

-rwsrwxr-x 1 root root 29064 Jan 4 19:45 GameOfChance

Еще одна вещь, которую я не мог понять, это когда я устанавливаю точку останова в строке 54 и проверяю значение uid, я получаю 1000 как UID GDB.

Breakpoint 16, main () at gameofchance.c:54
54      player_exists = get_player_data(uid); // returns -1 if player does not exist
gdb-peda$ x/wd &uid
0x7ffd4ed4aee8: 1000

Как возможно, что GDB имеет ИД пользователя 1000? поскольку нет записи gdb в / etc / passwd. 1000 - это идентификатор пользователя masterdungeon .

Хорошо, поэтому он работает, когда GDB запускается с использованием sudo gdb. Но почему я должен запустить его как root, чтобы он нормально работал в GDB ?

В противном случае в BASH программа успешно запускается как пользователь masterdungeon . Только в GDB он должен быть запущен как root

1 Ответ

2 голосов
/ 19 апреля 2020

Есть ли у GDB идентификатор пользователя?

Да. Каждый запущенный процесс, включая процессы GDB, имеет как эффективный UID, так и реальный UID. Часто это одно и то же. Но у тебя, кажется, есть недоразумение. Они не описывают сам процесс. Скорее они описывают пользователя , от имени которого выполняется процесс.

Как возможно, что GDB имеет ИД пользователя 1000? поскольку нет записи gdb в / etc / passwd. 1000 - это идентификатор пользователя masterdungeon.

Поскольку вы используете gdb как пользователь "masterdungeon" или как другой пользователь с тем же номером UID.

Хорошо, так это работает, когда GDB запускается с использованием sudo GDB. Но почему я должен запустить его как root, чтобы он нормально работал в GDB ?

Ваш файл данных доступен только для root:

-rw------- 1 root masterdungeon 240 Apr 19 13:54 gameofchance.data

. При непосредственном запуске программа учитывает это, будучи root -обладателем и имея установленный бит SUID:

-rwsrwxr-x 1 root root 29064 Jan  4 19:45 GameOfChance

(обратите внимание на «s» в первой триаде битов разрешений) ). Это приводит к тому, что программа при прямом запуске запускается с эффективным UID root, хотя root фактически не запускал ее. Это один из случаев, когда эффективные и реальные идентификаторы отличаются. Это также очень плохой вариант использования SUID, потому что программы SUID root представляют собой существенный риск безопасности для хост-системы, и этот риск не оправдан для игры.

Риск будет намного хуже, если бит SUID учитывался при запуске программы под управлением отладчика. Отладчик может вносить произвольные изменения в программные данные и даже двоичный код во время работы программы, и это обеспечило бы простой вектор для повышения привилегий, если в таких контекстах учитывается SUID. Соответственно, бит SUID в исполняемом файле не действует, когда программа запускается в отладчике . (См. Также Может ли gdb отлаживать suid root программы? )

Таким образом, если вы отлаживаете программу как пользователь, отличный от root, она не сможет открыть данные файл, но если вы используете sudo для запуска отладчика, тогда вы получаете необходимую привилегию для доступа к файлу данных через sudo, и тот факт, что бит SUID в исполняемом файле не учитывается, * не имеет значения.

Лучший способ отладки программы в ее среде сборки перед установкой, такой, что она принадлежит вам и не требует (или не имеет) установленного для нее бита SUID . Это может потребовать некоторых манипуляций с тем, где и как он ищет свой файл данных, который также должен принадлежать вам.


Что касается того, как установлена ​​программа, у вас есть противоречие между приоритетами:

  • Программы, доступные для запуска всем пользователям, должны принадлежать root и доступны для записи только root, чтобы другим пользователям было сложно их изменять или заменять другими программами, оба из которых может привести к нарушению данных и (дальнейшему) повышению привилегий.

  • Вы, очевидно, требуете, чтобы пользователи, запускающие игровую программу, могли выполнять запись в общий файл данных. Неясно, что содержит этот файл, но общий список рекордов может быть примером.

  • Но вы (предположительно) не хотите разрешать пользователям произвольно манипулировать файлом данных под их собственные полномочия, чтобы они не обманывали каким-либо образом, или еще хуже.

Самый простой подход - предоставить каждому пользователю собственный файл данных общего доступа, созданный программой по необходимости в рамках пользователя. домашний каталог, и доступный для этого пользователя. Тогда вам не нужно связываться с SUID / SGID, а также не нужно беспокоиться о том, что пользователи мешают друг другу. Конечно, они могут обманывать, но это повлияет только на них. И вы сможете отлаживать программу с помощью GDB.

Если важно, чтобы файл данных был как общим для пользователей программы, так и доступным для записи (через программу) для всех них, то лучшим подходом, чем создание программы SUID- root, было бы сделать его SGID-some_group_not_ root и сделать файл данных доступным для записи этой группой. Более того, избегайте бита SGID и просто требуйте, чтобы пользователи были членами выбранной группы, чтобы использовать программу. Обратите внимание, что SGID также не учитывается при отладке.

...