<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>hackndo</title>
    <description>This blog talks about computer security. Tutorials about buffer overflow, Active Directory, everything is explained with examples</description>
    <link>https://en.hackndo.com/</link>
    <atom:link href="https://en.hackndo.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 30 Jan 2026 10:39:01 +0000</pubDate>
    <lastBuildDate>Fri, 30 Jan 2026 10:39:01 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Spray passwords, avoid lockouts</title>
        <description>&lt;p&gt;Password spraying is a well-known technique which consists of testing the same password on several accounts, in the hope that it will work for one of them. This technique is used in many different contexts: On web applications, the Cloud, services like SSH, FTP, and many others. It’s also widely used in internal penetration testing with Active Directory. It’s the latter that we’re going to focus on, because although the technique seems simple, it’s not easy to put it into practice without side effects.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;This article is not about something new, but rather a report on my research into password policies in an Active Directory environment. Indeed, there are several ways of limiting an attacker by locking accounts. These different levers are very useful when they are understood, which is not always the case (and wasn’t the case for me a few weeks ago). This article will, I hope, clarify what password policies allow, how they are applied, and therefore, as a pentester, how to do password spraying while minimizing the risk of locking accounts.&lt;/p&gt;

&lt;h2 id=&quot;authentication-mechanism&quot;&gt;Authentication mechanism&lt;/h2&gt;

&lt;p&gt;Password spraying on an Active Directory directory consists in choosing a password considered highly likely to be used by at least one user, and testing it on all users in the domain. We won’t go into detail here on how to test the validity of a password, as there are many different ways of doing this. A password can be tested via Kerberos or NTLM, via different services (SMB, LDAP, etc.). In any case, when authentication is tested, the domain controller will first check whether the account is locked by the password policy. If not, it will check the validity of the password. Finally, if the password is valid, the account will be authenticated, and the user’s LDAP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; attribute will be reset to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;. If, on the other hand, the password is incorrect, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; will be incremented, and if this failure results in the account being locked, according to password policy criteria, then the account will be marked as locked. This is done by ptoviding the current date and time in the user’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutTime&lt;/code&gt; LDAP attribute.&lt;/p&gt;

&lt;p&gt;That’s quite a verification process, which I’ve tried to summarize in a diagram. Does this make things clearer? I’m not sure. But here it is anyway.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/password_verification_process.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/password_verification_process.png&quot; alt=&quot;Password testing process&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve clarified this logic, we understand that there’s one unknown factor that seems rather important: the password policy. Because it’s by following the password policy applied to the account that the domain controller is able to know whether or not the account is locked, or whether it should be. Let’s take a look at where this default policy can be found, and explain the parameters we’re interested in.&lt;/p&gt;

&lt;h2 id=&quot;the-default-password-policy&quot;&gt;The default password policy&lt;/h2&gt;

&lt;p&gt;When an Active Directory is installed, many things are created and set up by default. Among them are two GPOs: The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt; linked to the domain root, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Controller Policy&lt;/code&gt; linked to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Domain Controllers&lt;/code&gt; OU.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt; contains the following parameters for defining account lockout rules.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/default_domain_policy.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/default_domain_policy.png&quot; alt=&quot;Default Domain Password Policy&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Account lockout duration&lt;/strong&gt; : When an account is locked out, this parameter defines the time during which the account remains locked.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Account lockout threshold&lt;/strong&gt;: Determines the number of incorrect attempts allowed. If this parameter is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;, then 3 incorrect attempts will lock the account.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reset account lockout counter after&lt;/strong&gt;: As a general rule, when an authentication fails, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; is incremented. However, if the previous failed attempt is older than the time set here, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; is reset to 0. For example, if this parameter is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5 minutes&lt;/code&gt;, then on a first failure, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; is set to &lt;strong&gt;1&lt;/strong&gt;. On a 2nd failure a few seconds later, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; is set to &lt;strong&gt;2&lt;/strong&gt;. If a 3rd failure occurs, but 5min10 after the 2nd failure, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; will have been reset to &lt;strong&gt;0&lt;/strong&gt;, and this failure therefore sets it back to &lt;strong&gt;1&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the parameters that the domain controller takes into account to determine whether an account is locked out. In other terms (and because the previous diagram wasn’t complex enough, of course), these values are used in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/password_verification_process_with_policy.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/password_verification_process_with_policy.png&quot; alt=&quot;Password testing process with policy&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the bad password counter is calculated by taking the date of the last logon failure, and if the time defined in &lt;strong&gt;Reset account lockout counter after&lt;/strong&gt; has passed, then the counter is reset to zero. Otherwise, it is incremented. This counter is then compared with &lt;strong&gt;Account lockout threshold&lt;/strong&gt;. If it’s equal to (or greater than) this threshold, then the account is locked out, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutTime&lt;/code&gt; field is filled in. On a subsequent attempt, if the time defined in &lt;strong&gt;Account lockout duration&lt;/strong&gt; has passed (using the date in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutTime&lt;/code&gt; as a starting point) then the account is no longer locked, and the password will be tested.&lt;/p&gt;

&lt;p&gt;If it’s still not clear, then take these explanations from the beginning, and concentrate. I can’t explain it any better. All this has to be clear to understand what’s coming next. We’ve already talked about the password policy in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt; GPO. But we’ll see that this is not the only place where this policy can be defined.&lt;/p&gt;

&lt;h2 id=&quot;gpos-application-order&quot;&gt;GPOs application order&lt;/h2&gt;

&lt;p&gt;Personally, I like to create a new, dedicated GPO for every settings (or group of settings) I want to apply to my users or computers. To apply a password policy, I’ll create a dedicated GPO, in which there will only be settings related to the password policy. And it’ll work just fine. Indeed, we’ve seen that the password policy can be defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt;, but they can obviously be set in any GPO.&lt;/p&gt;

&lt;p&gt;But how does it work when several GPOs contain different password policies?&lt;/p&gt;

&lt;p&gt;There is in fact a &lt;strong&gt;priority order&lt;/strong&gt; which defines which GPO takes precedence in the event of a conflict. In the Group Policy Management Console, when you click on an OU (or on the domain), you’ll see the list of applied GPOs in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Linked Group Policy Objects&lt;/code&gt; tab. You’ll notice that they are numbered, via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Link Order&lt;/code&gt; column, which makes it possible to determine the priority of each GPO. Specifically, the last GPO in the list will be applied first, up to GPO number 1. This means that GPO number 1 has the “last word”. If its settings conflict with those of other GPOs, its own settings will effectively take effect.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/gpo_link_order.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/gpo_link_order.png&quot; alt=&quot;GPO Link Order&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, if one password policy is defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PASSWORD POLICY&lt;/code&gt; and another in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt;, the latter will be applied.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There is no attribute that allows you to read the GPO number in the list. For each Organizational Unit (and for the domain object), the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gpLink&lt;/code&gt; attribute contains the list of GPOs that are linked to this object, and they are saved in order of application, i.e. in &lt;strong&gt;decreasing&lt;/strong&gt; order of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Link Order&lt;/code&gt;. On the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hackn.lab&lt;/code&gt; object, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PASSWORD POLICY&lt;/code&gt; GPO is listed first in its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gpLink&lt;/code&gt; attribute, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOCKSCREEN&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FIREWALL&lt;/code&gt; and finally &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Default Domain Policy&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So… By listing the GPOs that are applied to the domain object, we’re now able to find out which password policy is actually being applied. Of course, it doesn’t stop there. What if we want to apply a different, stronger password policy to the administrators, for example?&lt;/p&gt;

&lt;h2 id=&quot;password-policy-on-an-organizational-unit&quot;&gt;Password policy on an Organizational Unit&lt;/h2&gt;

&lt;p&gt;Before even starting this chapter, I’m announcing that &lt;strong&gt;this won’t work&lt;/strong&gt;. We’ll have to use PSOs to achieve this goal, which we’ll see right after.&lt;/p&gt;

&lt;p&gt;We might be tempted to organize our Active Directory in such a way that our administrators are in a dedicated Organizational Unit, and we’d like to apply a specific password policy to these users. Why not create a GPO dedicated to this OU, in which we define our robust criteria for secure passwords?&lt;/p&gt;

&lt;p&gt;Let’s take this example. We have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PASSWORD POLICY&lt;/code&gt; GPO placed at the domain level, which allows you to make 10 mistakes before locking accounts for 10 minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/password_policy_policy.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/password_policy_policy.png&quot; alt=&quot;Password Policy details&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s then create a much more robust GPO linked to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Admins&lt;/code&gt; OU in which the &lt;strong&gt;adm_pixis&lt;/strong&gt; account resides. This GPO should lockout an account for 60 minutes after 2 failed attempts.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/super_strict_password_policy.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/super_strict_password_policy.png&quot; alt=&quot;Super Strict Password Policy details&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can try to log in with the user &lt;strong&gt;adm_pixis&lt;/strong&gt;, but we deliberately get the password wrong. Once, twice, … three times, four times. The account is still unlocked.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/fail_to_loggon.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/fail_to_loggon.png&quot; alt=&quot;Fail to logon&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the 11th try, however, it doesn’t fail: our account is locked.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/locked_out.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/locked_out.png&quot; alt=&quot;Fail to logon&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why this black magic? Well, simply because when defining a password policy in a GPO, it will update some specific LDAP attributes of the object to which they are linked, and these attributes &lt;strong&gt;only exist on the domain object&lt;/strong&gt;, not on the Organizational Units.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/domain_attributes.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/domain_attributes.png&quot; alt=&quot;Domain attributes&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutDuration&lt;/code&gt; attribute, which corresponds to the &lt;strong&gt;Account lockout duration&lt;/strong&gt; parameter, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutObservationWindow&lt;/code&gt; set by &lt;strong&gt;Reset account lockout counter after&lt;/strong&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutThreshold&lt;/code&gt; which can be defined with &lt;strong&gt;Account lockout threshold&lt;/strong&gt;. So, when a password policy is defined by GPO and linked to an OU, this policy will have &lt;strong&gt;no effect&lt;/strong&gt; on this Organizational Unit, and therefore no effect on domain accounts in this OU.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you apply a GPO with a password policy to an OU that contains computers (workstations or servers), it has no effect on the domain policy, but it will apply to the &lt;strong&gt;local accounts&lt;/strong&gt; of said computers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All this means that it seems only possible to apply a global password policy to all users. But how do we harden this policy for our administrators? This is where PSOs, or &lt;strong&gt;Password Settings Objects&lt;/strong&gt;, come in.&lt;/p&gt;

&lt;h2 id=&quot;psos&quot;&gt;PSOs&lt;/h2&gt;

&lt;p&gt;Ah, PSOs. The answer to all our problems. PSOs are Active Directory objects that let you define the same password policy settings as those found in GPO, and apply them to users or groups of users. This makes it possible to create &lt;strong&gt;Fine-Grained Password Policies&lt;/strong&gt; (FGPP).&lt;/p&gt;

&lt;p&gt;These objects must be created in a very specific place, in a container called &lt;strong&gt;Password Settings Container&lt;/strong&gt;, itself in the &lt;strong&gt;System&lt;/strong&gt; container at the root level. A simple way to create a PSO is to use &lt;strong&gt;Active Directory Administrative Center&lt;/strong&gt; tool and navigate to this container.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/PSO_objects.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/PSO_objects.png&quot; alt=&quot;PSO Objects&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this console, you can easily create password policies and decide to whom these policies should apply. If we wanted to take over our super secure policy, we could create a PSO with these same parameters and apply it to all members of the &lt;strong&gt;Domain Admins&lt;/strong&gt; group.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/pso_da.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/pso_da.png&quot; alt=&quot;PSO DA&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same question of priority arises as for GPOs. Firstly, PSOs have &lt;strong&gt;priority over the domain’s password policy&lt;/strong&gt;. But then, if several PSOs are created, and users are affected by different PSOs, which one will be taken into account?&lt;/p&gt;

&lt;p&gt;It’s the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Precedence&lt;/code&gt; parameter present in the PSO, just after its name, that is used to sort PSOs. Like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Link Order&lt;/code&gt; for GPOs, PSOs are applied from highest to lowest &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Precedence&lt;/code&gt;. This means that the lowest values have priority over the highest, since they also have the last word.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If two PSOs ever have the same value in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Precedence&lt;/code&gt;, the last PSO created will take precedence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s get a little more technical. We’ve seen that when GPOs set the password policy, an order of priority will be followed and the attributes of the domain object will be updated to reflect the actual password policy. These domain attributes are readable by all authenticated users, so all you have to do is read the attributes on the domain object to find out the default password policy applied to the domain.&lt;/p&gt;

&lt;p&gt;What about PSOs? How do you know if a user is affected by a particular PSO? PSOs can’t modify domain attributes, since by their very nature they are designed to have different password policies. In fact, as each PSO is an Active Directory object, password policies are stored in the attributes of the object.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/pso_attributes.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/pso_attributes.png&quot; alt=&quot;PSO attributes&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The attributes don’t have exactly the same names as on the domain, which would be too simple, but they’re still there. Still with password spraying in mind, we’re particularly interested in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-LockoutThreshold&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-LockoutObservationWindow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another attribute of great interest to us is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-PSOAppliesTo&lt;/code&gt;. It contains the list of users and/or groups to which the PSO applies.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/pso_applies_to.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/pso_applies_to.png&quot; alt=&quot;PSO applies to&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pso-container-rights-problem&quot;&gt;PSO container rights problem&lt;/h2&gt;

&lt;p&gt;At this stage, you might think that we have all the information we need to know the effective password policy for each user. By default, we take the domain password policy by reading the domain object attributes, and then we list all the PSOs in the right order of priority, list the users in the groups on which each PSO is applied, and we can thus deduce which PSO is applied to which user.&lt;/p&gt;

&lt;p&gt;In theory, this would work, but there’s a small hitch in this approach.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/psc_security.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/psc_security.png&quot; alt=&quot;PSC security&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Can you see the problem? No ? By default, only administrators have the right to list PSOs. So, as an ordinary user, we have no way of listing the contents of the &lt;strong&gt;Password Settings Container&lt;/strong&gt;, and therefore of seeing the PSOs, the policies applied, and to whom they are applied. For our purposes of password spraying, this is quite dangerous. This means we can never be certain of knowing the effective password policies for various domain users, as there is always a risk that a PSO (which we cannot see or read) is applied to one or more users.&lt;/p&gt;

&lt;h2 id=&quot;constructed-attributes--backlinks&quot;&gt;Constructed Attributes &amp;amp; Backlinks&lt;/h2&gt;

&lt;p&gt;It was while facing this wall that I discovered &lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a3aff238-5f0e-4eec-8598-0a59c30ecd56&quot;&gt;constructed attributes&lt;/a&gt;. You probably know that when a user is added to a group, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;member&lt;/code&gt; attribute of the group is updated, adding the user. However, if you simply list a user’s attributes, you won’t see any LDAP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memberOf&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/no_memberof.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/no_memberof.png&quot; alt=&quot;No MemberOf&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many more attributes than those shown by default, but they are automatically managed by Active Directory. You can’t change them manually. These are attributes built from other attributes.&lt;/p&gt;

&lt;p&gt;Among them, one class of attributes is called &lt;strong&gt;backlinks&lt;/strong&gt;. These are attributes that go hand in hand with another attribute, on the same object or on other objects.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/backlinks.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/no_memberof.png&quot; alt=&quot;Backlinks&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memberOf&lt;/code&gt; attribute is a backlink that goes hand in hand with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;member&lt;/code&gt; attribute. So, as soon as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;member&lt;/code&gt; attribute of an object is modified (adding or deleting a user or group), this change is automatically reflected in its pair, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memberOf&lt;/code&gt;, of the object concerned. So if we display these backlinks, we can see the list of groups to which a user belongs.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/memberof.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/memberof.png&quot; alt=&quot;MemberOf&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, guess what, the same applies to PSOs. We’re not allowed to list PSOs with a standard user, so we can’t read the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-PSOAppliesTo&lt;/code&gt; attribute present on each PSO. But we’re in luck, there’s a &lt;strong&gt;constructed link&lt;/strong&gt; for this attribute, and it’s called &lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/ad735d45-ba6a-42fc-a41c-e91ced8e72d9&quot;&gt;msDS-ResultantPSO&lt;/a&gt;. It’s not a &lt;strong&gt;backlink&lt;/strong&gt;, because it’s a bit smarter. All users in the domain have this attribute, which is potentially updated every time a PSO is applied to users, but also to groups. If a group is added to a PSO, all members of that group will have their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-ResultantPSO&lt;/code&gt; attribute updated, &lt;strong&gt;provided the PSO has priority&lt;/strong&gt;. So as well as dynamically resolving group members, this attribute will always contain the name of the &lt;strong&gt;effective&lt;/strong&gt; PSO that applies to each user.&lt;/p&gt;

&lt;p&gt;And the icing on the cake in all this is that &lt;strong&gt;this attribute can be read on all users in the domain, even with a non-privileged account&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remember, we applied a PSO to the &lt;strong&gt;Domain Admins&lt;/strong&gt; group. Let’s take a look at the &lt;strong&gt;constructed&lt;/strong&gt; attributes of the &lt;strong&gt;adm_pixis&lt;/strong&gt; account, which is part of this group.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/msds_resultantpso.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/msds_resultantpso.png&quot; alt=&quot;Resultant PSO&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can clearly see our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memberOf&lt;/code&gt; &lt;strong&gt;backlink&lt;/strong&gt;, which contains &lt;strong&gt;Domain Admins&lt;/strong&gt;, as well as our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-ResultantPSO&lt;/code&gt; &lt;strong&gt;constructed attribute&lt;/strong&gt;, which contains the PSO we created and applied to the &lt;strong&gt;Domain Admins&lt;/strong&gt; group.&lt;/p&gt;

&lt;p&gt;It’s perfect, now we can see whether or not a user’s password policy is affected by a PSO. Mind you, &lt;strong&gt;we still don’t have the right to read the contents of the PSO&lt;/strong&gt;, at least not as a standard user. But from a password spraying point of view, just knowing that a PSO has been applied to a user is extremely valuable. We can simply ignore all accounts for which a PSO is applied, and restrict our tests to users for whom the effective password policy is the default domain policy.&lt;/p&gt;

&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;

&lt;p&gt;I followed this white rabbit of password policies by writing a password spraying tool, in an attempt to minimize the risk of locking accounts during my penetration tests. The tool I’ve developed follows this whole process to determine the list of users and the effective password policy for each of them. If the tool is unable to read the contents of the PSO, it will simply ignore the affected accounts during the spraying.&lt;/p&gt;

&lt;p&gt;But I wanted to go a step further. We saw that after a certain period of time, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badPwdCount&lt;/code&gt; attribute of users was reset. This certain duration, found in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lockoutObservationWindow&lt;/code&gt; attribute on the domain, or in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-LockoutObservationWindow&lt;/code&gt; attribute on a PSO, can thus vary from one user to another. The tool I’ve developed takes as input a list of passwords we wish to test on users, and will try all the passwords on all the users, taking care to follow locking thresholds and waiting times for the counter to be reset to zero before continuing with the tests.&lt;/p&gt;

&lt;p&gt;To ensure that everything runs smoothly, the tool starts by retrieving the time from the domain controller so that it’s perfectly synchronized, and synchronizes regularly with LDAP (a real user might be trying a wrong password during our password spraying).&lt;/p&gt;

&lt;p&gt;In short, I’m very happy to share with you the &lt;a href=&quot;https://github.com/login-securite/conpass&quot;&gt;conpass&lt;/a&gt; tool, which is extremely useful for me in penetration testing, and I hope it will be as useful for you.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2024/05/conpass.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2024/05/conpass.png&quot; alt=&quot;Conpass&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be careful&lt;/strong&gt;, it worked during my last pentests, but it’s still a tool written by a human who makes mistakes, that’s going to test passwords. So it’s possible that there are bugs and that it crashes, or that it locks accounts. So I’m very keen to get feedbacks from tests in controlled environments, to make it as robust as possible.&lt;/p&gt;
</description>
        <pubDate>Tue, 04 Jun 2024 08:25:55 +0000</pubDate>
        <link>https://en.hackndo.com/password-spraying-lockout/</link>
        <guid isPermaLink="true">https://en.hackndo.com/password-spraying-lockout/</guid>
        
        <category>Active Directory</category>
        
        <category>Windows</category>
        
        
      </item>
    
      <item>
        <title>Tokens ERC20 et ERC721</title>
        <description>&lt;p&gt;A large proportion of decentralised applications use &lt;strong&gt;tokens&lt;/strong&gt; to work properly. While &lt;strong&gt;coins&lt;/strong&gt; are inherent to each blockchain (Ether for Ethereum, for example, Sol for Solana, etc.), &lt;strong&gt;tokens&lt;/strong&gt; are tokens that are created on an existing blockchain using smart contracts. So, using a smart contract, it is possible to create a token called a “HackndoToken” whose symbol would be “HND”, for example. This token could exist in a limited number, and we could even ensure that each HND token is unique.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;These tokens can be transferred from one address to another, they can be created, destroyed, kept in a “safe”, etc. However, if everyone creates their token in their own way, with their own rules, it would quickly become a merry mess. Some tokens might have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transfer&lt;/code&gt; function to transfer a token, others might use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sendTo()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferToken()&lt;/code&gt;, or even &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionToTransferATokenToSomeoneLikeYouuuuu()&lt;/code&gt;. In short, things wouldn’t work out. It wouldn’t be possible to exchange one token for another without listing all the functions of all the existing tokens.&lt;/p&gt;

