homepage
Menu
Open menu
  • Training
    Go one level top Back

    Training

    • Courses

      Build cyber prowess with training from renowned experts

    • Hands-On Simulations

      Hands-on learning exercises keep you at the top of your cyber game

    • Certifications

      Demonstrate cybersecurity expertise with GIAC certifications

    • Ways to Train

      Multiple training options to best fit your schedule and preferred learning style

    • Training Events & Summits

      Expert-led training at locations around the world

    • Free Training Events

      Upcoming workshops, webinars and local events

    • Security Awareness

      Harden enterprise security with end-user and role-based training

    Featured: Solutions for Emerging Risks

    Discover tailored resources that translate emerging threats into actionable strategies

    Risk-Based Solutions

    Can't find what you are looking for?

    Let us help.
    Contact us
  • Learning Paths
    Go one level top Back

    Learning Paths

    • By Focus Area

      Chart your path to job-specific training courses

    • By NICE Framework

      Navigate cybersecurity training through NICE framework roles

    • DoDD 8140 Work Roles

      US DoD 8140 Directive Frameworks

    • By European Skills Framework

      Align your enterprise cyber skills with ECSF profiles

    • By Skills Roadmap

      Find the right training path based on critical skills

    • New to Cyber

      Give your cybersecurity career the right foundation for success

    • Leadership

      Training designed to help security leaders reduce organizational risk

    • Degree and Certificate Programs

      Gain the skills, certifications, and confidence to launch or advance your cybersecurity career.

    Featured

    New to Cyber resources

    Start your career
  • Community Resources
    Go one level top Back

    Community Resources

    Watch & Listen

    • Webinars
    • Live Streams
    • Podcasts

    Read

    • Blog
    • Newsletters
    • White Papers
    • Internet Storm Center

    Download

    • Open Source Tools
    • Posters & Cheat Sheets
    • Policy Templates
    • Summit Presentations
    • SANS Community Benefits

      Connect, learn, and share with other cybersecurity professionals

    • CISO Network

      Engage, challenge, and network with fellow CISOs in this exclusive community of security leaders

  • For Organizations
    Go one level top Back

    For Organizations

    Team Development

    • Why Partner with SANS
    • Group Purchasing
    • Skills & Talent Assessments
    • Private & Custom Training

    Leadership Development

    • Leadership Courses & Accreditation
    • Executive Cybersecurity Exercises
    • CISO Network

    Security Awareness

    • End-User Training
    • Phishing Simulation
    • Specialized Role-Based Training
    • Risk Assessments
    • Public Sector Partnerships

      Explore industry-specific programming and customized training solutions

    • Sponsorship Opportunities

      Sponsor a SANS event or research paper

    Interested in developing a training plan to fit your organization’s needs?

    We're here to help.
    Contact us
  • Talk with an expert
  • Log In
  • Join - it's free
  • Account
    • Account Dashboard
    • Log Out
  1. Home >
  2. Blog >
  3. Using gdb to Call Random Functions
Ron Bowes

Using gdb to Call Random Functions

December 11, 2018

Sometimes reverse engineering is graceful and purposeful, where you thread the needle just right to figure out some obscure, undocumented function and how it can be used to the best of your ability. This article isn't about that.

In this post, we'll look at how we can find hidden functionality by jumping to random functions in-memory! This is normally a good way to crash the program, but who knows? You might find a gem!

This technique is useful for finding hidden functionality, but it's somewhat limited: it'll only work for applications that you're capable of debugging. With few exceptions (I've used a technique like this to break out of an improperly implemented sandbox before), this technique is primarily for analysis, not for exploitation or privilege escalation.

Creating a Test Binary

Let's start by writing a simple toy program. You can download this program as a 32- and 64-bit Linux binary, as well as the source code and Makefile, here

Here's the full code:


#include <stdio.h>

void random_function() {
  printf("You called me!\n");
}

int main(int argc, char *argv[]) {
  printf("Can you call random_function()?\n");
  printf("Press <enter> to continue\n");
  getchar();

  printf("Good bye!\n");
}

Put that in a file called jumpdemo.c and compile with the following command:

gcc -g -O0 -o jumpdemo jumpdemo.c


We add -00  to the command line to prevent the compiler from performing optimizations such as deleting unused functions under the guise of "helping". If you grabbed our source code, you can simply run make after extracting it.

Finding Interesting Functions

Let's assume for the purposes of this post that the binaries are compiled with symbols. That means that you can see the function names! My favorite tool for analyzing binaries is IDA, but for our purposes, the nm command is more than sufficient:


