aCis

PUBLIC SECTION => Announcements => Topic started by: Tryskell on February 25, 2019, 01:15:50 PM

Title: EnterWorld exploit fix - ALL L2J versions
Post by: Tryskell on February 25, 2019, 01:15:50 PM
Short version : upon L2PHX (or any packet manipulation tool) use, the manual or automatic send of EnterWorld packet creates issues (for example, if the config spawn protection is activated, it sends anew the spawn protection, making you immune everytime you send back the packet). Simply select EnterWorld packet from "Packet Sniffer" tab, "Add packet to send..." and check "send every 100 ms".


Issue : packet manipulation spam, calling multiple times the same subroutines (spawn protection custom and whatever custom you added in EnterWorld). Potentially fix other exploits based on your spawnMe() content.


Fix : generate a new GameClientState (personally called ENTERING), isolate EnterWorld on it (RequestManorList being called automatically, it must be part of ENTERING too). Any subsequent calls of EnterWorld will call onUnknownPacket, because it will be considered out of ENTERING scope, since we're already at IN_GAME scope once the Player instance is fully loaded (such stuff already exists for all packets : login packets can't be called during ingame state, etc. It's just than EnterWorld is a transition packet between lobby and ingame, but it is considered an ingame packet while it shouldn't).


Since chronicle got different opcodes, you have to adapt using your own chronicle opcodes. I can't and won't deliver a unique version for all chronicles. Since I'm an IL guy, I share for IL. The diff patch can help you to guess what to edit.


Possible improvements :

aCis version, based on latest (GameClient is generally called L2GameClient) :

Code: [Select]
### Eclipse Workspace Patch 1.0
#P aCis_gameserver
Index: java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java (revision 1146)
+++ java/net/sf/l2j/gameserver/network/clientpackets/CharacterSelected.java (working copy)
@@ -62,7 +62,7 @@
 
  sendPacket(SSQInfo.sendSky());
 
- client.setState(GameClientState.IN_GAME);
+ client.setState(GameClientState.ENTERING);
 
  sendPacket(new CharSelected(cha, client.getSessionId().playOkID1));
  }
Index: java/net/sf/l2j/gameserver/network/GameClient.java
===================================================================
--- java/net/sf/l2j/gameserver/network/GameClient.java (revision 1157)
+++ java/net/sf/l2j/gameserver/network/GameClient.java (working copy)
@@ -64,6 +64,7 @@
  {
  CONNECTED, // client has just connected
  AUTHED, // client has authed but doesnt has character attached to it yet
+ ENTERING, // client is currently loading his Player instance, but didn't end
  IN_GAME // client has selected a char and is in game
  }
@@ -168,6 +168,7 @@
  case AUTHED:
  return "[Account: " + getAccountName() + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
 
+ case ENTERING:
  case IN_GAME:
  return "[Character: " + (getPlayer() == null ? "disconnected" : getPlayer().getName()) + " - Account: " + getAccountName() + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]";
 
Index: java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java (revision 1145)
+++ java/net/sf/l2j/gameserver/network/L2GamePacketHandler.java (working copy)
@@ -51,6 +51,7 @@
  break;
  }
  break;
+
  case AUTHED:
  switch (opcode)
  {
@@ -80,6 +81,43 @@
  break;
  }
  break;
+
+ case ENTERING:
+ switch (opcode)
+ {
+ case 0x03:
+ msg = new EnterWorld();
+ break;
+
+ case 0xd0:
+ int id2 = -1;
+ if (buf.remaining() >= 2)
+ {
+ id2 = buf.getShort() & 0xffff;
+ }
+ else
+ {
+ _log.warning("Client: " + client.toString() + " sent a 0xd0 without the second opcode.");
+ break;
+ }
+
+ switch (id2)
+ {
+ case 8:
+ msg = new RequestManorList();
+ break;
+ default:
+ printDebugDoubleOpcode(opcode, id2, buf, state, client);
+ break;
+ }
+ break;
+
+ default:
+ printDebug(opcode, buf, state, client);
+ break;
+ }
+ break;
+
  case IN_GAME:
  switch (opcode)
  {
@@ -89,9 +127,6 @@
  // case 0x02:
  // // Say ... not used any more ??
  // break;
- case 0x03:
- msg = new EnterWorld();
- break;
  case 0x04:
  msg = new Action();
  break;
Index: java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (revision 1150)
+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -35,6 +35,7 @@
 import net.sf.l2j.gameserver.model.pledge.SubPledge;
 import net.sf.l2j.gameserver.model.zone.ZoneId;
 import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.GameClient.GameClientState;
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
 import net.sf.l2j.gameserver.network.serverpackets.Die;
 import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
@@ -77,6 +78,8 @@
  return;
  }
 
+ getClient().setState(GameClientState.IN_GAME);
+
  final int objectId = player.getObjectId();
 
  if (player.isGM())

WILL BE PART OF REV 381.