OverTheWire_Wargame Bandit

[ level25 -> level26 ]


와.. 드디어 마지막 문제입니다. bandit는 난이도가 어려운 편은 아니었지만 단계가 너무 많아서 시간이 오래 걸렸던 것 같습니다.

바로 시작합니다!


이번 문제는 bandit26은 /bin/bash로 로그인이 되지 않는다고 합니다. 어떤 식의 문제일 지 한번 살펴보죠.



아.. RSA key를 던져줬습니다. 이건 이전에 풀었던 문제와 동일한 문제인 것 같습니다. 오히려 더 쉽네요. 방법은 아래 글에 정리 되어 있습니다.


OverTheWire Bandit [Level13 -> Level14]




이렇게 bandit26이 나타나면서 끝이 납니다!


이렇게 putty로 keygen을 해서 접속하는 방법 외에 그냥 바로 ssh 명령어로 붙을 수도 있습니다.



해당 RSA key를 ssh -i 속성을 줘서 import 시키고 bandit26으로 접속하면 동일하게 클리어 가능합니다.





OverTheWire Bandit 끝!

  1. AAA 2016.12.15 13:29

    안녕하세요 pwnable.kr unlink 문제를 풀고있는데 너무 안풀려요 혹시 힌트라도 줄수 있나요 ? DFB 인것은 알고있는데 어딜 덮어야하는지 전혀 모르겠어요 .. ㅠㅠㅠㅠㅠㅠ

  2. 2016.12.17 15:18

    비밀댓글입니다

  3. asd123 2016.12.17 15:19

    관리자의 승인을 기다리고 있는 댓글입니다

  4. 2016.12.18 12:14

    비밀댓글입니다

  5. 2016.12.18 16:58

    비밀댓글입니다

  6. 2016.12.31 01:45

    비밀댓글입니다

OverTheWire_Wargame Bandit

[ level24 -> level25 ]




자, 이번 문제는 드디어 cron에서 벗어났네요.

한 데몬이 30002포트로 listening 상태에 있다고 합니다. 만약 bandit24의 패스워드와 함께 4자리의 숫자 핀코드를 제대로 때려박아준다면 bandit25로 향하는 패스워드를 알려주겠다네요.

전형적인 브루트포싱 문제입니다. 파이썬으로 코드를 짜서 돌리도록 합시다.



먼저, nc로 반응이 어떠한지 확인을 해 보았습니다.

한 번 연결하면 계속 입력을 받는 구조군요. 실패 시 출력 값은 Fail! You did not supply enough data. Try again. 입니다.

그런줄 알았는데....

Fail 부분은 제대로 된 길이의 인자를 전송하지 않았을 때 발생하는 에러 출력값이었습니다.

제대로 된 문자열을 전송했을 경우의 실패 메시지는 Wrong! Please enter the correct pincode. 입니다.

이걸 기반으로 코드를 짜보도록 하겠습니다.



4중 for문으로 브루트포싱하였습니다. 맨 처음 기본 출력값이 있기 때문에 recv를 한번 해주었고, 그 이후에는 send와 recv를 번갈아가며 실행, 실패 메시지가 출력되지 않았을 경우 그 문자열을 뱉어내는 코드입니다.



bandit25로 향하는 문을 열어줄 패스워드를 뱉어냈습니다!

OverTheWire_Wargame Bandit

[ level23 -> level24 ]




이번 레벨 또한 cron을 이용한 문제입니다.

NOTE 부분을 확인 해 보니 이번엔 우리가 쉘스크립트를 짜야 한다고 하네요.

바로 cron을 확인 해 봅시다.



역시 다음 레벨을 위한 cronjob_bandit24가 우릴 기다리고 있습니다.

내용은 /usr/bin/cronjob_bandit24.sh을 실행하는 것입니다.

cronjob_bandit24.sh에는 어떤 내용이 있는 지 살펴보도록 하죠.



이 쉘스크립트를 실행하는 주체는 bandit24이므로, $myname에는 bandit24가 들어 갈 것입니다.

그리고 경로를 /var/spool/bandit24로 바꿔주는군요.

그리고 해당 경로에 있는 모든 파일(와일드 카드로 *, .*이기에 숨김파일도 포함)의 이름을 i에 저장하면서 루프를 돌기 시작합니다.

현재 경로와 이전 경로를 나타내는 .과 ..을 제외한 나머지(모든 파일)의 경우 timeout 명령어를 이용하여 프로그램을 실행합니다.

그리고 프로그램의 실행이 끝나면 rm 명령어로 해당 프로그램을 삭제합니다.

모든 파일이 삭제 될 때 까지 루프를 도는 쉘 스크립트입니다.

그렇다면 /var/spool/bandit24로 넘어가서 쉘 스크립트를 짜보도록 하겠습니다.



