1 Attachment(s)
Re: Kal Online Packet Filter
Spoiler :
Code:
#include <direct.h>#include <conio.h>
#include <cstdlib>
#include <cstddef>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#define CONFIG_FILE "PacketFilterConfig.ini"
#define SILENT_MODE 0
#define PRINT_MODE 1
#define FILE_MODE 2
static int LOG_MEMORY_BUFFER;
static int LOG_MODE;
std::vector<unsigned char> Packet_Header_Filter;
std::vector<int> Packet_Size_Filter;
std::vector<std::vector<unsigned char>> Packet_Content_Filter;
std::string buffer;
namespace tcp_proxy
{
namespace ip = boost::asio::ip;
class bridge : public boost::enable_shared_from_this<bridge>
{
public:
typedef ip::tcp::socket socket_type;
typedef boost::shared_ptr<bridge> ptr_type;
bridge(boost::asio::io_service& ios)
: downstream_socket_(ios),
upstream_socket_(ios)
{}
socket_type& downstream_socket()
{
return downstream_socket_;
}
socket_type& upstream_socket()
{
return upstream_socket_;
}
void start(const std::string& upstream_host, unsigned short upstream_port)
{
upstream_socket_.async_connect(
ip::tcp::endpoint(
boost::asio::ip::address::from_string(upstream_host),
upstream_port),
boost::bind(&bridge::handle_upstream_connect,
shared_from_this(),
boost::asio::placeholders::error));
}
void handle_upstream_connect(const boost::system::error_code& error)
{
if (!error)
{
std::string datetime = format_datetime(boost::posix_time::microsec_clock::universal_time());
std::string upstream_file_name = "us_" + upstream_socket_.remote_endpoint().address().to_string()+ "_" + datetime + ".log";
std::string downstream_file_name = "ds_" + downstream_socket_.remote_endpoint().address().to_string()+ "_" + datetime + ".log";
upstream_log.open(upstream_file_name.c_str(),std::ios::hex);
downstream_log.open(downstream_file_name.c_str(),std::ios::hex);
upstream_socket_.async_read_some(
boost::asio::buffer(upstream_data_,max_data_length),
boost::bind(&bridge::handle_upstream_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
downstream_socket_.async_read_some(
boost::asio::buffer(downstream_data_,max_data_length),
boost::bind(&bridge::handle_downstream_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
close();
}
private:
void handle_downstream_write(const boost::system::error_code& error)
{
if (!error)
{
upstream_socket_.async_read_some(
boost::asio::buffer(upstream_data_,max_data_length),
boost::bind(&bridge::handle_upstream_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
close();
}
void log_bytes(const void *object, size_t size, std::string ip)
{
switch (LOG_MODE)
{
case SILENT_MODE:
break;
case PRINT_MODE:
print_bytes(object,size,ip);
break;
case FILE_MODE:
write_to_file(object,size,ip);
break;
default:
break;
}
}
bool check_bytes(const void *object, size_t size)
{
for (int i=0;i < Packet_Size_Filter.size();i++)
{
if (size >= Packet_Size_Filter.at(i))
return FALSE;
}
for (int i=0;i < Packet_Header_Filter.size();i++)
{
if (((const unsigned char *) object)[0] == Packet_Header_Filter.at(i))
return FALSE;
}
for (int i=0;i < Packet_Content_Filter.size();i++)
{
int x = 0;
for(x;x<size && x<Packet_Content_Filter.at(i).size();x++)
{
if ( Packet_Content_Filter.at(i).at(x) != 0x00)
if (((const unsigned char *) object)[x] != Packet_Content_Filter.at(i).at(x))
break;
}
if (x == Packet_Content_Filter.at(i).size())
return FALSE;
}
return TRUE;
}
std::string get_hex_stream(const void *object, size_t size)
{
char bytesBuffer[16];
size_t i;
std::stringstream msg (std::stringstream::in | std::stringstream::out);
msg << "[ ";
for(i = 0; i < size; i++)
{
sprintf_s(bytesBuffer, sizeof(bytesBuffer),"%02x ", ((const unsigned char *) object)[i] & 0xff);
msg << bytesBuffer;
}
msg << "] Size: " << size;
return msg.str();
}
void print_bytes(const void *object, size_t size, std::string ip)
{
std::cout << "--- Packet from " << ip << " ---" << std::endl;
std::cout << get_hex_stream(object,size) << std::endl << std::endl;
}
void write_to_file(const void *object, size_t size, std::string ip)
{
std::stringstream msg (std::stringstream::in | std::stringstream::out);
msg << "--- Packet from " << ip << " ---" << std::endl << get_hex_stream(object,size) << std::endl << std::endl;
buffer.append(msg.str());
if (buffer.size() > LOG_MEMORY_BUFFER)
{
time_t t = time(0);
struct tm * now = localtime(&t);
FILE* pSendLogFile;
char filename[500];
sprintf_s(filename, sizeof(filename),"Log\\MadPacketLog_%04d_%02d_%02d_%02d_%02d.txt", now->tm_year+1900, now->tm_mon+1,
now->tm_mday, now->tm_hour, now->tm_min);
pSendLogFile = fopen(filename, "a+");
fprintf(pSendLogFile, "Timestamp %04d/%02d/%02d %02d:%02d:%02d \n %s \n",now->tm_year+1900, now->tm_mon+1,
now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec , buffer);
fclose(pSendLogFile);
buffer.clear();
}
}
void handle_downstream_read(const boost::system::error_code& error,
const size_t& bytes_transferred)
{
if (!error)
{
log_bytes(&downstream_data_[0],static_cast<std::streamsize>(bytes_transferred),
downstream_socket_.remote_endpoint().address().to_string());
if (check_bytes(&downstream_data_[0],static_cast<std::streamsize>(bytes_transferred)))
async_write(upstream_socket_,
boost::asio::buffer(downstream_data_,bytes_transferred),
boost::bind(&bridge::handle_upstream_write,
shared_from_this(),
boost::asio::placeholders::error));
else
std::cout << "Packet successfully filtered!" << std::endl;
}
else
close();
}
void handle_upstream_write(const boost::system::error_code& error)
{
if (!error)
{
downstream_socket_.async_read_some(
boost::asio::buffer(downstream_data_,max_data_length),
boost::bind(&bridge::handle_downstream_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
close();
}
void handle_upstream_read(const boost::system::error_code& error,
const size_t& bytes_transferred)
{
if (!error)
{
async_write(downstream_socket_,
boost::asio::buffer(upstream_data_,bytes_transferred),
boost::bind(&bridge::handle_downstream_write,
shared_from_this(),
boost::asio::placeholders::error));
}
else
close();
}
void close()
{
boost::mutex::scoped_lock lock(mutex_);
if (downstream_socket_.is_open())
downstream_socket_.close();
if (upstream_socket_.is_open())
upstream_socket_.close();
downstream_log.close();
upstream_log.close();
}
std::string format_datetime(boost::posix_time::ptime pt)
{
std::string s;
std::ostringstream datetime_ss;
boost::posix_time::time_facet * p_time_output = new boost::posix_time::time_facet;
std::locale special_locale (std::locale(""), p_time_output);
datetime_ss.imbue (special_locale);
(*p_time_output).format("%Y%m%d%H%M%S.%f");
datetime_ss << pt;
s = datetime_ss.str().c_str();
return s;
}
socket_type downstream_socket_;
socket_type upstream_socket_;
enum { max_data_length = 8192 }; //8KB
unsigned char downstream_data_[max_data_length];
unsigned char upstream_data_[max_data_length];
boost::mutex mutex_;
std::ofstream downstream_log;
std::ofstream upstream_log;
public:
class acceptor
{
public:
acceptor(boost::asio::io_service& io_service,
const std::string& local_host, unsigned short local_port,
const std::string& upstream_host, unsigned short upstream_port)
: io_service_(io_service),
localhost_address(boost::asio::ip::address_v4::from_string(local_host)),
acceptor_(io_service_,ip::tcp::endpoint(localhost_address,local_port)),
upstream_port_(upstream_port),
upstream_host_(upstream_host)
{}
bool accept_connections()
{
try
{
session_ = boost::shared_ptr<bridge>(new bridge(io_service_));
acceptor_.async_accept(session_->downstream_socket(),
boost::bind(&acceptor::handle_accept,
this,
boost::asio::placeholders::error));
}
catch(std::exception& e)
{
std::cerr << "acceptor exception: " << e.what() << std::endl;
return false;
}
return true;
}
private:
void handle_accept(const boost::system::error_code& error)
{
if (!error)
{
session_->start(upstream_host_,upstream_port_);
if (!accept_connections())
{
std::cerr << "Failure during call to accept." << std::endl;
}
}
else
{
std::cerr << "Error: " << error.message() << std::endl;
}
}
boost::asio::io_service& io_service_;
ip::address_v4 localhost_address;
ip::tcp::acceptor acceptor_;
ptr_type session_;
unsigned short upstream_port_;
std::string upstream_host_;
};
};
}
char m_szFileName[MAX_PATH];
char *bindAddress;
u_short bindPort;
char *redirectAddress;
u_short redirectPort;
void load_packet_filter()
{
char sMessage[255];
std::string prefix_size = "[PACKET_SIZE_FILTER]";
std::string prefix_header = "[PACKET_HEADER_FILTER]";
std::string prefix_content = "[PACKET_CONTENT_FILTER]";
std::ifstream f;
std::string s;
std::string t;
std::ifstream ifile(CONFIG_FILE);
if (ifile)
{
f.open(CONFIG_FILE, std::ios::in);
while (!f.eof())
{
getline(f, s);
if (s.substr(0, prefix_size.size()) == prefix_size)
{
getline(f, s);
t = (s.substr(0,30));
sprintf_s(sMessage, sizeof(sMessage), " [PACKET_SIZE_FILTER] -> %i installed", atoi( t.c_str()));
std::cout << sMessage << std::endl;
Packet_Size_Filter.push_back( atoi( t.c_str()) );
}
if (s.substr(0, prefix_header.size()) == prefix_header)
{
getline(f, s);
t = (s.substr(0,30));
sprintf_s(sMessage, sizeof(sMessage), " [PACKET_HEADER_FILTER] -> %s installed", t.c_str());
std::cout << sMessage << std::endl;
std::istringstream hex_chars_stream(t);
unsigned int c;
while (hex_chars_stream >> std::hex >> c)
{
Packet_Header_Filter.push_back(c);
}
}
if (s.substr(0, prefix_content.size()) == prefix_content)
{
getline(f, s);
t = (s.substr(0,1024));
sprintf_s(sMessage, sizeof(sMessage), " [PACKET_CONTENT_FILTER] -> %s installed", t.c_str());
std::cout << sMessage << std::endl;
std::vector<unsigned char> temp;
std::istringstream hex_chars_stream(t);
unsigned int c;
while (hex_chars_stream >> std::hex >> c)
{
temp.push_back(c);
}
Packet_Content_Filter.push_back(temp);
}
}
}
f.close();
}
char* get_config_val(char* szSection, char* szKey)
{
char *szResult = new char[255];
memset(szResult, 0x00, 255);
GetPrivateProfileStringA(szSection, szKey, "", szResult, 255, m_szFileName);
return szResult;
}
void load_config()
{
char szSelfPath[MAX_PATH];
char *szData[2];
getcwd(szSelfPath, sizeof(szSelfPath));
sprintf_s(m_szFileName, sizeof(m_szFileName), "%s\\%s", szSelfPath, CONFIG_FILE);
szData[0] = get_config_val("SERVER", "SERVER_BIND_IP");
szData[1] = get_config_val("SERVER", "SERVER_BIND_PORT");
szData[2] = get_config_val("REDIRECT", "REDIRECT_IP");
szData[3] = get_config_val("REDIRECT", "REDIRECT_PORT");
szData[4] = get_config_val("MODE", "MODE");
szData[5] = get_config_val("BUFFER", "LOG_MEMORY_BUFFER");
if (strlen(szData[0]) <= 0 || strlen(szData[1]) <= 0 ||
strlen(szData[2]) <= 0 || strlen(szData[3]) <= 0 ||
strlen(szData[4]) <= 0 || strlen(szData[5]) <= 0)
{
std::cout << "Reading Config File failed" << std::endl;
exit(EXIT_SUCCESS);
}
else
{
load_packet_filter();
bindAddress = (char *)szData[0];
bindPort = (u_short)atoi(szData[1]);
redirectAddress = (char *)szData[2];
redirectPort = (u_short)atoi(szData[3]);
LOG_MODE = ((u_short)atoi(szData[4]));
LOG_MEMORY_BUFFER= (atoi(szData[5]));
}
}
void Thread( void* pParams )
{
while(1)
{
Sleep(10);
unsigned char key;
key = getch();
switch(key)
{
case 'f':
load_packet_filter();
std::cout << "Filter Reloaded" << std::endl;
break;
case 's':
if (LOG_MODE != 0) {
LOG_MODE = 0; std::cout << "Silent Mode activated" << std::endl;
} else {
LOG_MODE = 1; std::cout << "Silent Mode deactivated" << std::endl; }
break;
case 'l':
if (LOG_MODE != 2) {
LOG_MODE = 2; std::cout << "Log Mode activated" << std::endl;
} else {
LOG_MODE = 1; std::cout << "Log Mode deactivated" << std::endl; }
break;
default:
break;
}
}
}
int main(int argc, char* argv[])
{
load_config();
_beginthread( Thread, 0, NULL );
boost::asio::io_service ios;
std::cout << "MadKnight Packet Filter Version 2.0" << std::endl;
try
{
tcp_proxy::bridge::acceptor acceptor(ios,
bindAddress, bindPort,
redirectAddress, redirectPort);
acceptor.accept_connections();
ios.run();
}
catch(std::exception& e)
{
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
This is Packet Filter Version 2.0 it also contains Log Files instead of printing on Console and some other little fixes. And now you also have the Source Code : )
Re: Kal Online Packet Filter
Hello! Can you provide a program of this without a proxy config. I have a ran server and we do only direct connection. Client -> Server Same IP Same Port.
Re: Kal Online Packet Filter
How is this used? No one can help me
Re: Kal Online Packet Filter
Quote:
How it works:
here you can follow
Shortcuts:
Press f for reload the Filter Settings
Press s to Toggle Console Silent Mode (on/off)
Server Settings:
[SERVER] << The Server on wich the Packet Filter Proxy runs
SERVER_BIND_IP=127.0.0.1 << Packet Filter Proxy IP
SERVER_BIND_PORT=30001 << Packet Filter Proxy PORT
[REDIRECT] << Redirect to Mainserver
REDIRECT_IP=127.0.0.1 << IP of Mainserver
REDIRECT_PORT=30002 << Port of Mainserver
Console:
[MODE]
CONSOLE_SILENT=0 << 0 OFF all packets will be printed, 1 ON No Packets will be printed
Filter:
[PACKET_SIZE_FILTER] << Filters all Packets with Size 20
20
[PACKET_SIZE_FILTER] << Filters all Packets with Size 59
59
[PACKET_HEADER_FILTER] << Filters all Packets wich begin with 0x16 Packet
0x16
[PACKET_HEADER_FILTER] << Filters all Packets wich begin with 0x17 Packet
0x17
[PACKET_CONTENT_FILTER] << Filter all Packets with Content 0x08 0x08 0xXX 0xXX 0xXX 0xXX 0x02 // 0x00 can be used as Wildcard like * in IP BLock (145.54.*.*)
0x08 0x08 0x00 0x00 0x00 0x02
[PACKET_CONTENT_FILTER] << Filter all Packets with Content 0x07 0x07
0x07 0x07
[PACKET_CONTENT_FILTER] << This for example will Filter all Packets
0x00
have fun.
Re: Kal Online Packet Filter
Windows 2008 R2 is missing MSmsvcp100.dll?
Re: Kal Online Packet Filter
Re: Kal Online Packet Filter
Quote:
Originally Posted by
shiref6
thanks for release
:fanny:
http://i.epvpimg.com/0IUve.jpg
Re: Kal Online Packet Filter
Hello guys of KAL Online. I am from AO Servers, I was trying to find some tips of package filtering and I've seen this thread.
Well done job about the package filtering.
Now I would like to ask you because the servers are different, and the packages aswell + logs etc.
In my main server of AO, I got some packages that results in one of the binaries of the server to get in to debugging state (FieldServer.exe) which works on port 15103.
These are the errors from FieldServer Logs. It's starting with error of hackshield and results in deadlock (this makes fieldserver to get in debug state)
Logs:
Code:
05-04 18:32:39|[Error] CFieldIOCPSocket::SecurityClientCheck_ TermTick(99000) = CurrentTick(2082924686) - BeforeTick(2082825686)
05-04 18:32:39| SendErrorMsg to [A(alexander:474) C(dasLegit:699) CI(1221)] 5.254.113.19 ==> ERR_SECURITY_HACKING_CRC(0xe002 ) AT T_FC_MOVE_HACKSHIELD_CRCAckMsg Param1(0) Param2(0) Msg((null))
05-04 18:32:39|[ERROR] deadlock : ThreadType(THREAD_CHECK_TYPE_IOCP_WORKER), ThreadId( 6128), TimeGap(137796) StartTick(2082787218) SocketIndex(1234) MessageType[ T_FC_CLIENT_REPORT(0x3500 )] Parma1( 0) Param2(0)
In here I made red the bytes I believe I must filter and I would like to receive an opinion if is correct what I am filtering or not.
I will wait for an answer.
Thank you !
- - - Updated - - -
Edit:
Oh I've just seen the source code.
Code:
sprintf_s(filename, sizeof(filename),"Log\\MadPacketLog_%04d_%02d_%02d_%02d_%02d.txt"
So, if someone is using a package I can see it in Log folder as it is in this code right?
Re: Kal Online Packet Filter
Quote:
Originally Posted by
WARonline
Edit:
Oh I've just seen the source code.
Code:
sprintf_s(filename, sizeof(filename),"Log\\MadPacketLog_%04d_%02d_%02d_%02d_%02d.txt"
So, if someone is using a package I can see it in Log folder as it is in this code right?
As it is in the TCP Packet : )
This Filter should work for all Games in principal.
Check the MadPacketLog, try to make a pattern rule based filter and see if it works.
Re: Kal Online Packet Filter
Yes it's a good filter. Just that My proxy DDoS Protection ip which is used by the client of the server, connects to the main IP Server where is the gameserver, and the thing is I can not add this filter on to the Proxy DDoS Protected IP. I am trying to use it to work on the mainserver IP
At bind i use ip:15103 and at server i use thesameip:thesameport.
It would work I assume?
Thanks for info
Re: Kal Online Packet Filter
You can change your kal server port in the MainConfig, DBConfig and AuthConfig files.
Re: Kal Online Packet Filter
Quote:
Originally Posted by
General
You can change your kal server port in the MainConfig, DBConfig and AuthConfig files.
I am trying to use it for ACE Online Server not Kal Online. We got different binaries. PreServer, IMServer, LogServer, FieldServer (where I must filter the packages) and NPCServer.
Re: Kal Online Packet Filter
this is just for Kal Online ? i want to setup this for RF Online.
Re: Kal Online Packet Filter
Quote:
Originally Posted by
rfan72
this is just for Kal Online ? i want to setup this for RF Online.
Quote:
Originally Posted by
MadKnight
As it is in the TCP Packet : )
This Filter should work for all Games in principal.
Check the MadPacketLog, try to make a pattern rule based filter and see if it works.
_____
Re: Kal Online Packet Filter
If this one works in all games in principal now my problem is what packet should I filter and how can I identify those packets that used for crashing, hacking, duping, etc. ?