&lt;p&gt;That’s why, as with every emerging technology, a standard must be used to facilitate communication between applications, between tokens. Several improvements to Ethereum (&lt;a href=&quot;https://github.com/ethereum/EIPs&quot;&gt;Ethereum Improvement Proposal - EIP&lt;/a&gt;) have therefore been proposed in order to define different token standards depending on the application’s needs.&lt;/p&gt;

&lt;h2 id=&quot;fungible-tokens---erc20&quot;&gt;Fungible tokens - ERC20&lt;/h2&gt;

&lt;p&gt;The improvement proposal &lt;a href=&quot;https://github.com/ethereum/EIPs/issues/20&quot;&gt;#20&lt;/a&gt; describes a “classic” token standard. This proposal has been accepted, and the details of this standard are available &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-20&quot;&gt;at this address&lt;/a&gt;. As it was issue #20 that was at the origin of this standardisation, this standard is called &lt;strong&gt;ERC20&lt;/strong&gt; (ERC for &lt;em&gt;Ethereum Request for Comments&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;When I say that it’s a “classic” token, I mean that it’s a token with basic properties. It has a name, a symbol, and can be transferred from one address to another. All tokens (from the same contract) are equivalent, just as two bus tickets from the same town are equivalent. These tickets, like these tokens (or like Ethers), are interchangeable. They are therefore called &lt;strong&gt;fungible&lt;/strong&gt; tokens.&lt;/p&gt;

&lt;p&gt;In reality, having a name or symbol isn’t even required. It’s only convenient for humans, to help distinguish between tokens other than by their address. It’s a bit like URLs, which are much easier to remember than IP addresses. These two pieces of information, if used, must be accessible via the following methods:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another optional information can be provided: the number of decimals supported by the token. If the “HND” token has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8&lt;/code&gt; decimals, then in order to have 1 HND you actually need to have 100,000,000! It’s like euros: you need 100 cents to get one full euro. You would then need 10^8 fractions of HND to get 1 HND. So if a user has 150,000,000 HND, a web application will indicate that they have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.5&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;150,000,000 / 100,000,000&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This information can then be accessed using the following method:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decimals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In addition to these three pieces of information, which make them easier to use by humans, these tokens &lt;strong&gt;must&lt;/strong&gt; implement the following functions:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// This function must return the total supply of tokens (whether or not they have been distributed).&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// If there is only 1 HND, with 8 decimals, this function returns 100,000,000.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Returns the number of tokens owned by an address.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Transfers tokens to another address.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Transfers tokens from a source address to a destination address.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// For this to work, the source address must have given prior authorisation to the // address performing the transfer.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// performing this `transferFrom` to transfer tokens (it would be too easy otherwise ;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This function can be used to delegate the spending of a set number of tokens to an account.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// of tokens. This function must be called before the delegated account can&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// use the `transferFrom()` function.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;approve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This function returns the number of tokens that an account can spend on behalf of another account.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;allowance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;

&lt;p&gt;With all these functions in mind, you can create a brand new token from scratch with Solidity!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Please note that this example is given for information only. It is absolutely &lt;strong&gt;not suitable for production&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: GPL-3.0&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HackndoToken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// When state variables are declared as public, getters are automatically created by Solidity&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// For example, we can call the HackndoToken.symbol() function;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decimals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Find out how many tokens each address has&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Allows you to find out which address has authorised which addresses to spend how many tokens on its behalf&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// For example :&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// allowed[address1][address2] = 10&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// This means that address2 can spend 10 tokens from address1, instead of address1.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Events must be emitted for certain actions&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Approval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenOwner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// When the contract is created, information about the tokens will be supplied&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_decimals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;decimals&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_decimals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;totalSupply&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_totalSupply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Returns the number of tokens owned by an address.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;



    &lt;span class=&quot;c1&quot;&gt;// Transfers tokens to another address&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// To transfer tokens, you need to have enough of them&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;INSUFFICIANT_FUNDS&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// The tokens are deleted from the sender&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// And we add them to the receiver&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// An event is sent to register the transfer&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Delegate the spending of a defined number of tokens to an account&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;approve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Whoever calls the function authorises &quot;spender&quot; to spend &quot;value&quot; tokens on their behalf&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Approval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Spend tokens on behalf of another account, provided that the person calling the function has been authorised to do so&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// We check that the person calling the function is authorised to spend the same number of tokens&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NO_APPROVAL&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Then we check that the account spending the tokens has enough tokens&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;INSUFFICIANT_FUNDS&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Authorisation is decremented by the number of tokens used&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Then we exchange the number of tokens from one account to another&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Allows you to know how many tokens &quot;spender&quot; can use on behalf of &quot;tokenOwner&quot;.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;allowance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenOwner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenOwner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This contract can be compiled and deployed on the Ethereum blockchain to create a new token. Incredible, isn’t it?&lt;/p&gt;

&lt;p&gt;This type of token (this example, or another) can represent just about anything. It could be the equivalent of money in a video game, skill points, shares in a company (centralised or not), etc.&lt;/p&gt;

&lt;p&gt;In this example, we’ve written a token from scratch. However, to avoid mistakes, and to ensure that standardisation goes as smoothly as possible, you shouldn’t reinvent the wheel, and you should use an audited and proven version, such as the one &lt;a href=&quot;https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol&quot;&gt;proposed by OpenZeppelin&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;non-fungible-tokens-nft---erc721&quot;&gt;Non-Fungible Tokens (NFT) - ERC721&lt;/h2&gt;

&lt;p&gt;Non-Fungible Tokens (&lt;strong&gt;NFT&lt;/strong&gt;) are a category of tokens that are specifically &lt;strong&gt;non-fungible&lt;/strong&gt;. This means that two tokens, even though they come from the same smart contract, are different. This concept can be compared to cards that can be collected. Although the same company publishes cards representing, for example, the best hackers on the planet, each card represents a particular hacker. It may be from the same collection, but it is not equivalent to another card representing another person.&lt;/p&gt;

&lt;p&gt;To standardise tokens with this notion of &lt;strong&gt;uniqueness&lt;/strong&gt;, a new Ethereum enhancement request has been made, the &lt;a href=&quot;https://github.com/ethereum/EIPs/issues/721&quot;&gt;#721&lt;/a&gt;, and this new standard is described in the &lt;a href=&quot;https://ethereum.org/fr/developers/docs/standards/tokens/erc-721/&quot;&gt;Ethereum documentation&lt;/a&gt;, called &lt;strong&gt;ERC721&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To ensure that each token from the same smart contract is unique, a new variable is introduced, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokenId&lt;/code&gt;. This variable must be unique for each token in a smart contract in order to comply with the &lt;strong&gt;ERC721&lt;/strong&gt; standard.&lt;/p&gt;

&lt;p&gt;In addition to this variable, the following methods must be implemented:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Allows you to find out how many NFTs an account has&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Determines the owner of a particular NFT&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Send an NFT from one address to another, making sure that the destination address&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// is either an EOA account or a contract that can handle NFTs&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// We&apos;ll explain how in the rest of this article&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;safeTransferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;safeTransferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Send an NFT from one address to another&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Authorise an account to manage an NFT on its behalf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;approve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Authorise an account to manage ALL its NFTs on its behalf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setApprovalForAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Check who can manage a particular NFT&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getApproved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Check whether an account has full delegation for another account&apos;s NFTs&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isApprovedForAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are a number of functions that are very similar to ERC20 token functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;balanceOf&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferFrom&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approve&lt;/code&gt; for example). However, two other methods deserve a little more detail.&lt;/p&gt;

&lt;h3 id=&quot;safetransferfrom&quot;&gt;safeTransferFrom&lt;/h3&gt;

&lt;p&gt;The first is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom()&lt;/code&gt;. This method exists to prevent NFTs being sent to contracts which do not know how to handle NFTs. If this were the case, as the destination contract had not been created to handle NFTs, there would be no function to handle the newly received NFT. This would mean that this NFT could not be bought by anyone, or recovered in any way whatsoever. It would be locked into this contract forever. It’s easy to imagine that, when you offer a limited collection of something, you want to avoid losing it in the wild, unusable and non-exchangeable.&lt;/p&gt;

&lt;p&gt;To avoid this kind of problem, when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom()&lt;/code&gt; function is called to send tokens to a contract, the destination contract must use a special function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onERC721Received&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onERC721Received&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This function will be called by the token contract, and expects a very specific response. If this function does not exist in the destination contract (or if the function exists but does not return what is expected) then the NFT transfer will be cancelled. So, to receive NFTs via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom&lt;/code&gt;, a contract must have explicitly included this function. As this function only exists to validate a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom&lt;/code&gt;, as a general rule, if a contract contains this function, it means that it is also capable of managing NFTs.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/onERC721Received.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/onERC721Received.png&quot; alt=&quot;onERC721Received&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The presence of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onERC721Received&lt;/code&gt; does not guarantee that the contract can handle NFTs. You could very well create a contract that only implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onERC721Received&lt;/code&gt;, and nothing else. The call to this callback is more of a safeguard against silly errors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;setapprovalforall&quot;&gt;setApprovalForAll&lt;/h3&gt;

&lt;p&gt;The other function that deserves attention is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setApprovalForAll&lt;/code&gt;, simply because it can be dangerous. When a user uses this function to approve a destination address, it allows the destination to manage &lt;strong&gt;ALL&lt;/strong&gt; of the user’s NFT collection. When we say “manage”, we mean that the destination can send the user’s NFTs to arbitrary destination addresses. He could send them to the address null (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt;), which would cause these NFTs to be lost forever, or even send them to himself. Once the transfer is complete, the user has no way of recovering them.&lt;/p&gt;

&lt;p&gt;This function is dangerous and should only be used if you have absolute trust in the recipient (if it’s an EOA) or absolute understanding of the code (if the destination is a smart contract).&lt;/p&gt;

&lt;h3 id=&quot;example-1&quot;&gt;Example&lt;/h3&gt;

&lt;p&gt;Here is an example of an implementation of ERC721 &lt;em&gt;from scratch&lt;/em&gt; showing a simplistic implementation of the functions.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Please note that this example is for illustrative purposes only. It is absolutely &lt;strong&gt;not suitable for production&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: GPL-3.0&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This interface must be declared in order to be able to call the callback when&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// a safeTransferFrom&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IERC721Receiver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onERC721Received&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HackndoToken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// When state variables are declared and made public, getters are automatically created by Solidity&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Each NFT is assigned an owner&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Each address is assigned the number of NFTs it owns&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Allows you to find out which address has delegation rights over which NFT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Addresses which have full rights over the NFTs of other addresses&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operatorApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;



    &lt;span class=&quot;c1&quot;&gt;// When the contract is created, information about the NFT will be supplied&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// This function is not included in the standard, but it allows you to create&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// NFT at will, with no restrictions! Enjoy :)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]++;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// As an NFT is created, the identifier must be incremented&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// so that the next NFT is different&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Allows you to find out how many NFTs an account has&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;balanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;balances&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Determines the owner of a particular NFT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// You cannot have a tokenId greater than the last one created&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NOT_EXISTANT&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Send an NFT from one address to another, while ensuring that the destination address&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// is either an EOA account or a contract that can handle NFTs&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;safeTransferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// If it&apos;s a contract, call the onERC721Received() callback.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// If there is an error, or if the return value is not what was expected, we revert();&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// -&amp;gt; If there is a revert(), then the transferFrom() function previously called will be cancelled&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IERC721Receiver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onERC721Received&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IERC721Receiver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onERC721Received&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;revert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;revert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;safeTransferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;safeTransferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Send an NFT from one address to another&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Either it owns the NFT, or it has been approved for this NFT, or it has been approved for all the NFTs (including this one) in another account&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operatorApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NO_APPROVAL&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// The transfer source must own the NFT&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NOT_OWNER&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Authorise an account to manage an NFT on its behalf&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;approve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;owners&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NOT_OWNER&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tokenApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Allow an account to manage ALL its NFTs on its behalf&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setApprovalForAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;operatorApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_approved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Check who can manage this particular NFT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getApproved&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Check whether an account has full delegation for another account&apos;s NFTs&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isApprovedForAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operatorApprovals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As with ERC20, there is a version of &lt;a href=&quot;https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol&quot;&gt;ERC721&lt;/a&gt; proposed by OpenZeppelin which means you don’t have to start from scratch and can use a solid, tried and tested code base.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;These two standards are the most widely known and used, but they are far from being the only ones in existence. In fact, tokens can be used for so many applications that standards develop (and sometimes die) as new ideas for their use are put forward.&lt;/p&gt;

&lt;p&gt;Understanding how these tokens work is essential for any good auditor, as they are extremely common in decentralised applications, or dApps.&lt;/p&gt;
</description>
        <pubDate>Mon, 16 Oct 2023 03:13:32 +0000</pubDate>
        <link>https://en.hackndo.com/tokens-standards/</link>
        <guid isPermaLink="true">https://en.hackndo.com/tokens-standards/</guid>
        
        <category>Blockchain</category>
        
        
      </item>
    
      <item>
        <title>Sensitive Data in smart contracts</title>
        <description>&lt;p&gt;Do you remember the different storage spaces to which the EVM has access? The one comparable to a computer hard disk is the &lt;strong&gt;account storage&lt;/strong&gt;. This is the memory area in which the state of the contract is recorded. But you’ll also remember that the Ethereum blockchain is a decentralised state machine that can be read by anyone. Do you see where I’m going with this? All the data recorded by a smart contract can be read by anyone. If any sensitive data is recorded by a smart contract, we will be able to read it.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;memory-reminder&quot;&gt;Memory reminder&lt;/h2&gt;

&lt;p&gt;EVM memory is divided as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/evm_storage.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/evm_storage.png&quot; alt=&quot;EVM Storage&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the article on &lt;a href=&quot;/ethereum-virtual-machine/&quot;&gt;EVM&lt;/a&gt;, we described the usefulness of the different memory zones and how they are arranged.&lt;/p&gt;

&lt;p&gt;What we’re interested in in this article is &lt;strong&gt;account storage&lt;/strong&gt;, the permanent storage of the smart contract’s account. It is in this storage area that the contract will record its variables, which must be persistent on the blockchain. For example, if a smart contract manages registration for an event, it is necessary for the list of registrants to be recorded, and to be able to be modified. It is typically for this type of information that &lt;strong&gt;acount storage&lt;/strong&gt; is used.&lt;/p&gt;

&lt;p&gt;As a reminder, here’s what this memory area looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/account_storage.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/account_storage.png&quot; alt=&quot;Account Storage&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is organised into &lt;strong&gt;slots&lt;/strong&gt;, which function like an index. There are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; locations, and each location can store &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;256&lt;/code&gt; bits.&lt;/p&gt;

&lt;p&gt;If a contract (written with Solidity) wishes to store variables in this space (which we will call &lt;strong&gt;state variables&lt;/strong&gt;), it must declare them outside the functions.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hackndo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;cm&quot;&gt;/**
   * State variables registered in Account Storage
   */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; 
  &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalAmount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;


  &lt;span class=&quot;cm&quot;&gt;/**
   * Contract code
   */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Code&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Local variable (not stored on the blockchain)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;localVariable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;totalAmount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;totalAmount&lt;/code&gt; variables will be stored in this contract’s &lt;strong&gt;account storage&lt;/strong&gt;, and will be accessible by all functions in this contract. If they are updated by a function (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update()&lt;/code&gt;), the contract’s &lt;strong&gt;account storage&lt;/strong&gt; will be updated and these new values will be available for future transactions.&lt;/p&gt;

&lt;h2 id=&quot;variable-visibility&quot;&gt;Variable visibility&lt;/h2&gt;

&lt;p&gt;With Solidity, the visibility of a variable can be defined in three different ways:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt;: The variable is &lt;strong&gt;readable&lt;/strong&gt; by other smart contracts. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getter&lt;/code&gt; is automatically created. It can therefore be read by calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;totalAmount()&lt;/code&gt; function, for example.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;internal&lt;/code&gt;: The variable can only be read or modified by the contract in which it is defined, or contracts which inherit from this contract. This is the default visibility for variables.&lt;/li&gt;
  &lt;li&gt;private’: The variable cannot be read or modified by any smart contract other than the one in which it is defined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The definitions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;internal&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; variables in the &lt;a href=&quot;https://docs.soliditylang.org/en/v0.8.20/contracts.html#state-variable-visibility&quot;&gt;Solidity documentation&lt;/a&gt; can be confusing:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Internal&lt;/strong&gt; state variables can only be accessed from within the contract they are defined in and in derived contracts. They &lt;strong&gt;cannot be accessed externally&lt;/strong&gt;. This is the default visibility level for state variables.
&lt;strong&gt;Private&lt;/strong&gt; state variables are like internal ones but they are &lt;strong&gt;not visible&lt;/strong&gt; in derived contracts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we were not careful, we might think that by defining an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;internal&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; variable, this variable could not be read by anyone other than the contract itself, or contracts inherited from it, and that we could therefore be storing confidential information.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;internal&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt; variables are only private within the smart contract. However, &lt;strong&gt;their values can be freely read outside the blockchain by anyone&lt;/strong&gt;, so they do not hide data in this way.&lt;/p&gt;

&lt;h2 id=&quot;account-storage-layout&quot;&gt;Account storage layout&lt;/h2&gt;

&lt;p&gt;As an attacker, it is then necessary to understand how variables are stored in &lt;strong&gt;account storage&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;storage-order&quot;&gt;Storage order&lt;/h3&gt;

&lt;p&gt;The first thing to understand is that &lt;strong&gt;storage variables&lt;/strong&gt; are stored by the Solidity compiler in the order in which they are declared. In the example given above, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; variable will be stored first, then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;totalAmount&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;If no value is assigned to the variable, it will take the default value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x00&lt;/code&gt;, and its slot is still reserved.&lt;/p&gt;

&lt;p&gt;When the smart contract is compiled, the compiler will try to optimise the storage space required. To do this, if variables can fit into the same 32-byte slot, they will be put into the same slot.&lt;/p&gt;

&lt;p&gt;For example, if the state variables are as follows:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hackndo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;cm&quot;&gt;/**
   * State variables stored in Account Storage
   */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; 
  &lt;span class=&quot;n&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint128&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint128&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The size of a slot is 256 bits. The first 3 variables occupy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;32+32+128 = 192&lt;/code&gt; bits. The 4th variable cannot be added to the same slot, as there are only 64 bits available. It therefore goes into the second slot, along with the 5th and 6th variables. The size of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var4&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var5&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var6&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;128+32+8 = 168&lt;/code&gt; bits, which fits into one slot.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/storage_compression.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/storage_compression.png&quot; alt=&quot;Storage compression&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives the following data in the &lt;strong&gt;storage&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Slot 0&lt;/span&gt;
0x00000000000000000000 0000000000000000000000000000000a 0000000f 00000007
&lt;span class=&quot;c&quot;&gt;# empty var3 var2 var1&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# Slot 1&lt;/span&gt;
0x00000000000000000000 0003 00000002 00000000000000000000000000000009
&lt;span class=&quot;c&quot;&gt;# empty var6 var5 var4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;constant--immutable&quot;&gt;Constant &amp;amp; Immutable&lt;/h3&gt;

&lt;p&gt;With Solidity, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constant&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;immutable&lt;/code&gt; keywords can be used on state variables.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If a variable is defined as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constant&lt;/code&gt;, a value &lt;strong&gt;must&lt;/strong&gt; be assigned to it when it is declared, and this value can never be changed.&lt;/li&gt;
  &lt;li&gt;If a variable is defined as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;immutable&lt;/code&gt;, it &lt;strong&gt;must&lt;/strong&gt; be assigned a value, either &lt;strong&gt;at declaration time&lt;/strong&gt; or in the &lt;strong&gt;constructor&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What these two types of variable have in common is that all uses of these variables in the code will be &lt;strong&gt;replaced by their value by the compiler before the bytecode is saved on the blockchain&lt;/strong&gt;. So in fact, these notions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constant&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;immutable&lt;/code&gt; don’t exist for EVM. It’s just something practical for developers.&lt;/p&gt;

&lt;p&gt;If, for example, we have the following contract:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hackndo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MAX_SUPPLY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;immutable&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEST_ADDR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_dest_addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;DEST_ADDR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_dest_addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someFunc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MAX_SUPPLY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;MAX_SUPPLY reached&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEST_ADDR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not allowed&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Some code&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Two variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAX_SUPPLY&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEST_ADDR&lt;/code&gt; are declared. However, they will be replaced by their values when the contract is deployed on the blockchain. So finally, if this code is deployed by address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1234...&lt;/code&gt;, it is &lt;strong&gt;exactly equivalent to&lt;/strong&gt; :&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hackndo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;someFunc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;MAX_SUPPLY reached&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1234&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not allowed&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Some code&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From a &lt;em&gt;bytecode&lt;/em&gt; point of view, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constant&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;immutable&lt;/code&gt; variables don’t exist. So if you see this type of variable in a contract, you mustn’t take them into account when calculating slots.&lt;/p&gt;

&lt;h2 id=&quot;storing-variables&quot;&gt;Storing variables&lt;/h2&gt;

&lt;p&gt;Now that we’ve clarified which variables are stored in storage, and the optimisation used to limit the size of storage used, let’s look at how the different types of variable are technically stored.&lt;/p&gt;

&lt;h3 id=&quot;integers-and-booleans&quot;&gt;Integers and Booleans&lt;/h3&gt;

&lt;p&gt;As we saw in the previous examples, integers (and booleans) are simply stored in the corresponding slot. The maximum size of an integer was 256 bits, so it can never be larger than the size of a slot, which is also 256 bits.&lt;/p&gt;

&lt;h3 id=&quot;table&quot;&gt;Table&lt;/h3&gt;

&lt;p&gt;When a &lt;strong&gt;array&lt;/strong&gt; has a defined size, then its elements are stored one after the other following the rules already seen.&lt;/p&gt;

&lt;p&gt;But a &lt;strong&gt;array&lt;/strong&gt; can have a &lt;strong&gt;dynamic&lt;/strong&gt; size. We are not going to change the slots of all the variables that follow the array every time the size of the array changes. Each element of the array has its own slot in which it is stored.&lt;/p&gt;

&lt;p&gt;In this way, only the size of the array is stored in the slot that follows the rules we have described (so if a dynamic array is stored in slot 3, its size will be found in this slot).&lt;/p&gt;

&lt;p&gt;To find the first element of the array, calculate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(arrayIndex))&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arrayIndex&lt;/code&gt; would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt; in the previous case). This result is a 256-bit hash, which corresponds to the number of the slot in which the first element of the array is located. The following elements are simply in the following slots.&lt;/p&gt;

&lt;h3 id=&quot;mapping&quot;&gt;Mapping&lt;/h3&gt;

&lt;p&gt;For a &lt;strong&gt;mapping&lt;/strong&gt;, a slot is reserved to determine its base index, but nothing is stored there, unlike arrays where the size is stored.&lt;/p&gt;

&lt;p&gt;To access an element in a mapping, you don’t use an index, but the element’s key to find out its value.&lt;/p&gt;

&lt;p&gt;To determine where a mapping value is based on its key, you need to calculate the hash that concatenates the key of the element you are looking for and the slot reserved for the mapping (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slot&lt;/code&gt;). The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(key, slot))&lt;/code&gt; function must therefore be applied. As with arrays, this function returns a hash, which corresponds to the slot in which the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key&lt;/code&gt; is located.&lt;/p&gt;

&lt;h3 id=&quot;string&quot;&gt;String&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;strings&lt;/strong&gt; of less than 32 bytes are stored in a slot. The most significant bits are used to store the string, and the least significant bits to indicate the length of the string multiplied by 2 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length*2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If it is 32 bytes or longer, then the slot reserved for the string contains the length of the string multiplied by two, plus 1, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length*2+1&lt;/code&gt;, and the location of the string is simply the hash of the reserved slot.&lt;/p&gt;

&lt;p&gt;For example, if a long string is supposed to be in slot 2, then the address where the string is actually located can be found with the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(2))&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;➜ bytes32 slot &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; keccak256&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;abi.encode&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
➜ slot
Type: bytes32
└ Data: 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;This technique of storing double the length of the string, or double plus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, lets you know whether you are storing a string of less than 32 bytes or more than 32 bytes. If the least significant bit of the size is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, then the string is longer than 32 bytes. Otherwise, it is less than 32 bytes. Removing this bit and dividing the size by 2 gives the actual size of the string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;structure&quot;&gt;Structure&lt;/h3&gt;

&lt;p&gt;Finally, the variables in a &lt;strong&gt;structure&lt;/strong&gt; are stored one after the other, as if they were independent variables. If, in the structure, there are dynamic types (array, mapping etc.), then the rules we have seen apply.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;

&lt;p&gt;Here’s an example to summarise what we’ve seen so far:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Definition of a structure&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Coin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;// Definition of the example contract&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StorageContract&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MAX_SUPPLY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;immutable&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEST_ADDR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalSupply&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;pixis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This is an example of storage layout made by pixis. All details in https://hackndo.com&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coinsId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Coin&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Coin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;PixCoin&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;DEST_ADDR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pixis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;empty&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When this contract is deployed, this is what the storage looks like :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/storage_slots_example.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/storage_slots_example.png&quot; alt=&quot;Storage slots examples&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s try to break this down. Firstly, the first two variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAX_SUPPLY&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEST_ADDR&lt;/code&gt; are not stored in storage, so no slots are reserved for them.&lt;/p&gt;

&lt;p&gt;Next, the following variables are assigned a slot, in the order in which they are declared.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;To perform the calculations, I use &lt;a href=&quot;https://github.com/foundry-rs/foundry/tree/master/chisel&quot;&gt;chisel&lt;/a&gt; from the &lt;strong&gt;Foundry&lt;/strong&gt; suite.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/chisel_example.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/chisel_example.png&quot; alt=&quot;chisel&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;totalSupply&lt;/code&gt; is a 256-bit integer, so an entire slot is reserved for it, slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;. Its value is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10&lt;/code&gt;, so 0x0a&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt; is a string of less than 32 bytes. It is therefore stored in the next slot, slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, at the level of the most significant bits. Its size, multiplied by two (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; 5*2 = 10 = 0x0a&lt;/code&gt;) is stored in the least significant bits.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;description&lt;/code&gt; is a string of 86 bytes, so greater than 32 bytes. Thus, its slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; contains double its size, to which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; is added (remember, by adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, it indicates that the string is longer than 32 bytes), so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;86*2+1 = 173 = 0xad&lt;/code&gt;. The slot containing the string corresponds to the hash of the string’s slot, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;. However &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(2)) = 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace&lt;/code&gt; so the slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace&lt;/code&gt; contains the string.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;coinsId&lt;/code&gt; is an array containing 4 elements. Its size &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x04&lt;/code&gt; is therefore specified in its slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;. The slots of these 4 elements are calculated as follows:
    &lt;ul&gt;
      &lt;li&gt;Index 0: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(3)) = 0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b&lt;/code&gt;. For the other elements, the slot is incremented by 1 each time.&lt;/li&gt;
      &lt;li&gt;Index 1: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Index 2: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Index 3: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85e&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accounts&lt;/code&gt; is a mapping whose slot is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt;. It’s noticed that this slot is empty, that’s normal. The size of the mapping is not stored. To find the value of a particular key, the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encodePacked(key, slot))&lt;/code&gt; should be used so:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accounts[&quot;pixis&quot;]&lt;/code&gt; is found at the slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encodePacked(&quot;pixis&quot;, uint(4))) = 0x47e3196153c18a6193d6b7b92ecf7ea03bc91cce35ccd718094e10f1c50bd1e9&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accounts[&quot;empty&quot;]&lt;/code&gt; is found at the slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encodePacked(&quot;empty&quot;, uint(4))) = 0xace73dd693559189ef5ccbbc8f81155ea53ec7259b948d81d0791cf64125f053&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;coin&lt;/code&gt; is a structure containing two elements. They are therefore positioned in the slots &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;, less than 32 bytes) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;price&lt;/code&gt;, worth &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1000&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all these explanations, we are able to understand the entire &lt;strong&gt;account storage&lt;/strong&gt; of this contract, once deployed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/storage_slots_example_explained.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/storage_slots_example_explained.png&quot; alt=&quot;Storage slots examples&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;memory-reading&quot;&gt;Memory reading&lt;/h2&gt;

&lt;p&gt;It’s great, we are able to read and understand the storage space of contracts, but concretely, how do we access the storage space of a contract already deployed on the blockchain?&lt;/p&gt;

