owned this note
owned this note
Published
Linked with GitHub
Twitter: https://twitter.com/s3v3ru5_
# Work Experience
1. Blockchain Security Engineer, Trail of Bits (Jun 2022 - Jun 2024)
- My Job at Trail of Bits mainly comprised of security reviews. If not on a security review, I would focus on tool development, contributing to TOB internal SoKs and external content.
- Performed Security Reviews of
- Ethereum Smart contracts
- Algorand Smart contracts written in TEAL/PYTEAL.
- Solana smart contracts (Rust)
- Offchain components written in Rust. Offchain components include Compilers, VM, and some parts of blockchain node.
- Bench time
- Worked on development of Tealer, a static analyzer for Algorand Smart Contracts. (Jun 2022 to Nov 2023). [Tealer](https://github.com/crytic/tealer)
- Worked on development of Solana lints. Solana lints are rust lints which check for vulnerable patterns in solana programs using the rust linting API. (Dec 2023 to Jun 2024). [solana-lints](https://github.com/crytic/solana-lints).
- Added all the issues in the Algorand not-so-smart-contracts in [building-secure-contracts](https://github.com/crytic/building-secure-contracts/tree/master/not-so-smart-contracts/algorand).
- Added Improper Instruction Issue in Solana [not-so-smart-contracts](https://github.com/crytic/building-secure-contracts/tree/master/not-so-smart-contracts/solana/improper_instruction_introspection)
3. Auditor, Ottersec. (Mar 2022 to Apr 2022, ~1 month)
- Worked with Robert(NotDeGhost) on two Solana audits. (https://x.com/notdeghost)
4. Winternship, Trail of Bits. (Dec 2021 - Jan 2022, 6 weeks)
- Worked on Tealer, a static analyzer for Algorand smart contracts.
5. CTF Player, played with team Invaders and zer0pts (Jan 2019 - Oct 2021)
- Main Focus was cryptography. I have a good understanding of cryptographic primitives. Also have basic understanding of other areas (pwn, reversing and web hacking).
- Have global rank of #228 and rank #12 country wise in cryptohack: https://cryptohack.org/user/S3v3ru5/
- CTF Writeups: https://s3v3ru5.github.io/
# Audit Experience
## Folks Finance
[Report](https://github.com/trailofbits/publications/blob/master/reviews/2022-11-folksfinance-securityreview.pdf
)
- Date: Oct 31 to Nov 25, 2022
- Protocol: Folks Finance, Lending protocol
- Tech Stack: Algorand Smart contracts written in PyTeal
### Issues
- 2. Lack of a two-step process for admin role transfers
- 3. Insufficient validation of applicatin initialization arguments
- 5. oracle_adapter could be forced to use outdated LP token information in price calculations
- 7. Risk of global state variable collision
- 9. Incorrect decoding of method arguments results in use of invalid values
- Found a bug in the fix for issue 5 during fix review.
Issues 2, 3 are common and trivial issues.
I'm describing the other issues here to showcase the complexity and my skills in identifying these issues.
Prequistics to understand the issues 5 and 9:
- Algorand supports group transactions, a list of transactions which either all are included or none are included (Atomicity).
- Developers designed contracts by leveraging this feature. An operation of the protocol might consist of calling different contracts in a group transaction; trasaction 1 calls contract 1, transaction 2 calls contract 2, ...
- The contracts sometimes need to verify the correctness of the group transaction as a whole; contract 2 might have to verify that transaction 1 is calling the contract 1 with right arguments.
### Issue 5
- There are two contracts, lp_token_oracle and oracle_adapter.
- `lp_token_oracle.update_lp_tokens` function and `oracle_adapter.refresh_prices` function each take a `uint64[]` argument. let argument of `update_lp_tokens` be `A` and argument of `refresh_prices` be `B`
- The `oracle_adapter` contract have to ensure that both these `uint64[]` are same i.e `A == B`.
- The `oracle_adapter` extracts the serialized bytes (calldata) for the both the arguments `A` and `B`.
- The `uint64[]` are encoded as `{uint16 length}{Encoded(element1)}{Encoded(element2)}...`.
- The `oracle_adapter` removes the first two bytes (`length` part) and performs a byte comparison between elements part of the serialized `A` and `B`
Bug:
- The PyTeal language does not ensure the correctness of serialized data. It is possible for the `length` part of the serialized `uint64[]` to be `0x0000`(`0`) and contain serialized elements. for e.g decoding `0x0001` + `0x01` + `0x02` into `uint8[]` will give `[1]`.
- Because the `oracle_adapter` ignores the `length` part, the serialized `A` can contain `0` length and same serialized elements as `B`. Serialized `A` could be `0x0000`(length) + `0x000..01`, length is `0` but has element `1` and if `B` is `0x0001` + `0x00..01` then byte comparison will succeed
- If an attacker provides such `A` and `B`, the `oracle_adapter` contract considers that `A` has same elements as `B` and that the `lp_token_oracle` contract will process all the elements in `B`. However, the `lp_token_oracle` does not process any elements because it checks the length of `A`, which is `0` and returns immediately.
The developer had to perform byte comparison of `A` and `B` because there could be multiple calls to `lp_token_oracle` i.e `A` is composed of `A1`, `A2`, `A3`, ... (`uint64[]` argument of each call). The `oracle_adapter` had to ensure that the elements in `A1`, `A2`, ... combined are equal to the elements of `B`.
Exploit Scenario should resolve any doubts about the issue.
The issue is complex and I identified the issue by checking the generated TEAL bytecode for the functions, whether any checks are performed on the serialzed arguments before decoding.
### Issue 9
- There are two contracts `loan` and `pool`.
- A function of `loan` contract has to check an `uint8` argument of call to the `pool` contract when called in a group transaction.
- The function uses `Btoi` instruction of Algorand Virtual Machine(`AVM`) to decode the `uint8` argument from serialized bytes (calldata).
- However, PyTeal uses `get_byte` instructions to decode `uint8` arguments.
- The `get_byte` instruction and `Btoi` instruction have different semantics. As a result, the two contracts see different values. if the `pool` contract is called with bytes `0x0001` for the `uint8` argument, the `pool` contract considers the value to be `0` and `loan` contract considers value to be `1`
Identification of this issue also involved checking the PyTeal source code and checking the generated Teal code for the contracts (The exact instructions used for encoding/decoding the arguments are not documented.)
### Issue 7
- PyTeal does not support state variable allocation, developers have to manually allocate the slots/keys for each variable (keys are equivalent to ethereum storage slots)
- The developers manually implemented the state variable allocation. Some keys depended on the user values.
- There was a possibility for an attacker to craft malicious input such that there is a collision between slots/keys used for two different state variables.
## Squads V4
[Report](https://github.com/trailofbits/publications/blob/master/reviews/2023-10-squadsv4-securityreview.pdf)
- Date: Sep 11 to Sep 22, 2023
- Protocol: Squads V4, Multisig
- Tech Stack: Solana, Anchor, Rust
### Issues
- 7. Attacker can front-run multisig creation transaction
- 8. Program uses same set of ephemeral keys for all transactions in a batch
- 9. Inefficient lookup table account verification during transaction execution
Issue 7 and 8 are best described in the report. Issue 9 was initially an high sev issue. however, there was an additional indirect check which made the vuln not exploitable. We have turned the issue into an informational. The issue 9 does show my understanding of Solana lookup tables.
## Catalog Protocol
Report: https://github.com/catalogfi/audits/blob/main/TrailOfBits.pdf
- Issue 2: Template contract which is used in delegate call is not initialized. Anyone can initialize it and make it self-destruct.
- Issue 3, 4: These are design level issues. The issues are identified by working through the flow-diagram.
- Issue 7: The contract deletes a struct containing a mapping from storage. The values from the `mapping` is not deleted leading to unintended behavior.
- Issue 8
- Issue 9: Probably the most complex issue in the audit. The protocol uses HTLCs for each swap to distribute fees. The group of HTLCs are signed by offline fee manager. Every HTLC expires after 48 hours starting from the swap initiation. The fee Manager always signs a list of all HTLCs which were not redemeed by the user and whose swap operation is complete. It is possible that some HTLCs expire while the user waits for completion of other swaps. The user cannot redeem fees from all HTLCs because first few would have expired.
- Reading the exploit scenario and the recommendations will help in understanding the issue.
# Tool familiarity
| Tool | Context |
| -------- | -------- |
| Slither | Used(sparingly) in Etherum audits |
| Echidna | Used in only one audit to write fuzz tests |
| Tealer | Tool developer, used on folks finance audits |
| solana-lints | Tool developer |
| Clippy | Familiar |
## Tealer
[Tealer](https://github.com/crytic/tealer)
- Was the main developer of the tool.
- Implemented detectors, printers and support for analyzing group transactions.
- Added the github wiki for the tool.
## Solana-lints
[solana-lints](https://github.com/crytic/solana-lints)
- Added documentation and updated the old lints to work on new solana programs.
- Worked on improving them to reduce false positivies and to make more relevant/usable
- Added [`sysvar_get`](https://github.com/crytic/solana-lints/tree/master/lints/sysvar_get) lint
# Contests
Username: S3v3ru5
## Zaros
Position: 4th
Leaderboard: https://codehawks.cyfrin.io/c/2024-07-zaros/results?t=leaderboard<=contest&sc=reward&sj=reward&page=1
Platform: CodeHawks
Tech Stack: Solidity, EVM
Protocol: Perpetual Markets
## Winnable Raffles
Position: 3rd
Leaderboard: https://audits.sherlock.xyz/contests/516/leaderboard
Platform: Sherlock
Tech Stack: Solidity, EVM, Chainlink CCIP
Protocol: Raffles
## Sentiment V2
Position: 25th
Leaderboard: https://audits.sherlock.xyz/contests/349/leaderboard
Platform: Sherlock
Tech Stack: Solidity, EVM
Protocol: Lending Protocol
## WooFi Swap on Solana
Position: 2nd
Leaderboard:
Contest Platform: Sherlock
Tech Stack: Rust, Anchor, Solana
Protocol: AMM