- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我写了一个简单的 go使用 YAML 和 MySQL 驱动程序的程序旨在提供一个简单的实用程序来更新数据库,而不会将用户名和密码凭据暴露给执行该程序的用户。
(我很清楚我也可以用 Python 或其他一些脚本语言编写它并使用 sudo 管理权限委托(delegate),但我想在这里尝试不同的方法,以供我自己借鉴)。
构建程序后,我使用了 chgrp sys dbcreds.yaml && chmod 0640 dbcreds.yaml
和 chgrp sys ./myprog && chmod g+s ./myprog
(作为 root)......一切似乎都有效。 (我还测试了在 setGID 步骤之前访问被拒绝,因为它应该被拒绝)。
我还测试了 strace
并导致权限被拒绝(这是应该的)。 (为了好玩,我还在它上面运行了 ltrace -S
;这是在 Linux 下。正如预期的那样,我没有看到很多正常的 libc 函数调用......我很惊讶地看到了一些 pthread_....() 和一个 malloc() 调用。我猜 GO 运行时毕竟确实链接到一些系统库函数)。
我的问题:这样安全吗?是否有任何已知的方法可以使 Go 程序(如下所示)在读取这些私有(private)凭证后进行核心转储或暴露其内存?有没有办法在我阅读我的凭据后删除我的 SGID 权限?在 Go 二进制文件上有任何 SUID/SGID 漏洞利用的例子吗?有一个更好的方法吗?有没有办法主动防止核心转储或确保敏感数据(凭据)不会出现在核心转储中?
另一个注意事项:我发现 gopkg.in/yaml.v2 语义有点令人不安。在我的 YAML 文件中,我有类似的内容:
---
user me
pw mypassword
但在我的代码中我必须使用 User 和 Pw(大写)而不是使用小写正如我所料。我认为这是 Goyaml 作者的实现决定。 .是这样吗?
#!go
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
"gopkg.in/yaml.v2"
"io/ioutil"
"os"
"strconv"
)
type Creds struct {
User string
Pw string
}
func main() {
filename := "./dbcreds.yaml"
var creds Creds
conf, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
err = yaml.Unmarshal(conf, &creds)
if err != nil {
panic(err)
}
var arg1 int
arg1, err = strconv.Atoi(os.Args[1])
if err != nil {
panic(err.Error()) // Just for example purpose. You should use proper error handling instead of panic
}
fmt.Println("arg1: ", arg1, "\n")
dsn := fmt.Sprintf("%s:%s@/mydatabase", creds.User, creds.Pw)
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err.Error())
}
defer db.Close()
err = db.Ping()
if err != nil {
panic(err.Error())
}
stmtOut, err := db.Prepare("SELECT quant FROM c WHERE id >= ?")
if err != nil {
panic(err.Error())
}
defer stmtOut.Close()
rows, err := stmtOut.Query(arg1)
if err != nil {
panic(err.Error())
}
defer rows.Close()
for rows.Next() {
var quant int
err = rows.Scan(&quant)
if err != nil {
panic(err.Error())
}
fmt.Println(quant)
}
}
最佳答案
setuid/setgid Go 程序相当安全,但有一个主要警告。 Go setuid/setgid 程序通常不比 C/C++ setuid/setgid 程序更安全。
的确,您可以通过使用环境变量 GOTRACEBACK=crash 运行一个 Go 程序然后向它发送一个信号来强制转储核心。但是,这对您的目的来说是可以的,因为 Go 程序将(尝试)通过向自己发送 SIGABRT 信号来创建核心转储。内核不会为被信号杀死的 setuid/setgid 程序生成核心转储。
Go 的主要警告是在 GNU/Linux 系统上你不能退回到原来的用户 ID。这是因为 setuid(以及 setgid、setgroups、setreuid、setregid、setresuid 和 setresgid)是如何在 GNU/Linux 上为多线程程序实现的。详情在http://golang.org/issue/1435 .
最后,Uw 和 Pw 需要大写,因为标准反射包不允许写入未导出的字段。
关于go - Go[lang] 二进制文件上的 SetGID/SetUID 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30552760/
这其实是一个三段式的问题,下面我会解释,但是问题是: 如何使用 gdb 以 root 权限运行程序的一部分,而其余部分以正常方式运行? 为什么我使用 mkstemp 在/tmp 中创建文件时会得到“权
我不得不为某人做一个肮脏的 Linux hack,这样他们就可以在非根用户的情况下使用 cupsenable printername shell 命令启动打印机。我不希望他们能够以 root 身份使用
我编写的一个 Python 扩展需要 root 访问权限才能执行单个硬件初始化调用。我不想仅仅为了我的扩展中的这个调用而以 root 身份运行整个脚本,所以我想编写一个包装器来执行此初始化,然后再降低
我已经使用 root 运行了一个程序,在其中我为 uid 9999999 调用了 setuid 函数,然后它成功地设置了这个 uid,即使它不存在于/etc/passwd 中。那么 setuid 如何
我有一个要设置 uid 位的 shell 脚本。我将所有者设置为 root 并设置 uid 位。我在 shell 中添加了 'whoami' 以检查它是否正常工作但是当我执行脚本时,whoami 返回
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
如果我在循环中调用 setuid 以成为 root 并重置 uid,这只会工作一次。我有以下代码: #include #include #include int my_func(int i) {
我正在扩展一些在 GNU/Linux (Ubuntu 14.04) 下运行的软件(我不是作者),由一个 manager 进程和几个 worker 组成过程。管理器可以通过我可以在配置文件中指定的命令行
当我在我的程序中尝试 setuid 时,它创建了 2 个进程。一个是父进程,另一个是子进程。 int isRoot() { if (getuid() != 0) {
假设我们正在查看以下场景: 文件 saymyname.c(包括省略) int main(int argc, char** argv){ system("whoami"); } 构建并设置权
正在尝试设置 cap_setgid、cap_setuid、cap_setpcap。 #include #include int main() { cap_t caps; caps
我目前正在尝试了解文件权限中的特殊位的作用,但目前正试图了解 setuid 位的作用。从所有在线资源中,它说: Commonly noted as SUID, the special permissi
我有以下简单代码来检查我的 getuid 函数: uidActual=getuid(); printf ("User id is [%d]\n", ui
我被要求找到一个命令,该命令将仅列出从当前目录(及其下)开始的具有 setuid 位的文件。有人告诉我这是正确的方法: find /home/anyuser -type f \( -perm -400
伙计们。 这是我的问题: 我有一个可执行文件需要在系统的特定位置创建一个文件夹。 无论谁执行它,我都希望它能够这样做。 我的想法是将父文件夹(可执行文件需要在其中创建文件夹的文件夹)提供给用户,并将可
我正在尝试了解缓冲区溢出和 setuid。我使用这个来源: #include #include #include int main(void){ char prog[]="/bin/ls
我在 Linux 中工作,并尝试在 Linux 上使用 setuid 执行 C 程序。这是我的代码: #include #include #include #include int main(
需要一些关于传递 argv 的帮助,以便 shell 脚本可以作为/usr/local/bin/script.sh 用户域运行 #include #include #include #inclu
我一直在努力思考 setuid/setgid 是如何工作的……我想到了这个人为的例子: 用户: 用户A属于A组 用户B属于B组 文件 a.txt 由用户 A 拥有,权限为 rw-rw----- (66
changeIDs() is trying to use setuid() to change the effective user id but it always errors out and I
我是一名优秀的程序员,十分优秀!