&lt;p&gt;Different tools allow reading the slots of a contract’s storage. Personally, I use the &lt;strong&gt;cast&lt;/strong&gt; tool from the &lt;a href=&quot;https://github.com/foundry-rs/foundry&quot;&gt;foundry&lt;/a&gt; suite.&lt;/p&gt;

&lt;p&gt;Indeed, when you install &lt;strong&gt;foundry&lt;/strong&gt; on your machine, different tools are installed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Forge&lt;/strong&gt;: Framework for performing tests on Ethereum&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cast&lt;/strong&gt;: Tool for interacting with smart contracts and the blockchain&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Anvil&lt;/strong&gt;: Local Ethereum node&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Chisel&lt;/strong&gt;: REPL tool for quickly executing Solidity code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;cast&lt;/strong&gt; tool is very handy for reading a contract’s slots. The syntax is as follows:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cast storage 0xcontract_address slot_number &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; RPC_URL]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example, to read the slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; of the contract at address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x099A3B242dceC87e729cEfc6157632d7D5F1c4ef&lt;/code&gt; on Ethereum (&lt;a href=&quot;https://etherscan.io/address/0x099a3b242dcec87e729cefc6157632d7d5f1c4ef#code&quot;&gt;random contract&lt;/a&gt;), the following command line can be used:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cast storage 0x099A3B242dceC87e729cEfc6157632d7D5F1c4ef 0 &lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; https://eth.llamarpc.com 
0x0000000000000000000000000000000000000000000000000000000000000001
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x01&lt;/code&gt; is in slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; of the contract. We can loop to read the first 6 slots:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;I &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;0..5&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SLOT &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$I&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &quot;&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;cast storage &lt;span class=&quot;nv&quot;&gt;$CONTRACT_ADDR&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$I&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$RPC_URL&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done
&lt;/span&gt;SLOT 0:  0x0000000000000000000000000000000000000000000000000000000000000001
SLOT 1:  0x0000000000000000000000000000000000000000000000000000000000000000
SLOT 2:  0x00000000000000000000000000000000000000000000000000c6645100000000
SLOT 3:  0x0000000000000000000000000000000000000000000000000000000000000205
SLOT 4:  0x000000000000000000000000000000000000000003f806d77433774f8c683600
SLOT 5:  0x0000000000000000000000000000000000000000000000000000000000c6647c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;putting-it-into-practice&quot;&gt;Putting it into practice&lt;/h2&gt;

&lt;p&gt;A contract is deployed at address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x84229eeFb7DB3f1f2B961c61E7CbEfd9D4c665E3&lt;/code&gt; on the &lt;a href=&quot;https://www.alchemy.com/overviews/sepolia-testnet&quot;&gt;Sepolia test network&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This contract is a game whose code is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GuessingGame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasGuessed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Declared as private. Is it really private?&lt;/span&gt;
    
    
    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12345&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// This is not the real number&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;guess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;hasGuessed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isWinner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasGuessed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The goal is to call the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;guess()&lt;/code&gt; by providing a number. If you hit the right number, you win, and you can prove it with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isWinner()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;As we have seen in this article, the variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretNumber&lt;/code&gt; has been declared as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private&lt;/code&gt;, but that will not prevent us from retrieving this value. For this, let’s use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cast&lt;/code&gt; tool.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;To encourage you to try, the result provided below is not the real result. It’s up to you to find the real secret value! The logic remains the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;RPC_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://rpc2.sepolia.org                                        
&lt;span class=&quot;nv&quot;&gt;CONTRACT_ADDR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x84229eeFb7DB3f1f2B961c61E7CbEfd9D4c665E3

&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;I &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;0..3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SLOT &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$I&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &quot;&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;cast storage &lt;span class=&quot;nv&quot;&gt;$CONTRACT_ADDR&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$I&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$RPC_URL&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output&lt;/span&gt;
SLOT 0:  0x00000000000000000000000031d6273610256e6cefd6f26a503c72bb2bdcfe15
SLOT 1:  0x0000000000000000000000000000000000000000000000000000000000000000
SLOT 2:  0x0000000000000000000000000000000000000000000000000000000042424242
SLOT 3:  0x0000000000000000000000000000000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We see that the first three slots are used. The first corresponds to the first state variable, that is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;owner&lt;/code&gt; address. The second variable seems empty, but that’s normal. This is the slot used by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hasGuessed&lt;/code&gt; mapping.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretNumber&lt;/code&gt; is recorded in the 3rd slot, and its value is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x42424242&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations, you have discovered a secret variable in a contract deployed on an Ethereum network!&lt;/p&gt;

&lt;p&gt;To interact with the contract, still with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cast&lt;/code&gt; utility, here’s how to proceed:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# To create a transaction, we use cast send&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# To be able to sign the transaction, the private key must be provided.&lt;/span&gt;
cast send &lt;span class=&quot;nv&quot;&gt;$CONTRACT_ADDR&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;guess(uint256)&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;10&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--private-key&lt;/span&gt; 0xabcdabcd...abcd &lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$RPC_URL&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# To read information without modifying the storage, we use cast call.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# isWinner() writes nothing in the storage, so no need to give it a private key. It&apos;s just information reading.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# If the output is 0, your address has still not found the right number.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# If the output is 1, congratulations, you have found the secret number!&lt;/span&gt;
cast call &lt;span class=&quot;nv&quot;&gt;$CONTRACT_ADDR&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;isWinner(address)&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;your address&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--rpc-url&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$RPC_URL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s your turn to play!&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Oct 2023 08:09:08 +0000</pubDate>
        <link>https://en.hackndo.com/sensitive-data/</link>
        <guid isPermaLink="true">https://en.hackndo.com/sensitive-data/</guid>
        
        <category>Blockchain</category>
        
        
      </item>
    
      <item>
        <title>Ethereum Virtual Machine</title>
        <description>&lt;p&gt;&lt;strong&gt;Ethereum Virtual Machine&lt;/strong&gt; (EVM) is a virtual machine used to manage transactions on the &lt;a href=&quot;/ethereum/&quot;&gt;Ethereum blockchain&lt;/a&gt; via smarts contracts. It’s an essential component of Ethereum, which we’re going to try and understand together.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;evm&quot;&gt;EVM&lt;/h2&gt;

&lt;p&gt;To execute smart contracts (programs in Ethereum’s world), rules must be followed. These rules are partly described in Ethereum’s &lt;a href=&quot;https://ethereum.github.io/yellowpaper/paper.pdf&quot;&gt;Yellow Paper&lt;/a&gt;, and can be implemented by anyone in any language. There is a python version of EVM (&lt;a href=&quot;https://github.com/ethereum/py-evm&quot;&gt;py-evm&lt;/a&gt;), a Rust version (&lt;a href=&quot;https://github.com/bluealloy/revm&quot;&gt;revm&lt;/a&gt;), and a Go version (&lt;a href=&quot;https://github.com/duanbing/go-evm&quot;&gt;go-evm&lt;/a&gt;). This list is by no means exhaustive.&lt;/p&gt;

&lt;h2 id=&quot;opcodes&quot;&gt;Opcodes&lt;/h2&gt;

&lt;p&gt;One of EVM’s key features (like any computer) is the ability to read and execute instructions, or &lt;strong&gt;opcodes&lt;/strong&gt;. Ethereum instructions are described on the official Ethereum website, &lt;a href=&quot;https://ethereum.org/fr/developers/docs/evm/opcodes/&quot;&gt;Opcodes for the EVM&lt;/a&gt;. The website &lt;a href=&quot;https://evm.codes/&quot;&gt;evm.codes&lt;/a&gt; is also very useful.&lt;/p&gt;

&lt;p&gt;This is the kind of code that is understood by the EVM. It is generated when a high-level language is compiled. One of the most widely used languages for writing smart contracts is &lt;strong&gt;Solidity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a very simple example of a smart contract written in Solidity.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: GPL-3.0&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HackndoMembers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Declaring persistent variables in the blockchain&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memberCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Constructor, executed when smart contract is deployed&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Public function to register as a member&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;becomeMember&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;memberCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Public function to find a member&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMember&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;member&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memberCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;id too big&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not a member&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;member&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Function only available to the smart contract creator to delete a member&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;removeMember&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Owner only&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once compiled, this program will be a sequence of instructions, or opcodes, understood by the EVM. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;solc&lt;/code&gt; tool can be used to compile Solidity.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;solc contract.sol &lt;span class=&quot;nt&quot;&gt;--bin&lt;/span&gt;        

&lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt; contract.sol:HackndoMembers &lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt;
Binary:
608060405234801561001057600080fd5b5033600080610100[...]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It also shows the generated opcodes.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;solc contract.sol &lt;span class=&quot;nt&quot;&gt;--opcodes&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt; contract.sol:HackndoMembers &lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt;
Opcodes:
PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Some of these instructions are used to execute mathematical operations, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mul&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt;. Others are used to compare elements, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lt&lt;/code&gt; (Lower Than), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gt&lt;/code&gt; (Greater Than) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is possible to read from and write to different storage areas, such as &lt;strong&gt;memory&lt;/strong&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mLoad&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mStore&lt;/code&gt;, or &lt;strong&gt;storage&lt;/strong&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sLoad&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sStore&lt;/code&gt; for example.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;stack&lt;/strong&gt; (another memory area) is managed with opcodes such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push2&lt;/code&gt;, …, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push32&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;These different types of storage will be discussed later in this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A contract can make calls to other functions, potentially other contracts, via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;staticcall&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;revert&lt;/code&gt; instruction can be used to make a kind of exception that terminates the current call. In most cases, the transaction will be considered invalid, and no changes will be made.&lt;/p&gt;

&lt;p&gt;These examples are by no means exhaustive, but they give an idea of what the EVM has to deal with when a smart contract is executed.&lt;/p&gt;

&lt;h2 id=&quot;gas&quot;&gt;Gas&lt;/h2&gt;

&lt;p&gt;Each instruction executed on the nodes has a price, the unit of which is the &lt;strong&gt;gas&lt;/strong&gt;. For example, executing an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt; costs 3 gas, while a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop&lt;/code&gt; costs just 2.&lt;/p&gt;

&lt;p&gt;When calling a smart contract function, a user must pay the price required to execute the instructions. He must therefore provide sufficient &lt;strong&gt;gas&lt;/strong&gt; during his transaction. If he has supplied too much, it’s no problem - the remaining gas will be refunded.&lt;/p&gt;

&lt;p&gt;If, on the other hand, he has &lt;strong&gt;not supplied enough&lt;/strong&gt;, the instructions will be executed until the gas is exhausted. When this happens, the transaction is cancelled, and the gas supplied by the user is lost. Although the transaction is cancelled, it still took resources to detect it, so it’s too late.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This notion of &lt;strong&gt;gas&lt;/strong&gt; was introduced to prevent resources from being used unnecessarily, in particular to avoid infinite loops or attacks that would clog up the network. In fact, there is a maximum number of &lt;strong&gt;gas&lt;/strong&gt; possible in a single block (currently 30 million gas).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;solidity&quot;&gt;Solidity&lt;/h2&gt;

&lt;p&gt;For the rest of this article, bear in mind that EVM, in the end, just executes opcodes, one after the other. It also offers various empty storage spaces that can be used, and that’s it. How these opcodes are organized, or how the data is structured, is up to the compiler.&lt;/p&gt;

&lt;p&gt;What we’re going to look at in this article concerns the Solidity compiler (and language). Other language compilers often use Solidity as a reference and follow the same conventions, but this is not always the case.&lt;/p&gt;

&lt;h2 id=&quot;global-variables&quot;&gt;Global variables&lt;/h2&gt;

&lt;p&gt;When a smart contract is written with Solidity, there are three global variables accessible to the smart contract, providing information about the context in which it is executed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Block&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;block&lt;/code&gt;): This variable contains information about the block in which the transaction was validated. This includes the block number, the time it was added to the blockchain, and its hash.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Transaction&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tx&lt;/code&gt;): Information relating to the current transaction is available in this variable. This is where we’ll know, for example, who initiated the transaction (who may be different from who initiated the last message), so it will always be an EOA.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Message&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg&lt;/code&gt;): Several messages can be sent within a transaction. In these messages, you can find out who sent the message, how many Ethers were supplied, the data included in the message, and so on. Depending on the context and the message, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg&lt;/code&gt; variable may change. For example, when a contract calls another contract, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt; attribute will be modified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;storage&quot;&gt;Storage&lt;/h2&gt;

&lt;p&gt;The smart contract code (made up of opcodes such as the ones we’ve introduced) needs to be stored somewhere, as do the contract variables and other temporary or permanent data required for proper execution. For this purpose, the EVM has various types of storage, permanent or not, for different purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/evm_storage.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/evm_storage.png&quot; alt=&quot;EVM Storage&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;permanent-storage&quot;&gt;Permanent storage&lt;/h2&gt;

&lt;p&gt;There are two types of persistent storage. These are the places where information is stored by nodes, and persistent during transaction execution. So, when a transaction is completed, this storage will be saved, and can be used for the next transaction. How convenient!&lt;/p&gt;

&lt;h3 id=&quot;bytecode&quot;&gt;Bytecode&lt;/h3&gt;

&lt;p&gt;The smart contract code is permanently stored, but &lt;strong&gt;cannot be modified&lt;/strong&gt;. It’s read-only. If an issue is detected in the smart contract after it has been deployed, it’s too late. You have to deploy a new smart contract with its fix, and warn users that the smart contract address has changed.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There are ways of dealing with this problem with proxy smart contracts, but that’s not the topic, and these contracts can also have bugs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;account-storage&quot;&gt;Account storage&lt;/h3&gt;

&lt;p&gt;The persistent storage location for smart contracts is &lt;strong&gt;account storage&lt;/strong&gt;. It’s a bit like a computer hard drive. We talked about this in &lt;a href=&quot;/ethereum/&quot;&gt;Ethereum&lt;/a&gt; article. In the &lt;strong&gt;world state&lt;/strong&gt; (Ethereum’s global state), each address is associated with various elements, such as the account’s Ether balance, but also, in the case of smart contracts, a “storage space” specific to the smart contract.&lt;/p&gt;

&lt;p&gt;In practical terms, this &lt;strong&gt;account storage&lt;/strong&gt; is a key/value database. The key is a 256-bit value, and so is the value. We can therefore store &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; keys, which should be more than enough. For the sake of clarity, we can also think of this storage as an array of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; rows, and each row can be assigned a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; bits value.&lt;/p&gt;

&lt;p&gt;Before anything is executed, this array is empty - it’s all zeros. So each contract has, by default, an array of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; lines, and each line has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; bits set to zero.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/account_storage.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/account_storage.png&quot; alt=&quot;Account Storage&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generally speaking, the first slots (or rows) of a Solidity contract contain the contract’s &lt;strong&gt;state variables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s take the following example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hackndo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/**
     * State variables
     */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalAmount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * Contract code
     */&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Code&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;myFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Code&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once the contract has been created, the &lt;strong&gt;account storage&lt;/strong&gt; will contain the following key/values:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/account_storage_updated.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/account_storage_updated.png&quot; alt=&quot;Account Storage Updated&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When referring to a key, the term &lt;strong&gt;slot&lt;/strong&gt; is often used. In the following example, &lt;strong&gt;slot 0&lt;/strong&gt; is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; variable and &lt;strong&gt;slot 1&lt;/strong&gt; is associated with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;totalAmount&lt;/code&gt; variable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;optimisation&quot;&gt;Optimisation&lt;/h4&gt;

&lt;p&gt;The declared variables were &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint256&lt;/code&gt;, i.e. 256 bits, which took up an entire slot, but if smaller variables are used, the storage will be optimized by the Solidity compiler. If two variables fit into one slot, then they will be put into that same slot. We’ll see this in details in another article.&lt;/p&gt;

&lt;h4 id=&quot;other-types&quot;&gt;Other types&lt;/h4&gt;

&lt;p&gt;In this account storage area, you can store not only integers, but also strings, arrays, mappings and so on. Each type of variable has its own storage rules, which are managed by the Solidity compiler so that they can be retrieved. Here’s a quick overview:&lt;/p&gt;

&lt;p&gt;When a &lt;strong&gt;array&lt;/strong&gt; is stored, the size of the array is stored at an index which follows the previous rule. To find the array &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nth&lt;/code&gt; element, you need to compute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(arrayIndex))+N&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256&lt;/code&gt; is a hash function (old SHA3 version).
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abi.encode&lt;/code&gt; is used to encode information in order to transform potentially complex data structures (such as arrays) into a sequence of bytes, enabling a hash function to work correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a &lt;strong&gt;mapping&lt;/strong&gt; (a key-value association), a slot is reserved to determine its base index (but nothing is stored there, unlike arrays for which the size is stored), then to determine where a value in the mapping is located, the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(abi.encode(key, mappingIndex))&lt;/code&gt; must be applied. It returns the index where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key&lt;/code&gt; value is located.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;strings&lt;/strong&gt; of less than 32 bytes are stored in a slot. The most significant bits are used to store the string, and the least significant bits to indicate its length. If it’s 32 bytes or longer, then the same mechanism as for arrays applies.&lt;/p&gt;

&lt;p&gt;Finally, variables in a &lt;strong&gt;structure&lt;/strong&gt; are stored one after the other, as if they were independent variables. If, in the structure, there are dynamic types (array, mapping etc.), then the rules we’ve seen apply.&lt;/p&gt;

&lt;h2 id=&quot;volatile-storage&quot;&gt;Volatile storage&lt;/h2&gt;

&lt;p&gt;Volatile memory is memory which, once the contract has been executed, is erased, leaving no trace of it. You could compare this memory to RAM (random access memory) in a computer.&lt;/p&gt;

&lt;h3 id=&quot;stack&quot;&gt;Stack&lt;/h3&gt;

&lt;p&gt;The stack is a &lt;strong&gt;LIFO&lt;/strong&gt; (Last In, First Out) memory location.&lt;/p&gt;

&lt;p&gt;This means that the last element pushed on the stack will be the first element to be unstacked. To better understand this, imagine a stack of plates. If you stack plates on top of each other, you’ll have to remove the last plate placed on top, then the second-to-last plate, etc., before you can retrieve the first plate placed on top.&lt;/p&gt;

&lt;p&gt;This memory area is used by the compiler to store temporary information, such as a function’s local variables, or opcodes arguments, for example. Typically, all smart contracts compiled with Solidity start with these 3 instructions to store the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt; at memory address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PUSH1 0x80 // destination
PUSH1 0x40 // value
MSTORE // mstore(destination, value)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mstore&lt;/code&gt; function arguments are pushed onto the stack in the reverse order of their use. In fact, the first element to be popped will be the last element pushed. So, first the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt; is pushed, then the destination &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40&lt;/code&gt;. When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mstore&lt;/code&gt; is executed, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40&lt;/code&gt; (the destination) will be popped, followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt; (the value).&lt;/p&gt;

&lt;p&gt;This is a memory area that changes a lot as a program is executed. Up to 1024 elements of 256 bits (32 bytes) can be stored here.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Please note that only the first &lt;strong&gt;16&lt;/strong&gt; elements of the stack can be used to perform operations, call functions, etc. This means, for example, that a function cannot have more than 16 arguments, or more than 16 local variables.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/stack.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/stack.png&quot; alt=&quot;Stack&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;memory&quot;&gt;Memory&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;memory&lt;/strong&gt; of a smart contract is a large memory area accessible for reading and writing in no predefined order, unlike the stack. It can store any size of information, from one byte up to 32 bytes at a time. On the other hand, information can only be read by 256 bits (32 bytes). This is where you’ll find variables with dynamic sizes, such as arrays or mappings, but you can also store integers or Booleans.&lt;/p&gt;

&lt;p&gt;Addressing is done on 32 bytes. So, theoretically, you can store up to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; bits of information. In practice, this is mainly to avoid collisions when storing dyamically-sized data. We use the hash of certain elements to decide on the storage destination. There’s plenty of time to win the lottery before two hashes in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2**256&lt;/code&gt; space are close!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/memory.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/memory.png&quot; alt=&quot;Memory&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;reserved-space&quot;&gt;Reserved space&lt;/h4&gt;

&lt;p&gt;The first two bytes (at addresses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x00&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x20&lt;/code&gt;) are used by the compiler to perform temporary calculations or operations.&lt;/p&gt;

&lt;p&gt;The third location (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40&lt;/code&gt;) contains a pointer to the next free, usable memory area. This is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free memory pointer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/free_memory_pointer.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/free_memory_pointer.png&quot; alt=&quot;Free memory pointer&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, it is this pointer that is initialized at the start of every contract compiled with Solidity as we saw earlier in this article. The following operations store &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt; at address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PUSH1 0x80
PUSH1 0x40
MSTORE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the next area free for memory allocation is located at address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80&lt;/code&gt;. And why not address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x60&lt;/code&gt;? Because this address is also special: it’s always &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;. It can be copied to initialize an array, for example.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/memory_null_data.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/memory_null_data.png&quot; alt=&quot;Null data&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;data-storage&quot;&gt;Data storage&lt;/h4&gt;

&lt;p&gt;Simple formats such as &lt;strong&gt;integers&lt;/strong&gt; are simply stored at the address assigned to them.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;strings&lt;/strong&gt;, when an address is assigned to store them, the length of the string is stored in the 256 bits starting at that address, then the string is stored.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;arrays&lt;/strong&gt;, a placeholder corresponding to the number of elements is reserved, and the array elements are added one after the other.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;structure&lt;/strong&gt; is organized in the same way as an array.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/memory_string_array.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/memory_string_array.png&quot; alt=&quot;Memory string array&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;calldata&quot;&gt;Calldata&lt;/h3&gt;

&lt;p&gt;When calling a smart contract function, the call must be created by the client before sending the transaction, i.e. before the EVM is instantiated anywhere. The function’s parameters cannot therefore be in a stack or in the EVM’s memory.&lt;/p&gt;

&lt;p&gt;The function, and its arguments, are sent in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; field of the transaction, as we briefly saw in the article on &lt;a href=&quot;ethereum/#sending-data&quot;&gt;Ethereum&lt;/a&gt;. When the contract is actually instantiated and executed in the Ethereum virtual machine, what has been sent in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; will be copied into the memory area called &lt;strong&gt;calldata&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This memory area, &lt;strong&gt;calldata&lt;/strong&gt;, is used when an Ethereum client calls a function, but not only. It is used every time a message is sent, whether from an EOA to a contract, or from a contract to a contract.&lt;/p&gt;

&lt;p&gt;From a memory point of view, &lt;strong&gt;calldata&lt;/strong&gt; is very similar to &lt;strong&gt;memory&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It is linear&lt;/li&gt;
  &lt;li&gt;Addressing is byte-by-byte.&lt;/li&gt;
  &lt;li&gt;Only 32 bytes can be read per call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, unlike &lt;strong&gt;memory&lt;/strong&gt;, this memory area is &lt;strong&gt;read only&lt;/strong&gt;. It cannot be written to. The EVM is responsible for copying the parameters sent by the message source.&lt;/p&gt;

&lt;h4 id=&quot;function-selector&quot;&gt;Function selector&lt;/h4&gt;

&lt;p&gt;The first 4 bytes are reserved for the &lt;strong&gt;function selector&lt;/strong&gt;. As explained in the article on &lt;a href=&quot;/ethereum/&quot;&gt;Ethereum&lt;/a&gt;, the function selector is calculated by hashing the function signature, and keeping only the first 4 bytes.&lt;/p&gt;

&lt;p&gt;For example, let’s take the following function:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getItemValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_itemName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_itemId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Function code&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Function signature is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;getItemValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And its selector:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;bytes4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getItemValue(string,uint256)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;mh&quot;&gt;0xc2e58fec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The rest of this memory area is dedicated to function arguments.&lt;/p&gt;

&lt;h4 id=&quot;function-arguments-storage&quot;&gt;Function arguments storage&lt;/h4&gt;

&lt;p&gt;Simple formats such as &lt;strong&gt;integers&lt;/strong&gt; are stored as is.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;strings&lt;/strong&gt;, we store the offset of where the string actually is. This offset is used to find the string, starting with its size (on 256 bits) and then the string itself.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;arrays&lt;/strong&gt;, similarly, we store the offset where the array is located. This offset is then used to store the array elements.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;structure&lt;/strong&gt; is organized in the same way as an array.&lt;/p&gt;

&lt;p&gt;Let’s take the same example as in the previous article about &lt;a href=&quot;/ethereum/&quot;&gt;Ethereum&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;getItemValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pixis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calldata&lt;/code&gt; value will be:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0xc2e58fec0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000057069786973000000000000000000000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be broken down as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/calldata.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/calldata.png&quot; alt=&quot;Calldata&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;pc---program-counter&quot;&gt;PC - Program Counter&lt;/h3&gt;

&lt;p&gt;For the record, there’s also a memory area called the &lt;strong&gt;Program Counter&lt;/strong&gt; or &lt;strong&gt;PC&lt;/strong&gt;. For those familiar with the Intel world, this is the equivalent of “EIP” (or “RIP”) register. It’s a memory area containing the address of the next instruction to be executed. It allows the virtual machine to know where to execute the next opcode. Often, this address increases little by little, and sometimes, when there’s a jump, the destination of the jump is assigned to the &lt;strong&gt;PC&lt;/strong&gt;, so that the next instruction executed will be the jump destination.&lt;/p&gt;

