2013-04-12 41 views
5

是否有(兼容)的方式来欺骗(作为root)的Unix套接字(文件系统套接字)对等凭证其可以通过getsockopt()获得,选项SO_PEERCREDUNIX套接字:是否有可能欺骗getsockopt()SO_PEERCRED?

背景:
我需要连接到服务器应用程序(我不能修改),其检查其经由SO_PEERCRED连接到它的处理的UID。我想欺骗这些信息,以便能够连接到应用程序作为根,也可以

UPDATE

为了澄清问题
我在寻找一种非侵入性的方式该服务器发现的特定对UID/GID。 解决方案是气馁这就需要改变内核(或采取使用内核模块的)或改变服务器进程或其装载/以任何方式联过程LD_PRELOAD,系统呼叫拦截等)。

基本上,解决方案应该在没有任何特殊要求的任何linux(或一般unix)服务器上运行。服务器进程可能已经在运行。

+1

如果你是'root',为什么不只是'setuid'?你可以从一个完全控制的子进程中做到这一点,这样你就可以避免实际上失去权限。 – nneonneo

+0

我不确定,但在Linux下,'/ proc//fdinfo/'中有一个八进制值前缀标志。 – alk

+1

您可以控制服务器进程的启动,即,您是否可以使用LD_PRELOAD修改库函数/ syscall thunk来更改报告的凭据? –

回答

-1

不可以。原因是提供对等体的UID和GID的机制在内核内部为,您无法欺骗内核!内核使用对等体的PID来推导对等体的有效凭证。当一方在插座上执行connect时会发生这种情况。请登录net/unix/af_unix.c查看unix_stream_connect()的电话copy_peercred()。对等体无法改变它发送的数据或者说服内核说对等体的PID不是它的那个套接字。这与AF_INET套接字不同,内核没有对等进程的内部知识,只能看到对等方发送的IP数据包头中的数据。

您可以做的唯一的事情就是将对等进程的有效UID设置为root或任何你想要的UID/GID,并且你需要root密码或者sudo权限。

+1

但是你*可以*欺骗内核 - 作为root用户,你可以通过加载模块来修改正在运行的内核的行为。 –

+0

@ChrisStratton:你编写的任何模块都可以改变Unix域套接字的行为。 –

+0

你是**严重**误认为相信。最简单的方法是创建一个模块,在进入内核后立即在调度点重定向系统调用,但修改unix域套接字实现的内部结构最终也是一种选择。请记住,某些未导出的内容不受*保护*,它只是很难找到*,而且在源打开并且可能已知构建设置时并非如此。 –

3

你说得对。根进程有权欺骗这样的事情,问题在于SO_PEERCRED没有提供进程的机制或API来指定应该呈现给对等方的身份。

两件事情可以做:

  1. 暂时放弃了root(setreuid(desired,-1))时,你的电话connect。在进程名为connect(和listen以其他方式)时,unix域连接将标记对等方的凭证。 SO_PEERCRED不会告诉你当前对方的凭证。然后你可以恢复根目录。

  2. 更好的是,使用另一个API。消息传递API允许进程选择要向对等体呈现的标识。请致电sendmsg并使用struct cmsg包含要发送的凭据。内核将忽略非特权用户指定的凭证,并始终确保对方看到实际身份,但特权进程可以假装为其他任何人。这更符合您的需求,因为丢弃和重获根源是一项危险的活动,在这种情况下是不必要的。 Google获取“SCM_CREDENTIALS”(或者在您的系统上使用“man -K”)来获取代码示例。

+1

如果服务器未设置SO_PASSCRED套接字选项并读取凭据,则解决方案2将不起作用。如果它只使用SO_PEERCRED,那么你坚持使用简单的一次性PID认证。有关SO_PEERCRED示例,请参阅http://man7.org/tlpi/code/online/dist/sockets/scm_cred_recv.c.html。无论如何,root用来使用SCM_CREDENTIALS来降低权限几乎不是“欺骗”。 –

+1

好吧,叫它“模仿”,然后......另外,我似乎记得,如果你发送了一些证书,你不需要在另一端设置SO_PASSCRED;他们应该在'recvmsg'输出中找到你。也许这是操作系统的依赖?我不倾向于使用Linux。 SO_PASSCRED通常用于当你想读出凭证但另一方不写他们;它会告诉内核为每个消息提供对等凭证(对于DGRAM套接字来说特别好)。 –

+1

阅读示例,“我们必须设置SO_PASSCRED套接字选项才能接收凭据”。 BSD/FreeBSD的选项称为SCM_CREDS也是如此。 –