nm ./jumpdemo
0000000000601040 B __bss_start
0000000000601030 D __data_start
0000000000601030 W data_start
0000000000601038 D __dso_handle
0000000000601040 D _edata
0000000000601048 B _end
0000000000400624 T _fini
                 U getchar@@GLIBC_2.2.5
                 w __gmon_start__
0000000000400400 T _init
0000000000400630 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
0000000000400620 T __libc_csu_fini
00000000004005b0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400577 T main
                 U puts@@GLIBC_2.2.5
0000000000400566 T random_function
0000000000400470 T _start
0000000000601040 D __TMC_END__

Everything you see here is a symbol, and the ones with T  in front are ones that we can actually call, but the ones that start with an underscore ('_') are built-in stuff that we can just ignore (in a "real" situation, you shouldn't discount something simply because the name starts with an underscore, of course).

The two functions that might be interesting are "main" and "random_function", so that's what we're going to target!

Load in gdb

Before we can call one of these functions, we need to run the project in gdb ? the GNU Project Debugger. On the command line (from the directory containing the compiled jumpdemo  binary), run ./jumpdemo  in gdb: 

gdb -q ./jumpdemo
Reading symbols from ./jumpdemo...(no debugging symbols found)...done.
(gdb)

The -q  flag is simply to disable unnecessary output. After you get to the (gdb)  prompt, the jumpdemo application is loaded and ready to run, but it hasn't actually been started yet. You can verify that by trying to run a command such as continue :

(gdb)continue
The program is not being run.

 gdb is an extremely powerful tool, with a ton of different commands. You can enter help  into the prompt to learn more, and you can also use help <command>  on any of the commands we use (such as help break)  to get more details. Give it a try!

Simple Case: Just Call It!

Now that the program is ready to go in gdb, we can run it with the run command (don't forget to try help run ). You'll see the same output as you would if you'd run it directly until it ends, at which point we're back in gdb. You can run it over and over if you desire, but that's not really going to get you anywhere.

In order to modify the application at runtime, it is necessary to run the program and then stop it again before it finishes cleanly. The most common way is to use a breakpoint  (help break) on main:


$ gdb -q ./jumpdemo
Reading symbols from ./jumpdemo...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x40057b
(gdb) 

Then run the binary and watch what happens:


(gdb) run
Starting program: /home/ron/blogs/jumpdemo

Breakpoint 1, 0x000000000040057b in main ()
(gdb)

Now we have control of the application in the running (but paused) state! We can view/edit memory, modify registers, continue execution, jump to another part of the code, and much much more!

In our case, as I'm sure you've guessed by now, we're going to move the program's execution to another part of the program. Specifically, we're just going to use gdb's jump command (help jump)  to resume execution at the start of random_function():

$ gdb -q ./jumpdemo
Reading symbols from ./jumpdemo...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x40057b
(gdb) run
Starting program: /home/ron/blogs/jumpdemo 

Breakpoint 1, 0x000000000040057b in main ()
(gdb) help jump
Continue program being debugged at specified line or address.
Usage: jump <location>
Give as argument either LINENUM or *ADDR, where ADDR is an expression
for an address to start at.
(gdb) jump random_function
Continuing at 0x40056a.
You called me!
[Inferior 1 (process 11391) exited with code 017]</location>

We did it! The program printed, "You called me!", which means we successfully ran random_function( )  Exit code 017 means the process didn't exit cleanly, but that is to be expected. We just ran an unexpected function with absolutely no context!

If for some reason you can't get breakpoints to work (maybe the program was compiled without symbols and you don't actually know where main  is), you can do the same thing without breakpoints by pressing ctrl-c while the binary is running:

(gdb)run
Starting program: /home/ron/blogs/jumpdemo 
Can you call random_function()?
Press <enter> to continue
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b04260 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) jump random_function
Continuing at 0x40056a.
You called me!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000001 in ?? ()</enter>


Don't worry about the segmentation fault, like the 017 exit code above, it's happening because the program has no idea what to do after it's finished running random_function.

Another mildly interesting thing that you can do is jump back to main ( ) to make the program think it's starting over:

(gdb) run
Starting program: /home/ron/blogs/jumpdemo 
Can you call random_function()?
Press <enter> to continue
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b04260 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) jump main
Continuing at 0x40057b.
Can you call random_function()?
Press <enter> to continue</enter></enter>

I use jump-back-to-main a lot while doing actual exploit development to check whether or not I actually have code execution without trying to develop working shellcode. If the program appears to start over, you've changed the current instruction!

Real-world Example

For a quick example of this technique doing something visible against a "real" application, I took a look through my tools/  folder for a simple command line Linux application, and found THC-Hydra. I compiled it the standard way ? ./configure && make ? and ran nm against it:

