由order by排序注入实战引发的思考

最近一直忙着实习面试,在准备面试的过程确实也补充了很多自己以前的知识盲区,虽然有点考前恶补的意思,但能学到知识总归是好的。当然,面试的结果也还算满意,虽然还没有拿到自己心中T0的大厂offer,但也获得了很多其他乙方包括某个大厂甲方的实习offer。师哥们也陆续去实习了,老师这边压着比较多的项目正在推进,大都是渗透方向的,包括这个月的业务,所以趁着实习面试的尾声,好好的干一波嘿嘿。

一、Result

这个月的业务挖洞成果对自己来说还是很满意的,除了漏洞数量外,漏洞质量也比较高。具体就不多说了,言归正传,在本月的业务渗透测试里发现一个很有趣的sql注入,也是自己之前的一个盲区——order by排序注入,一直想着在实战中接触这种类型的注入场景,还真就来了。

二、Process

话不多说,上接口:

https://xxxx.com/xxx/xxx/xxx/getAreaSpotPageList?&pageindex=1&pagesize=20&passAreaId=2&orderby=pass_area_spot_id+desc&userId=1181163&hotelId=5&brandId=5

这是一个比较正常的get类型的获取数据接口,但orderby参数比较惹眼,因为参数的值为pass_area_spot_id+desc,desc表示的是sql中的降序排序,却以orderby参数值的方式输入,所以就对该参数进行了测试:

Step 1:

令orderby=pass_area_spot_id+desc,返回数据如下:

image.png

Step 2:

令orderby=pass_area_spot_id+asc,返回数据如下:

image.png

(解释一下,两种情况下返回内容不一致)

Step 3:

这里其实大致可以判断存在排序注入的可能,但还是有歧义,需要进一步进行判断,这里采用基于时间的盲注辅助判断:

Payload1:pass_area_spot_id+desc,(select*from(select+sleep(3)union/**/select+1)a)

返回如下:


image.png

该请求在5s多时得到响应。

Payload2:pass_area_spot_id+desc,(select*from(select+sleep(6)union/**/select+1)a)

返回如下:


image.png

该请求在8s多时得到响应。
在不考虑测试环境本身的网络状况,上述测试过程可以证明漏洞的存在。

Step 4:

Time-based还是不太方便,并且时间较长。所以更换注入手法,直观输出注入结果:

Payload:pass_area_spot_id+desc,if(ascii(substr(database(),? ,1))=?,1,(select%201%20from%20information_schema.tables))

通过布尔类型的盲注,利用上述payload进行fuzz(省略通过二分法判断当前数据库长度的步骤):


image.png

查找对应ascii所代表的字符,获得当前数据库名:xxxxxxxx,测试结束。

三、Review

在整个测试阶段里,虽然注入成功,但是也引发了自己的两个问题,这两个问题也是自己在面试的过程中所碰到的。

Q1、为什么预编译不太好防order by注入(就mysql数据库来谈)?

A1:

这个问题不管在面试的过程中还是个人的平时积累过程中都能够折射出个人的学习深度,很遗憾,我并没有在面试的过程中很好的回答这个问题,其实并不是不知道这个问题的答案,而是不太好组织语言去系统性的带扩展的回答它,并且在之前的挖洞经历里没有对应的场景支撑,所以还是比较遗憾吧,另一方面更说明自己的知识体系太弱,表面徘徊较多。
言归正传,为什么预编译不太好防order by注入?这个问题等于是在问为什么在预编译中order by后不能参数化?一般的sql执行片段代码(预编译方式)是这样的:

Connection conn = DBConnect.getConnection();
String sql = " SELECT xxx FROM xxx WHERE xxx = ? ";
ps = conn.prepareStatement(sql);
ps.setString(1, xxx); //或者ps.setInt(1, username);
rs = ps.executeQuery();

当我们输入xxx=abc时,预编译的代码会自动给abc加上引号,变成'abc',sql语句也变成了:

String sql = " SELECT xxx FROM xxx WHERE xxx = 'abc' ";

这样可以有效的防止用户的输入直接拼接在sql语句之后,譬如用户输入xxx=' or '1'='1时,实际上的sql语句却为:

String sql = " SELECT xxx FROM xxx WHERE xxx = '' or '1'='1' ";

无法达到攻击的效果。说回order by,order by的用法一般为order by [字段名] [desc/asc],如果对order by之后的输入进行参数化,那么sql语句将会变成这样:

String sql = " SELECT xxx FROM xxx WHERE xxx ='xxx' order by 'xxx' "

这样会造成sql语法错误,因为此时'xxx'是字符串而不是字段名。
那么为什么预编译的函数在参数化时非要把输入加上引号呢?如果没有引号不就可以防御order by注入了吗?是的,但确实没有不加引号的预编译的方法哈哈。
引伸来说,这样的sql注入不仅仅发生在order by处,任何需要字符串且不能够加引号的地方都有可能发生类似的注入,因为不能参数化的位置,不管怎么拼接,最终都是和使用“+”号拼接字符串的功效一样。
那么又引出了新的问题,既然预编译防不了order by,那么该怎么样防?答案是采用白名单的方式,因为order by之后跟的字段名肯定是有限的并且是数据库中已经存在的字段,只要对这些有限字段设置白名单,任何不在白名单内的数据统一报错,那么就可以解决啦。

Q2、面对时间较长的Time-based或者Boolean-Base,除了用工具自动化跑结果外,有没有其他较好的方式?

A2

答案是利用Dnslog,当时面试的时候比较紧张,一直想着payload的改进和工具自动化,把这个给忘了,其实也跟平时使用这个技巧不多的原因有关,所以认了。。不过在面试过后确实对Dnslog又强化了一波,的确很好用。直接上链接把->Dnslog-<,这个博主关于Dnslog在各个场景下的使用技巧总结的十分详细了。

四、Re-review

参与面试的过程其实是对自己之前所积累的技术体系的一种测试,更重要的对我来说收获最多是了解圈内的大牛们都在关注着哪些他们感兴趣的方向和技术细节,在丢人的同时的确获得了很多自己想要的信息哈哈。也发现了自己在hack的过程中深度的确不够,容易满足于眼前的成果,挖洞是一方面,学习知识也是。因为hack的过程永远比挖到漏洞更重要。

五、To-Do

1、接下来的时间里继续靶场的练习,回顾之前浮躁状态下所忽略的技术细节,直到hack清楚为止。
2、思考自己的知识框架和技术框架,乘早跳出渗透的圈子,接触真正的企业体系安全建设。
3、培养好奇心,保持好奇心。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 0x00 背景 看了之前Gr36_前辈在先知上的议题,其中有提到排序注入,这个在最近经常遇到这样的问题,所以先总结...
    漏斗社区阅读 786评论 0 1
  • 为什么会存在SQL注入 通俗来讲,sql作为一种解释型语言,在运行时是由一个运行时组件解释语言代码并执行其中包含的...
    hxhdip阅读 605评论 0 0
  • sql注入及防护 一、常见获取变量 request.getParameter() request.getCooki...
    thelostworldSec阅读 509评论 0 0
  • Web安全篇之SQL注入攻击 在网上找了一篇关于sql注入的解释文章,还有很多技术,走马观花吧 文章来源:http...
    hao0_0阅读 1,598评论 0 0
  • 一、WAF介绍 传统防火墙只是在第三层(网络层)有效的阻断一些数据包;而随着web应用的功能越来越丰富的时候,We...
    卿酌南烛_b805阅读 1,026评论 0 0