1、暴力破解-low

1、暴力破解-low

暴力破解介绍

使用攻击者准备的自己的用户名和密码,一个一个枚举,尝试是否能登陆

理论来说,字典够大,就能破解

low

环境准备

java安装

字典准备

工具:brup

分析源码

<?php

if( isset( $_GET[ 'Login' ] ) ) {//是否提交了login参数
    // Get username
    $user = $_GET[ 'username' ];//接受usename传给user

    // Get password
    $pass = $_GET[ 'password' ];//接受password传给pass
    $pass = md5( $pass );//给passmd5加密

    // Check the database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";//sql语句查询,从users表里面查询所有user=‘user’并且password=‘pass’的值
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' .((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );//连接错误,或者没有设置连接就会报错

    if( $result && mysqli_num_rows( $result ) == 1 ) {//结果存在并且行数等于一
        // Get users details
        $row    = mysqli_fetch_assoc( $result );//结果集中取得一行作为关联数组放在row里面
        $avatar = $row["avatar"];//row的avatar下标

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";//输出avatar对应的图片
    }
    else {
        // Login failed
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }//如果验证失败就会返回登录失败

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?> //没有提交login参数就不执行任何操作

获取用户名、密码(md5加密)、使用数据库查询语句进行数据库查询、结果判断是否存在

判断语句:如果查询结果在数据库中存在,得到用户详细信息,显示welcome……,否则返回用户名和(或)密码错误

从源码中发现对**$user**没有做任何过滤,存在明显的sql注入漏洞;

而**$pass**设置了md5加密算法,杜绝了通过参数password进行sql注入的可能性。

暴力破解-low

随便输入账号密码

brup代理拦截
在这里插入图片描述

login

在这里插入图片描述

send to intruder

在这里插入图片描述
然后设置参数,表示爆破的字段
在这里插入图片描述

第一种:
Sniper标签 这个是我们最常用的,Sniper是狙击手的意思。这个模式会使用单一的payload【就是导入字典的payload】组。它会针对每个position中$$位置设置payload。这种攻击类型适合对常见漏洞中的请求参数单独地进行测试。攻击中的请求总数应该是position数量和payload数量的乘积。

第二种:
Battering ram – 这一模式是使用单一的payload组。它会重复payload并且一次把所有相同的payload放入指定的位置中。这种攻击适合那种需要在请求中把相同的输入放到多个位置的情况。请求的总数是payload组中payload的总数。简单说就是一个playload字典同时应用到多个position中

第三种:
Pitchfork – 这一模式是使用多个payload组。对于定义的位置可以使用不同的payload组。攻击会同步迭代所有的payload组,把payload放入每个定义的位置中。比如:position中A处有a字典,B处有b字典,则a【1】将会对应b【1】进行attack处理,这种攻击类型非常适合那种不同位置中需要插入不同但相关的输入的情况。请求的数量应该是最小的payload组中的payload数量

第四种:
Cluster bomb – 这种模式会使用多个payload组。每个定义的位置中有不同的payload组。攻击会迭代每个payload组,每种payload组合都会被测试一遍。比如:position中A处有a字典,B处有b字典,则两个字典将会循环搭配组合进行attack处理这种攻击适用于那种位置中需要不同且不相关或者未知的输入的攻击。攻击请求的总数是各payload组中payload数量的乘积。

在这里插入图片描述

设置线程,网络失败重试多少次,多少秒重试

start attack
在这里插入图片描述

点length,按响应状态码排序,一般不一样的那个就是正确破解的,可以点开查看响应报文

这里爆破出密码是password

试了试果然可以

SQL注入

手工sql注入

1. Username: admin’ or ’1′=’1

Password: (空)

注入成功

原理:

select name from 表 where name='admin' or '1'='1'
1=1 永真

在这里插入图片描述

2. Username : admin’ #

Password : (空)

注入成功

原理:# 为注释 后面均无效

在这里插入图片描述

#include<iostream> #define MAXSIZE 4000000 using namespace std; struct Point { long long x, y; }; struct Point point[MAXSIZE]; long long times = 0; long long value[MAXSIZE]; void mergex(Point* point, int low, int mid, int high) { Point* A = point + low; int lb = mid - low; Point* B = new Point[lb]; for (int i = 0; i < lb; B[i] = A[i++]); int lc = high - mid; Point* C = point + mid; for (int i = 0, j = 0, k = 0; (j<lb)||(k<lc); ) { if ((j<lb)&&((lc<=k)||(B[j].x<=C[k].x))) { A[i++] = B[j++]; } if ((k<lc)&&((lb<=j)||(C[k].x< B[j].x))) { A[i++] = C[k++]; } } delete[] B; } void x_mergesort(Point* point,int low,int high) { if (high-low<2) { return; } int mid = (high + low) / 2; x_mergesort(point, low, mid); x_mergesort(point, mid, high); mergex(point, low, mid, high); } void mergey(long long* value, int low, int mid, int high) { long long* A = value + low; int lb = mid - low; long long* B = new long long[lb]; for (int i = 0; i < lb; B[i] = A[i++]); int lc = high - mid; long long* C = value + mid; for (int i = 0, j = 0, k = 0; (j < lb) || (k < lc); ) { if ((j < lb) && ((lc <= k) || (B[j] <= C[k]))) { A[i++] = B[j++]; if (k < lc) { times = times + (lc - k); } } if ((k < lc) && ((lb <= j) || (C[k] < B[j]))) { A[i++] = C[k++]; } } delete[] B; } void y_mergesort(long long* value, int low, int high) { if (high - low < 2) { return; } int mid = (high + low) / 2; y_mergesort(value, low, mid); y_mergesort(value, mid, high); mergey(value, low, mid, high); } int main() { int n, x, y; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%lld %lld", &point[i].x, &point[i].y); } x_mergesort(point, 0, n); for (int i = 0; i < n; i++) { value[i] = point[i].y; } y_mergesort(value, 0, n); printf("%lld\n", times); } 这是清华大学数据结构的lighthouse问题,要求用归并实现,给这段代码是参考答案,但是没有注释,能不能加注释,并告诉我这道题的解题思路。
最新发布
05-22
### 清华大学数据结构 Lighthouse 问题的归并排序实现 Lighthouse 问题是典型的二维平面上点的关系判断问题。目标是从给定的一组点中统计满足特定条件的点对数量。通过分析引用内容[^1]和[^2]可知,暴力求解的方法时间复杂度较高 \(O(n^2)\),无法应对大规模输入;因此采用更高效的算法——基于 **归并排序** 的解决方案。 #### 解题思路 该问题的核心在于如何高效地统计符合条件的点对数目。具体来说: - 如果两个点 \((x_1, y_1)\) 和 \((x_2, y_2)\) 满足 \(x_1 < x_2\) 并且 \(y_1 < y_2\),则它们构成一对有效点对。 - 需要找到一种方式快速统计这些点对的数量,而不是逐一检查每一对可能的情况。 为了降低时间复杂度,可以借助 **归并排序** 来完成这一任务。以下是具体的步骤说明: 1. 将所有点按照其 \(x\)-坐标升序排列(如果 \(x\)-坐标相同,则按 \(y\)-坐标升序)。这一步可以通过快速排序或其他稳定排序算法来实现。 2. 对于已经按 \(x\)-坐标排序好的序列,进一步应用归并排序的思想处理 \(y\)-坐标的顺序关系。 3. 在归并的过程中,记录那些在左子区间中的点能够与右子区间的某些点形成有效的点对。这种操作可以在 \(O(\log n)\) 时间内完成。 最终的时间复杂度为 \(O(n \log n)\),相比暴力方法显著优化。 --- #### 实现代码及其注释 下面是完整的 Python 实现代码,并附有详细的注释以便理解每一部分的功能。 ```python def count_light_house(points): """ 统计满足 (xi < xj and yi < yj) 的点对数量。 参数: points: list of tuples [(x1, y1), (x2, y2)...], 表示各个灯塔的位置 返回: int: 符合条件的点对总数 """ # Step 1: 定义辅助函数 merge_sort_and_count,用于执行带统计功能的归并排序 def merge_sort_and_count(arr): """递归调用归并排序的同时统计符合条件的点对""" if len(arr) <= 1: return arr, 0 mid = len(arr) // 2 left_arr, left_count = merge_sort_and_count(arr[:mid]) # 左侧子数组及内部的有效点对数 right_arr, right_count = merge_sort_and_count(arr[mid:]) # 右侧子数组及内部的有效点对数 merged_arr, split_count = merge_and_count_split(left_arr, right_arr) total_count = left_count + right_count + split_count # 总的有效点对数 return merged_arr, total_count # Step 2: 合并两段已排序的部分,并在此过程中统计跨区域的有效点对 def merge_and_count_split(left, right): result = [] i = j = inversions = 0 while i < len(left) and j < len(right): if left[i][1] <= right[j][1]: # 若左侧当前点的 y 不大于右侧当前点的 y result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 # 关键逻辑:当右侧某个点被加入到结果列表时, # 所有尚未处理的左侧点都可以与其组成有效点对 inversions += len(left) - i # 添加剩余未处理的元素 result.extend(left[i:]) result.extend(right[j:]) return result, inversions # Step 3: 主程序入口 sorted_points = sorted(points, key=lambda p: (p[0], p[1])) # 初步按 x 升序排序,若有冲突则按 y 排序 _, answer = merge_sort_and_count(sorted_points) return answer # 测试案例 if __name__ == "__main__": test_data = [ (1, 1), (2, 2), (3, 3), (1, 2), (2, 3), (3, 4) ] print(count_light_house(test_data)) # 输出应为 9 ``` --- #### 注释详解 1. `merge_sort_and_count` 函数实现了带有额外统计功能的归并排序过程。每次分割都会返回一个有序数组以及对应的点对计数值。 2. `merge_and_count_split` 是核心部分之一,负责合并两个子数组并将其中间断层的有效点对计入总和。 3. 外部主函数首先对原始点集进行了初步排序,确保后续仅需专注于 \(y\)-轴方向上的相对次序即可。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值