&lt;h3 id=&quot;gas-1&quot;&gt;Gas&lt;/h3&gt;

&lt;p&gt;Finally, the EVM keeps track of the number of consumed &lt;strong&gt;gas&lt;/strong&gt;, to check that there is sufficient &lt;strong&gt;gas&lt;/strong&gt; supplied by the user.&lt;/p&gt;

&lt;h2 id=&quot;calls&quot;&gt;Calls&lt;/h2&gt;

&lt;p&gt;Having reviewed the different memory zones that enable the EVM to run, we’ll finish by talking about the different types of calls that can be made to a smart contract to execute code. These calls are used to execute a smart contract function, with arguments if necessary.&lt;/p&gt;

&lt;p&gt;Each type of call has its own specificities. To understand what we’re talking about, we first need to explain that a contract is executed in a certain context. Sometimes, when a function is called, a new instance of EVM is deployed to execute the function code. Sometimes the memory areas are different, sometimes shared. Global information (such as the message source) may or may not also vary, depending on the type of call.&lt;/p&gt;

&lt;p&gt;We’ll summarize the details of each call in a table below.&lt;/p&gt;

&lt;h3 id=&quot;internal-calls&quot;&gt;Internal calls&lt;/h3&gt;

&lt;p&gt;The simplest are &lt;strong&gt;internal calls&lt;/strong&gt;. This is what happens when a smart contract calls one of its own functions, or a function from a contract it inherits. In &lt;strong&gt;opcode&lt;/strong&gt; terms, when an internal call is made, a jump is executed. There is &lt;strong&gt;no change of context&lt;/strong&gt;, we remain in the same contract, in the same virtual machine instance. The called function shares the same information and storage areas as the calling function.&lt;/p&gt;

