/// <summary>
/// 递归扫描(广搜)
/// </summary>
private void SubScan()
{
// 临时表清空
tmpPoints.Clear();
// 线程同步
// 锁住可能注入点集合
lock (PossibleInjectionPoints.SyncRoot)
{
// 遍历当前层的各页面
foreach (InjectionPoint point in PossibleInjectionPoints)
{
#region 处理当前层各页面
// 若该点“已处理”,过
if (point.IsDealed) { continue; }
// 标记为“已处理”
point.IsDealed = true;
// 检查是否可注入
if (CanInject(point.Url) == true)
{
point.CanInject = true;
this.InjectablePageCount++;
this.IsInjectable = true;
}
// 不可注入,即为安全页面
else
{
this.SecurePageCount++;
}
// 在第一次发现可注入点时检测数据库类型,且只检测这一次
// 发现的第一个可注入点还未曾更新数据,且当前检测点的URL中不含字符‘%’
if (this.FirstInjectionPoint == "" && point.Url.IndexOf('%') == -1)
{
// 给发现的第一个可注入点赋值
this.FirstInjectionPoint = point.Url;
// 获取数据库类型
this.DBType = this.GetDBType(this.FirstInjectionPoint);
}
#endregion
#region 触发多线程,进行下一轮扫描
this.url = point.Url;
// 实例化一个线程,获取当前页面中的可能注入点
t[n % t_num] = new Thread(new ThreadStart(ThreadProc));
// 线程开始执行
t[n % t_num].Start();
// 将当前线程挂起指定的时间(毫秒)
Thread.Sleep(300);
// 内部线程数n再加1
n++;
#endregion
}
// 等待发出的最多100个线程是否返回
for (int i = 0; i < (n > t_num ? t_num : n); i++)
{
// 若有返回
if (t[i] != null)
{
// 阻塞该线程
t[i].Join();
}
// 若该线程对应页面中仍有可能注入点
if (tmpPoints.Count > 0)
{
#region 过滤重复的URL类型,将不重复的可能注入点添加到可能注入点集合中
// 两层遍历
for (int j = 0; j < tmpPoints.Count; j++)
// foreach (InjectionPoint tmpPoint in tmpPoints)
{
InjectionPoint tmpPoint = (InjectionPoint)tmpPoints[j];
foreach (InjectionPoint point in PossibleInjectionPoints)
{
// 添加当前point到可能注入点集合中
if (CheckInsert(tmpPoint, point))
{
// 以首页url开头
if (tmpPoint.Url.StartsWith(RootUrl))
{
// 把当前新的url插入到可能注入点集合中
//InsertPoint(tmpPoint, PossibleInjectionPoints);
while (locked_point) ;
if (!locked_point)
{
// 锁住
locked_point = true;
// 把当前新的url插入到可能注入点集合中
PossibleInjectionPoints.Add(tmpPoint);
// 解锁
locked_point = false;
// 该层子线程数+1
floor_threads_num[floor]++;
break;
}
}
else
{
foreach (IPAddress ip in IpList)
{
if (tmpPoint.Url.StartsWith("http://" + ip.ToString()))
{
// 把当前新的url插入到可能注入点集合中
// InsertPoint(tmpPoint, PossibleInjectionPoints);
// 锁住
locked_point = true;
// 把当前新的url插入到可能注入点集合中
PossibleInjectionPoints.Add(tmpPoint);
// 解锁
locked_point = false;
// 该层子线程数+1
floor_threads_num[floor]++;
break;
}
}
}
}
}
tmpPoints.Clear();
if (floor_threads_num[floor] > 0)
{
floor++;
floor_threads_num[floor] = 0;
// 依次终止该层所有完成的线程
for (int k = 0; k < ((n > t_num) ? t_num : n); k++)
{
if (t[k] != null)
{
// 终止线程
t[k].Abort();
}
}
// 当前层子线程数清零
n = 0;
// 递归扫描
SubScan();
}
}
#endregion
}
// 若该线程对应页面中没有可能注入点
else
{
// 标识扫描结束
floor_threads_num[floor] = -1;
}
}
}
}
递归扫描(广搜)
最新推荐文章于 2022-05-19 13:02:54 发布