递归扫描(广搜)

/// <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;
			}
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值