이 쉘 스크립트의 이름은 test.sh로 해주었으며, bandit24로 통하는 패스워드를 1이라는 파일명으로 출력해주는 스크립트입니다.

처음에는 /tmp 경로에 폴더를 새로 만들어 출력 해 주려고 하였으나, 폴더를 만들 경우 bandit23에만 권한이 있기 때문에 파일 생성이 되지 않았습니다.

그래서 결국 동일한 경로에 생성을 해 주기로 생각하였습니다.

또한, cronjob_bandit24.sh의 경우 60초 주기로 돌기 때문에 1이라는 파일은 삭제가 되기까지 약간의 시간이 있을거라 생각하고 풀이하였습니다.



test.sh에 실행 권한을 주고 약간의 텀을 주면서 ls를 여러 번 실행 한 결과 1이라는 이름의 파일만 남게 되었고, cat으로 출력해주면 24레벨로 통하는 패스워드를 얻을 수 있습니다.

OverTheWire_Wargame Bandit

[ level22 -> level23 ]




이번 레벨도 cron을 이용한 문제네요. 저번 문제와 동일하게 쉘스크립트가 실행되고 있는 모양입니다. 확인 해 보도록 합시다.



/etc/cron.d/ 폴더 안에 cronjob_bandit23이 존재하고 있습니다.



cat으로 확인 해 본 결과, 역시 쉘스크립트를 실행하고 있네요.

스크립트는 echo I am user $myname | md5sum | cut -d ' ' -f 1 을 실행하고, 그 결과값을 파일명으로 패스워드를 저장하네요.

whoami의 결과는 현재 환경에서는 bandit22가 나오겠네요. 하지만 우리가 찾아야 하는 것은 bandit23의 패스워드이므로, $myname은 bandit23이 되어야 합니다.

md5sum은 md5 checksum을 확인하는 용도로, 해당 이름의 md5값을 반환시켜줍니다. 그리고 cut 명령어는 문자열을 자르는 substring과 비슷한 명령어입니다.

cut 명령어의 -d 옵션은 문자열을 자르기 위한 기준 문자를 지정해주는데, 위 스크립트에서는 공백을 기준으로 잡았습니다. -f 옵션은 필드를 뜻하는데, 첫 번째 필드에 있는 문자열을 반환하는거죠.

md5sum에 의해 "I am user bandit23"의 md5값을 반환시키는데, 본래 md5sum의 반환값이 [md5변환값 원래문자열] 이기 때문에, cut 명령어를 실행하면 md5변환값만 남게 됩니다.

자, 이제 동작 원리는 파악했으니 직접 명령어를 때려보도록 하죠.



$myname 부분을 bandit23으로 수정 후 바로 출력시켜줍니다.

반환 된 md5값을 파일명으로 cat 해보니 레벨23으로 갈 수 있는 패스워드가 출력되었습니다.

OverTheWire_Wargame Bandit

[ level21 -> level22 ]




이번 문제는 윈도우에서 예약작업에 해당하는 cron에 대한 것입니다.

/etc/cron.d/ 폴더를 확인하여 어떤 작업이 실행되고 있는 지 확인하라고 하네요. 한 번 확인해주도록 하죠.



해당 폴더에 들어가 보니 딱 bandit22라는 이름이 들어 가 있는 게 보이네요. cat으로 읽어줍니다.

/usr/bin/cronjob_bandit22.sh이라는 쉘스크립트를 실행시키네요. 이건 또 어떤 작업을 하는 지 확인 해봐야겠죠?



cat으로 읽어 준 결과, /etc/bandit_pass/bandit22 에 적혀있는 내용을 /tmp/t706lds9S0RqQh9aMcz6ShpAoZKF7fgv에 옮겨줍니다.

이 말은 bandit22의 패스워드를 저 파일 안에 넣어준다는 소리죠.

cat으로 저 파일을 읽어주면 다음 레벨로 통하는 패스워드를 획득 할 수 있습니다.


OverTheWire_Wargame Bandit

[ level20 -> level21 ]




이번 문제 또한 레벨19와 동일하게 setuid가 걸려있어, bandit21의 권한으로 무언가를 실행 시킬 수 있습니다. 문제를 읽어보면 setuid가 걸려있는 바이너리를 이용하여 네트워크 데몬을 연결하고, level20의 패스워드를 넣으면 level21로 넘어갈 수 있는 패스워드를 던져준다고 합니다.

직접 한번 해보도록 합시다!



홈 디렉토리에 suconnect라는 바이너리가 하나 존재합니다. setuid가 level21 권한으로 걸려있고, 실행 시켜 보니 localhost에 열려있는 다른 포트를 넣어주고, 다른 쪽에서 level20의 패스워드를 넣으라는 문구가 나타났습니다.

