gyue 님의 블로그

리눅스 기반 시스템 탐색 및 데이터 분석 본문

블로그 & 기술문서

리눅스 기반 시스템 탐색 및 데이터 분석

gyue 2026. 5. 10. 20:56

미션 목표 : WSL(Windows Subsystem for Linux) 환경에서 리눅스 기본 명령어를 활용하여 파일 시스템을 탐색하고, 숨김 파일 및 특수 파일을 식별하며, 인코딩된 데이터를 해석하는 능력을 습득한다. 또한CLI(Command Line Interface) 환경에 익숙해지고, 보안 및 시스템 분석의 기초 역량을 기른다.

관련 링크 : https://overthewire.org/wargames/bandit/

 

레벨 0

 

pw : bandit0

 

레벨 0 > 1

 

로그인 후 ls 를 통해 파일을 확인하고 readme 파일을 cat을 통해 불러온다.

  • ls : 현재 디렉토리 파일 목록 확인
  • cat : 파일 내용 출력

 

pw : ZjLjTmM6FvvyRnrb2rfNWOZOTa6ip5If

 

레벨 1 > 2

 

로그인 후 ls 로 파일 목록 확인, - 는 파일명이 아니라 표준 입력으로 해석되기때문에 cat ./- 를 통해 비밀번호를 얻는다.

 

pw : 263JGJPfgU6LtdEvgfWU1XP5yac29mFx

 

레벨 2 > 3

 

로그인 후 ls 로 파일 목록을 확인하고 쉘이 공백을 기준으로 파일명을 여러개로 분리하기 때문에

cat "./--spaces in this filename--" 를 통해 비밀번호를 얻는다.

 

pw : MNk8KNH3Usiio41PRUEoDFPqfxLPlSmx

 

레벨 3 > 4

 

로그인 후 ls 로 파일 목록을 확인하고 cd inhere 을 통해 디렉토리로 이동한다. ls 로 파일 목록을 확인했지만 아무것도 뜨지않아서

ls -a 를 통해 숨겨져있는 파일 목록까지 불러온다. 이후 cat ...Hiding-From-You 을 통해 비밀번호를 얻는다.

  • ls -a : 숨김 파일 포함 전체 출력

 

pw : 2WmrDFRmJIq3IPxneAaMGhap0pFhF3NJ

 

레벨 4 > 5

 

로그인 후 ls 로 파일 목록을 확인하고 cd inhere 을 통해 디렉토리로 이동한다. 다시 ls 를 통해 파일 목록 확인.

