1月月赛Web3

WriteUp

说一下我整个的做题过程吧。
刚开始对Web1 Web3…emmm…就是那种哪道题都不会做,不知道要专注于做哪道题的感觉。??太真实了。
Web3就是…不管我输入什么…结果都是一样的current content is update the content,爆了目录,什么都没,然后各种特殊字符测试了一下,也什么都没…然后题目本身的提示信息我还压根不理解。所以…我就一直发呆,这个题目的门在哪??

后来让出题人给我指了一下门在哪,就是告诉我那个提示信息是什么意思…oh…原来是还有一个content字段,提示我,现在这个字段值是update the content…emmm…这么一说,好像提示的也不是很隐晦。

接着就有搞头了。

测试发现后台的逻辑应该是:
判断有没有传入content参数,如果有,那就执行update语句,再执行select语句,把更新后的content字段值查询出来,输出到界面上。
如果没有,那就执行select content字段值。

?对了,出题人还顺口跟我提了一句说,注入点不在content,在table参数,所以我做的时候,就是直接集中注意力到table参数了。

非预期解法

猜测后台sql语句

首先要执行update语句,那到底是怎么执行的呢?正常的update语句如下:
update table_name set column_x='xxx' where column_y='xxx'
table_name在这个题目中当然就是test了,column_x就是content,测试发现单引号,双引号这些都是被转义了的,又因为在sql语句中,表明经常会用反引号给括起来,所以就试了一下test`,发现给了报错信息,然后知道column_yid,同时知道,是有报错回显的,我们可以根据报错提示来帮助猜测后台的sql语句是怎么写的。
到这里猜测语句是:update `code.test` set `content`=‘1’ where id=1

在这里插入图片描述

接着按正常套路去测试test`#,按照我猜测的语句,应该是会报错,因为注释掉之后,语句应该就只剩下update `code.test`了,语句不完整,但是实际发现没有报错,语句正常执行,并且更新了content字段的值???哈???怎么回事,然后就在本地的mysql也测试了一下。之后就不知道怎么突然想到是多行注释,并且也注意到了在报错信息中,就是多行的,所以现在猜测后台的语句是:

update `code.test`
set `content`=1
where id=1

这样就可以解释看到的不报错,正常更新现象啦。

构造payload

那接下来怎么做呢??

我想要注释掉后面的部分,只执行我想要的结果。我肯定是要把flag通过content字段给显示出来的,所以我就想要在set content的时候,把它set为我查询出来的一个值。所以就很直接地多行注释,并且content值我们也是可以控制的,而且出题人过滤不严格,是可以让我们实现多行注释的。

update `code.test` set `content`=1/*
set `content`=‘3*/%23’
where id=1

喏,解题方法就出来了。后面做的过程中也没有遇到绕不过的过滤。最终的payload

?table=test`%20set%20`content`%3d(select%20column_name%20from%20information_schema.columns%20where%20table_schema%3ddatabase()%20and%20table_name=(select%20table_name%20from%20information_schema.tables%20where%20table_schema%3ddatabase()%20limit%201)%20limit%201)%20%2f*&content=6*%2f%23

通过这样的方式拿到表名是flag,列名是idfl3g,然后直接查询,就可以把content字段更新为flag值了。美滋滋。

我跟出题人说我做出来了,?然后发现是非预期,他的过滤不严格,导致我可以多行注释,可以用information_schema…emmm…我知道正确做法之后,emm…非常理解为什么我做出来他这么惊讶了。

预期解法

接下来就说一下正确做法。
说一下真正的出题人要过滤的东西:

  1. 首先,content字段进行了严格的处理,对*进行了过滤,所以按之前的方法进行多行注释是不可能的了,而百度之后发现多行注释好像也就只有那一种方法,那多行注释应该是行不通了;
  2. informaiton_schema被过滤掉了,也就是说我们不能通过直接查这个来得到表名和列名,那正好我出的那个题目就是在过滤掉information_schema的情况下去用子查询的方式来在不知道列名的情况下进行注入,查询,这里用到的是相同的方法。flag这个表名是靠猜出来的。

接下来就是完完全全只能对table这个参数值进行处理了。
还是想要怎么摆脱掉后面set xxx=xxx where xxx=xxx这两个语句,我本来是想用;隔成两个语句,我先执行前面的语句,后面的语句让它错误,或者是怎么样的:

update `code.test` set `content`=9 where id=1;update `code.test`%23`
set `content`=‘3’
where id=1

