[英]How to intercept SSH stdin and stdout? (not the password)
我意識到這個問題經常被問到,主要是那些想截取SSH密碼詢問階段的人提出的。 這不是我想要的。 我需要登錄后的文字。
我想為ssh寫一個包裝器,它充當SSH和終端之間的中介。 我想要這樣的配置:
(typing on keyboard / stdin) ----> (wrapper) ----> (ssh client)
和來自ssh的輸出相同:
(ssh client) -----> (wrapper) -----> stdout
通過執行我在網上發現的標准技巧(簡化代碼),我似乎能夠達到我想要的標准輸出的效果:
pipe(fd)
if (!fork()) {
close(fd[READ_SIDE]);
close(STDOUT_FILENO); // close stdout ( fd #1 )
dup(fd[WRITE_SIDE]); // duplicate the writing side of my pipe ( to lowest # free pipe, 1 )
close(STDERR_FILENO);
dup(fd[WRITE_SIDE]);
execv(argv[1], argv + 1); // run ssh
} else {
close(fd[WRITE_SIDE]);
output = fdopen(fd[READ_SIDE], "r");
while ( (c = fgetc(output)) != EOF) {
printf("%c", c);
fflush(stdout);
}
}
就像我說的,我認為這可行。 但是,我似乎不能相反。 我無法關閉(STDIN_FILENO)並重疊管道的讀取側。 似乎SSH可以檢測到並阻止它。 我已經讀過我可以使用“ -t -t”選項來強制SSH忽略其輸入的非標准輸入特性。 但是當我嘗試此操作仍然無效。
有什么提示嗎?
非常感謝!
使用popen (而不是execv )執行ssh cmd並能夠讀取和寫入會話。
如果要在攔截器就位的情況下允許對ssh進行交互使用,則管道將無法工作。 在這種情況下,您需要創建一個偽tty。 查找posix_openpt
, ptsname
和grantpt
函數。 還有一個名為openpty
的非標准但更直觀的函數,以及一個名為forkpty
的包裝器,它使您嘗試做的事情變得非常容易。
Python的Paramiko使用SSH來完成所有這些工作,但是它是Python源代碼。 但是,對於C程序員而言,閱讀Python與閱讀偽代碼非常相似,因此請參閱源代碼並確切地了解有效的方法。
這是一個寫到ssh的工作示例:
#include <unistd.h>
int main(int argc, char **argv)
{
int pid;
int fds[2];
if (pipe(fds))
return -1;
pid = fork();
if (!pid)
{
close(fds[1]);
close(STDERR_FILENO);
dup2(fds[0], STDIN_FILENO);
execvp(argv[1], argv + 1);
}
else
{
char buf[256];
int rc;
close(fds[0]);
while ((rc = read(STDIN_FILENO, buf, 256)) > 0)
{
write(fds[1], buf, rc);
}
}
wait(NULL);
return 0;
}
這行可能是錯誤的:
execv(argv[1], argv + 1); // run ssh
如果您使用的是argv [] 編輯:剛剛檢查了C99標准和argv是NULL終止。 main()
的參數,則該數組必須以NULL指針終止,我認為無法保證是這種情況。
execv()
不會在路徑中搜索要執行的文件,因此,如果您將ssh
作為參數傳遞,則它等效於./ssh
,可能不是您想要的。 您可以使用execvp()
但如果在$ PATH中/bin/ssh
之前出現了一個名為ssh
的惡意程序,則存在安全風險。 最好使用execv()
並強制使用正確的路徑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.