file ./* 를 통해 파일 타입을 확인하고 그 중에서 ACSII text 로 되어있는 ./-file07cat 을 통해 불러온다.

 

pw : 4oQYVPkxZOOEOO5pTW81FB8j8lxXGUQw

 

레벨 5 > 6

 

로그인 후 ls 로 파일 목록을 확인하고 cd inhere 을 통해 디렉토리로 이동한다. 다시 ls 를 통해 파일 목록 확인.

find 명령어를 통해 조건에 맞는 파일을 검색한다. 이후 cat 을 통해 비밀번호를 얻는다.

  • find : 파일 검색

 

pw : HWasnPhtq9AVKe0dmk45nxy20cvUa6EG

 

레벨 6 > 7

 

find 명령어를 통해 조건에 맞는 파일을 검색한다. 이후 cat 을 통해 비밀번호를 얻는다.

 

pw : morbNTDkSW6jIlUc0ymOdMaLnOlFVAaj

 

레벨 7 > 8

 

로그인 후 ls 로 파일 목록을 확인하고 grep 명령어를 통해 data.txt 에서 "millionth" 문자열이 포함된 줄 찾는다.

  • grep : 문자열 검색

 

pw : dfwvzFQi4mU0wfNbFOe9RoWskMLg7eEc

 

레벨 8 > 9

 

로그인 후 ls 로 파일 목록을 확인하고 sort 명령어를 통해 문자열을 정렬한다.

유일하게 한번만 나타나는 텍스트라고 하였으니 uniq -u 를 통해 중복되지 않는 줄만 출력하도록 한다.

  • sort : 문자열 정렬
  • uniq -u : 중복되지 않은 줄만 출력
  • Pipe ( | ) : 왼쪽 출력 > 오른쪽 입력 전달

 

pw : 4CKMh1JI91bUIZZPXDqGanal4xvAg0JM

 

레벨 9 > 10

 

로그인 후 ls 로 파일 목록을 확인하고 사람이 읽을 수 있는 문자열 중 하나에 저장되어있다고 하며

'=' 문자가 붙어있다고 하여 strings data.txt | grep "=" 을 통해서 문자열을 추출한다.

  • strings : 바이너리 내부 문자열 추출

 

pw : FGUW5ilLVJrxX9kMYMmlN4MgbpfMiqey

 

레벨 10 > 11

 

로그인 후 ls 로 파일 목록을 확인하고 base64로 인코딩된 데이터로 포함된 data.txt 파일에 저장되어 있기때문에

base64 -d data.txt 를 통해 비밀번호를 얻는다.

 

pw : dtR173fZKb0RRsDFSGsg2RWnpNVj3qRr

 

레벨 11 > 12

 

로그인 후 ls 로 파일 목록을 확인하고 cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m' 을 통해서

회전되어 있는 알파벳을 다시 회전시키는 치환방식으로 비밀번호를 얻는다.

  •  tr : 문자 치환 명령어

 

pw : 7x16WNeHIi5YkIhWsfFIqoognUTyj9Q4

 

레벨 12 > 13

 

우선 디렉토리를 생성하고 생성한 디렉토리로 이동한다.

cp ~/data.txt . 를 통해 원본파일을 복사하고 xxd -r data.txt > data.bin 를 통해 hex dump를 복원시킨다.

반복적으로 gunzip / bunzip2 / tar -xf 를 진행하고 중간마다 file 파일명을 통해 타입을 확인한다. 

최종적으로 data8 을 통해 비밀번호를 얻는다.

 

pw : FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn

 

레벨 13 > 14

 

로그인 후 ls 로 파일 목록을 확인하고 HINT 파일을 확인했다.

The current version of OverTheWire prevents logging in from one level to another via localhost.
Log out. 라인을 통해서 기존처럼 서버 내부에서 ssh -i sshkey.private bandit14@localhost -p 2220 처럼 접속하는 방식이 

막혀있어서 로컬에서 직접 접속해야함을 알수있다.

scp -P 2220 bandit13@bandit.labs.overthewire.org:sshkey.private . 를 통해서

현재 bandit 서버에 있는 private key를 로컬 WSL 환경으로 가져온다.

권한이 너무 넓으면 보안상 거부하기 때문에 chmod 600 sshkey.private 를 통해 권한을 설정해준다.

ssh -i sshkey.private bandit14@bandit.labs.overthewire.org -p 2220 를 통해 로그인을 하면 로그인이 성공적으로 된다.

cat /etc/bandit_pass/bandit14 를 통해 현재 단계의 비밀번호를 얻는다.

 

pw : MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS

 

레벨 14 > 15

 

현재 레벨의 비밀번호를 localhost의 30000번 포트 로 전송하면 얻을수있다고 적혀있기에

echo "MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS" | nc localhost 30000 를 통해서 비밀번호를 얻는다.

  • netcat (nc) : TCP 연결 테스트 도구
  • Pipe 입력 : echo 결과를 nc로 전달

 

pw : 8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo

 

레벨 15 > 16

 

echo " 8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo " | openssl s_client -connect localhost:30001 -quiet

를 통해서 비밀번호를 얻는다.

  • openssl s_client : SSL/TLS 연결 테스트 도구
  • -quiet : 불필요한 출력 최소화

 

pw : kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx

 

레벨 16 > 17

 

nmap -sV -p 31000-32000 localhost 를 통해 포트를 스캔한다. 

echo " kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx " | openssl s_client -connect localhost:31790 -quiet

를 통해서 SSH private key 를 얻는다.

 

pw : jmMyCOppv3KKkRgiHI4s5h3I7LwyCgms8uSG06KClQ4

 

레벨 17 > 18

 

로그인 후 ls 를 통해 파일을 확인하고 diff 명령어를 통해 두개의 파일 차이를 확인한다.

  • diff : 두 파일 차이 비교

 

pw : x2gLTTjFwMOhQ8oWNbMN362QKxfRqGlO

 

레벨 18 > 19

 

그냥 로그인을 시도하면 Byebye! 가 뜨며 로그아웃이 된다.

ssh bandit18@bandit.labs.overthewire.org -p 2220 "cat readme" 를 통해 SSH 접속 시 명령어를 직접 실행한다.

 

pw : cGWpMaKXVwDUNgPAVJbWYuGHVn9zl3j8

 

레벨 19 > 20

 

로그인 후 ls 를 통해서 파일을 확인하고 ls -l 을 통해 파일 권한을 확인한다.

./bandit20-do 를 통해 확인하고 ./bandit20-do cat /etc/bandit_pass/bandit20 을 통해 비밀번호를 얻는다.

 

pw : 0qXahG8ZjOVMN9Ghs7iOWsCfZyXOUbYO

 

레벨 20 > 21

netcat listener

nc는 간단한 네트워크 연결을 만들거나 테스트할 때 사용하는 도구다.

이번 문제에서는 특정 포트에서 대기하는 서버 역할로 사용했다.

 
nc -lvp 8888
 

옵션 의미:

-l : listen 모드
-v : verbose, 연결 정보 출력
-p : 포트 지정
 

파이프

echo "password" | nc -lvp 8888
 

echo의 출력값을 nc의 입력으로 전달한다.

즉 클라이언트가 연결되면 nc가 해당 문자열을 보내게 된다.

백그라운드 실행

&
 

명령어 뒤에 &를 붙이면 해당 명령이 백그라운드에서 실행된다.

이번 문제에서는 nc가 포트에서 계속 대기해야 하므로, 백그라운드로 실행한 뒤 같은 터미널에서 suconnect를 실행했다.

suconnect 동작 구조

이번 문제의 흐름은 다음과 같다.

[echo 비밀번호] → [nc listener: 8888번 포트 대기]
                         ↑
                  [suconnect 8888]
 

즉 suconnect가 8888번 포트에 연결하면, nc가 현재 비밀번호를 보내고, suconnect가 이를 검증한 뒤 다음 비밀번호를 출력한다.

트러블슈팅

처음에는 nc -lvp 8888을 실행한 상태에서 같은 터미널에 ./suconnect 8888을 입력하려고 하면,

그것은 명령어 실행이 아니라 nc를 통해 전송되는 문자열이 된다.

따라서 반드시 두 개의 터미널을 사용하거나, 이번 풀이처럼 nc를 백그라운드로 실행해야 한다.

(echo "0qXahG8ZjOVMN9Ghs7iOWsCfZyXOUbYO" | nc -lvp 8888 &) && ./suconnect 8888

 

pw : EeoULMCra2q0dSkYj561DX7s1CpBuOBt

 

레벨 21 > 22

cron 설정 디렉토리 확인

먼저 cron 설정 파일 목록을 확인했다.

ls /etc/cron.d/
 

출력:

behemoth4_cleanup
cronjob_bandit22
cronjob_bandit24
...
 

이번 문제와 관련 있는 cronjob_bandit22 파일이 보인다.

cron 설정 파일 확인

cat /etc/cron.d/cronjob_bandit22
 

출력:

@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
 

해석:

  • 서버 부팅 시 실행
  • 매 1분마다 실행
  • 실행 계정: bandit22
  • 실행 파일: /usr/bin/cronjob_bandit22.sh

즉 1분마다 bandit22 권한으로 특정 스크립트가 실행된다.

실제 스크립트 확인

cat /usr/bin/cronjob_bandit22.sh
 

출력:

#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
 

분석

스크립트 동작:

  1. /etc/bandit_pass/bandit22 읽음
  2. 내용을 /tmp/... 파일에 저장
  3. 읽기 가능 권한 부여

즉 비밀번호를 /tmp에 복사해둔다.

비밀번호 확인

cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
 

출력:

********
 

이 값이 bandit22 비밀번호다.

cron

리눅스 예약 작업 스케줄러.

 

형식:

* * * * * command
 

의미:

분 시 일 월 요일
 

예:

* * * * *
 

매 분 실행.

/tmp 디렉토리

임시 파일 저장 위치.

여러 사용자가 접근 가능한 경우가 많다.

 

pw : tRae0UfB9v0UzbCdn9cY0gQnds9GF58Q

 

레벨 22 > 23

cron 설정 확인

cat /etc/cron.d/cronjob_bandit23
 

출력:

@reboot bandit23 /usr/bin/cronjob_bandit23.sh
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh
 

실제 스크립트 분석

cat /usr/bin/cronjob_bandit23.sh
 

출력:

#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

cat /etc/bandit_pass/$myname > /tmp/$mytarget
 

동작 분석

스크립트 흐름:

myname=$(whoami)
 

현재 사용자 이름 저장.

 

cron은:

bandit23
 

권한으로 실행되므로:

myname = bandit23
 

다음:

echo I am user bandit23 | md5sum
 

실행:

echo I am user bandit23 | md5sum
 

결과:

8ca319486bfbbc3663ea0fbe81326349
 

즉 파일 경로:

/tmp/8ca319486bfbbc3663ea0fbe81326349

 

비밀번호 읽기

cat /tmp/8ca319486bfbbc3663ea0fbe81326349
 

출력:

********
 

bandit23 비밀번호 획득.

whoami

현재 사용자 확인.

md5sum

문자열 해시 생성.

 

예:

echo hello | md5sum

 

command substitution

$(command)
 

명령 결과를 변수에 저장.

whoami
 ↓
bandit23
 ↓
echo "I am user bandit23"
 ↓
md5
 ↓
파일명 생성
 ↓
/tmp/해시값

 

pw : 0Zf11ioIjMVN551jX3CmStKLYqjk54Ga

 

레벨 23 > 24

cron 설정 확인

먼저 cron 설정 파일 확인:

cat /etc/cron.d/cronjob_bandit24
 

출력:

@reboot bandit24 /usr/bin/cronjob_bandit24.sh
* * * * * bandit24 /usr/bin/cronjob_bandit24.sh
 

즉 매 1분마다 bandit24 권한으로 특정 스크립트가 실행된다.

실행 스크립트 분석

cat /usr/bin/cronjob_bandit24.sh
 

출력:

#!/bin/bash

for i in /var/spool/bandit24/foo/*
do
    timeout -s 9 60 $i
    rm -f $i
done

 

동작 분석

스크립트 흐름:

  1. /var/spool/bandit24/foo/ 내부 파일 확인
  2. 각 파일 실행
  3. 60초 제한
  4. 실행 후 삭제

즉 작성한 스크립트를 이 디렉토리에 넣으면 bandit24 권한으로 실행된다.

작업 디렉토리 생성

임시 디렉토리 생성:

mktemp -d
 

예:

/tmp/tmp.IvmEd0yuZc
 

이동:

cd /tmp/tmp.IvmEd0yuZc

 

스크립트 작성

처음에는 nano로 만들려 했지만:

Unable to create directory /home/bandit23/.local/share/nano/
 

경고가 발생했다.

 

그래서 heredoc 방식 사용:

cat > getpass.sh << 'EOF'
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/my_bandit24_pass_yh
chmod 644 /tmp/my_bandit24_pass_yh
EOF
 

내용 설명:

cat /etc/bandit_pass/bandit24
 

bandit24 비밀번호 읽기

> /tmp/my_bandit24_pass_yh
 

임시 파일 저장

chmod 644
 

읽기 권한 부여

실행 권한 부여

chmod +x getpass.sh

 

cron 실행 디렉토리에 복사

cp getpass.sh /var/spool/bandit24/foo/

 

cron 실행 대기

sleep 70
 

cron은 1분마다 실행되므로 여유 있게 기다렸다.

결과 확인

cat /tmp/my_bandit24_pass_yh
 

출력:

gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8
 

bandit24 비밀번호 획득.

Privilege Escalation

낮은 권한 사용자가 높은 권한으로 코드 실행.

 

이번 구조:

bandit23
   ↓
cron
   ↓
bandit24 권한 실행

 

heredoc

멀티라인 파일 생성:

cat << EOF
내용
EOF

 

chmod +x

실행 권한 부여.

 

pw : gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8

 

레벨 24 > 25

문제 분석

입력 형식:

현재비밀번호 PIN
 

예:

gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 1234
 

PIN 경우의 수:

10000개
 

수동 불가능.

자동화 필요.

홈 디렉토리 실패

처음 홈 디렉토리에서:

cat > brute.sh
 

시도했지만:

Permission denied
 

발생.

 

Bandit 홈은 쓰기 제한이 걸려 있었다.

/tmp 사용

작업 디렉토리 생성:

mktemp -d
cd /tmp/tmp.xxxxx

 

brute force 스크립트 작성

cat > brute.sh << 'EOF'
#!/bin/bash
for i in $(seq -w 0 9999)
do
    echo "gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 $i"
done | nc localhost 30002
EOF

 

분석

seq -w 0 9999
 

생성:

0000
0001
0002
...
9999
 

-w는 자리수 고정.

 

루프:

for i in ...
 

각 PIN 반복.

 

전송:

echo "비밀번호 PIN"
 

형식 생성.

 

파이프:

| nc localhost 30002
 

서버 전송.

실행 권한

chmod +x brute.sh
 

실행

./brute.sh
 

출력:

Wrong!
Wrong!
Wrong!
...
Correct!
iCi86ttT4KSNe1armKiwbQNmB3YJP3q4
 

bandit25 비밀번호 획득.

Brute Force

가능한 모든 경우를 시도.

seq -w

고정 자리 숫자 생성.

Automation

수작업 대신 스크립트 자동화.

0000~9999 생성
   ↓
현재비밀번호와 조합
   ↓
nc로 서버 전송
   ↓
정답 PIN 발견
   ↓
비밀번호 획득

 

pw : iCi86ttT4KSNe1armKiwbQNmB3YJP3q4