<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 𝐒𝐮𝐧𝐝𝐫𝐚𝐦 𝐘𝐚𝐝𝐚𝐯</title>
    <description>The latest articles on DEV Community by 𝐒𝐮𝐧𝐝𝐫𝐚𝐦 𝐘𝐚𝐝𝐚𝐯 (@siryadav1).</description>
    <link>https://dev.to/siryadav1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4182259%2Fb30ef9e8-f16d-4fc1-96bc-031ba876c56d.jpg</url>
      <title>DEV Community: 𝐒𝐮𝐧𝐝𝐫𝐚𝐦 𝐘𝐚𝐝𝐚𝐯</title>
      <link>https://dev.to/siryadav1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siryadav1"/>
    <language>en</language>
    <item>
      <title>Sonar Bypass: how Minecraft anti-bot verification works on the wire</title>
      <dc:creator>𝐒𝐮𝐧𝐝𝐫𝐚𝐦 𝐘𝐚𝐝𝐚𝐯</dc:creator>
      <pubDate>Thu, 22 Oct 2026 02:32:44 +0000</pubDate>
      <link>https://dev.to/siryadav1/sonar-bypass-how-minecraft-anti-bot-verification-works-on-the-wire-2j8h</link>
      <guid>https://dev.to/siryadav1/sonar-bypass-how-minecraft-anti-bot-verification-works-on-the-wire-2j8h</guid>
      <description>&lt;p&gt;The kick message said "verification failed". No stage, no hint.&lt;/p&gt;

&lt;p&gt;Sonar sits in front of a Minecraft server and makes you prove you are a real client: a teleport, a fall, two packet echoes, a boat ride. It all happens at protocol level, so there is no config flag to turn it off. I logged both directions until the sequence made sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The teleport.&lt;/strong&gt; First packet puts you at &lt;code&gt;y=3019&lt;/code&gt;. You confirm with your position, and the position matters. The second teleport arrives as &lt;code&gt;y=39&lt;/code&gt; with the relative flag set, so spawn is &lt;code&gt;3019 + 39 = 3058&lt;/code&gt;, not 39. Treat it as absolute and you confirm a spot inside the ground.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The platform.&lt;/strong&gt; A section block update right before the fall gives the block id (&lt;code&gt;8185&lt;/code&gt;) and its height (&lt;code&gt;0.8125&lt;/code&gt;). It is a slab, so you land at &lt;code&gt;spawnY - 4 + 0.8125&lt;/code&gt;. Miss the half block and you land inside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Gravity.&lt;/strong&gt; Eight ticks of &lt;code&gt;dy = (dy - 0.08) * 0.98&lt;/code&gt;, one position packet per tick, then the landing packet with &lt;code&gt;onGround&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;spawnY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.98&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;sendPos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;sendPos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spawnY&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;platformHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Echo one: animation.&lt;/strong&gt; The server swings your arm and waits. Swing back once. Twice gets you kicked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Echo two: held slot.&lt;/strong&gt; The first slot packet is invalid on purpose, then the real one follows. A vanilla client only confirms a valid slot that actually changed, so a bot that answers everything fails here without a clue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. The boat.&lt;/strong&gt; Driven by keepalives: boat, out, minecart, out. No packet tells you it started. And while you are in the boat you send vehicle movement, not player movement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two that cost me days
&lt;/h2&gt;

&lt;p&gt;I confirmed the teleport &lt;strong&gt;after&lt;/strong&gt; sending my position. Logs looked perfect. But the server compares the confirm against where you were when it issued the teleport, and by then I had moved. One line of reordering fixed it.&lt;/p&gt;

&lt;p&gt;I also forgot the &lt;strong&gt;tick end&lt;/strong&gt; packet. Without it the movement packets never close and the whole fall is discarded - exact same symptom as a wrong position, which is why it ate an evening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;About 600 lines of Node.js, zero dependencies. Framing is the only part worth showing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mh"&gt;0x7f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;varint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that it is just a state machine over the packets you receive - no proxy in the middle, nothing that breaks on a server update.&lt;/p&gt;

&lt;p&gt;Tested against Sonar 2.1.52 and 2.1.53, on 1.21.x and 26.1.x, on servers I had permission to test.&lt;/p&gt;

&lt;p&gt;One caveat: this is a research tool. Running it on a server you do not own breaks that server's rules, and it will get your account banned. I wrote it to understand the verification, not to farm one.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/SirYadav1/sonar-bypass" rel="noopener noreferrer"&gt;github.com/SirYadav1/sonar-bypass&lt;/a&gt;&lt;br&gt;
Site: &lt;a href="https://www.yadav.codes" rel="noopener noreferrer"&gt;yadav.codes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>minecraft</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
