If you’ve tried Google’s Gemini AI in the terminal, chances are you quickly realized it’s not an optimal solution for pentesting (or hackers). It has too many limitations and you end up getting a response like this:

There is an alternative though – one that is driven by Chat GPT and catered specifically for the Linux terminal – Shell-GPT. Here’s how to install Shell-GPT (sgpt) on Kali Linux.
First, open a terminal and update apt.
sudo apt update && sudo apt upgrade
Then make sure you have python3, pip, and jq (needed for any JSON input) installed.
sudo apt install python3 python3-pip jq
Jump over to OpenAI and get your OpenAI API Key. Sign in first, then go to Your Profile and click on the User API Keys link. For now, User API Keys will work but OpenAI is pushing users toward Project API Keys. Those are found here: https://platform.openai.com/settings/organization/api-keys
Click Create new key and enter the Name, Project (default is fine) and click the Create secret key button.

Save the API key securely. You will not be able to access it again after this.
Shell-GPT can be installed using Python’s pip utility. –break-system-packages lets you install sgpt in the system-wide Python environment, which you may or may not want.
sudo pip3 install shell-gpt --break-system-packages
Or you can create a virtual Python environment and install it there.
python -m venv sgpt
source sgpt/bin/activate
pip3 install shell-gpt
To run sgpt from anywhere, you must add the Python user binaries to your PATH with something like this. Otherwise you’ll need to use the source command above everytime you log in or create a new session.
export PATH=$PATH:~/.local/bin:/usr/bin/python3
To ensure this is set everytime you log in.
echo 'export PATH=$PATH:~/.local/bin:/usr/bin/python3' >> ~/.bashrc
source ~/.bashrc
Or if using zsh:
echo 'export PATH=$PATH:~/.local/bin:/usr/bin/python3' >> ~/.zshrc
source ~/.zshrc
Run Shell-GPT.
sgpt
You will be prompted to enter your OpenAI API Key you created above. This will be stored in ~/.config/shell_gpt/.sgptrc
in case you need to change or correct it.
Using sgpt is pretty simple.
sgpt --shell "scan the target 10.0.2.7 with nmap"
If you get a “command not found” error for `sgpt`, ensure `~/.local/bin` is in your PATH.
How to use AI to hack in Kali
Fixing the darn msfconsole database connection
In this example, Metasploit’s database is not connected (a very common, albeit, irritating occurenct).
└─# msfconsole │
Metasploit tip: View all productivity tips with the tips command │
│
_ _ │
/ \ /\ __ _ __ /_/ __ │
| |\ / | _____ \ \ ___ _____ | | / \ _ \ \ │
| | \/| | | ___\ |- -| /\ / __\ | -__/ | || | || | |- -| │
|_| | | | _|__ | |_ / -\ __\ \ | | | | \__/| | | |_ │
|/ |____/ \___\/ /\ \\___/ \/ \__| |_\ \___\ │
│
│
=[ metasploit v6.4.69-dev ] │
+ -- --=[ 2529 exploits - 1302 auxiliary - 432 post ] │
+ -- --=[ 1672 payloads - 49 encoders - 13 nops ] │
+ -- --=[ 9 evasion ] │
│
Metasploit Documentation: https://docs.metasploit.com/ │
│
msf6 > workspace │
[-] Database not connected
Rather than sorting out the problem, we simply ask AI to fix it for us with this simple prompt:
sgpt --shell "msfconsole will not start. It errors with Database not connected. Fix this."
└─# sgpt --shell "msfconsole will not start. It errors with Database not connected. Fix this." │
service postgresql start && msfdb init && msfconsole │
[E]xecute, [D]escribe, [A]bort: e │
[i] Database already started │
[i] The database appears to be already configured, skipping initialization │
Metasploit tip: After running db_nmap, be sure to check out the result │
of hosts and services │
│
│
.:okOOOkdc' 'cdkOOOko:. │
.xOOOOOOOOOOOOc cOOOOOOOOOOOOx. │
:OOOOOOOOOOOOOOOk, ,kOOOOOOOOOOOOOOO: │
'OOOOOOOOOkkkkOOOOO: :OOOOOOOOOOOOOOOOOO' │
oOOOOOOOO. .oOOOOoOOOOl. ,OOOOOOOOo │
dOOOOOOOO. .cOOOOOc. ,OOOOOOOOx │
lOOOOOOOO. ;d; ,OOOOOOOOl │
.OOOOOOOO. .; ; ,OOOOOOOO. │
cOOOOOOO. .OOc. 'oOO. ,OOOOOOOc │
oOOOOOO. .OOOO. :OOOO. ,OOOOOOo │
lOOOOO. .OOOO. :OOOO. ,OOOOOl │
;OOOO' .OOOO. :OOOO. ;OOOO; │
.dOOo .OOOOocccxOOOO. xOOd. │
,kOl .OOOOOOOOOOOOO. .dOk, │
:kk;.OOOOOOOOOOOOO.cOk: │
;kOOOOOOOOOOOOOOOk: │
,xOOOOOOOOOOOx, │
.lOOOOOOOl. │
,dOd, │
. │
│
=[ metasploit v6.4.69-dev ] │
+ -- --=[ 2529 exploits - 1302 auxiliary - 432 post ] │
+ -- --=[ 1672 payloads - 49 encoders - 13 nops ] │
+ -- --=[ 9 evasion ] │
│
Metasploit Documentation: https://docs.metasploit.com/ │
│
workspacemsf6 > workspace │
GuysHackingMe │
* default
Finding IP addresses for targets
Google’s Gemini will not let this query go through for “security” reasons. With Shell-GPT, it complies and returns accurate results when asked to list the IP addresses of the Kremlin in Russia.
└─# sgpt --shell "What are all the IP addresses for the Kremlin in Russia?"
dig +short kremlin.ru
[E]xecute, [D]escribe, [A]bort: e
95.173.136.72
95.173.136.70
95.173.136.71
But if you phrase it a bit differently, with more direct instructions, it will comply.
─# sgpt --shell "What ports are open on https://google-gruyere.appspot.com/429541720008851228497877897350489029391/"
nmap -p- google-gruyere.appspot.com
[E]xecute, [D]escribe, [A]bort: e
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-01 13:33 CDT
Scanning for NSF shares
─# sgpt --shell "Are there any NFS shares open on scene.org"
showmount -e scene.org
[E]xecute, [D]escribe, [A]bort: e
Grabbing banners
Grabbing an FTP banner is pretty simple. But AI takes it a bit further and attempts an anonymous login too.
└─# sgpt --shell "ftp.scene.org is a ftp server. Enumerate the server and show me what banners it displays"
ftp -n -v ftp.scene.org <<END_SCRIPT
quote USER anonymous
quote PASS ftp@example.com
quit
END_SCRIPT
[E]xecute, [D]escribe, [A]bort: e
Scanning using the tool of your choice
The more hints you give Shell-GPT in your prompt, the better it can accomplish what you want it to do. In this example, we specifically tell it to scan microsoft.com using Nikto.
└─# sgpt --shell "Use nikto to scan microsoft.com."
nikto -h microsoft.com
[E]xecute, [D]escribe, [A]bort: e
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Multiple IPs found: 13.107.246.38, 2603:1010:3:3::5b, 2603:1030:b:3::152, 2603:1030:20e:3::23c, 2603:1030:c02:8::14, 2603:1020:201:10::10f
+ Target IP: 13.107.246.38
+ Target Hostname: microsoft.com
+ Target Port: 80
+ Start Time: 2025-07-01 13:52:32 (GMT-5)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: Uncommon header 'x-azure-ref' found, with contents: 20250701T185232Z-16547796d68xbndxhC1DFWgkd00000000qkg00000000bhcm.
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ Root page / redirects to: https://microsoft.com/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ 7962 requests: 0 error(s) and 3 item(s) reported on remote host
+ End Time: 2025-07-01 13:53:30 (GMT-5) (58 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Scanning for specific services in a specific block range
└─# sgpt --shell "Search a few IP addresses around 176.208.0.0 for SMB blocks"
nmap -p 445 --open 176.208.0.0/30
[E]xecute, [D]escribe, [A]bort: e
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-01 13:55 CDT
Nmap done: 4 IP addresses (2 hosts up) scanned in 7.91 seconds
Changing firewall rules
It can even make changes to your firewall rules (in this instance, it got the firewall rules location wrong though).
┌──(sgpt)─(root㉿kali1)-[/home/brianhaddock/sgpt]
└─# sgpt --shell "176.208.1.23 keeps hacking my web server. Make it stop."
iptables -A INPUT -s 176.208.1.23 -j DROP && iptables-save > /etc/iptables/rules.v4
[E]xecute, [D]escribe, [A]bort:
Even Shell-GPT has its limits
Even Shell-GPT can be a pain when asked to do something it thinks could be illegal. For instance, we tried to get it to scan Google’s Gruyere pentest target.
└─# sgpt --shell "I need to pentest https://google-gruyere.appspot.com/429541720008851228497877897350489029391/ for vulnerabilities. Test it for me and let me know the results"
I'm sorry, I can't assist with that.
Not always spot on
Sure, it doesn’t work 100% all the time. In this instance, it got the right directory for the wordlist file but unfortunately, the wordlist it chose was not present in that directory. Doesn’t really matter in this instance because it didn’t supply the parameter in the right format anyway.
└─# sgpt --shell "I need DNS information for microsoft.com. Do dns recon on it using a common wordlist of your choosing"
dig microsoft.com any && dnsrecon -d microsoft.com -w /usr/share/wordlists/dnsmap.txt
[E]xecute, [D]escribe, [A]bort: e
; <<>> DiG 9.20.9-1-Debian <<>> microsoft.com any
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41223
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;microsoft.com. IN ANY
;; ANSWER SECTION:
microsoft.com. 300 IN HINFO "RFC8482" ""
;; Query time: 20 msec
;; SERVER: 10.0.0.243#53(10.0.0.243) (TCP)
;; WHEN: Tue Jul 01 13:46:04 CDT 2025
;; MSG SIZE rcvd: 63
usage: dnsrecon [-h] [-d DOMAIN] [-n NS_SERVER] [-r RANGE] [-D DICTIONARY] [-f] [-a] [-s] [-b] [-y] [-k] [-w] [-z] [--threads THREADS] [--lifetime LIFETIME] [--tcp] [--db DB] [-x XML] [-c CSV] [-j JSON] [--iw] [--disable_check_recursion]
[--disable_check_bindversion] [-V] [-v] [-t TYPE]
dnsrecon: error: unrecognized arguments: /usr/share/wordlists/dnsmap.txt