哈哈哈,太美的爱情因为太年轻?‍♀️
测试不成功,在本地命令行直接执行这样的语句的话,是可以的,但是通过php连接mysql执行这样的语句是不行的,百度了一下发现:通过php这样的编程去执行sql语句,为了防止sql注入,本来就是限制了只能执行一条语句的。(我不知道查的对不对,或者说的是不是全面啊,意思就是这么个意思)那这条路肯定行不通了,不可能让我执行两条语句的,然后我就卡在这里了。

我还在草稿纸里写了这么一句话:
在这里插入图片描述

不能去掉后面的两个句子,就只能让它融进来了…期间想到怎么用个union这样的,和code.test合在一起,emm…但是union是不能这样用的…后来出题人告诉我用jion…?,我自己出题也用到join了啊…为什么我没有想到,这样不就是联合在一起,但是没有用union嘛…感觉还是对join太不熟悉了,不过整体的想的过程…哈哈哈,再次对自己很满意?

那,payload如下:

?table=test`%20join%20(select(ST_LongFromGeoHash((select%20i.2%20from%20(select%20*%20from%20(select%201)a%20join%20(select%202)b%20union%20select%20*%20from%20`flag`)i%20limit%201%20offset%201))))a%23&content=6

?让我来把正常形式列出来:

table=test` join (select(ST_LongFromGeoHash((select i.2 from (select * from (select 1)a join (select 2)b union select * from `flag`)i limit 1 offset 1))))a#&content=6

对了,忘记说这个报错注入了,emm…大佬知道的真多,mysql5.7的报错注入函数。

ST_LatFromGeoHash
ST_LongFromGeoHash
ST_PointFromGeoHash
floor
geometrycollection
multipoint
polygon
multipolygon
linestring
multilinestring
exp
GTID_SUBSET
GTID_SUBTRACT

那个子查询,查到的表是1,2是第一行,后面再接着flag表的内容的,我们只能查询一行,所以就用limit 1 offset 1,刚开始一直想着用order by…然后发现order也被过滤了(就应该直接想到用limit offset的?‍♀️)

因为我出的那个题目也用到了这个子查询,我记得当时写writeup时候还想来着,为什么只显示一行,出来的不是1,2,而是我真正要查的那个表的内容呢????因为很正好,所以我就没有继续去想了。感觉讲道理,出来的就应该是1,2,不知道咋回事。

感想

那,最后就是一些感想啦。

  1. sql注入的题目,要去猜后台的sql语句是怎么写的,并且要根据现象,来判断猜测的对不对,要确保后台的语句我们知道了, 要不然还做个鬼哦?
  2. 在做的过程中,多在本地测试,看对不对,帮我我们去猜测后台语句;
  3. 要知道后台过滤了哪些关键字,哪些可以用,哪些不能用,不能盲目地乱试;
  4. 在没有过滤information_schema时候,可以通过information_schema去得到表名,列名;过滤时,猜测表名,然后通过子查询在不知道列名的情况下注入(之前每次做题目的时候都是心里盼着人家没有把information_schema过滤掉,如果过滤了我就不知道怎么办了。虽然现在还不知道是不是只能这样绕过,但是至少又有一个尝试的了,以后又知道新方法的话,会总结到一起的)
  5. 另外,做题目的时候还是要把自己的思路,写在草稿文档里的,emmm,一定要有思路,思路清晰

(感觉题目都好难哦,十道题有九道题我都是拿到完全什么都不知道的那种,emm,碰到一道自己能动手的题目真是开心啊)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值