$  nm ./hydra
0000000000657abc b A
0000000000657cb4 B accntFlag
                 U alarm@@GLIBC_2.2.5
000000000043baf0 T alarming
0000000000657ae4 B alarm_went_off
00000000004266f0 T analyze_server_response
0000000000654200 B apop_challenge
                 U ASN1_OBJECT_free@@OPENSSL_1.0.0
                 U __assert_fail@@GLIBC_2.2.5
0000000000655c00 B auth_flag
0000000000657ab8 b B
0000000000408b60 T bail
000000000044b760 r base64digits
000000000044b6e0 r base64val
0000000000433450 T bf_get_pcount
?


Turns out, there are over 700 exported symbols. Wow! We can narrow it down by grepping for T,  which refers to a symbol in the code section, but there are still a lot of those. I manually looked over the list to find ones that might work (ie, functions that might print output without having any valid context / parameters).

I started by running the application with a "normal" set of arguments to make note of the "normal" output:


$ gdb -q --args ./hydra -l john -p doe localhost http-head
Reading symbols from ./hydra...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/ron/tools/hydra-7.1-src/hydra -l john -p doe localhost http-head
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Hydra v7.1 (c)2011 by van Hauser/THC & David Maciejak - for legal purposes only

Hydra (http://www.thc.org/thc-hydra) starting at 2018-10-15 14:47:12
Error: You must supply the web page as an additional option or via -m
[Inferior 1 (process 3619) exited with code 0377]
(gdb)

The only new thing here is --args  which is simply a signal to gdb that there are going to be command line arguments to the binary.

After I determined what the output is supposed to look like, I set a breakpoint on main,  like before, and jumped to help( )  after breaking:

$ gdb -q --args ./hydra -l john -p doe localhost http-head 
Reading symbols from ./hydra...(no debugging symbols found)...done. 
(gdb) break main 
Breakpoint 1 at 0x403bf0 
(gdb) run
Starting program: /home/ron/tools/hydra-7.1-src/hydra -l john -p doe localhost http-head [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, 0x0000000000403bf0 in main () 
(gdb) jump help 
Continuing at 0x408420. Syntax: (null) [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | [-C FILE]] [-e nsr] [-o FILE] [-t TASKS] [-M FILE [-T TASKS]] [-w TIME] [-W TIME] [-f] [-s PORT] [-x MIN:MAX:CHARSET] [-SuvV46] [server service [OPT]]|[service://server[:PORT][/OPT]]

Options: -R restore a previous aborted/crashed session -S perform an SSL connect ..

I tried help_bfg  as well:

(gdb) jump help_bfg
Continuing at 0x408580.
Hydra bruteforce password generation option usage:

  -x MIN:MAX:CHARSET

     MIN     is the minimum number of characters in the password
     MAX     is the maximum number of characters in the password
     CHARSET is a specification of the characters to use in the generation
             valid CHARSET values are: 'a' for lowercase letters,
             'A' for uppercase letters, '1' for numbers, and for all others,
             just add their real representation.

Examples:
   -x 3:5:a  generate passwords from length 3 to 5 with all lowercase letters
   -x 5:8:A1 generate passwords from length 5 to 8 with uppercase and numbers
   -x 1:3:/  generate passwords from length 1 to 3 containing only slashes
   -x 5:5:/%,.-  generate passwords with length 5 which consists only of /%,.-

The bruteforce mode was made by Jan Dlabal, <a href="http://houbysoft.com/bfg/" class="redactor-autoparser-object">http://houbysoft.com/bfg/</a>
[Inferior 1 (process 9980) exited with code 0377]

Neat! Another help output! Although these are easy to get to legitimately, it's really neat to see them called when they aren't expected to be called! Stuff "just works", kinda.

Speaking of kinda working, I also jumped to hydra_debug( ),  which had slightly more interesting results:

(gdb) jump hydra_debug
Continuing at 0x408b40.
[DEBUG] Code: ????   Time: 1539640228
[DEBUG] Options: mode 0  ssl 0  restore 0  showAttempt 0  tasks 0  max_use 0 tnp 0  tpsal 0  tprl 0  exit_found 0  miscptr (null)  service (null)
[DEBUG] Brains: active 0  targets 0  finished 0  todo_all 0  todo 0  sent 0  found 0  countlogin 0  sizelogin 0  countpass 0  sizepass 0
[Inferior 1 (process 7761) exited normally]

It does its best to print out the statistics, but because it didn't expect that function to be called, it just prints nonsense.

Every other function I tried either does nothing or simply crashes the application. When you call a function that expects certain parameters without any such parameters, it normally tries to access invalid memory, so it's pretty unsurprising. It's actually surprising that it works at all! It's pure luck that the string it tried to print is an invalid string rather than invalid memory (which would crash).

Conclusion

This may not seem like much, but it's actually a very simple and straightforward reverse engineering technique that sometimes works shockingly well. Grab some open source applications, run nm on them, and try calling some functions. You never know what you'll figure out!

-Ron Bowes
@iagox86

Share:
TwitterLinkedInFacebook
Copy url Url was copied to clipboard
Subscribe to SANS Newsletters
Receive curated news, vulnerabilities, & security awareness tips
United States
Canada
United Kingdom
Spain
Belgium
Denmark
Norway
Netherlands
Australia
India
Japan
Singapore
Afghanistan
Aland Islands
Albania
Algeria
American Samoa
Andorra
Angola
Anguilla
Antarctica
Antigua and Barbuda
Argentina
Armenia
Aruba
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belize
Benin
Bermuda
Bhutan
Bolivia
Bonaire, Sint Eustatius, and Saba
Bosnia And Herzegovina
Botswana
Bouvet Island
Brazil
British Indian Ocean Territory
Brunei Darussalam
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Cape Verde
Cayman Islands
Central African Republic
Chad
Chile
China
Christmas Island
Cocos (Keeling) Islands
Colombia
Comoros
Cook Islands
Costa Rica
Cote D'ivoire
Croatia (Local Name: Hrvatska)
Curacao
Cyprus
Czech Republic
Democratic Republic of the Congo
Djibouti
Dominica
Dominican Republic
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Eswatini
Ethiopia
Falkland Islands (Malvinas)
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
French Southern Territories
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guernsey
Guinea
Guinea-Bissau
Guyana
Haiti
Heard And McDonald Islands
Honduras
Hong Kong
Hungary
Iceland
Indonesia
Iraq
Ireland
Isle of Man
Israel
Italy
Jamaica
Jersey
Jordan
Kazakhstan
Kenya
Kiribati
Korea, Republic Of
Kosovo
Kuwait
Kyrgyzstan
Lao People's Democratic Republic
Latvia
Lebanon
Lesotho
Liberia
Liechtenstein
Lithuania
Luxembourg
Macau
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mayotte
Mexico
Micronesia, Federated States Of
Moldova, Republic Of
Monaco
Mongolia
Montenegro
Montserrat
Morocco
Mozambique
Myanmar
Namibia
Nauru
Nepal
Netherlands Antilles
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
North Macedonia
Northern Mariana Islands
Oman
Pakistan
Palau
Palestine
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Pitcairn
Poland
Portugal
Puerto Rico
Qatar
Reunion
Romania
Russian Federation
Rwanda
Saint Bartholemy
Saint Kitts And Nevis
Saint Lucia
Saint Martin
Saint Vincent And The Grenadines
Samoa
San Marino
Sao Tome And Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Sint Maarten
Slovakia
Slovenia
Solomon Islands
South Africa
South Georgia and the South Sandwich Islands
South Sudan
Sri Lanka
St. Helena
St. Pierre And Miquelon
Suriname
Svalbard And Jan Mayen Islands
Sweden
Switzerland
Taiwan
Tajikistan
Tanzania, United Republic Of
Thailand
Togo
Tokelau
Tonga
Trinidad And Tobago
Tunisia
Turkey
Turkmenistan
Turks And Caicos Islands
Tuvalu
Uganda
Ukraine
United Arab Emirates
United States Minor Outlying Islands
Uruguay
Uzbekistan
Vanuatu
Vatican City State
Venezuela
Vietnam
Virgin Islands (British)
Virgin Islands (U.S.)
Wallis And Futuna Islands
Western Sahara
Yemen
Zambia
Zimbabwe

By providing this information, you agree to the processing of your personal data by SANS as described in our Privacy Policy.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tags:
  • Offensive Operations, Pen Testing, and Red Teaming

Related Content

Blog
HackFest_blog_image.png
Offensive Operations, Pen Testing, and Red Teaming, Open-Source Intelligence (OSINT), Penetration Testing and Red Teaming
November 16, 2023
A Visual Summary of SANS HackFest Summit
Check out these graphic recordings created in real-time throughout the event for SANS HackFest Summit 2023
No Headshot Available
Alison Kim
read more
Blog
Offensive Operations, Pen Testing, and Red Teaming, Penetration Testing and Red Teaming
October 4, 2023
SEC670 Prep Quiz Answers
Answers for the SEC670 Prep Quiz. For more details about the course and the quiz, please clickthrough to see the quiz article.
370x370_jonathan-reiter.jpg
Jonathan Reiter
read more
Blog
Offensive Operations, Pen Testing, and Red Teaming, Penetration Testing and Red Teaming
October 4, 2023
Take The Prerequisite SEC670 Quiz
This ten question quiz will help you in determining if you are ready to take SEC670.
370x370_jonathan-reiter.jpg
Jonathan Reiter
read more
  • Company
  • Mission
  • Instructors
  • About
  • FAQ
  • Press
  • Contact Us
  • Careers
  • Policies
  • Training Programs
  • Work Study
  • Academies & Scholarships
  • Public Sector Partnerships
  • Law Enforcement
  • SkillsFuture Singapore
  • Degree Programs
  • Get Involved
  • Join the Community
  • Become an Instructor
  • Become a Sponsor
  • Speak at a Summit
  • Join the CISO Network
  • Award Programs
  • Partner Portal
Subscribe to SANS Newsletters
Receive curated news, vulnerabilities, & security awareness tips
United States
Canada
United Kingdom
Spain
Belgium
Denmark
Norway
Netherlands
Australia
India
Japan
Singapore
Afghanistan
Aland Islands
Albania
Algeria
American Samoa
Andorra
Angola
Anguilla
Antarctica
Antigua and Barbuda
Argentina
Armenia
Aruba
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belize
Benin
Bermuda
Bhutan
Bolivia
Bonaire, Sint Eustatius, and Saba
Bosnia And Herzegovina
Botswana
Bouvet Island
Brazil
British Indian Ocean Territory
Brunei Darussalam
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Cape Verde
Cayman Islands
Central African Republic
Chad
Chile
China
Christmas Island
Cocos (Keeling) Islands
Colombia
Comoros
Cook Islands
Costa Rica
Cote D'ivoire
Croatia (Local Name: Hrvatska)
Curacao
Cyprus
Czech Republic
Democratic Republic of the Congo
Djibouti
Dominica
Dominican Republic
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Eswatini
Ethiopia
Falkland Islands (Malvinas)
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
French Southern Territories
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guernsey
Guinea
Guinea-Bissau
Guyana
Haiti
Heard And McDonald Islands
Honduras
Hong Kong
Hungary
Iceland
Indonesia
Iraq
Ireland
Isle of Man
Israel
Italy
Jamaica
Jersey
Jordan
Kazakhstan
Kenya
Kiribati
Korea, Republic Of
Kosovo
Kuwait
Kyrgyzstan
Lao People's Democratic Republic
Latvia
Lebanon
Lesotho
Liberia
Liechtenstein
Lithuania
Luxembourg
Macau
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mayotte
Mexico
Micronesia, Federated States Of
Moldova, Republic Of
Monaco
Mongolia
Montenegro
Montserrat
Morocco
Mozambique
Myanmar
Namibia
Nauru
Nepal
Netherlands Antilles
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
North Macedonia
Northern Mariana Islands
Oman
Pakistan
Palau
Palestine
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Pitcairn
Poland
Portugal
Puerto Rico
Qatar
Reunion
Romania
Russian Federation
Rwanda
Saint Bartholemy
Saint Kitts And Nevis
Saint Lucia
Saint Martin
Saint Vincent And The Grenadines
Samoa
San Marino
Sao Tome And Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Sint Maarten
Slovakia
Slovenia
Solomon Islands
South Africa
South Georgia and the South Sandwich Islands
South Sudan
Sri Lanka
St. Helena
St. Pierre And Miquelon
Suriname
Svalbard And Jan Mayen Islands
Sweden
Switzerland
Taiwan
Tajikistan
Tanzania, United Republic Of
Thailand
Togo
Tokelau
Tonga
Trinidad And Tobago
Tunisia
Turkey
Turkmenistan
Turks And Caicos Islands
Tuvalu
Uganda
Ukraine
United Arab Emirates
United States Minor Outlying Islands
Uruguay
Uzbekistan
Vanuatu
Vatican City State
Venezuela
Vietnam
Virgin Islands (British)
Virgin Islands (U.S.)
Wallis And Futuna Islands
Western Sahara
Yemen
Zambia
Zimbabwe

By providing this information, you agree to the processing of your personal data by SANS as described in our Privacy Policy.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
  • Privacy Policy
  • Terms and Conditions
  • Do Not Sell/Share My Personal Information
  • Contact
  • Careers
© 2025 The Escal Institute of Advanced Technologies, Inc. d/b/a SANS Institute. Our Terms and Conditions detail our trademark and copyright rights. Any unauthorized use is expressly prohibited.
  • Twitter
  • Facebook
  • Youtube
  • LinkedIn