&lt;p&gt;Here are two examples of internal calls, one for a function from the same contract (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionA()&lt;/code&gt;) and the other calling a function from a parent contract (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionParent()&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionParent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Internal call to a function within the same contract&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionChild&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Internal call to a function in the inherited contract&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;functionParent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionA()&lt;/code&gt; could have been put into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionB()&lt;/code&gt;, it wouldn’t have made much difference.&lt;/p&gt;

&lt;h3 id=&quot;external-calls&quot;&gt;External calls&lt;/h3&gt;

&lt;p&gt;External calls are more interesting. They allow you to call functions from other contracts. There are 3 different types of external call.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In fact, there’s a 4th, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;callcode&lt;/code&gt;, but it’s been deprecated in favor of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt;, so we won’t talk about it here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;call&quot;&gt;call&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; opcode is the basic call. It allows you to call a function from another contract. This function will be executed in a new EVM instance, with its own memory zones (stack, memory, etc.). The called code can then do as it wishes, modify its own memory, update its variables, etc. Understand, however, that the variables of the &lt;strong&gt;called&lt;/strong&gt; contract are completely &lt;strong&gt;independent&lt;/strong&gt; of the variables of the &lt;strong&gt;calling&lt;/strong&gt; contract. Good fences make good neighbors.&lt;/p&gt;

&lt;p&gt;In addition, message data is updated. Thus, the originating address (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt;) becomes that of the calling contract, and the value included in the message (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.value&lt;/code&gt;) is also updated.&lt;/p&gt;

&lt;p&gt;You can also send Ethers via a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callCounter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;callCounter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// call because functionA modifies information in storage, in this case its &quot;callCounter&quot; variable&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is possible to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; function explicitly, as follows:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ether&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;encodeWithSignature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;functionA()&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The call will return a boolean status on the successful execution of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; as well as the data optionally returned by the called function. Note also that, in this example, we have sent &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.1 ether&lt;/code&gt; to the called contract.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/call.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/call.png&quot; alt=&quot;Call&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;staticcall&quot;&gt;staticcall&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;staticcall&lt;/code&gt; is in every respect similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt;, but the function called &lt;strong&gt;cannot make any modifications to the blockchain&lt;/strong&gt;, neither its storage nor its ether balance. It’s a kind of read-only call.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Some code&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// staticcall because functionA is declared as &quot;view&quot;, so it won&apos;t modify its storage&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;functionA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As this call cannot modify the blockchain, the balance of the called contract cannot be modified. It is therefore not possible to send Ethers via this call. It is also possible to call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;staticcall&lt;/code&gt; function explicitly, as follows:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;staticcall&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;encodeWithSignature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;functionA()&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/staticcall.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/staticcall.png&quot; alt=&quot;Static Call&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;delegatecall&quot;&gt;delegatecall&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt; call is very special. It can be extremely useful, but also extremely dangerous. Whereas with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;staticcall&lt;/code&gt; calls, the memory areas were clearly separated between the caller and the called party, this is not completely the case with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;In this case, all volatile memory areas (stack, memory, PC) are specific to the called contract, contract B, &lt;strong&gt;however&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;reads and writes to storage will be done in the storage of contract A&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;The message origin address (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt;) and value (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.value&lt;/code&gt;) &lt;strong&gt;will not be updated&lt;/strong&gt;. So if an EOA calls contract A, and contract A performs a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt; to contract B, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt; will &lt;strong&gt;still be the EOA&lt;/strong&gt; when contract B executes its code.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateSecret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1337&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;


    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;callContractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// B&apos;s storage is updated because of the delegatecall&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;delegatecall&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;encodeWithSignature&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;updateSecret()&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getSecretNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractB&lt;/code&gt; has a private storage variable, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretNumber&lt;/code&gt;, equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;42&lt;/code&gt;. By performing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractA&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractA&lt;/code&gt; will update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretNumber&lt;/code&gt; variable. This update is made in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractB&lt;/code&gt;’s storage. So, following this call, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getSecretNumber()&lt;/code&gt; function will return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1337&lt;/code&gt;, not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/delegatecall.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/delegatecall.png&quot; alt=&quot;DelegateCall&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A classic use case for this type of call is proxy contracts. When a developer wants to update his contract, he has to deploy it again, and provide his users with the new address.&lt;/p&gt;

&lt;p&gt;One solution is to create a proxy contract, in which all application information is stored, and this contract performs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegatecall&lt;/code&gt; to the real application. The developer communicates the proxy address to all his users.&lt;/p&gt;

&lt;p&gt;If one day, the application needs to be updated, all that’s needed is to call a specific function in the proxy to update the application’s address. This update is transparent to users, since the proxy has not been modified.&lt;/p&gt;

&lt;h4 id=&quot;calls-summary&quot;&gt;Calls summary&lt;/h4&gt;

&lt;p&gt;Here’s a small table summarizing the different types of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt;.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Call from contract A to contract B&lt;/th&gt;
      &lt;th&gt;New EVM instance&lt;/th&gt;
      &lt;th&gt;Storage&lt;/th&gt;
      &lt;th&gt;msg.sender/msg.value&lt;/th&gt;
      &lt;th&gt;Blockchain state update&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;call&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Contrat B&lt;/td&gt;
      &lt;td&gt;Updated&lt;/td&gt;
      &lt;td&gt;Possible&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;staticcall&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Contrat B&lt;/td&gt;
      &lt;td&gt;Updated&lt;/td&gt;
      &lt;td&gt;Impossible&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;delegatecall&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Contrat A&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Not updated&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Possible&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This article has given us an overview of the &lt;strong&gt;EVM&lt;/strong&gt;, &lt;strong&gt;Ethereum Virtual Machine&lt;/strong&gt;. The virtual machine executes &lt;em&gt;opcodes&lt;/em&gt;, within the limit of the &lt;strong&gt;gas&lt;/strong&gt; sent by the user, since code execution has a cost.&lt;/p&gt;

&lt;p&gt;To function properly, the EVM uses different memory areas to store temporary and persistent information.&lt;/p&gt;

&lt;p&gt;Lastly, so that contracts can call each other, different &lt;strong&gt;calls&lt;/strong&gt; are supported by the EVM.&lt;/p&gt;

&lt;p&gt;These basics should be enough for us to take a serious look at smart contract vulnerabilities in future articles.&lt;/p&gt;
</description>
        <pubDate>Wed, 19 Jul 2023 08:12:43 +0000</pubDate>
        <link>https://en.hackndo.com/ethereum-virtual-machine/</link>
        <guid isPermaLink="true">https://en.hackndo.com/ethereum-virtual-machine/</guid>
        
        <category>Blockchain</category>
        
        
      </item>
    
      <item>
        <title>Ethereum</title>
        <description>&lt;p&gt;Unlike blockchains such as Bitcoin, which essentially allow Bitcoin cryptocurrency transactions to be sent, Ethereum also has something quite extraordinary: &lt;strong&gt;decentralized&lt;/strong&gt; code execution.&lt;/p&gt;

&lt;p&gt;Yes, decentralized. This means that we can write a program, code that is, and have it run not on one server, but on thousands of servers, or &lt;strong&gt;nodes&lt;/strong&gt;. And the output of our program is also recorded in a decentralized way. I don’t know about you, but I think it’s incredible, and it really made me want to dig a little deeper into the subject.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;So Ethereum is just another blockchain. There’s no shortage of blockchains today, but to date, Ethereum is the best-known and most widely used, at least in terms of blockchains that allow you to execute code. It does have its drawbacks, which other blockchains have addressed (albeit often to the detriment of other aspects), but that’s not really the point.&lt;/p&gt;

&lt;p&gt;Let’s take a look at how Ethereum works, covering the notions of EOA accounts, contracts, states and transactions.&lt;/p&gt;

&lt;h2 id=&quot;ethereum-101&quot;&gt;Ethereum 101&lt;/h2&gt;

&lt;p&gt;We discussed how blockchains work in general in the article &lt;a href=&quot;/blockchain/&quot;&gt;Blockchain 101&lt;/a&gt;. Ethereum operates in a similar way, with the consensus mechanism being the Proof of Stake. Ethereum’s own cryptocurrency is Ether (or ETH). Like Bitcoin and all other blockchains, Ethers can be sent to other users via transactions. Each user has his own address.&lt;/p&gt;

&lt;p&gt;What Ethereum brings is that, in addition to regular users who send transactions, it is possible to create small programs, &lt;strong&gt;smart contracts&lt;/strong&gt;, which also live on the blockchain. They all have addresses, just like users, but they also have code, stored on the blockchain.&lt;/p&gt;

&lt;p&gt;To distinguish these two types of accounts, we call classic human users &lt;strong&gt;EOA&lt;/strong&gt; (Externally Owned Accounts), which we distinguish from contract accounts, which we’ll simply refer to as &lt;strong&gt;contracts&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;eoa-vs-contrats&quot;&gt;EOA vs Contrats&lt;/h2&gt;

&lt;p&gt;Human-created accounts, or &lt;strong&gt;EOAs&lt;/strong&gt;, are accounts with an address, a public key and a private key. They can initiate transactions by signing them, send Ethers and receive them. These transactions can be sent to other EOAs, allowing Ethers to be sent, but also to contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contracts&lt;/strong&gt; also have an address, but no private key. &lt;strong&gt;They cannot initiate transactions&lt;/strong&gt;. They can only react to transactions initiated by EOAs, or to messages sent by other contracts. Indeed, once called by an EOA, a contract can send messages to other contracts. The notion of &lt;em&gt;message&lt;/em&gt; is discussed at the end of this article.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/eoa_contract.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/eoa_contract.png&quot; alt=&quot;EOA vs Contract&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;data-organization&quot;&gt;Data organization&lt;/h2&gt;

&lt;p&gt;Before we dive into why and how a contract account can execute code within the Ethereum ecosystem, let’s zoom in on the various data managed and used by Ethereum. Indeed, in this ecosystem, a &lt;strong&gt;global state&lt;/strong&gt; of addresses must be kept up to date (with account balances, for example), the list of &lt;strong&gt;transactions&lt;/strong&gt; must be stored and verifiable, the messages emitted in the various transactions must be accessible, and the permanent storage of each smart contract must, by definition, also be stored somewhere.&lt;/p&gt;

&lt;p&gt;All this data &lt;strong&gt;is not stored in the blocks of the blockchain&lt;/strong&gt;. Surprising as it may seem (at least to me at first sight), this information is stored in databases, &lt;strong&gt;outside the blocks&lt;/strong&gt;, in the form of trees that follow a specific format: these are &lt;strong&gt;Merkle Patricia Tries&lt;/strong&gt;, which enable a list of keys/values to be stored in an optimized way.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There’s no typo, it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Trie&lt;/code&gt;, not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tree&lt;/code&gt;, in reference to the word Re&lt;strong&gt;trie&lt;/strong&gt;ve. We’ll probably see the Merkle Patricia Tries in detail in a dedicated article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These data are therefore stored in the following trees:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;State trie&lt;/strong&gt;, or &lt;strong&gt;world state&lt;/strong&gt;, which itself contains links to &lt;strong&gt;storage tries&lt;/strong&gt;.
&lt;strong&gt;Transactions tries&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Receipt tries**&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In blocks, only the hash of the root of each of these trees is stored.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/ethereum_blocks.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/ethereum_blocks.png&quot; alt=&quot;Ethereum Blocks&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s up to each client to know how to store the contents of the trees and manage queries based on the root node hash (not all clients use the same database solutions, by the way).&lt;/p&gt;

&lt;p&gt;This enables lightweight devices (mobile, IoT) to synchronize quickly and easily with the blockchain without having to download huge volumes of data, so that they only know the root nodes hashes for each block. With this information, they can query &lt;em&gt;full nodes&lt;/em&gt;, i.e. nodes that have stored the blockchain, and also all the data in the databases, to send them the few pieces of information they need to validate any given data.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that even an Ethereum full node only requires around 1TB of disk space. It’s accessible to everyone, which is why so many people participate in the decentralized network. There are also &lt;strong&gt;archive nodes&lt;/strong&gt;. Unlike &lt;strong&gt;full nodes&lt;/strong&gt;, which only synchronize with the last 128 blocks, archive nodes store the &lt;strong&gt;entire&lt;/strong&gt; blockchain. For more information, please read &lt;a href=&quot;https://www.quicknode.com/guides/infrastructure/node-setup/ethereum-full-node-vs-archive-node&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s see what these different data trees correspond to.&lt;/p&gt;

&lt;h2 id=&quot;world-state&quot;&gt;World State&lt;/h2&gt;

&lt;p&gt;Let’s start with the &lt;strong&gt;State Trie&lt;/strong&gt;, or &lt;strong&gt;World State&lt;/strong&gt;. We can point out that, while we were comparing a blockchain to a decentralized database, Ethereum is more complex and comprehensive than that. Instead, we could describe Ethereum as &lt;strong&gt;a decentralized state machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, the general state of Ethereum is called &lt;strong&gt;World State&lt;/strong&gt;. In this world state, there are all active user addresses (i.e. addresses present in at least one transaction), and each address has an associated &lt;strong&gt;account state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/world_state_basic.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/world_state_basic.png&quot; alt=&quot;World State&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;account-state&quot;&gt;Account State&lt;/h2&gt;

&lt;p&gt;The status of each account is therefore recorded in the &lt;strong&gt;world state&lt;/strong&gt; containing the following 4 fields:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;balance&lt;/code&gt;: the account’s Ether balance&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt;: A number that increments with each transaction for an EOA, and with each contract creation for a contract.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codeHash&lt;/code&gt; : A hash that can be used to retrieve the smart contract’s code (the hash of an empty character string for an EOA).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;storageRoot&lt;/code&gt;: The root node hash of the Merkle Patricia Trie of &lt;strong&gt;account storage&lt;/strong&gt;, or &lt;strong&gt;storage trie&lt;/strong&gt;. It is used to retrieve the state of the contract, such as the value of permanently stored variables. This field is empty for an EOA account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/world_state.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/world_state.png&quot; alt=&quot;Account State&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each time a block on the blockchain is validated, all the transactions make changes to the &lt;strong&gt;world state&lt;/strong&gt;, resulting in a new state.&lt;/p&gt;

&lt;p&gt;In the following diagram, a block sends two transactions:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Address &lt;strong&gt;A&lt;/strong&gt; sends 2 coins to address &lt;strong&gt;C&lt;/strong&gt;. The balances (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;balance&lt;/code&gt;) of &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;C&lt;/strong&gt; will be updated, as will &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; of &lt;strong&gt;A&lt;/strong&gt; (which increments with each transaction).&lt;/li&gt;
  &lt;li&gt;Address &lt;strong&gt;A&lt;/strong&gt; sends 4 coins to address &lt;strong&gt;D&lt;/strong&gt;. The balance of &lt;strong&gt;A&lt;/strong&gt; will be updated, and address &lt;strong&gt;D&lt;/strong&gt;, which does not yet exist in the &lt;strong&gt;world state&lt;/strong&gt;, will be added, with a balance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;, and an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fields in red are therefore those that are modified following the execution of the block’s transactions, leading to a new &lt;strong&gt;N+1&lt;/strong&gt; state.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/world_state_bloc.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/world_state_bloc.png&quot; alt=&quot;World State Update&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;transactions&quot;&gt;Transactions&lt;/h2&gt;

&lt;p&gt;We now have a more precise overview of the account types that exist, and how they are stored within Ethereum. We’ve explained that blocks contain &lt;strong&gt;transactions&lt;/strong&gt; which modify the state of the involved accounts, and therefore the general state, or &lt;strong&gt;world state&lt;/strong&gt;. These transactions are actually recorded in a database, the &lt;strong&gt;Transactions Trie&lt;/strong&gt;, in an orderly fashion.&lt;/p&gt;

&lt;p&gt;A transaction contains several elements:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt;: The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; is specific to each account (stored for each address in the &lt;strong&gt;world state&lt;/strong&gt;, if you’ve been following along), and is incremented for each new transaction.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gasPrice&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gasLimit&lt;/code&gt;: Allow the user to define transaction fees&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt;: The destination address of the transaction&lt;/li&gt;
  &lt;li&gt;value`: The number of sent Eth&lt;/li&gt;
  &lt;li&gt;v,r,s`: The user’s signature&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt;: Allows you to send data to another account, or to create a contract&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you’re an observer, you’ll notice that a &lt;strong&gt;transaction&lt;/strong&gt; must be &lt;strong&gt;signed&lt;/strong&gt;. However, the only type of account that has a private key is the &lt;strong&gt;EOA&lt;/strong&gt;. Contracts don’t have private keys. Therefore, they cannot initiate a transaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are actually &lt;strong&gt;two&lt;/strong&gt; types of transaction in Ethereum, those that allow you to send a message to another account, and those that allow you to create a contract.&lt;/p&gt;

&lt;h3 id=&quot;sending-a-message&quot;&gt;Sending a message&lt;/h3&gt;

&lt;p&gt;In a transaction, account A sends a message to account B. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; destination address is that of account B, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; fields can be used.&lt;/p&gt;

&lt;h4 id=&quot;sending-ether&quot;&gt;Sending Ether&lt;/h4&gt;

&lt;p&gt;To send Ether to the destination address, the desired amount will be set in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt;. When an account sends Ether to another account, only the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; field is filled in. The destination account may be an EOA or a contract.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the destination is a contract, the contract must have been designed to receive Ethers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;sending-data&quot;&gt;Sending data&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; field is mainly used to execute the code of a smart contract, when the transaction is intended for it. It’s also possible to send data to an EOA, and the recipient will process it as it sees fit.&lt;/p&gt;

&lt;p&gt;When calling a contract function, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; field must be formatted as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;data: &amp;lt;Sélecteur de la fonction&amp;gt; &amp;lt;arguments&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function’s &lt;strong&gt;selector&lt;/strong&gt; is computed by hashing the function’s signature, keeping only the first 4 bytes.&lt;/p&gt;

&lt;p&gt;For example, let’s imagine the following function:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getItemValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_itemName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_itemId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Function code&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Function’s signature is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;getItemValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And it’s selector is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;bytes4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getItemValue(string,uint256)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;mh&quot;&gt;0xc2e58fec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; will be something like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;data:&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xc2e58fec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll see how the arguments are structured in a later article, but here’s an example for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getItemValue(&quot;pixis&quot;, 8)&lt;/code&gt; call:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0xc2e58fec                                                       # function selector
0000000000000000000000000000000000000000000000000000000000000040 # pointer to string &quot;pixis&quot;
0000000000000000000000000000000000000000000000000000000000000008 # 8
0000000000000000000000000000000000000000000000000000000000000005 # string length
7069786973000000000000000000000000000000000000000000000000000000 # string &quot;pixis&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This type of message can therefore be sent from an EOA account transaction to a smart contract.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that it is also possible for a contract to call another contract’s function by sending the same message format. Everything will happen in the &lt;strong&gt;same transaction&lt;/strong&gt;, since a contract &lt;strong&gt;cannot&lt;/strong&gt; sign a &lt;strong&gt;new&lt;/strong&gt; transaction. This type of call between contracts is a &lt;strong&gt;message call&lt;/strong&gt;, a specific instruction of the Ethereum virtual machine. Only the message is sent, the destination contract is executed, and the result of this call is returned to the calling contract. We’ll look at these calls in more detail in future articles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;contract-creation&quot;&gt;Contract creation&lt;/h3&gt;

&lt;p&gt;The second type of transaction enables an EOA account to create a new contract. To do this, the transaction is sent to the null address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x00000...&lt;/code&gt;, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; field is used.&lt;/p&gt;

&lt;p&gt;This &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; field is divided into two parts:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;initialization bytecode&lt;/strong&gt;, which is used to deploy the contract. It contains the contract constructor code and its arguments (if there is a constructor), as well as storage modifications if variables are declared. This code ends by returning the memory address of the &lt;strong&gt;*runtime bytecode&lt;/strong&gt; and its size.&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;runtime bytecode&lt;/strong&gt; is the contract code, which includes all functions code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this transaction has been processed, a new contract account is created. Its address is derived from the contract creator’s address and his &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt;. In this way, each time a new contract is created by the same user, a different address is generated.&lt;/p&gt;

&lt;p&gt;As we saw earlier, a new entry in the &lt;strong&gt;world state&lt;/strong&gt; will be created for this address. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; will be 0, the contract balance will depend on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; field of the transaction that created it (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; by default), but the most important fields are :&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codeHash&lt;/code&gt;: used to locate the account’s &lt;strong&gt;runtime bytecode&lt;/strong&gt;, i.e. all the smart contract’s logic.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;storageRoot&lt;/code&gt;: As a contract is always associated with a permanent storage, the &lt;strong&gt;account storage&lt;/strong&gt;, this value is used to find this storage in order to read and modify all the variables used in the smart contract.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;receipts&quot;&gt;Receipts&lt;/h2&gt;

&lt;p&gt;The last Trie we haven’t talked about is the &lt;strong&gt;Receipts Trie&lt;/strong&gt;. It is used to store information that is not required for the smart contracts to run properly, but which can be used by third-party applications, such as front-ends or clients.&lt;/p&gt;

&lt;p&gt;This includes, for example, the &lt;strong&gt;status&lt;/strong&gt; of the transaction (whether it failed or not), or the amount of &lt;strong&gt;gas&lt;/strong&gt; used.&lt;/p&gt;

&lt;p&gt;Furthermore, when a smart contract is executed, it can issue &lt;strong&gt;events&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyContract&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// &quot;Transfer&quot; event declaration&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Event&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transferTokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Function code&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// &quot;Transfer&quot; event emitted&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Transfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Transfer&lt;/code&gt; event is emitted at the end of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferToken&lt;/code&gt; function. This event will be added to the &lt;strong&gt;Receipts Trie&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;These various elements give us a better understanding of how Ethereum works, what defines a smart contract, how a user can create a smart contract and how he can interact with it. This article, together with &lt;a href=&quot;/blockchain/&quot;&gt;Blockchain 101&lt;/a&gt;, lays the foundations for explaining how Ethereum Virtual Machine (EVM) works. But that’s for the &lt;a href=&quot;/ethereum-virtual-machine/&quot;&gt;next article&lt;/a&gt;!&lt;/p&gt;
</description>
        <pubDate>Mon, 10 Jul 2023 04:13:37 +0000</pubDate>
        <link>https://en.hackndo.com/ethereum/</link>
        <guid isPermaLink="true">https://en.hackndo.com/ethereum/</guid>
        
        <category>Blockchain</category>
        
        
      </item>
    
      <item>
        <title>Blockchain 101</title>
        <description>&lt;p&gt;For several years now, I’ve been interested in a subject you’ve probably heard of: &lt;strong&gt;blockchains&lt;/strong&gt;. I find it fascinating that a technology allows thousands of people to agree on so many subjects &lt;strong&gt;without the need for an intermediary&lt;/strong&gt;. Decentralization is a subject that I believe has a lot of potential, and we’ll see in the long term whether this technology will endure or not. In any case, as it stands, it’s a hot topic! More recently, I’ve become interested in the &lt;strong&gt;Ethereum&lt;/strong&gt; blockchain, &lt;strong&gt;smart contracts&lt;/strong&gt;, and the &lt;strong&gt;security of smart contracts&lt;/strong&gt;. We’re going to talk about all that here, here we go.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Before diving into the security of smart contracts, it’s important to recap some &lt;strong&gt;key concepts about blockchains&lt;/strong&gt;. What is it, how does it work, who are the actors involved, we’ll look at all this in this introduction article. The idea is not to go into all the details, but to get an &lt;strong&gt;overview&lt;/strong&gt; of how blockchains work in general. As the technical specifics vary greatly from one blockchain to another, we’ll cover them in due course in future articles.&lt;/p&gt;

&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;/h2&gt;

&lt;p&gt;There are hundreds of definitions for the term &lt;strong&gt;blockchain&lt;/strong&gt;. What I think is important to understand is that it represents a decentralized registry (or database). There is no central entity deciding whether a transaction is valid or not, but rather thousands of people or machines working to verify and validate these transactions, all driven by mathematical rules and concepts.&lt;/p&gt;

&lt;p&gt;In a nutshell, we can simplify a blockchain by imagining it as a huge Excel spreadsheet in which you can add rows one after the other. It is also possible to read the entire Excel file, from the moment it was created. However, it is not possible to modify a line that has already been written and validated. It’s &lt;em&gt;append only&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Of course, this is a simplification, as blockchains such as Ethereum include, in addition to classic transactions, a virtual machine with its own storage space and so on. We’ll talk about this in the next article.&lt;/p&gt;

&lt;h2 id=&quot;transactions&quot;&gt;Transactions&lt;/h2&gt;

&lt;p&gt;What are these transactions? They are simply transfers of coins from one account to another. If Alice wants to send 1 coin to Bob, that’s a transaction.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A &lt;strong&gt;coin&lt;/strong&gt; is the cryptocurrency of the blockchain. For the Bitcoin blockchain, it’s Bitcoin, for the Ethereum blockchain it’s Ether, for Solana it’s Sol, and so on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To find out if Alice has enough &lt;em&gt;coins&lt;/em&gt;, all you have to do is read the transaction history. &lt;strong&gt;The whole&lt;/strong&gt; history. If one day she received &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt; &lt;em&gt;coins&lt;/em&gt;, spent &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; of them, then received &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt;, we can know, at the current time, that Alice has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3-2+4&lt;/code&gt;, i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt; &lt;em&gt;coins&lt;/em&gt;. She is then entitled to spend 1 coin, so everything’s fine.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/alice_balance.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/alice_balance.png&quot; alt=&quot;Alice balance&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that this is how Bitcoin works, but for other blockchains, the balance of each account is sometimes kept up to date (in the blockchain or not) to avoid having to recompute users’ balances for each transaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s what a classic blockchain contains. A record of all users’ spending since the blockchain was created.&lt;/p&gt;

&lt;h2 id=&quot;user&quot;&gt;User&lt;/h2&gt;

&lt;p&gt;To be a blockchain user, you need to have a pair of asymmetric keys: a public key and a private key. The private key, obviously carefully stored by each user, is used to sign all transactions. This is how, when Alice claims to be sending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; coin to some address, it is possible to verify that it was Alice who initiated the transaction. She has &lt;strong&gt;signed&lt;/strong&gt; it with her &lt;strong&gt;private key&lt;/strong&gt;, and anyone can check that this signature is valid with her public key.&lt;/p&gt;

&lt;p&gt;This means that in a blockchain, we don’t know that the user is &lt;strong&gt;Alice&lt;/strong&gt;. Rather, a user is defined by an address (derived from the public key). So when Alice wants to execute a transaction, from the blockchain’s point of view, her &lt;strong&gt;address&lt;/strong&gt; is the source of the transaction.&lt;/p&gt;

&lt;p&gt;Furthermore, to communicate with the blockchain, the user will use a &lt;strong&gt;client&lt;/strong&gt;. This is nothing more than a program that knows how to generate transactions, communicate with the network and so on. The user could code everything himself, but that’s not practical. It’s a bit like using a web browser to go online. It’s more practical than writing code to make HTTP requests.&lt;/p&gt;

&lt;h2 id=&quot;validation&quot;&gt;Validation&lt;/h2&gt;

&lt;p&gt;That’s all very well, but who validates these transactions? Who does the math to verify that Alice has at least &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; coin to send to someone? And checks that it’s really Alice who’s doing the transaction?&lt;/p&gt;

&lt;p&gt;This is where the concepts of &lt;strong&gt;blocks&lt;/strong&gt; and &lt;strong&gt;validators&lt;/strong&gt; come in. For a blockchain to work properly, several people need to get to work validating transactions. They create so-called &lt;strong&gt;nodes&lt;/strong&gt;, which will be able to broadcast themselves to the network and become part of it, retrieving past transactions and those awaiting validation. It’s a true &lt;strong&gt;peer-to-peer&lt;/strong&gt; network. As soon as a user wants to send a transaction (&lt;strong&gt;1&lt;/strong&gt;), the client he is using to send his transaction will notify another node (via &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-2464&quot;&gt;NewPooledTransactionHashes&lt;/a&gt;) that a new transaction has been sent (&lt;strong&gt;2&lt;/strong&gt;). The transaction will be &lt;strong&gt;verified&lt;/strong&gt; (signature verification, funds available, etc.) (&lt;strong&gt;3&lt;/strong&gt;), but it is not yet &lt;strong&gt;validated&lt;/strong&gt;. It will join the waiting list of transactions that have been sent but not yet validated, called the &lt;strong&gt;mempool&lt;/strong&gt;. This node will also notify other nodes by broadcasting this transaction (&lt;strong&gt;4&lt;/strong&gt;), and these new nodes will do the verification work themselves (&lt;strong&gt;6&lt;/strong&gt;) and add this transaction to their mempool, and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/tx_propagation.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/tx_propagation.png&quot; alt=&quot;Tx Propagation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there’s a whole bunch of transactions waiting to be validated, and that’s where the magic of the blockchain comes in. Transactions have to be validated, and all the nodes in the network will need to agree on which transactions should be validated, and the order in which they should be validated.&lt;/p&gt;

&lt;p&gt;Each node then creates a block, the size of which is limited (and differs from one blockchain to another) by selecting pending transactions in the mempool. Once this block has been created, all the nodes compete to make its block the new reference block. The winner’s block becomes the last block in the chain. It is added to the previously validated blocks, the underlying transactions are no longer in the mempool, since they have been validated, and all nodes must therefore rebuild a new block with the transactions that have not yet been validated to try, once again, to win this competition.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2023/06/blockchain_new_block.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2023/06/blockchain_new_block.png&quot; alt=&quot;New block&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;consensus&quot;&gt;Consensus&lt;/h2&gt;

&lt;p&gt;This “competition” we’re talking about is the consensus mechanism, i.e. a way of getting everyone to agree on the next block. There are many different consensus mechanisms.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Proof of Work (PoW)&lt;/strong&gt; is a consensus mechanism that requires each node to make a huge number of calculations to find a solution to a specific problem.&lt;/p&gt;

&lt;p&gt;In simple terms, it’s as if you were asked to supply a string such that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;md5(block + string)&lt;/code&gt; begins with ten times the number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;. There’s really no right or wrong way to do this.&lt;/p&gt;

&lt;p&gt;You can simply generate completely random strings, compute the md5 hash, until you find, by chance, an entry that satisfies the condition. And at some point, in a completely random fashion, someone may test :&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[bloc data]aa33bdsk&apos;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;md5sum&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
000000000035d3695b3a133766f60d42
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By being the first to find this solution to the problem, their block will be added to the existing blockchain, and therefore the transactions they took from the mempool will be validated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of Stake (PoS)&lt;/strong&gt; avoids the need for all all nodes to perform calculations. Instead, each node must set aside cryptocurrencies from the blockchain (&lt;strong&gt;staking&lt;/strong&gt;). Each node prepares its block, and at regular intervals, an algorithm randomly selects a node from those that have &lt;strong&gt;staked&lt;/strong&gt; cryptocurrencies. The selected node’s block will be validated, and we move on to the next block. If the node does not respect the rules or tries to cheat (by modifying transactions or creating a block that is too big, for example), his &lt;strong&gt;stake&lt;/strong&gt; will be confiscated. You gotta play by the rules.&lt;/p&gt;

&lt;p&gt;There are many other consensus mechanisms, but you get the idea. The goal is for a random node to validate a block regularly, but it should not be possible for the same node to validate all blocks. Everyone is in competition.&lt;/p&gt;

&lt;h2 id=&quot;incentives&quot;&gt;Incentives&lt;/h2&gt;

&lt;p&gt;Rest assured, the individuals behind these nodes are not blockchain enthusiasts working for free. Every job deserves a salary, and that applies to the blockchain as well. The people who are part of the network, verifying and validating transactions, earn rewards.&lt;/p&gt;

&lt;p&gt;To send a transaction on the network, users must also send a small amount called &lt;strong&gt;transaction fees&lt;/strong&gt; (known as &lt;strong&gt;gas&lt;/strong&gt; in Ethereum). Thus, when someone validates a block, they will collect the fees from the transactions they have validated. It becomes clear then that as a user, if we want to ensure that our transaction doesn’t stay indefinitely in the mempool, we need to pay sufficient transaction fees to be in the average range or even at the higher end if we want to be prioritized.&lt;/p&gt;

&lt;p&gt;Furthermore, with each validated block, a small amount of the cryptocurrency is created from scratch and sent to the validator. This increases the total circulating supply of the coin.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;These paragraphs hopefully clarify the overall concept of a blockchain and serve as an introduction to the next articles that focus on the &lt;a href=&quot;/ethereum/&quot;&gt;Ethereum blockchain&lt;/a&gt;, specifically the &lt;a href=&quot;/ethereum-virtual-machine&quot;&gt;Ethereum Virtual Machine&lt;/a&gt;, which enables the execution of smart contracts, and the security challenges associated with this decentralized code execution. See you soon!&lt;/p&gt;
</description>
        <pubDate>Mon, 03 Jul 2023 02:12:43 +0000</pubDate>
        <link>https://en.hackndo.com/blockchain/</link>
        <guid isPermaLink="true">https://en.hackndo.com/blockchain/</guid>
        
        <category>Blockchain</category>
        
        
      </item>
    
      <item>
        <title>Kerberos Delegation</title>
        <description>&lt;p&gt;Within an Active Directory, services can be used by users. Sometimes these services need to contact others, on behalf of the user, like a web service might need to contact a file server. In order to allow a service to access another service &lt;strong&gt;on behalf of the user&lt;/strong&gt;, a solution has been implemented (introduced in Windows Server 2000) to meet this need : &lt;strong&gt;Kerberos Delegation.&lt;/strong&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;delegation-principle&quot;&gt;Delegation principle&lt;/h2&gt;

&lt;p&gt;In order to understand what is Kerberos Delegation, let’s take a concrete example. A web server with a nice interface allows a user to access his personal folder, hosted on a file server. We are in the following situation :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/webfsuser.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/webfsuser.png&quot; alt=&quot;Actual state&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The web server is front-end, and it’s this web server that will fetch the information instead of the user on the file server in order to display the content of a file, for example.&lt;/p&gt;

&lt;p&gt;However, the web server does not know what belongs to the user on the file server. It is not his role to unpack the user’s &lt;a href=&quot;/kerberos-silver-golden-tickets/#pac&quot;&gt;PAC&lt;/a&gt; to make a specific demand to the file server. This is where the &lt;strong&gt;delegation&lt;/strong&gt;  comes in. This mechanism allows the web server to &lt;strong&gt;impersonate&lt;/strong&gt; the user, and to authenticate on the user’s behalf to the file server. Thus, from the file server’s point of view, it is the user who makes the request. The file server will be able to read and check user’s rightsr, then send back the information to which this account has access. This is how the web server can then display this information in a nice interface back to the user.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/impersonation.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/impersonation.png&quot; alt=&quot;Impersonation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;constrained--unconstrained-delegation&quot;&gt;Constrained &amp;amp; Unconstrained Delegation&lt;/h2&gt;

&lt;p&gt;The ability to relay credentials can be given to an account with at least one &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; attribute set. It could be a computer account or a service account.&lt;/p&gt;

&lt;p&gt;Today, there are three ways to authorize a computer or service account to impersonate a user in order to communicate with one or more other service(s) : &lt;strong&gt;Unconstrained Delegation&lt;/strong&gt;, &lt;strong&gt;Constrained Delegation&lt;/strong&gt; and &lt;strong&gt;Resource Based Constrained Delegation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;unconstrained-delegation&quot;&gt;Unconstrained Delegation&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;Unconstrained Delegation&lt;/strong&gt;, the server or the service account that is granted this right is able to impersonate a user to authenticate to &lt;strong&gt;any services&lt;/strong&gt; on &lt;strong&gt;any host&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/unconstrained_delegation_schema.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/unconstrained_delegation_schema.png&quot; alt=&quot;Unconstrained Delegation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is an example, in my lab, of a machine that is in &lt;strong&gt;Unconstrained Delegation&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/unconstrained_delegation.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/unconstrained_delegation.png&quot; alt=&quot;Unconstrained Delegation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is historically the only choice there was when the delegation principle was introduced. But for obvious security reason, &lt;strong&gt;Constrained Delegation&lt;/strong&gt; has been added.&lt;/p&gt;

&lt;h3 id=&quot;constrained-delegation&quot;&gt;Constrained Delegation&lt;/h3&gt;

&lt;p&gt;If a computer or a service account has the &lt;strong&gt;Constrained Delegation&lt;/strong&gt; flag set, a list of authorized services shall be associated to this flag. For example, in previous example (web server and file server), the web server will have the &lt;strong&gt;Constrained Delegation&lt;/strong&gt; flag indicating that this account can only impersonate some users against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CIFS&lt;/code&gt; service hosted by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SERVER01&lt;/code&gt;, the file server.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/constrained_delegation_schema.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/constrained_delegation_schema.png&quot; alt=&quot;Constrained Delegation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This list of allowed SPN is set on the relaying account, the computer account hosting the web server..&lt;/p&gt;

&lt;p&gt;In other words, the Domain Controller will read the SPN list on this account, and will decide: “This account is allowed to impersonate a user, so he can authenticate against one of these services on behalf of the user”.&lt;/p&gt;

&lt;p&gt;In my lab, the web server is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEB-SERVER-01&lt;/code&gt; and the one with file sharing is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEB-SERVER-02&lt;/code&gt;. So here is what the list of services for which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEB-SERVER-01&lt;/code&gt; can pretend  to be the user looks like :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/delegation_cifs.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/delegation_cifs.png&quot; alt=&quot;Delegation CIFS&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;resource-based-constrained-delegation---rbcd&quot;&gt;Resource Based Constrained Delegation - RBCD&lt;/h3&gt;

&lt;p&gt;Finally, we have the &lt;strong&gt;Resource Based Constrained Delegation&lt;/strong&gt; (RBCD) case. Introduced with Windows Server 2012, this solution allows to overcome some problems related to the &lt;strong&gt;Constrained Delegation&lt;/strong&gt; (Responsibility, inter-domains delegation, …). Without going into too much details, the delegation responsibility is moved. Whereas in &lt;strong&gt;Constrained Delegation&lt;/strong&gt;, it’s the relaying server that holds the list of allowed target services, in the case of &lt;strong&gt;Resource Based Constrained Delegation&lt;/strong&gt;, it’s the resources (or services) that have a list of accounts they trust for delegation. Thus, the diagram is as follows :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/resource_based_constrained_delegation_schema.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/resource_based_constrained_delegation_schema.png&quot; alt=&quot;Resource Based Constrained Delegation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The responsibility is shifted, it’s at the level of the resource that receives the delegated authentications that the information of whether or not the delegation is accepted is found.&lt;/p&gt;

&lt;p&gt;In other words, it’s the end resource that says “I allow this list of account […] to authenticate to me on behalf of someone else”.&lt;/p&gt;

&lt;h2 id=&quot;technical-details&quot;&gt;Technical details&lt;/h2&gt;

&lt;p&gt;Now that the high-level behavior is understood (at least I hope so), let’s go into a little more detail about this process. Concretely, how can a machine or an account can pretend to be a user when using a resource ? That’s what we are going to see now. Details between every different techniques are relatively different, that’s why each of them will be explained separately. Stay close on your seat, it’s gonna get dirty.&lt;/p&gt;

&lt;h3 id=&quot;unconstrained-delegation-1&quot;&gt;Unconstrained Delegation&lt;/h3&gt;

&lt;p&gt;As seen before, in this case, the server or the service account can authenticate on behalf of the user to any other services. For this to be possible, two prerequisites are required :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The first one is that the account that wants to delegate an authentication has the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TRUSTED_FOR_DELEGATION&lt;/code&gt; flag in his &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/adschema/a-useraccountcontrol?redirectedfrom=MSDN&quot;&gt;UAC - User Account Control&lt;/a&gt; flags. In order to set this flag, you need to have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SeEnableDelegationPrivilege&lt;/code&gt; right, which is usually only available for domain administrators. Here is how the flag is set on the account (machine or service account):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/unconstrained_delegation.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/unconstrained_delegation.png&quot; alt=&quot;Unconstrained Delegation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once set, we can list UAC flags and check that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TRUSTED_FOR_DELEGATION&lt;/code&gt; has been set.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/04/UAC_UD.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/04/UAC_UD.png&quot; alt=&quot;Unconstrained Delegation UAC&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The second one is that the user account which will be relayed is effectively “relayable”. To &lt;strong&gt;disable&lt;/strong&gt; relaying capabilities on an account, &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/desktop/api/iads/ne-iads-ads_user_flag&quot;&gt;NOT_DELEGATED&lt;/a&gt; flag is set. By default, no account on the AD has this flag set, so they are all “relayable”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/04/UAC_user_not_delegated.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/04/UAC_user_not_delegated.png&quot; alt=&quot;Not delegated flag unset&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Concretely, during exchanges with the Domain Controller as described in the &lt;a href=&quot;/kerberos&quot;&gt;Kerberos in Active Directory&lt;/a&gt; article, when the user asks for a TGS (&lt;a href=&quot;/kerberos/#krb_tgs_req&quot;&gt;KRB_TGS_REQ&lt;/a&gt;), he will specify the &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; of the service he wants to use. It is at this point that the Domain Controller will look for the two prerequisites :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TRUSTED_FOR_DELEGATION&lt;/code&gt; flag set in the attributes of the account associated to the &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT_DELEGATED&lt;/code&gt; flag &lt;strong&gt;not&lt;/strong&gt; set for the requesting user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If both prerequisites are met, then the Domain Controller will respond to the user with a &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_TGS_REP&lt;/a&gt; containing standard information, but it will also contains a &lt;strong&gt;copy of the user’s TGT&lt;/strong&gt; in his response, and a new associated session key.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/cop_tgt.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/cop_tgt.png&quot; alt=&quot;TGT Copy&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once in possession of these elements, the user will continue the classic process by sending a request to the service (&lt;a href=&quot;/kerberos/#krb_ap_req&quot;&gt;KRB_AP_REQ&lt;/a&gt;) by sending the TGS and an authenticator. The service will be able to decrypt the content of the TGS, verify the user’s identity by decrypting the authenticator, but above all it will be able to retrieve the copy of the TGT and the associated session key, in order to pretend to be the user at the Domain Controller.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/tgt_memory.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/tgt_memory.png&quot; alt=&quot;TGT Memory&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in possession of a copy of the user’s TGT and a valid session key, the service can authenticate to any other service on the user’s behalf by requesting the TGS from the Domain Controller, by providing this TGT and by encrypting an authenticator with the session key. It’s the &lt;strong&gt;Unconstrained Delegation&lt;/strong&gt; principle.&lt;/p&gt;

&lt;p&gt;Here is a summary diagram :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/unconstrained_delegation_detailed.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/unconstrained_delegation_detailed.png&quot; alt=&quot;Unconstrained Delegation Detailed&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;constrained-delegation-1&quot;&gt;Constrained Delegation&lt;/h3&gt;

&lt;p&gt;For the &lt;strong&gt;Constrained Delegation&lt;/strong&gt;, a list of &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; or of authorized accounts will be provided to indicate the services/accounts accepted for the delegation. Therefore, the process is not the same. The service involved will not be in possession of the user’s TGT, otherwise there is no way to control service’s authentication. A different mechanism is used.&lt;/p&gt;

&lt;p&gt;Let’s consider the case where the user authenticate to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; and then this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; has to impersonate the user to access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resource B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The user makes a TGS request, then sends it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt;. Since this service needs to access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resource B&lt;/code&gt; as the user, it will request a TGS to the Domain Controller on behalf of the user. This request is governed by the &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a&quot;&gt;S4U2Proxy&lt;/a&gt; extension. To tell the Domain Controller it wants to authenticate on behalf of someone else, two attributes will be defined in the &lt;a href=&quot;/kerberos/#krb_tgs_req&quot;&gt;KRB_TGS_REQ&lt;/a&gt; ticket request:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional-tickets&lt;/code&gt;, usually empty, must contain the user’s TGS (given that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT_DELEGATED&lt;/code&gt; flag is &lt;strong&gt;not&lt;/strong&gt; set for the requesting user. If that was the case, the user’s TGS would &lt;strong&gt;not&lt;/strong&gt; be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forwardable&lt;/code&gt;, and the Domain Controller would not accept it in the rest of the process)&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/17b9af82-d45a-437d-a05c-79547fe969f5&quot;&gt;cname-in-addl-tkt&lt;/a&gt; flag, which should be set to indicate to the Domain Controller that it should not use the server information, but the ticket information in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional-tickets&lt;/code&gt;, i.e. the information of the user the server wants to pretend to be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is during this request that the Domain Controller, upon seeing this information, will verify that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; has the right to authenticate to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resource B&lt;/code&gt; on behalf of the user.&lt;/p&gt;

&lt;h4 id=&quot;constrained-delegation---classic&quot;&gt;Constrained Delegation - Classic&lt;/h4&gt;

&lt;p&gt;In the classic &lt;strong&gt;Constrained Delegation&lt;/strong&gt; case (when delegation information is located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt;), this information is found in the &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-ada2/86261ca1-154c-41fb-8e5f-c6446e77daaa&quot;&gt;msDS-AllowedToDelegateTo&lt;/a&gt; attribute &lt;strong&gt;of the requesting account&lt;/strong&gt;, thus of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt;. This attribute specifies the list of authorized &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; for the delegation.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/delegation_cifs.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/delegation_cifs.png&quot; alt=&quot;Delegation CIFS&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example here the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msDS-AllowedToDelegateTo&lt;/code&gt; attribute will contain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cifs/WEB-SERVER-02&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/04/allowedToDelegateTo.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/04/allowedToDelegateTo.png&quot; alt=&quot;allowedToDelegateTo&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the targeted &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; is present, then the Domain Controller sends back a valid TGS, with the name of the user, for the requested service. Here is a summary diagram :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/constrained_delegation_schema_detailed.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/constrained_delegation_schema_detailed.png&quot; alt=&quot;Constrained Delegation Detailed&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;constrained-delegation---resource-based&quot;&gt;Constrained Delegation - Resource Based&lt;/h4&gt;

&lt;p&gt;This time, the Domain Controller will look at the attributes of &lt;strong&gt;Resource B&lt;/strong&gt; (instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt;). It will check that the account associated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; is present in the &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-ada2/cea4ac11-a4b2-4f2d-84cc-aebb4a4ad405&quot;&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/a&gt; attribute of the account linked to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resource B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to set up RBCD on a resource, we need to use powershell.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/04/set_rbcd.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/04/set_rbcd.png&quot; alt=&quot;Set RBCD&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEB-SERVER-01&lt;/code&gt; is added to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WEB-SERVER-02&lt;/code&gt; trusting list, so &lt;strong&gt;msDS-AllowedToActOnBehalfOfOtherIdentity&lt;/strong&gt; is updated.&lt;/p&gt;

&lt;p&gt;Then, when a service wants to access a resource, here’s how it works:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/resource_based_constrained_delegation_schema_detailed.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/resource_based_constrained_delegation_schema_detailed.png&quot; alt=&quot;Resource Based Constrained Delegation Detailed&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the diagram shows, the technical functioning is similar to classic constrained delegation, however the responsibilities of each entity is radically different.&lt;/p&gt;

&lt;h3 id=&quot;s4u2self&quot;&gt;S4U2Self&lt;/h3&gt;

&lt;p&gt;If you are still there and you are not lost, you should have noticed that we haven’t touched on the notion of protocol transition in this article. Indeed, in the explanation of constrained delegation, we assumed that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; had a service ticket coming from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USER&lt;/code&gt;, which was added in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional-tickets&lt;/code&gt; field of the TGS request (&lt;strong&gt;S4U2Proxy&lt;/strong&gt;). But sometimes the user may authenticate to the server in other ways than the Kerberos protocol (e.g. via NTLM, or even a Web form). In this case, the server is not in possession of the TGS sent by the user. Thus, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; cannot fill the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional-tickets&lt;/code&gt; field as it did in the case described above.&lt;/p&gt;

&lt;p&gt;That is why there is an extra step, possible through the &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/02636893-7a1f-4357-af9a-b672e3e3de13&quot;&gt;S4U2Self&lt;/a&gt; extension, that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service A&lt;/code&gt; must perform. This step allows it to obtain a TGS for a user &lt;strong&gt;arbitrarily chosen&lt;/strong&gt;. To do this, it makes a classic TGS request (&lt;a href=&quot;/kerberos/#krb_tgs_req&quot;&gt;KRB_TGS_REQ&lt;/a&gt;) except that instead of putting his own name in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PA-FOR-USER&lt;/code&gt; block (present in the pre-authentication part), it puts the name of a user &lt;strong&gt;it chooses&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This ability to manage &lt;strong&gt;protocol transition&lt;/strong&gt; is accepted by the Domain Controller only if it has been explicitly granted to the service account wishing to manage this delegation. It is in delegation management tab that an administrator can choose a constrained delegation using Kerberos only, therefore without protocol transition, or using any protocol, thus allowing &lt;strong&gt;protocol transition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/04/protocol_transition.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/04/protocol_transition.png&quot; alt=&quot;Protocol transition&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first case, no specific flag is set on the account, and the service can only relay kerberos authentication. It cannot use the S4U2Self extension to create a ticket out of nowhere.&lt;/p&gt;

&lt;p&gt;In the second case, the &lt;strong&gt;TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION&lt;/strong&gt; flag is set. If this is the case, then the service with this flag &lt;strong&gt;can pretend to be anyone&lt;/strong&gt; when accessing services in its list via the &lt;strong&gt;S4U2Self&lt;/strong&gt; extension.&lt;/p&gt;

&lt;p&gt;This diagram is getting a little bit more complicated, but I hope it remains relatively clear.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/s4u2self.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/s4u2self.png&quot; alt=&quot;S4U2Self&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If such an account is compromised, then all services to which that account is entitled to authenticate via delegation will also be compromised, since the attacker can create service tickets on behalf of arbitrary users, such as administrators.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I was thinking of doing an article that would describe kerberos delegation as well as associated attacks, however the explanations are much more dense than expected, so this article remains devoted to explanation. Associated attacks will be presented in other articles.&lt;/p&gt;

&lt;p&gt;To sum up, there are three types of delegation:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Unconstrained delegation&lt;/strong&gt;: In this case, the client sends a copy of his TGT to a service, and that service uses it to impersonate the client to any other service. Only an administrator can set this option on an account.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Constrained delegation&lt;/strong&gt;: A list of resources is set on the service that wishes to delegate authentication. If &lt;strong&gt;protocol transition&lt;/strong&gt; is allowed, then the service can pretend to be anyone when accessing resources in its list. In any case, only an administrator can set this option.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resource-based Constraint Delegation&lt;/strong&gt;: The final resource has a list of trusted accounts. All accounts in this list can delegate authentication when accessing the resource. Resources can modify this list as they wish, they don’t need an administrator to update it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have any questions or suggestions, do not hesitate, I’m all ears.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;p&gt;Big thanks to them for their clear explanations.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.harmj0y.net/activedirectory/s4u2pwnage/&quot;&gt;S4U2Pwnage - Harmj0y&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://adsecurity.org/&quot;&gt;ADSecurity - Pyrotek3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.sstic.org/media/SSTIC2014/SSTIC-actes/secrets_dauthentification_pisode_ii__kerberos_cont/SSTIC2014-Article-secrets_dauthentification_pisode_ii__kerberos_contre-attaque-bordes_2.pdf&quot;&gt;Secrets d’authentification épisode II Kerberos contre-attaque - Aurélien Bordes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html&quot;&gt;Wagging the dog - Edla Shamir&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 18 Apr 2020 12:17:22 +0000</pubDate>
        <link>https://en.hackndo.com/constrained-unconstrained-delegation/</link>
        <guid isPermaLink="true">https://en.hackndo.com/constrained-unconstrained-delegation/</guid>
        
        <category>Active Directory</category>
        
        <category>Windows</category>
        
        
      </item>
    
      <item>
        <title>NTLM Relay</title>
        <description>&lt;p&gt;NTLM relay is a technique of standing between a client and a server to perform actions on the server while impersonating the client. It can be very powerful and can be used to take control of an Active Directory domain from a black box context (no credentials). The purpose of this article is to explain NTLM relay, and to present its limits.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;preliminary&quot;&gt;Preliminary&lt;/h2&gt;

&lt;p&gt;This article is not meant to be a tutorial to be followed in order to carry out a successful attack, but it will allow the reader to understand in detail the &lt;strong&gt;technical details&lt;/strong&gt; of this attack, its limitations, and can be a basis to start developing his own tools, or understand how current tools work.&lt;/p&gt;

&lt;p&gt;In addition, and to avoid confusion, here are some reminders:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;NT Hash&lt;/strong&gt; and &lt;strong&gt;LM Hash&lt;/strong&gt; are hashed versions of user passwords. LM hashes are totally obsolete, and will not be mentioned in this article. NT hash is commonly called, wrongly in my opinion, “NTLM hash”. This designation is confusing with the protocol name, NTLM. Thus, when we talk about the user’s password hash, we will refer to it as &lt;strong&gt;NT hash&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;NTLM&lt;/strong&gt; is therefore the name of the &lt;strong&gt;authentication protocol&lt;/strong&gt;. It also exists in version 2. In this article, if the version affects the explanation, then NTLMv1 and NTLMv2 will be the terms used. Otherwise, the term NTLM will be used to group all versions of the protocol.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;NTLMv1 Response&lt;/strong&gt; and &lt;strong&gt;NTLMv2 Response&lt;/strong&gt; will be the terminology used to refer to the challenge response sent by the client, for versions 1 and 2 of the NTLM protocol.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Net-NTLMv1&lt;/strong&gt; and &lt;strong&gt;Net-NTLMv2&lt;/strong&gt; are pseudo-neo-terminologies used when the NT hash is called NTLM hash in order to distinguish the NTLM hash from the protocol. Since we do not use the NTLM hash terminology, these two terminologies will not be used.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Net-NTLMv1 Hash&lt;/strong&gt; and &lt;strong&gt;Net-NTLMv2 Hash&lt;/strong&gt; are also terminologies to avoid confusion, but will also not be used in this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;NTLM relay relies, as its name implies, on NTLM authentication. The basics of NTLM have been presented in &lt;a href=&quot;/pass-the-hash/#protocol-ntlm&quot;&gt;pass-the-hash article&lt;/a&gt;. I invite you to read at least the part about NTLM protocol and local and remote authentication.&lt;/p&gt;

&lt;p&gt;As a reminder, NTLM protocol is used to authenticate a client to a server. What we call client and server are the two parts of the exchange. The client is the one that wishes to authenticate itself, and the server is the one that validates this authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_basic.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_basic.png&quot; alt=&quot;NTLM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This authentication takes place in 3 steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;First the client tells the server that it wants to authenticate.&lt;/li&gt;
  &lt;li&gt;The server then responds with a challenge which is nothing more than a random sequence of characters.&lt;/li&gt;
  &lt;li&gt;The client encrypts this challenge with its secret, and sends the result back to the server. This is its response.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process is called &lt;strong&gt;challenge/response&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_challenge_response.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_challenge_response.png&quot; alt=&quot;NTLM Challenge Response&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The advantage of this exchange is that the user’s secret never passes through the network. This is known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Zero-knowledge_proof&quot;&gt;Zero-knowledge proof&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;ntlm-relay&quot;&gt;NTLM Relay&lt;/h2&gt;

&lt;p&gt;With this information, we can easily imagine the following scenario: An attacker manages to be in a man-in-the-middle position between a client and a server, and simply relays information from one to the other.&lt;/p&gt;

&lt;p&gt;The man-in-the-middle position means that from the client’s point of view, the attacker’s machine is the server to which he wants to authenticate, and from the server’s point of view, the attacker is a client like any other who wants to authenticate.&lt;/p&gt;

&lt;p&gt;Except that the attacker does not “just” want to authenticate to the server. He wishes to do so by pretending to be the client. However, he does not know the secret of the client, and even if he listens to the conversations, as this secret is never transmitted over the network (zero-knowledge proof), the attacker is not able to extract any secret. So, how does it work?&lt;/p&gt;

&lt;h3 id=&quot;message-relaying&quot;&gt;Message Relaying&lt;/h3&gt;

&lt;p&gt;During NTLM authentication, a client can prove to a server its identity by encrypting with its password some piece of information provided by the server. So the only thing the attacker has to do is to let the client do its work, and passing the messages from the client to the server, and the replies from the server to the client.&lt;/p&gt;

&lt;p&gt;All the client has to send to the server, the attacker will receive it, and he will send the messages back to the real server, and all the messages that the server sends to the client, the attacker will also receive them, and he will forward them to the client, as is.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_basic.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_basic.png&quot; alt=&quot;NTLM Relay&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it’s all working out! Indeed, from the client’s point of view, on the left part on the diagram, an NTLM authentication takes place between the attacker and him, with all the necessary bricks. The client sends a negotiate request in its first message, to which the attacker replies with a challenge. Upon receiving this challenge, the client builds its response using its secret, and finally sends the last authentication message containing the encrypted challenge.&lt;/p&gt;

&lt;p&gt;Ok, that’s great but the attacker cannot do anything with this exchange. Fortunately, there is the right side of the diagram. Indeed, from the server’s point of view, the attacker is a client like any other. He sent a first message to ask for authentication, and the server responded with a challenge. As &lt;strong&gt;the attacker sent this same challenge to the real client&lt;/strong&gt;, the real client &lt;strong&gt;encrypted this challenge&lt;/strong&gt; with &lt;strong&gt;its secret&lt;/strong&gt;, and responded &lt;strong&gt;with a valid response&lt;/strong&gt;. The attacker can therefore send this &lt;strong&gt;valid response&lt;/strong&gt; to the server.&lt;/p&gt;

&lt;p&gt;This is where the interest of this attack lies. From the server’s point of view, the attacker has authenticated himself using the victim’s secret, but in a transparent way for the server. It has no idea that the attacker was replaying his messages to the client in order to get the client to give him the right answers.&lt;/p&gt;

&lt;p&gt;So, from the server’s point of view, this is what happened:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_server_pov.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_server_pov.png&quot; alt=&quot;NTLM Relay from server&apos;s point of view&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the end of these exchanges, the attacker is authenticated on the server with the client’s credentials.&lt;/p&gt;

&lt;h3 id=&quot;net-ntlmv1-and-net-ntlmv2&quot;&gt;Net-NTLMv1 and Net-NTLMv2&lt;/h3&gt;

&lt;p&gt;For information, it is this &lt;strong&gt;valid response&lt;/strong&gt; relayed by the attacker in message 3, the encrypted challenge, that is commonly called Net-NTLMv1 hash or Net-NTLMv2 hash. But in this article, it will be called &lt;strong&gt;NTLMv1 response&lt;/strong&gt; or &lt;strong&gt;NTLMv2 response&lt;/strong&gt;, as indicated in the preliminary paragraph.&lt;/p&gt;

&lt;p&gt;To be exact, this is not exactly an encrypted version of the challenge, but a hash that uses the client’s secret. It is HMAC_MD5 function which is &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3&quot;&gt;used for NTLMv2&lt;/a&gt; for example. This type of hash can only be broken by brute force. The cryptography associated with &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5&quot;&gt;computation of the NTLMv1 hash&lt;/a&gt; is obsolete, and the NT hash that was used to create the hash can be retrieved very quickly. For NTLMv2, on the other hand, it takes much longer. It is therefore preferable and advisable &lt;strong&gt;not to allow NTLMv1 authentication on a production network&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;in-practice&quot;&gt;In practice&lt;/h2&gt;

&lt;p&gt;As an example, I set up a small lab with several machines. There is &lt;strong&gt;DESKTOP01&lt;/strong&gt; client with IP address &lt;strong&gt;192.168.56.221&lt;/strong&gt; and &lt;strong&gt;WEB01&lt;/strong&gt; server with IP address &lt;strong&gt;192.168.56.211&lt;/strong&gt;. My host is the attacker, with IP address &lt;strong&gt;192.168.56.1&lt;/strong&gt;. So we are in the following situation:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing.png&quot; alt=&quot;NTLM Relay - Example&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The attacker has therefore managed to put himself man-in-the-middle position. There are different techniques to achieve this, whether through abuse of default IPv6 configurations in a Windows environment, or through LLMNR and NBT-NS protocols. Either way, the attacker makes the client think that he is the server. Thus, when the client tries to authenticate itself, it is with the attacker that it will perform this operation.&lt;/p&gt;

&lt;p&gt;The tool I used to perform this attack is &lt;a href=&quot;https://github.com/SecureAuthCorp/impacket/blob/master/examples/ntlmrelayx.py&quot;&gt;ntlmrelayx&lt;/a&gt; from &lt;strong&gt;impacket&lt;/strong&gt;. This tool is presented in details in &lt;a href=&quot;https://www.secureauth.com/blog/playing-relayed-credentials&quot;&gt;this article&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/agsolino&quot;&gt;Agsolino&lt;/a&gt;, impacket (&lt;em&gt;almighty&lt;/em&gt;) developer.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ntlmrelayx.py &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 192.168.56.211
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The tool creates different servers, including an SMB server for this example. If it receives a connection on this server, it will relay it to the provided target, which is &lt;strong&gt;192.168.56.211&lt;/strong&gt; in this example.&lt;/p&gt;

&lt;p&gt;From a network point of view, here is a capture of the exchange, with the attacker relaying the information to the target.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot; alt=&quot;NTLM Relay pcap&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In green are the exchanges between &lt;strong&gt;DESKTOP01&lt;/strong&gt; client and the attacker, and in red are the exchanges between the attacker and  &lt;strong&gt;WEB01&lt;/strong&gt; server. We can clearly see the 3 NTLM messages between &lt;strong&gt;DESKTOP01&lt;/strong&gt; and the attacker, and between the attacker and &lt;strong&gt;WEB01&lt;/strong&gt; server.&lt;/p&gt;

&lt;p&gt;And to understand the notion of &lt;strong&gt;relay&lt;/strong&gt;, we can verify that when &lt;strong&gt;WEB01&lt;/strong&gt; sends a challenge to the attacker, the attacker sends back exactly the same thing to &lt;strong&gt;DESKTOP01&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the challenge sent by &lt;strong&gt;WEB01&lt;/strong&gt; to the attacker :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap_challenge_1.png&quot; alt=&quot;Relai NTLM - Challenge&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the attacker receives this challenge, he sends it to &lt;strong&gt;DESKTOP01&lt;/strong&gt; without any modification. In this example, the challenge is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b6515172c37197b0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap_challenge_2.png&quot; alt=&quot;Relai NTLM - Challenge&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The client will then compute the response using his secret, as we have seen in the previous paragraphs, and he will send his response alongside with his username (&lt;strong&gt;jsnow&lt;/strong&gt;), his hostname (&lt;strong&gt;DESKTOP01&lt;/strong&gt;), and in this example he indicates that he is a domain user, so he provides the domain name (&lt;strong&gt;ADSEC&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap_response_1.png&quot; alt=&quot;Relai NTLM - Response&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The attacker who gets all that doesn’t ask questions. He sends the exact same information to the server. So he pretends to be &lt;strong&gt;jsnow&lt;/strong&gt; on &lt;strong&gt;DESKTOP01&lt;/strong&gt; and part of &lt;strong&gt;ADSEC&lt;/strong&gt; domain, and he also sends the response that has been computed by the client, called &lt;strong&gt;NTLM Response&lt;/strong&gt; in these screenshots. We call this response &lt;strong&gt;NTLMv2 hash&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_example_smb_smb_no_signing_pcap_response_2.png&quot; alt=&quot;Relai NTLM - Response&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the attacker was only relaying stuff. He just relayed the information from the client to the server and vice versa, except that in the end, the server thinks that the attacker is successfully authenticated, and the attacker can then perform actions on the server on behalf of &lt;strong&gt;ADSEC\jsnow&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;authentication-vs-session&quot;&gt;Authentication vs Session&lt;/h2&gt;

&lt;p&gt;Now that we have understood the basic principle of NTLM relay, the question that arises is how, concretely, can we perform actions on a server after relaying NTLM authentication? By the way, what do we mean by “actions”? What is it possible to do?&lt;/p&gt;

&lt;p&gt;To answer this question, we must first clarify one fundamental thing. When a client authenticates to a server to do &lt;em&gt;something&lt;/em&gt;, we must distinguish two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Authentication&lt;/strong&gt;, allowing the server to verify that the client is who he claims to be.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The session&lt;/strong&gt;, during which the client will be able to perform &lt;em&gt;actions&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thus, if the client has authenticated correctly, it will then be able to access the resources offered by the server, such as network shares, access to an LDAP directory, an HTTP server or a SQL database. This list is obviously not exhaustive.&lt;/p&gt;

&lt;p&gt;To manage these two steps, the protocol that is used must be able to encapsulate the authentication, thus the exchange of NTLM messages.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_smb.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_smb.png&quot; alt=&quot;NTLM encapsulé&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if all the protocols were to integrate NTLM technical details, it would quickly become a holy mess. That’s why Microsoft provides an interface that can be relied on to handle authentication, and packages have been specially developed to handle different types of authentication.&lt;/p&gt;

&lt;h3 id=&quot;sspi--ntlmssp&quot;&gt;SSPI &amp;amp; NTLMSSP&lt;/h3&gt;

&lt;p&gt;The SSPI interface, or &lt;strong&gt;Security Support Provider Interface&lt;/strong&gt;, is an interface proposed by Microsoft to standardize authentication, regardless of the type of authentication used. Different packages can connect to this interface to handle different types of authentication.&lt;/p&gt;

&lt;p&gt;In our case, it is the NTLMSSP package (&lt;strong&gt;NTLM Security Support Provider&lt;/strong&gt;) that interests us, but there is also a package for Kerberos authentication, for example.&lt;/p&gt;

&lt;p&gt;Without going into details, the SSPI interface provides several functions, including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcquireCredentialsHandle&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InitializeSecurityContext&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptSecurityContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;During NTLM authentication, both the client and the server will use these functions. The steps are only briefly described here.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The client calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcquireCredentialsHandle&lt;/code&gt; in order to gain indirect access to the user credentials.&lt;/li&gt;
  &lt;li&gt;The client then calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InitializeSecurityContext&lt;/code&gt;, a function which, when called for the first time, will create a message of type 1, thus of type &lt;strong&gt;NEGOTIATE&lt;/strong&gt;. We know this because we’re interested in NTLM, but for a programmer, it doesn’t matter what this message is. All that matters is to send it to the server.&lt;/li&gt;
  &lt;li&gt;The server, when receiving the message, calls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptSecurityContext&lt;/code&gt; function. This function will then create the type 2 message, the &lt;strong&gt;CHALLENGE&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;When receiving this message, the client will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InitializeSecurityContext&lt;/code&gt; again, but this time passing the &lt;strong&gt;CHALLENGE&lt;/strong&gt; as an argument. The NTLMSSP package takes care of everything to compute the response by encrypting the challenge, and will produce the last &lt;strong&gt;AUTHENTICATE&lt;/strong&gt; message.&lt;/li&gt;
  &lt;li&gt;Upon receiving this last message, the server also calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptSecurityContext&lt;/code&gt; again, and the authentication verification will be performed automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ssp.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ssp.png&quot; alt=&quot;NTLMSSP&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason these steps are explained is to show that in reality, from the client or server point of view, &lt;strong&gt;the structure of the 3 messages that are exchanged does not matter&lt;/strong&gt;. We, with our knowledge of the NTLM protocol, know what these messages correspond to, but both the client and the server don’t care. These messages are described in the Microsoft documentation as &lt;strong&gt;opaque tokens&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This means that these 5 steps are completely independent of client’s type or server’s type. They work regardless of the protocol used as long as the protocol has something in place to allow this opaque structure to be exchanged in one way or another from the client to the server.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ssp_opaque.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ssp_opaque.png&quot; alt=&quot;NTLMSSP Opaque&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the protocols have adapted to find a way to put an NTLMSSP, Kerberos, or other authentication structure into a specific field, and if the client or server sees that there is data in that field, it just passes it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InitializeSecurityContext&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AcceptSecurityContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This point is quite important, since it clearly shows that the application layer (HTTP, SMB, SQL, …) is completely independent from the authentication layer (NTLM, Kerberos, …). Therefore, security measures are both needed for the &lt;strong&gt;authentication&lt;/strong&gt; layer &lt;strong&gt;and&lt;/strong&gt; for the &lt;strong&gt;application&lt;/strong&gt; layer.&lt;/p&gt;

&lt;p&gt;For a better understanding, we will see the two examples of application protocols &lt;strong&gt;SMB&lt;/strong&gt; and &lt;strong&gt;HTTP&lt;/strong&gt;. It’s quite easy to find documentation for other protocols. It’s always the same principle.&lt;/p&gt;

&lt;h3 id=&quot;integration-with-http&quot;&gt;Integration with HTTP&lt;/h3&gt;

&lt;p&gt;This is what a basic HTTP request looks like.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /index.html HTTP/1.1
Host: beta.hackndo.com
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: fr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The mandatory elements in this example are the HTTP verb (&lt;strong&gt;GET&lt;/strong&gt;), the path to the requested page (&lt;strong&gt;/index.html&lt;/strong&gt;), the protocol version (&lt;strong&gt;HTTP/1.1&lt;/strong&gt;), or the Host header (&lt;strong&gt;Host: beta.hackndo.com&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;But it is quite possible to add other arbitrary headers. At best, the remote server is aware that these headers will be present, and it will know how to handle them, and at worst it will ignore them. This allows you to have the same request with some additional information.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /index.html HTTP/1.1
Host: beta.hackndo.com
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: en
X-Name: pixis
Favorite-Food: Beer &apos;coz yes, beer is food
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is this feature that is used to be able to transfer NTLM messages from the client to the server. It has been decided that the client sends its messages in a header called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization&lt;/code&gt; and the server in a header called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WWW-Authenticate&lt;/code&gt;. If a client attempts to access a web site requiring authentication, the server will respond by adding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WWW-Authenticate&lt;/code&gt; header, and highlighting the different authentication mechanisms it supports. For NTLM, it will simply say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NTLM&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The client, knowing that NTLM authentication is required, will send the first message in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization&lt;/code&gt; header, encoded in base 64 because the message does not only contain printable characters. The server will respond with a challenge in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WWW-Authenticate&lt;/code&gt; header, the client will compute the response and will send it in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization&lt;/code&gt;. If authentication is successful, the server will usually return a &lt;strong&gt;200&lt;/strong&gt; return code indicating that everything went well.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; GET /index.html HTTP/1.1
&amp;gt; Host: beta.hackndo.com
&amp;gt; User-Agent: Mozilla/5.0
&amp;gt; Accept: text/html
&amp;gt; Accept-Language: en

  &amp;lt; HTTP/1.1 401 Unauthorized
  &amp;lt; WWW-Authenticate: NTLM
  &amp;lt; Content type: text/html
  &amp;lt; Content-Length: 0

&amp;gt; GET /index.html HTTP/1.1
&amp;gt; Host: beta.hackndo.com
&amp;gt; User-Agent: Mozilla/5.0
&amp;gt; Accept: text/html
&amp;gt; Accept-Language: en
=&amp;gt; Authorization: NTLM &amp;lt;NEGOTIATE in base 64&amp;gt;

  &amp;lt; HTTP/1.1 401 Unauthorized
  =&amp;gt; WWW-Authenticate: NTLM &amp;lt;CHALLENGE in base 64&amp;gt;
  &amp;lt; Content type: text/html
  &amp;lt; Content-Length: 0

&amp;gt; GET /index.html HTTP/1.1
&amp;gt; Host: beta.hackndo.com
&amp;gt; User-Agent: Mozilla/5.0
&amp;gt; Accept: text/html
&amp;gt; Accept-Language: en
=&amp;gt; Authorization: NTLM &amp;lt;RESPONSE in base 64&amp;gt;

  &amp;lt; HTTP/1,200 OKAY.
  &amp;lt; WWW-Authenticate: NTLM
  &amp;lt; Content type: text/html
  &amp;lt; Content-Length: 0
  &amp;lt; Connection: close
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As long as the TCP session is open, authentication will be effective. As soon as the session closes, however, the server will no longer have the client’s security context, and a new authentication will have to take place. This can often happen, and thanks to Microsoft’s SSO (&lt;strong&gt;Single Sign On&lt;/strong&gt;) mechanisms, it is often transparent to the user.&lt;/p&gt;

&lt;h3 id=&quot;integration-with-smb&quot;&gt;Integration with SMB&lt;/h3&gt;

&lt;p&gt;Let’s take another example frequently encountered in a company network. It is SMB protocol, used to access network shares, but not only.&lt;/p&gt;

&lt;p&gt;SMB protocol works by using commands. They are &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/5cd5747f-fe0b-40a6-89d0-d67f751f8232&quot;&gt;documented by Microsoft&lt;/a&gt;, and there are many of them. For example, there are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMB_COM_OPEN&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMB_COM_CLOSE&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMB_COM_READ&lt;/code&gt;, commands to open, close or read a file.&lt;/p&gt;

&lt;p&gt;SMB also has a command dedicated to configuring an SMB session, and this command is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMB_COM_SESSION_SETUP_ANDX&lt;/code&gt;. &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/3a3cdd47-5b43-4276-91f5-645b82b0938f&quot;&gt;Two fields are dedicated&lt;/a&gt; to the contents of the NTLM messages in this command.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LM/LMv2 Authentication: OEMPassword&lt;/li&gt;
  &lt;li&gt;NTLM/NTLMv2 authentication: UnicodePassword&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is important to remember is that there is a specific SMB command with an allocated field for NTLM messages.&lt;/p&gt;

&lt;p&gt;Here is an example of an SMB packet containing the response of a server to an authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_smb_pcap_example.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_smb_pcap_example.png&quot; alt=&quot;NTLM in SMB&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These two examples show that the content of NTLM messages is protocol-independent. It can be included in any protocol that supports it.&lt;/p&gt;

&lt;p&gt;It is then very important to clearly distinguish the authentication part, i.e. the NTLM exchanges, from the application part, or the session part, which is the continuation of the exchanges via the protocol used once the client is authenticated, like browsing a website via HTTP or accessing files on a network share if we use SMB.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_auth_vs_session.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_auth_vs_session.png&quot; alt=&quot;Authentication vs Session&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As this information is independent, it means that a man-in-the-middle may very well receive authentication via HTTP, for example, and relay it to a server but using SMB. This is called &lt;strong&gt;cross-protocol relay&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol.png&quot; alt=&quot;Cross protocol&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all these aspects in mind, the following chapters will highlight the various weaknesses that exist or have existed, and the security mechanisms that come into play to address them.&lt;/p&gt;

&lt;h2 id=&quot;session-signing&quot;&gt;Session signing&lt;/h2&gt;

&lt;h3 id=&quot;principle&quot;&gt;Principle&lt;/h3&gt;

&lt;p&gt;A signature is an authenticity verification method, and it ensures that the item has not been tampered with between sending and receiving. For example, if the user &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jdoe&lt;/code&gt; sends the text &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I love hackndo&lt;/code&gt;, and digitally signs this document, then anyone who receives this document and his signature can verify that it was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jdoe&lt;/code&gt; who edited it, and can be assured that he wrote this sentence, and not another, since the signature guarantees that the document has not been modified.&lt;/p&gt;

&lt;p&gt;The signature principle can be applied to any exchange, as long as the protocol supports it. This is for example the case of &lt;a href=&quot;https://support.microsoft.com/en-us/help/887429/overview-of-server-message-block-signing&quot;&gt;SMB&lt;/a&gt;, &lt;a href=&quot;https://support.microsoft.com/en-us/help/4520412/2020-ldap-channel-binding-and-ldap-signing-requirements-for-windows&quot;&gt;LDAP&lt;/a&gt; and even &lt;a href=&quot;https://tools.ietf.org/id/draft-cavage-http-signatures-08.html&quot;&gt;HTTP&lt;/a&gt;. In practice, the signing of HTTP messages is rarely implemented.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_session_signing.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_session_signing.png&quot; alt=&quot;Signature d&apos;un paquet de session&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But then, what’s the point of signing packages? Well, as discussed earlier, session and authentication are two separate steps when a client wants to use a service. Since an attacker can be in a man-in-the-middle position and relay authentication messages, he can impersonate the client when talking with the server.&lt;/p&gt;

&lt;p&gt;This is where signing comes into play. Even if the attacker has managed to authenticate to the server as the client, he will not be able to sign packets, regardless of authentication. Indeed, in order to be able to sign a packet, one must &lt;strong&gt;know the secret&lt;/strong&gt; of the client.&lt;/p&gt;

&lt;p&gt;In NTLM relay, the attacker &lt;strong&gt;wants to pretend to be a client&lt;/strong&gt;, but he has &lt;strong&gt;no knowledge of his secret&lt;/strong&gt;. He is therefore unable to sign anything on behalf of the client. Since he can’t sign any packet, the server receiving packets will either see that the signature is not present, or that it doesn’t exist, and will reject the attacker’s request.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_session_signing_failed.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_session_signing_failed.png&quot; alt=&quot;No signature after NTLM relay&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you understand that if packets must necessarily be signed after authentication, then the attacker can no longer operate, since he has no knowledge of the client’s secret. So the attack will fail. &lt;strong&gt;This is a very effective measure to protect against NTLM relay&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s all very well, but how do the client and the server agree on whether or not to sign packets? Well that’s a very good question. Yes, I know, I’m the one asking it, but that doesn’t make it irrelevant.&lt;/p&gt;

&lt;p&gt;There are two things that come into play here.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The first one is to indicate if signing is &lt;strong&gt;supported&lt;/strong&gt;. This is done during NTLM negotiation.&lt;/li&gt;
  &lt;li&gt;The second one allows to indicate if signing will be &lt;strong&gt;required&lt;/strong&gt;, &lt;strong&gt;optional&lt;/strong&gt; or &lt;strong&gt;disabled&lt;/strong&gt;. This is a setting that is done at the client and server level.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;ntlm-negotiation&quot;&gt;NTLM Negotiation&lt;/h3&gt;

&lt;p&gt;This negotiation allows to know if the client and/or the server support signing (among other things), and is done during the NTLM exchange. So I lied to you a bit earlier, authentication and session are not &lt;em&gt;completely&lt;/em&gt; independent. (By the way, I said that since it was independent, you could change protocol when relaying, but there are limits, we will see them in the chapter on MIC in NTLM authentication).&lt;/p&gt;

&lt;p&gt;In fact, in NTLM messages, there is other information other than a challenge and the response that are exchanged. There are also negotiation flags, or &lt;strong&gt;Negotiate Flags&lt;/strong&gt;. These flags indicate what the sending entity supports.&lt;/p&gt;

&lt;p&gt;There are several flags, but the one of interest here is &lt;strong&gt;NEGOTIATE_SIGN&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_negotiate_flags.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_negotiate_flags.png&quot; alt=&quot;NEGOTIATE_SIGN&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When this flag is set to &lt;strong&gt;1&lt;/strong&gt; by the client, it means that the client &lt;strong&gt;supports&lt;/strong&gt; signing. Be careful, it does not mean that he &lt;strong&gt;will necessarily sign&lt;/strong&gt; his packets. Just that he’s capable of it.&lt;/p&gt;

&lt;p&gt;Similarly when the server replies, if it supports signing then the flag will also be set to &lt;strong&gt;1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This negotiation thus allows each of the two parties, client and server, to indicate to the other if it is able sign packets. For some protocols, even if the client and the server support signing, this does not necessarily mean that the packets will be signed.&lt;/p&gt;

&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;/h3&gt;

&lt;p&gt;Now that we’ve seen how both parties indicate to the other their &lt;strong&gt;ability&lt;/strong&gt; to sign packets, they have to agree on it. This time, this decision is made according to the protocol. So it will be decided differently for SMBv1, for SMBv2, or LDAP. But the idea remains the same.&lt;/p&gt;

&lt;p&gt;Depending on the protocol, there are usually 2 or even 3 options that can be set to decide wether signing will be enforced, or not. The 3 options are :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Disabled: This means that signing is not managed.&lt;/li&gt;
  &lt;li&gt;Enabled: This option indicates that the machine can handle signing if need be, but it does not require signing.&lt;/li&gt;
  &lt;li&gt;Mandatory: This finally indicates that signing is not only supported, but that packets &lt;strong&gt;must&lt;/strong&gt; be signed in order for the session to continue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will see here the example of two protocols, SMB and LDAP.&lt;/p&gt;

&lt;h3 id=&quot;smb&quot;&gt;SMB&lt;/h3&gt;

&lt;h4 id=&quot;signature-matrix&quot;&gt;Signature matrix&lt;/h4&gt;

&lt;p&gt;A matrix is provided in &lt;a href=&quot;https://docs.microsoft.com/fr-fr/archive/blogs/josebda/the-basics-of-smb-signing-covering-both-smb1-and-smb2&quot;&gt;Microsoft documentation&lt;/a&gt; to determine whether or not SMB packets are signed based on client-side and server-side settings. I’ve reported it in this table. Note however that for SMBv2 and higher, signing is necessarily handled, the &lt;strong&gt;Disabled&lt;/strong&gt; parameter no longer exists.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_signing_table.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_signing_table.png&quot; alt=&quot;Signing matrix&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a difference when client and server have the &lt;strong&gt;Enabled&lt;/strong&gt; setting. In SMBv1, the default setting for servers was &lt;strong&gt;Disabled&lt;/strong&gt;. Thus, all SMB traffic between clients and servers was not signed by default. This avoided overloading the servers by preventing them from computing signatures each time an SMB packet was sent. As the &lt;strong&gt;Disabled&lt;/strong&gt; status no longer exists for SMBv2, and servers are now &lt;strong&gt;Enabled&lt;/strong&gt; by default, in order to keep this load saving, the behavior between two &lt;strong&gt;Enable&lt;/strong&gt; entites has been modified, and signing is no longer required in this case. The client and/or the server must necessarily &lt;strong&gt;require&lt;/strong&gt; the signature for SMB packets to be signed.&lt;/p&gt;

&lt;h4 id=&quot;settings&quot;&gt;Settings&lt;/h4&gt;

&lt;p&gt;In order to change the default signing settings on a server, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnableSecuritySignature&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RequireSecuritySignature&lt;/code&gt; keys must be changed in registry hive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_sig_dc.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_sig_dc.png&quot; alt=&quot;SMB Signing required&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This screenshot was taken on a domain controller. By default, domain controllers require SMB signing when a client authenticates to them. Indeed, the GPO applied to domain controllers contains this entry:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_sig_dc_gpo.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_sig_dc_gpo.png&quot; alt=&quot;SMB Signing required by GPO&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, we can see on this capture that above this setting, the same parameter applied to &lt;strong&gt;Microsoft network client&lt;/strong&gt; is not applied. So when the domain controller acts as an SMB server, SMB signing is required, but if a connection comes &lt;strong&gt;from&lt;/strong&gt; the domain controller &lt;strong&gt;to&lt;/strong&gt; a server, SMB signing is &lt;strong&gt;not&lt;/strong&gt; required.&lt;/p&gt;

&lt;h4 id=&quot;setup&quot;&gt;Setup&lt;/h4&gt;

&lt;p&gt;Now that we know where SMB signing is configured, we can see this parameter applied during an communication. It is done just before authentication. In fact, when a client connects to the SMB server, the steps are as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Negotiation of the SMB version and signing requirements&lt;/li&gt;
  &lt;li&gt;Authentication&lt;/li&gt;
  &lt;li&gt;SMB session with negotiated parameters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is an example of SMB signing negotiation:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_sig_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_sig_pcap.png&quot; alt=&quot;Signature SMB enabled pcap&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see a response from a server indicating that it has the &lt;strong&gt;Enable&lt;/strong&gt; parameter, but that it does not &lt;strong&gt;require&lt;/strong&gt; signing.&lt;/p&gt;

&lt;p&gt;To summarize, here is how a negotiation / authentication / session takes place :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_nego_vs_auth_vs_session.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_nego_vs_auth_vs_session.png&quot; alt=&quot;Negotiation authentification session&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In the negotiation phase, both parties indicate their requirements: Is signing required for one of them?&lt;/li&gt;
  &lt;li&gt;In the authentication phase, both parties indicate what they support. Are they &lt;strong&gt;capable&lt;/strong&gt; of signing?&lt;/li&gt;
  &lt;li&gt;In the session phase, if the &lt;strong&gt;capabilities&lt;/strong&gt; and the &lt;strong&gt;requirements&lt;/strong&gt; are compatible, the session is carried out applying what has been negotiated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, if &lt;strong&gt;DESKTOP01&lt;/strong&gt; client wants to communicate with &lt;strong&gt;DC01&lt;/strong&gt; domain controller, &lt;strong&gt;DESKTOP01&lt;/strong&gt; indicates that it does not require signing, but that that he can handle it, if needed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ex1.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ex1.png&quot; alt=&quot;Negotiation DESKTOP01&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DC01&lt;/strong&gt; indicates that not only he supports signing, but that he requires it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ex2.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ex2.png&quot; alt=&quot;Negotiation DC01&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During negotiation phase, the client and server set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag to &lt;strong&gt;1&lt;/strong&gt; since they both support signing.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_negotiate_flags.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_negotiate_flags.png&quot; alt=&quot;NEGOTIATE_SIGN&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once this authentication is completed, the session continues, and the SMB exchanges are effectively signed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ex3.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ex3.png&quot; alt=&quot;Session signing&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;ldap&quot;&gt;LDAP&lt;/h3&gt;

&lt;h4 id=&quot;signing-matrix&quot;&gt;Signing matrix&lt;/h4&gt;

&lt;p&gt;For LDAP, there are also three levels:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Disabled: This means that packet signing is not supported.&lt;/li&gt;
  &lt;li&gt;Negotiated Signing: This option indicates that the machine can handle signing, and if the machine it is communicating with also handles it, then they will be signed.&lt;/li&gt;
  &lt;li&gt;Required: This finally indicates that signing is not only supported, but that packets &lt;strong&gt;must&lt;/strong&gt; be signed in order for the session to continue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can read, the intermediate level, &lt;strong&gt;Negotiated Signing&lt;/strong&gt; differs from the SMBv2 case, because this time, if the client and the server are &lt;strong&gt;able to&lt;/strong&gt; sign packets, then &lt;strong&gt;they will&lt;/strong&gt;. Whereas for SMBv2, packets were &lt;strong&gt;only&lt;/strong&gt; signed if it was a requirement for at least one entity.&lt;/p&gt;

&lt;p&gt;So for LDAP we have a matrix similar to SMBv1, except for the default behaviors.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_table.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_table.png&quot; alt=&quot;LDAP signing matrix&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference with SMB is that in Active Directory domain, &lt;strong&gt;all&lt;/strong&gt; hosts have &lt;strong&gt;Negotiated Signing&lt;/strong&gt; setting. The domain controller doesn’t &lt;strong&gt;require&lt;/strong&gt; signing.&lt;/p&gt;

&lt;h4 id=&quot;settings-1&quot;&gt;Settings&lt;/h4&gt;

&lt;p&gt;For the &lt;strong&gt;domain controller&lt;/strong&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldapserverintegrity&lt;/code&gt; registry key is in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters&lt;/code&gt; hive and can be 0, 1 or 2 depending on the level. It is set to &lt;strong&gt;1&lt;/strong&gt; on the domain controller by default.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_registry_server.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_registry_server.png&quot; alt=&quot;DC registry key&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;clients&lt;/strong&gt;, this registry key is located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ldap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_registry_client.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_ldap_signing_registry_client.png&quot; alt=&quot;Client registry key&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is also set to &lt;strong&gt;1&lt;/strong&gt; for clients. Since all clients and domain controllers have &lt;strong&gt;Negotiated Signing&lt;/strong&gt;, &lt;strong&gt;all LDAP packets are signed by default&lt;/strong&gt;.&lt;/p&gt;

&lt;h4 id=&quot;setup-1&quot;&gt;Setup&lt;/h4&gt;

&lt;p&gt;Unlike SMB, there is no flag in LDAP that indicates whether packets will be signed or not. Instead, LDAP uses flags set in NTLM negotiation. There is no need for more information. In the case where both client and server support LDAP signing, then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag will be set and the packets will be signed.&lt;/p&gt;

&lt;p&gt;If one party &lt;strong&gt;requires&lt;/strong&gt; signing, and the other party does not &lt;strong&gt;support&lt;/strong&gt; it, then the session simply won’t start. The party requiring signing will ignore the unsigned packets.&lt;/p&gt;

&lt;p&gt;So now we then understand that, contrary to SMB, if we are between a client and a server and we want to relay an authentication to the server using LDAP, we need two things :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;strong&gt;server&lt;/strong&gt; must not require packet signing, which is the case for all machines by default&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;client&lt;/strong&gt; must not set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag to &lt;strong&gt;1&lt;/strong&gt;. If he does, then the signature will be expected by the server, and since we don’t know the client’s secret, we won’t be able to sign our crafted LDAP packets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Regarding requirement &lt;strong&gt;2&lt;/strong&gt;, sometimes clients don’t set this flag, but unfortunately, the Windows SMB client sets it! By default, it is not possible to relay SMB authentication to LDAP.&lt;/p&gt;

&lt;p&gt;So why not just change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_FLAG&lt;/code&gt; flag and set it to &lt;strong&gt;0&lt;/strong&gt;? Well… NTLM messages are also signed. This is what we will see in the next paragraph.&lt;/p&gt;

&lt;h2 id=&quot;authentication-signing-mic&quot;&gt;Authentication signing (MIC)&lt;/h2&gt;

&lt;p&gt;We saw how a session could be protected against a middle man attacker. Now, to understand the interest of this chapter, let’s look at a specific case.&lt;/p&gt;

&lt;h3 id=&quot;edge-case&quot;&gt;Edge case&lt;/h3&gt;

&lt;p&gt;Let’s imagine that an attacker manages to put himself in man-in-the-middle position between a client and a domain controller, and that he receives an authentication request via SMB. Knowing that a domain controller requires SMB signing, it is not possible for the attacker to relay this authentication via SMB. On the other hand, it is possible to change protocol, as we have seen above, and the attacker decides to relay to the &lt;strong&gt;LDAPS&lt;/strong&gt; protocol, as authentication and session should be independant.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol_ldaps.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol_ldaps.png&quot; alt=&quot;Cross protocol LDAPS&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, they are &lt;strong&gt;almost&lt;/strong&gt; independent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Almost&lt;/strong&gt;, because we saw that in the authentication data, there was the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag which was only present to indicate whether the client and server supported signing. But in some cases, this flag is taken into account, as we saw with LDAP.&lt;/p&gt;

&lt;p&gt;Well for LDAPS, this flag is also taken into account by the server. If a server receives an authentication request with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag set to &lt;strong&gt;1&lt;/strong&gt;, it will reject the authentication. This is because LDAPS is LDAP over TLS, and it is TLS layer that handles packet signing (and encryption). Thus, an LDAPS client has no reason to indicate that it can sign its packets, and if it claims to be able to do so, the server laughs at it and slams the door.&lt;/p&gt;

&lt;p&gt;Now in our attack, the client we’re relaying wanted to authenticate via SMB, so yes, it supports packet signing, and yes, it sets the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag to &lt;strong&gt;1&lt;/strong&gt;. But if we relay its authentication, without changing anything, via LDAPS, then the LDAPS server will see this flag, and will terminate the authentication phase, no question asked.&lt;/p&gt;

&lt;p&gt;We could simply modify the NTLM message and remove the flag, couldn’t we? If we could, we would, it would work well. Except that there is also a &lt;strong&gt;signature at NTLM level&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That signature, it’s called the &lt;strong&gt;MIC&lt;/strong&gt;, or &lt;strong&gt;Message Integrity Code&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;mic---message-integrity-code&quot;&gt;MIC - Message Integrity Code&lt;/h3&gt;

&lt;p&gt;The MIC is a signature that is sent only in the last message of an NTLM authentication, the &lt;strong&gt;AUTHENTICATE&lt;/strong&gt; message. It takes into account the 3 messages. The MIC is computed with &lt;strong&gt;HMAC_MD5&lt;/strong&gt; function, using as a key that depends on the client’s secret, called the &lt;strong&gt;session key&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HMAC_MD5(Session key, NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What is important is that the session key &lt;strong&gt;depends on the client’s secret&lt;/strong&gt;, so an attacker can’t re-compute the MIC.&lt;/p&gt;

&lt;p&gt;Here’s an example of MIC:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_mic.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_mic.png&quot; alt=&quot;MIC NTLM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, if only one of the 3 messages has been modified, the MIC will no longer be valid, since the concatenation of the 3 messages will not be the same. So you can’t change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag, as suggested in our example.&lt;/p&gt;

&lt;p&gt;What if we just remove the MIC? Because yes, the MIC is optional.&lt;/p&gt;

&lt;p&gt;Well it won’t work, because there is another flag that indicates that a MIC will be present, &lt;strong&gt;msAvFlags&lt;/strong&gt;. It is also present in NTLM response and if it is &lt;strong&gt;0x00000002&lt;/strong&gt;, it tells the server that a MIC &lt;strong&gt;must&lt;/strong&gt; be present. So if the server doesn’t see the MIC, it will know that there is something going on, and it will terminate the authentication. If the flag says there must be a MIC, then there &lt;strong&gt;must&lt;/strong&gt; be a MIC.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_mic_av.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_mic_av.png&quot; alt=&quot;MIC AV NTLM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All right, and if we set that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msAcFlags&lt;/code&gt; to &lt;strong&gt;0&lt;/strong&gt;, and we remove the MIC, what happens? Since there’s no more MICs, we can’t verify that the message has been changed, can we?&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;Well, we can. It turns out that the &lt;strong&gt;NTLMv2 Hash&lt;/strong&gt;, which is the response to the challenge sent by the server, is a hash that takes into account not only the challenge (obviously), but also all the flags of the response. As you may have guessed, the flag indicating the MIC presence is part of this response.&lt;/p&gt;

&lt;p&gt;Changing or removing this flag would make the &lt;strong&gt;NTLMv2 hash&lt;/strong&gt; invalid, since the data will have been modified. Here what it looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_mic_protection.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_mic_protection.png&quot; alt=&quot;MIC Protection&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The MIC protects the integrity of the 3 messages, the msAvFlags protects the presence of the MIC, and the NTLMv2 hash protects the presence of the flag. The attacker, not being aware of the user’s secret, cannot re-compute this hash.&lt;/p&gt;

&lt;p&gt;So you will have understood that, we can do nothing in this case, and that’s because of the MIC.&lt;/p&gt;

&lt;h3 id=&quot;drop-the-mic&quot;&gt;Drop the MIC&lt;/h3&gt;

&lt;p&gt;A little review of a recent vulnerability found by Preempt that you will easily understand now.&lt;/p&gt;

&lt;p&gt;It’s CVE-2019-1040 nicely named &lt;strong&gt;Drop the MIC&lt;/strong&gt;. This vulnerability showed that if the MIC was just removed, even if the flag indicated its presence, the server accepted the authentication without flinching. This was obviously a bug that has since been fixed.&lt;/p&gt;

&lt;p&gt;It has been integrated in &lt;a href=&quot;https://github.com/SecureAuthCorp/impacket/blob/master/examples/ntlmrelayx.py&quot;&gt;ntlmrelayx&lt;/a&gt; tool via the use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--remove-mic&lt;/code&gt; parameter.&lt;/p&gt;

&lt;p&gt;Let’s take our earlier example, but this time with a domain controller that is still vulnerable. This is what it looks like in practice.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_removemic.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_removemic.png&quot; alt=&quot;Drop the MIC&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our attack is working. Amazing.&lt;/p&gt;

&lt;p&gt;For information, another vulnerability was discovered by the very same team, and they called it &lt;a href=&quot;https://www.preempt.com/blog/drop-the-mic-2-active-directory-open-to-more-ntlm-attacks/&quot;&gt;Drop The MIC 2&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;session-key&quot;&gt;Session key&lt;/h2&gt;

&lt;p&gt;Earlier we were talking about session and authentication signing, saying that to sign something you have to know the user’s secret. We said in the chapter about MIC that in reality it’s not exactly the user’s secret that is used, but a key called &lt;strong&gt;session key&lt;/strong&gt;, which depends on the user’s secret.&lt;/p&gt;

&lt;p&gt;To give you an idea, here’s how the session key is computed for NTLMv1 and NTLMv2.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# For NTLMv1
Key = MD4(NT Hash)

# For NTLMv2
NTLMv2 Hash = HMAC_MD5(NT Hash, Uppercase(Username) + UserDomain)
Key = HMAC_MD5(NTLMv2 Hash, HMAC_MD5(NTLMv2 Hash, NTLMv2 Response + Challenge))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Going into the explanations would not be very useful, but there is clearly a complexity difference from one version to the other. I repeat, &lt;strong&gt;do not use NTLMv1 in a production network&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With this information, we understand that the client can compute this key on his side, since he has all the information in hand to do so.&lt;/p&gt;

&lt;p&gt;The server, on the other hand, can’t always do it alone, like a big boy. For &lt;a href=&quot;/pass-the-hash/#local-account&quot;&gt;local authentication&lt;/a&gt;, there is no problem since the server knows the user’s NT hash.&lt;/p&gt;

&lt;p&gt;On the other hand, for &lt;a href=&quot;/pass-the-hash/#domain-account&quot;&gt;authentication with a domain account&lt;/a&gt;, the server will have to ask the domain controller to compute the session key for him, and send it back. We saw in pass-the-hash article that the server sends a request to the domain controller in a &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/e17b03b8-c1d2-43a1-98db-cf8d05b9c6a8&quot;&gt;NETLOGON_NETWORK_INFO&lt;/a&gt; structure and the domain controller responds with a &lt;a href=&quot;https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/bccfdba9-0c38-485e-b751-d4de1935781d&quot;&gt;NETLOGON_VALIDATION_SAM_INFO4&lt;/a&gt; structure. It is in this response from the domain controller that the session key is sent, if authentication is successful.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_session_key_struct.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_session_key_struct.png&quot; alt=&quot;Session key&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The question then arises as to what prevents an attacker from making the same request to the domain controller as the target server. Well before &lt;a href=&quot;https://www.coresecurity.com/advisories/windows-pass-through-authentication-methods-improper-validation&quot;&gt;CVE-2015-0005&lt;/a&gt;, nothing!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;What we found while implementing the NETLOGON protocol [12] is the domain controller not verifying whether the authentication information being sent, was actually meant to the domain-joined machine that is requesting this operation (e.g. NetrLogonSamLogonWithFlags()). What this means is that &lt;strong&gt;any domain-joined machine can verify any pass-through authentication against the domain controller&lt;/strong&gt;, and to get the base key for cryptographic operations for any session within the domain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So obviously, Microsoft has fixed this bug. To verify that only the server the user is authenticating to has the right to ask for the session key, the domain controller will verify that the target machine in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AUTHENTICATE&lt;/code&gt; response is the same as the host making the NetLogon request.&lt;/p&gt;

&lt;p&gt;In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AUTHENTICATE&lt;/code&gt; response, we detailed the presence of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msAvFlags&lt;/code&gt; indicating whether or not the MIC is present, but there is also other information, such as the Netbios name of the target machine.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_computer_name.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_computer_name.png&quot; alt=&quot;Computer name&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the name that is compared with the host making the NetLogon request. Thus, if the attacker tries to make a NetLogon request for the session key, since the attacker’s name does not match the targeted host name in NTLM response, the domain controller will reject the request.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_netlogon_session_key.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_netlogon_session_key.png&quot; alt=&quot;NetLogon NTLM session key&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, in the same way as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msAvFlags&lt;/code&gt;, we cannot change the machine name on the fly in the NTLM response, because it is taken into account in the calculation of the NTLMv2 response.&lt;/p&gt;

&lt;p&gt;A vulnerability similar to &lt;strong&gt;Drop the MIC 2&lt;/strong&gt; has been discovered recently by Preempt security team.&lt;/p&gt;

&lt;h2 id=&quot;channel-binding&quot;&gt;Channel Binding&lt;/h2&gt;

&lt;p&gt;We’re going to talk about one last notion. Several times we have repeated that the authentication layer, thus NTLM messages, was almost independent of the application layer, the protocol in use (SMB, LDAP, …). I say “almost” because we have seen that some protocols use some NTLM messages flags to know if the session must be signed or not.&lt;/p&gt;

&lt;p&gt;In any case, as it stands, it is quite possible for an attacker to retrieve an NTLM message from protocol A, and send it back using protocol B. This is called &lt;strong&gt;cross-protocol relay&lt;/strong&gt; as we already mentioned.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_relay_cross_protocol.png&quot; alt=&quot;Cross protocol&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, a new protection exists to counter this attack. It’s called &lt;strong&gt;channel binding&lt;/strong&gt;, or &lt;strong&gt;EPA&lt;/strong&gt; (Enhanced Protection for Authentication). The principle of this protection is to bind the authentication layer with the protocol in use, even with the TLS layer when it exists (LDAPS or HTTPS for example). The general idea being that in the last NTLM &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AUTHENTICATE&lt;/code&gt; message, a piece of information is put there and cannot be modified by an attacker. This information indicates the desired service, and potentially another information that contains the target server’s certificate’s hash.&lt;/p&gt;

&lt;p&gt;We’ll look at these two principles in a little more detail, but don’t you worry, it’s relatively simple to understand.&lt;/p&gt;

&lt;h3 id=&quot;service-binding&quot;&gt;Service binding&lt;/h3&gt;

&lt;p&gt;This first protection is quite simple to understand. If a client wishes to authenticate to a server to use a specific service, the information identifying the service will be added in the NTLM response.&lt;/p&gt;

&lt;p&gt;This way, when the legitimate server receives this authentication, it can see the service that was requested by the client, and if it differs from what is actually requested, it will not agree to provide the service.&lt;/p&gt;

&lt;p&gt;Since the service name is in the NTLM response, it is protected by the &lt;strong&gt;NtProofStr&lt;/strong&gt; response, which is an HMAC_MD5 of this information, the challenge, and other information such as &lt;strong&gt;msAvFlags&lt;/strong&gt;. It is computed with the client’s secret.&lt;/p&gt;

&lt;p&gt;In the example shown in the last diagram, we see a client trying to authenticate itself via HTTP to the server. Except that the server is an attacker, and the attacker replays this authentication to a legitimate server, to access a network share (SMB).&lt;/p&gt;

&lt;p&gt;Except that the client has indicated the service he wants to use in his NTLM response, and since the attacker cannot modify it, he has to relay it as is. The server then receives the last message, compares the service requested by the attacker (SMB) with the service specified in the NTLM message (HTTP), and refuses the connection, finding that the two services do not match.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_service_binding.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_service_binding.png&quot; alt=&quot;Cross protocol example&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Concretely, what is called &lt;strong&gt;service&lt;/strong&gt; is in fact the &lt;strong&gt;SPN&lt;/strong&gt; or &lt;strong&gt;Service Principal Name&lt;/strong&gt;. I dedicated &lt;a href=&quot;/service-principal-name-spn&quot;&gt;a whole article&lt;/a&gt; to the explanation of this notion.&lt;/p&gt;

&lt;p&gt;Here is a screenshot of a client sending SPN in its NTLM response.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_service_binding_pcap.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_service_binding_pcap.png&quot; alt=&quot;Service binding&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that it indicates to use the &lt;strong&gt;CIFS&lt;/strong&gt; service (equivalent to SMB, just a different terminology). Relaying this to an LDAP server that takes this information into account will result in a nice &lt;strong&gt;Access denied&lt;/strong&gt; from the server.&lt;/p&gt;

&lt;p&gt;But as you can see, not only there is the service name (CIFS) but there is also the target name, or IP address. It means that if an attacker relays this message to a server, the server will also check the target part, and will refuse the connexion because the IP address found in the SPN does not match his IP address.&lt;/p&gt;

&lt;p&gt;So if this protection is supported by all clients and all servers, and is required by every server, it mitigaes all relay attempts.&lt;/p&gt;

&lt;h3 id=&quot;tls-binding&quot;&gt;TLS Binding&lt;/h3&gt;

&lt;p&gt;This time, the purpose of this protection is to link the authentication layer, i.e. NTLM messages, to the TLS layer that can potentially be used.&lt;/p&gt;

&lt;p&gt;If the client wants to use a protocol encapsulated in TLS (HTTPS, LDAPS for example), it will establish a TLS session with the server, and it will compute the server certificate hash. This hash is called the &lt;strong&gt;Channel Binding Token&lt;/strong&gt;, or CBT. Once computed, the client will put this hash in its NTLM response. The legitimate server will then receive the NTLM message at the end of the authentication, read the provided hash, and compare it with the real hash of its certificate. If it is different, it means he wasn’t the original recipient of the NTLM
exchange.&lt;/p&gt;

&lt;p&gt;Again, since this hash is in the NTLM response, it is protected by the &lt;strong&gt;NtProofStr&lt;/strong&gt; response, like the &lt;strong&gt;SPN&lt;/strong&gt; for &lt;strong&gt;Service Binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to this protection, the following two attacks are no longer possible :&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If an attacker wishes to relay information from a client using a protocol &lt;strong&gt;without&lt;/strong&gt; a TLS layer to a protocol &lt;strong&gt;with&lt;/strong&gt; a TLS layer (HTTP to LDAPS, for example), the attacker will not be able to add the certificate hash from the target server into the NTLM response, since it cannot update the NtProofStr.&lt;/li&gt;
  &lt;li&gt;If an attacker wishes to relay a protocol with TLS to another protocol with TLS (HTTPS to LDAPS), when establishing the TLS session between the client and the attacker, the attacker will not be able to provide the server certificate, since it does not match the attacker’s identity. It will therefore have to provide a “homemade” certificate, identifying the attacker. The client will then hash this certificate, and when the attacker relays the NTLM response to the legitimate server, the hash in the response will not be the same as the hash of the real certificate, so the server will reject the authentication.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a diagram to illustrate the 2nd case. Seems complicated, but it’s not.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_channel_binding_tls.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_channel_binding_tls.png&quot; alt=&quot;Channel binding&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shows the establishment of two TLS sessions. One between the client and the attacker (in red) and one between the attacker and the server (in blue). The client will retrieve the attacker’s certificate, and calculate a hash, &lt;strong&gt;cert hash&lt;/strong&gt;, in red.&lt;/p&gt;

&lt;p&gt;At the end of the NTLM exchanges, this hash will be added in the NTLM response, and will be protected since it is part of the encrypted data of the NTLM response. When the server receives this hash, it will hash his own certificate, and seeing that it is not the same result, it will refuse the connection.&lt;/p&gt;

&lt;h2 id=&quot;what-can-be-relayed&quot;&gt;What can be relayed?&lt;/h2&gt;

&lt;p&gt;With all this information, you should be able to know which protocols can be relayed to which protocols. We have seen that it is impossible to relay from SMB to LDAP or LDAPS, for example. On the other hand, any client that does not set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NEGOTIATE_SIGN&lt;/code&gt; flag can be relayed to LDAP if the signature is not required, or LDAPS is channel binding is not required.&lt;/p&gt;

&lt;p&gt;As there are many cases, here is a table summarizing some of them.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2020/03/ntlm_resume.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2020/03/ntlm_resume.png&quot; alt=&quot;Relay NTLM resumed&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think we can’t relay LDAPS or HTTPS since the attacker doesn’t have a valid certificate but let’s say the client is permissive and allowed untrusted certificates. Other protocols could be added, such as SQL or SMTP, but I must admit I didn’t read the documentation for all the protocols that exist. Shame on me.&lt;/p&gt;

&lt;h2 id=&quot;stop-using-ntlmv1&quot;&gt;Stop. Using. NTLMv1.&lt;/h2&gt;

&lt;p&gt;Here is a little “fun fact” that &lt;a href=&quot;https://twitter.com/simakov_marina&quot;&gt;Marina Simakov&lt;/a&gt; suggested me to add. As we discussed, NTLMv2 hash takes into account the server’s challenge, but also the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msAvFlags&lt;/code&gt; flag which indicates the presence of a MIC field, the field indicating the NetBios name of the target host during authentication, the SPN in case of service binding, and the certificate hash in case of TLS binding.&lt;/p&gt;

&lt;p&gt;Well NTLMv1 protocol &lt;strong&gt;doesn’t do that&lt;/strong&gt;. It only takes into account the server’s challenge. In fact, there is no longer any additional information such as the target name, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msAvFlags&lt;/code&gt;, the SPN or the CBT.&lt;/p&gt;

&lt;p&gt;So, if an NTLMv1 authentication is allowed by a server, an attacker can simply remove the MIC and thus relay authentications to LDAP or LDAPS, for example.&lt;/p&gt;

&lt;p&gt;But more importantly, he can make NetLogon requests to retrieve the session key. Indeed, the domain controller has no way to check if he has the right to do so. And since it won’t block a production network that isn’t completely up to date, it will kindly give it to  the attacker, for “retro-compatibility reasons”.&lt;/p&gt;

&lt;p&gt;Once he has the session key, he can sign any packet that he wants. It means that even if the target requests signing, he will be able to do so.&lt;/p&gt;

&lt;p&gt;This is by design and it can not be fixed. So I repeat, &lt;strong&gt;do not allow NTLMv1 in a production network&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Well, that’s a lot of information.&lt;/p&gt;

&lt;p&gt;We have seen here the &lt;strong&gt;details of NTLM relay&lt;/strong&gt;, being aware that authentication and session that follows are two distinct notions allowing to do &lt;strong&gt;cross-protocol relay&lt;/strong&gt; in many cases. Although the protocol somehow includes authentication data, it is opaque to the protocol and managed by SSPI.&lt;/p&gt;

&lt;p&gt;We have also shown how &lt;strong&gt;packet signing&lt;/strong&gt; can protect the server from man-in-the-middle attacks. To do this, the target must wait for signed packet coming from the client, otherwise the attacker will be able to pretend to be someone else without having to sign the messages he sends.&lt;/p&gt;

&lt;p&gt;We saw that MIC was very important to protect NTLM exchanges, especially the flag indicating whether packets will be signed for certain protocols, or information about channel binding.&lt;/p&gt;

&lt;p&gt;We ended by showing how channel binding can link the authentication layer and the session layer, either via the service name or via a link with the server certificate.&lt;/p&gt;

&lt;p&gt;I hope this long article has given you a better understanding of what happens during an NTLM relay attack and the protections that exist.&lt;/p&gt;

&lt;p&gt;Since this article is quite substantial, it is quite likely that some mistakes have slipped in. Feel free to contact me on &lt;a href=&quot;https://twitter.com/hackanddo&quot;&gt;twitter&lt;/a&gt; or on my &lt;a href=&quot;https://discord.hackndo.com&quot;&gt;Discord Server&lt;/a&gt; to discuss this.&lt;/p&gt;
</description>
        <pubDate>Wed, 01 Apr 2020 10:11:52 +0000</pubDate>
        <link>https://en.hackndo.com/ntlm-relay/</link>
        <guid isPermaLink="true">https://en.hackndo.com/ntlm-relay/</guid>
        
        <category>Active Directory</category>
        
        <category>Windows</category>
        
        
      </item>
    
      <item>
        <title>Kerberoasting</title>
        <description>&lt;p&gt;With the help of previously discussed notions, we have everything in hand to explain the &lt;strong&gt;Kerberoasting&lt;/strong&gt; attack principle, based on the TGS request and the &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; attributes of Active Directory accounts.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;principle&quot;&gt;Principle&lt;/h2&gt;

&lt;p&gt;The article on how &lt;a href=&quot;/kerberos&quot;&gt;kerberos works&lt;/a&gt; helped to understand how a user requests a TGS from the domain controller. The &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_TGS_REP&lt;/a&gt; response is composed of two parts.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The first part is the &lt;strong&gt;TGS&lt;/strong&gt; whose content is encrypted with the &lt;strong&gt;secret of the requested service&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;The second part is a &lt;strong&gt;session key&lt;/strong&gt; which will be used between the user and the service. The whole is encrypted using the &lt;strong&gt;user’s secret&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2018/05/tgsrep.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2018/05/tgsrep.png&quot; alt=&quot;Ticket for the service&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A domain user can ask a domain controller for a TGS for any service. It is not the role of the domain controller to check access rights. The only purpose of the domain controller when asked for a TGS is to provide security information related to a user (via the &lt;a href=&quot;/kerberos-silver-golden-tickets/#pac&quot;&gt;PAC&lt;/a&gt;). It is the service who must check the user’s rights by reading the PAC provided in the TGS.&lt;/p&gt;

&lt;p&gt;For example, TGS request can be made by specifying arbitrary &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt;. If those &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; are registered in the Active Directory, the domain controller will provide a piece of information &lt;strong&gt;encrypted with the secret key of the account executing the service&lt;/strong&gt;. With this information, the attacker can now try to recover the account’s plaintext password via a brute-force attack.&lt;/p&gt;

&lt;p&gt;Fortunately, most of the accounts that runs services are machine accounts (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MACHINENAME$&lt;/code&gt;) and their password are very long, complex and completely random, so they’re not really vulnerable to this type of attack. However, there are some services executed by accounts whose password have been chosen by a humans. It is those accounts that are much simpler to compromise via brute-force attack, so it is those accounts which will be targeted by a &lt;strong&gt;Kerberoast&lt;/strong&gt; attack.&lt;/p&gt;

&lt;p&gt;In order to list those accounts, a LDAP filter can be used to extract user-type accounts with a non-empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;servicePrincipalName&lt;/code&gt;. The filter is as follow:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;amp;(objectCategory=person)(objectClass=user)(servicePrincipalName=*)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is a simple PowerShell script allowing you to retrieve users with at least one &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; :&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$search&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DirectoryServices.DirectorySearcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ADSI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$search&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(&amp;amp;(objectCategory=person)(objectClass=user)(servicePrincipalName=*))&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$search&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Findall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userEntry&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetDirectoryEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;User : &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;distinguishedName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;SPNs&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        
	&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SPN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;servicePrincipalName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SPN&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       
	&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
	&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my lab, a fake &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; as been set on user &lt;strong&gt;support-account&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/03/SPNOnUser.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/03/SPNOnUser.png&quot; alt=&quot;SPN on User&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, during our LDAP search, here is what we get:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/03/SPNListUsersPowershell.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/03/SPNListUsersPowershell.png&quot; alt=&quot;SPN MapListpings&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, there are several tools to automate this task. For instance &lt;a href=&quot;https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1&quot;&gt;Invoke-Kerberoast.ps1&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;@Harmj0y&lt;/a&gt;, which takes care of listing user accounts with one or more &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt;, request some TGS for those accounts and extract the encrypted part in a format that can be cracked (by John for example).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Invoke-Kerberoast -domain adsec.local | Export-CSV -NoTypeInformation output.csv
john --session=Kerberoasting output.csv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or &lt;a href=&quot;https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetUserSPNs.py&quot;&gt;GetUserSPNs.py&lt;/a&gt; provided by Impacket.&lt;/p&gt;

&lt;p&gt;We then hope to find password, which depends on the company’s password policy for these accounts.&lt;/p&gt;

&lt;h2 id=&quot;protection&quot;&gt;Protection&lt;/h2&gt;

&lt;p&gt;To protect ourselves against this attack, we must avoid having &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; on user accounts, in favor of machine accounts.&lt;/p&gt;

&lt;p&gt;If it really is necessary, then we should use Microsoft’s &lt;strong&gt;Managed Service Accounts&lt;/strong&gt; (MSA) feature , which ensures that the account password is robust and changed regularly and automatically. To do so, simply add a service account (only via PowerShell):&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;New-ADServiceAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sql-service&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then it has to be installed on the machine :&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Install-ADServiceAccount&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sql-service&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, this user must be assigned to the service.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/set-account-service.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/set-account-service.png&quot; alt=&quot;Service account assignation&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The Kerberoast attack allows us to retrieve new accounts within an Active Directory for lateral movement. The compromised accounts can have higher privileges, which is sometimes the case on the computer hosting the service. It is then important from a defensive perspective to control the &lt;a href=&quot;/service-principal-name-spn&quot;&gt;SPN&lt;/a&gt; attribute on domain accounts to prevent accounts with weak password from being vulnerable to this attack.&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Mar 2020 08:02:44 +0000</pubDate>
        <link>https://en.hackndo.com/kerberoasting/</link>
        <guid isPermaLink="true">https://en.hackndo.com/kerberoasting/</guid>
        
        <category>Active Directory</category>
        
        <category>Windows</category>
        
        
      </item>
    
      <item>
        <title>AS_REP Roasting</title>
        <description>&lt;p&gt;When asking for a TGT, by default, a user has to authenticate himself to the domain controller in order to get a response. Sometimes, no authentication is asked before returning a TGT for specific account, allowing an attacker to abuse this configuration.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;preamble&quot;&gt;Preamble&lt;/h2&gt;

&lt;p&gt;When we talk about TGT it’s often a language abuse, because we are talking about the &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt; which contains the TGT (encrypted by the domain controller’s secret) and the session key (encrypted with the user account secret).&lt;/p&gt;

&lt;p&gt;In this article, the TGT notion will refer to the TGT contained in the &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt; response.&lt;/p&gt;

&lt;h2 id=&quot;pre-authentication&quot;&gt;Pre-authentication&lt;/h2&gt;

&lt;p&gt;When we talked about how &lt;a href=&quot;/kerberos&quot;&gt;Kerberos works&lt;/a&gt;, it was highlighted that during the first exchange (&lt;a href=&quot;/kerberos/#krb_tgs_req&quot;&gt;KRB_AS_REQ&lt;/a&gt; - &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt;), the client must first authenticate himself to the domain controller, before obtaining a TGT. A part of the response of the domain controller being encrypted with the client’s account secret (the session key), it is important that this information is not accessible without authentication. Otherwise, anyone could ask for a TGT for a given account, and try to decrypt the encrypted part of the response &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt; in a brute-force way in order to recover the password of the targeted user.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2018/05/asrep.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2018/05/asrep.png&quot; alt=&quot;KRB_AS_REP&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s why the user, in his &lt;a href=&quot;/kerberos/#krb_tgs_req&quot;&gt;KRB_AS_REQ&lt;/a&gt; request, must send an authenticator encrypted with his own secret in order for the domain controller to decrypt it and send back the &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt; if it is successful. If an attacker asks for a TGT with an account he does not have control over, he won’t be able to encrypt the authenticator correctly, therefore the domain controller will not return the desired information.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/asreqroast_auth.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/asreqroast_auth.png&quot; alt=&quot;Authentication Required&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the default behavior, it protects the accounts against this offline attack.&lt;/p&gt;

&lt;h2 id=&quot;krb_as_rep-roasting&quot;&gt;KRB_AS_REP Roasting&lt;/h2&gt;

&lt;p&gt;However, for some strange reason (dark one though), it is possible to disable the pre-authentication prerequisite for one or more account(s).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/preauthsettings.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/preauthsettings.png&quot; alt=&quot;Preauthentication Setting&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example in &lt;a href=&quot;https://laurentschneider.com/wordpress/2014/01/the-long-long-route-to-kerberos.html&quot;&gt;this article&lt;/a&gt;, the author states that in order to benefit from SSO on a database hosted on a Unix server, he has to disable the pre-authentication for the user. It remains a very rare case, and even &lt;a href=&quot;https://twitter.com/cptjesus&quot;&gt;cptjesus&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;Harmj0y&lt;/a&gt; don’t really have an answer.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;cptjesus &amp;gt; As far as why its disabled, I couldn’t tell you&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Harmj0y &amp;gt; I honestly don’t really know why it would be disabled, just have heard from a people about the linux/”old” angle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anyway, if this option is disabled, anyone could ask for a TGT in the name of one of these accounts, without sending any authenticator, and the domain controller will send back a &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/asreqroast_no_auth.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/asreqroast_no_auth.png&quot; alt=&quot;Authentication Required&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This can be done with the &lt;a href=&quot;https://github.com/HarmJ0y/ASREPRoast&quot;&gt;ASREPRoast&lt;/a&gt; tool of &lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;@Harmj0y&lt;/a&gt; or more recently with &lt;a href=&quot;https://github.com/GhostPack/Rubeus#asreproast&quot;&gt;Rubeus&lt;/a&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asreproast&lt;/code&gt; functionnality.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/uploads/2019/02/attackasrep.png&quot;&gt;&lt;img src=&quot;/assets/uploads/2019/02/attackasrep.png&quot; alt=&quot;ASREPRoast&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is also impacket &lt;a href=&quot;https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py&quot;&gt;GetNPUsers.py&lt;/a&gt; tool that can perform this operation.&lt;/p&gt;

&lt;p&gt;Once in possession of the domain controller response &lt;a href=&quot;/kerberos/#krb_tgs_rep&quot;&gt;KRB_AS_REP&lt;/a&gt;, the attacker can try to find out the victim’s clear text password offline, by using John The Ripper with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;krb5asrep&lt;/code&gt; mode, or with hashcat for example.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This technique, also described in an &lt;a href=&quot;https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/&quot;&gt;article&lt;/a&gt; wrote by &lt;a href=&quot;https://twitter.com/harmj0y&quot;&gt;Harmj0y&lt;/a&gt;, is a way to retrieve a clear text password within an Active Directory environment &lt;strong&gt;when you don’t have any foothold&lt;/strong&gt;. But if you don’t have any account yet, it can be difficult to find out this information as you are not able to talk with the domain controller. An OSINT phase can be useful to enumerate as many valid account as possible, and try this attack on every account you found.&lt;/p&gt;

&lt;p&gt;If any account is set up so that it does not need a pre-authentication, an attacker could simply ask for a TGT for this account and try to recover its password. With powerful machine, the cracking speed can be really huge. However, you should be aware that accounts without the necessary pre-authentication required are pretty rare. They can exist for historical reason, but &lt;a href=&quot;/kerberoasting&quot;&gt;kerberoasting&lt;/a&gt; is still more widespread.&lt;/p&gt;
</description>
        <pubDate>Thu, 19 Mar 2020 07:10:06 +0000</pubDate>
        <link>https://en.hackndo.com/kerberos-asrep-roasting/</link>
        <guid isPermaLink="true">https://en.hackndo.com/kerberos-asrep-roasting/</guid>
        
        <category>Active Directory</category>
        
        <category>Windows</category>
        
        
      </item>
    
  </channel>
</rss>