그럼 새로운 콘솔을 띄워서 nc로 포트를 열어주면 되겠군요.



nc에 -l 옵션으로 listening 모드로 실행시키고, 포트를 50000으로 잡아주었습니다.

이 쪽이 listening 하는 입장이므로 서버라고 지칭하겠습니다.



자, 다시 다른 터미널로 넘어와서 suconnect 바이너리를 실행시켜줍니다.

우리는 서버 측에서 50000이라는 포트를 열어주었기에 suconnect 바이너리의 인자값에도 50000을 넣어주겠습니다.


다시 서버로 돌아와서, level20의 패스워드를 넣어주니 level21로 통하는 패스워드를 뱉어주었습니다!


OverTheWire_Wargame Bandit

[ level19 -> level20 ]




이번 레벨의 목표는 setuid가 걸려있는 바이너리를 이용하여 /etc/bandit_pass 안에 있는 파일을 읽어 key 값을 찾아내는 것입니다.

한 번 살펴보도록 하죠.



bandit20-do 바이너리를 살펴보니 group 권한에 setuid 비트가 있는 것을 확인 할 수 있었습니다.

그렇다면 bandit20-do 바이너리를 실행 할 때는 bandit20의 계정으로 실행이 된다는 것이죠.

실행을 시켜보니 "./bandit20-do id" 와 같은 형식으로 사용 하라고 하네요.

바로 cat 명령어를 이용하여 bandit20의 key값을 출력 해 주었습니다.


OverTheWire_Wargame Bandit

[ level18 -> level19 ]




이번 문제는 홈디렉토리에 readme라는 파일 안에 key 문자열이 들어있다고 하는데, 누군가 .bashrc 파일을 수정하여 SSH에 로그인 할 때마다 세션이 끊어진다고 합니다.

이 경우에는 일반적인 ssh 로그인으로는 문제를 풀 수 없고, ssh의 기능 중 원격 코드를 실행하는 것이 있는데 이 것을 이용하면 key를 얻어낼 수 있습니다.


ssh user@host "operation"


위와 같은 형식으로 원격 명령을 실행 할 수 있습니다.


직접 로그인을 한 것이 아니기 때문에 .bashrc는 실행되지 않고, key값만 출력 된 것을 확인 할 수 있습니다.


OverTheWire_Wargame Bandit

[ level17 -> level18 ]




이번 문제는 홈 디렉토리에 passwords.old, passwords.new로 2개의 파일이 존재하는데, passwords.new에 새로 추가된 한 줄의 문자열이 다음 레벨로 갈 수 있는 key라고 합니다.

여기서는 diff 명령어를 사용하도록 하죠.



< 의 경우 argv[1]에만 존재하는 문자열, >의 경우 argv[2]에만 존재하는 문자열입니다.

간단하게 key를 구하였으나.... 문제에도 나와 있듯이, level18로 로그인을 할 경우 "byebye !" 라는 문자열이 출력되고 세션이 종료된다고 나와 있습니다.

하지만 저는 이것까지 우회하는 것이 이 문제의 의도인줄 알고.. 4시간동안 삽질하다 다른분들의 write up을 보니 여기가 끝이었네요.


..쮸륵......

OverTheWire_Wargame Bandit

[ level16 -> level17 ]



이번 레벨은 31000~32000 사이에 있는 포트 중 하나에서 다음 레벨로 갈 수 있는 키를 얻을 수 있다고 합니다.

먼저, 이 포트들 사이에서 listening 하고 있는 포트를 찾고, SSL 통신을 하는 지 안하는 지 확인을 합니다. 그리고 추려 낸 SSL 통신 중 오직 1개의 서버만이 다음 레벨로 갈 수 있는 key값을 뱉어준다고 하네요.

그럼 nmap으로 포트스캔을 해 봅시다.


31000, 31046, 31518, 31691, 31790, 31960으로 총 6개의 포트가 listening 하고 있는 것을 알 수 있습니다.



31518, 31790 두 개의 포트에서만 SSL 통신을 하고 있었습니다.

OpenSSL 버전은 1.0.1f이므로, HEARTBLEED 취약점이 발생하는 것을 알 수 있습니다.


openssl s_client -connect localhost:31518 -ign_eof

openssl s_client -connect localhost:31790 -ign_eof


위 두 명령어로 현 레벨의 key값을 보내 주면 31790 포트에서 다음 레벨로 갈 수 있는 RSA_private key값을 얻을 수 있습니다.


이 RSA key값을 putty keygen을 이용하여 SSH_RSA key값으로 변경 해 준 후, bandit17로 연결하면 정상접속 되는 것을 확인 할수 있습니다.

+ Recent posts