Hacker programming language. Fundamentals of hacking. Authentication check and basic security hacking. Find a suitable job

Fifteen years ago, Chris Kaspersky's epic Fundamentals of Hacking was the go-to book for every aspiring computer security researcher. However, time passes, and the knowledge published by Chris loses its relevance. The editors of Hacker have tried to update this voluminous work and move it from the days of Windows 2000 and Visual Studio 6.0 to the times of Windows 10 and Visual Studio 2017.

Authentication check

Authenticity verification (from the Greek authentikos - genuine) is the “heart” of the vast majority of defense mechanisms. We must make sure that the person he claims to be is working with the program and whether this person is allowed to work with the program at all!

The “person” can be not only the user, but also his computer or storage medium storing a licensed copy of the program. Thus, all protective mechanisms can be divided into two main categories:

  • protection based on knowledge (password, serial number);
  • protection based on possession (key disk, documentation).

If the defense is based on the mere assumption that its code will not be examined and/or changed, it is a poor defense. The lack of source code does not at all serve as an insurmountable obstacle to studying and modifying the application. Modern reverse engineering technologies allow you to automatically recognize library functions, local variables, stack arguments, data types, branches, loops, etc. And in the near future, disassemblers will probably learn to generate listings that are similar in appearance to high-level languages.

But even today, analyzing binary code is not labor-intensive enough to stop attackers for long. The huge number of constantly occurring hacks is the best confirmation of this. Ideally, knowledge of the protection algorithm should not affect its resistance, but this is not always achievable. For example, if the developer of a server program decides to set a limit on the number of concurrent connections processed in the demo version (as often happens), an attacker simply needs to find the processor instruction that performs such a check and delete it. Modification of a program can be prevented by constantly checking its integrity, but again the code that checks the integrity can be found and removed.


Step one. Warm-up

The algorithm of the simplest authentication mechanism consists of character-by-character comparison of the password entered by the user with a reference value stored either in the program itself (as is often the case) or outside it, for example in a configuration file or the registry (which is less common).

The advantage of such protection is its extremely simple software implementation. Its core actually consists of one line, which in C can be written like this:

If (strcmp(entered password, reference password)) (/* Password is incorrect */) else (/* Password OK*/)

Let's supplement this code with procedures for requesting a password and displaying comparison results, and then test the resulting program for strength, that is, for resistance to hacking:

Listing 1. An example of a simple authentication system

#include "stdafx.h" // The simplest authentication system - // character-by-character password comparison #include #include #define PASSWORD_SIZE 100 #define PASSWORD "myGOODpassword\n" // This hyphen is needed so as to // not snatch a hyphen from the string // entered by the user int main() ( // Counter of failed authentication attempts int count=0; // Buffer for the password entered by the user char buff; // Main authentication loop for(;;) ( // Request and read the user // password printf("Enter password:"); fgets(&buff,PASSWORD_SIZE,stdin); // Compare original and entered password if (strcmp(&buff,PASSWORD)) // If the passwords do not match, we “quarrel” printf("Wrong password\n"); // Otherwise (if the passwords are identical) // exit the authentication cycle else break; // Increment the counter of failed authentication attempts and, if all // attempts are exhausted, exit the program if (++count>3) return -1 ) // Since we are here, the user entered the correct // password printf("Password OK\n"); )

In popular movies, tough hackers easily penetrate any terribly protected systems, somehow incomprehensibly guessing the required password after several attempts. Why not try to follow their path?

It's not uncommon for passwords to be meaningful words like Ferrari, QWERTY, the names of your favorite hamsters, or the names of geographic locations. Guessing a password is akin to guessing with tea leaves - there are no guarantees of success, you can only rely on luck. And luck, as you know, is a proud bird - don’t put your finger in its mouth. Is there a more reliable hacking method?

Let's think about it. Since the reference password is stored in the body of the program, then, unless it is encrypted in some clever way, it can be discovered by a trivial inspection of the program's binary code. By going through all the text lines found in it, starting with those that most closely resemble a password, we will very quickly select the required key and open the program with it! Moreover, the viewing area can be significantly narrowed - in the vast majority of cases, compilers place all initialized variables in the data segment (in PE files it is placed in the .data or .rdata section). The exception is, perhaps, the early Baghdad (Borland) compilers with their manic love of inserting text strings into a code segment - directly at the place where they are called. This simplifies the compiler itself, but creates many problems. Modern operating systems, unlike old MS-DOS, prohibit modification of the code segment, and all variables placed in it are read-only. In addition, on processors with a separate caching system, they “clog” the code cache, getting there during read ahead, but the first time they are accessed, they are loaded again from slow RAM (second-level cache) into the data cache. The result is slowdowns and a drop in performance.

Well, let's make it the data section! All that remains is to find a convenient tool for viewing the binary file. You can, of course, press the F3 key in your favorite shell (FAR, for example) and, pressing the Page Down key with a brick, admire the running numbers until you get bored.

You can use any hex editor (QView, Hiew...) - whichever one suits your taste - but in the article, for reasons of clarity, the result of the DUMPBIN utility from the standard Microsoft Visual Studio package is presented. DUMPBIN is run from the Developer Command Prompt.

Let's set the utility to the executable file of our program, which contains the password, and ask it to print the rdata section containing initialized read-only data (key /SECTION:.rdata) in its “raw” form (key /RAWDATA:BYTES), specifying the > icon for redirecting output to a file (the program response takes up a lot of space, and only the “tail” fits on the screen).

Listing 2

> dumpbin /RAWDATA:BYTES /SECTION:.rdata passCompare1.exe > rdata.txt 004020E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .............. .. 004020F0: 18 30 40 00 68 30 40 00 45 6E 74 65 72 20 70 61 [email protected]@.Enter pa 00402100: 73 73 77 6F 72 64 3A 00 6D 79 47 4F 4F 44 70 61 ssword:.myGOODpa 00402110: 73 73 77 6F 72 64 0A 00 57 72 6F 6E 67 20 70 61 ssword..Wrong pa 00402120 : 73 73 77 6F 72 64 0A 00 50 61 73 73 77 6F 72 64 ssword..Password 00402130: 20 4F 4B 0A 00 00 00 00 00 00 00 00 00 00 00 00 OK......... ... 00402140: 00 00 00 00 90 0A C1 5B 00 00 00 00 02 00 00 00 ......A[........ 00402150: 48 00 00 00 24 22 00 00 24 14 00 00 00 00 00 00 H...$"..$.......

Among other things, there is one line that is painfully similar to the standard password (it is highlighted in bold in the text). Shall we test her? However, what is the point - judging by the source text of the program, this is really the desired password, which opens the protection, like a golden key. The compiler chose a too prominent place to store it - it wouldn’t hurt to hide the password better.

One way to do this is to force the reference password into a section of our own choosing. This possibility is not provided for by the standard, and therefore each developer of a compiler (strictly speaking, not a compiler, but a linker, but this is not important) is free to implement it in his own way or not to implement it at all. Microsoft Visual C++ provides a special pragma data_seg for this purpose, indicating in which section to place the following initialized variables. Uninitialized variables are located in the .bss section by default and are controlled by the bss_seg pragma accordingly.

In Listing 1, before the main function, we will add a new section in which we will store our password:

// From now on, all initialized variables will // be placed in the section.kpnc #pragma data_seg(".kpnc") #define PASSWORD_SIZE 100 #define PASSWORD "myGOODpassword\n" char passwd = PASSWORD; #pragma data_seg()

Inside the main function, we initialize the array:

// Now all initialized variables will once again be // placed in the default section, that is.rdata char buff="";

The condition for comparing strings in the loop has changed slightly:

If (strcmp(&buff,&passwd))

Let's run the DUMPBIN utility on the new executable file:

> dumpbin /RAWDATA:BYTES /SECTION:.rdata passCompare2.exe > rdata.txt 004020C0: D3 17 40 00 00 00 00 00 D8 11 40 00 00 00 00 00 [email protected].@..... 004020D0: 00 00 00 00 2C 11 40 00 D0 11 40 00 00 00 00 00 ....,.@.?.@..... 004020E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 004020F0: 18 30 40 00 68 30 40 00 45 6E 74 65 72 20 70 61 [email protected]@.Enter pa 00402100: 73 73 77 6F 72 64 3A 00 57 72 6F 6E 67 20 70 61 ssword:.Wrong pa 00402110: 73 73 77 6F 72 64 0A 00 50 61 73 73 77 6F 72 64 ssword..Password 00402120 : 20 4F 4B 0A 00 00 00 00 00 00 00 00 00 00 00 00 OK............ 00402130: 00 00 00 00 6F CB C4 5B 00 00 00 00 02 00 00 00 . ...oEA[........ 00402140: 48 00 00 00 14 22 00 00 14 14 00 00 00 00 00 00 H...."......... 00402150: 6F CB C4 5B 00 00 00 00 0C 00 00 00 14 00 00 00 oEA[............

Yeah, now there is no password in the data section and the hackers are “resting”! But don't rush to conclusions. Let's first display a list of all the sections present in the file:

> dumpbin passCompare2.exe Summary 1000 .data 1000 .kpnc 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text

The non-standard section.kpnc immediately attracts attention. Well, let's see what's in it?

> dumpbin /SECTION:.kpnc /RAWDATA passCompare2.exe RAW DATA #4 00404000: 6D 79 47 4F 4F 44 70 61 73 73 77 6F 72 64 0A 00 myGOODpassword..

Here it is, the password! Hidden, it’s called... You can, of course, be perverted and put secret data in the uninitialized data section (.bss) or even the code section (.text) - not everyone will think to look there, but such placement will not disrupt the functionality of the program. But don't forget about the possibility of automated search for text strings in a binary file. Whatever section contains the reference password, the filter will easily find it (the only problem is to determine which of the many text strings represents the desired key; you may need to sort through a dozen or two potential “candidates”).

Step two. Introducing the Disassembler

Okay, we found out the password. But how tedious it is to enter it from the keyboard every time before starting the program! It would be nice to hack it so that no password is requested at all, or the program perceives any entered password as correct.

Hack, you say? Well, it's not difficult! It’s much more problematic to decide what exactly to hack. The hacker's toolkit is extremely diverse, and there's just so much to be found here: disassemblers, debuggers, API and message spies, monitors for access to files (ports, registry), and unpackers of executable files, and... It's a little complicated for a novice code digger with all this equipment figure out!

However, spies, monitors, unpackers are secondary background utilities, and the hacker's main weapon is a debugger and disassembler.

So, the disassembler is applicable for studying compiled programs and is partially suitable for analyzing pseudo-compiled code. If so, it should be suitable for breaking the password protection of passCompare1.exe. The whole question is which disassembler to choose.

Not all disassemblers are the same. Among them there are also “intellectuals” who automatically recognize many constructions, such as prologues and epilogues of functions, local variables, cross-references, and there are also “simpletons” whose abilities are limited to the translation of machine commands into assembly instructions.

The most logical thing to do is to use the services of an intelligent disassembler (if you have one), but... let's not rush, but try to perform the entire analysis manually. Technology, of course, is a good thing, but it is not always at hand, and it would be nice to learn how to work in the field in advance. In addition, communication with a bad disassembler perfectly emphasizes the “goodies” of a good one.

Let's use the already familiar DUMPBIN utility, a real “Swiss Army knife” with many useful functions, among which is a disassembler. Let's disassemble the code section (as we remember, called .text), redirecting the output to a file, since it obviously won't fit on the screen:

> dumpbin /SECTION:.text /DISASM passCompare1.exe > code-text.txt

Let's look again at the data section (or another, depending on where the password is stored): see Listing 2.

Let's remember the password we found: myGOODpassword. Unlike Visual C++ 6.0, which Chris used, Visual C++ 2017 does not access initialized variables by hex offset, but substitutes the value directly into the code section. Thus, let's try to find the previously identified password in the disassembled listing using a trivial contextual search using any text editor.

0040107D: B9 08 21 40 00 mov ecx,offset ??_C@_0BA@PCMCJPMK@myGOODpassword?6?$AA@ 00401082: 8A 10 mov dl,byte ptr 00401084: 3A 11 cmp dl,byte ptr 00401086: 75 1A jne 004010A2 00401088: 84 D2 test dl,dl 0040108A: 74 12 je 0040109E

See, the central part of this listing is responsible for comparing the values ​​of the EAX and ECX registers. In the latter, as we see, the reference password is written in the first line of the listing, therefore, in the first - entered by the user. Then a comparison occurs and jumps are made to almost the same point: 0x4010A2 and 0x40109E. Let's take a look at what's there:

0040109E: 33 C0 xor eax,eax 004010A0: EB 05 jmp 004010A7 004010A2: 1B C0 sbb eax,eax 004010A4: 83 C8 01 or eax,1 004010A7: 85 C0 test eax,eax 004010A 9: 74 63 je 0040110E 004010AB: 0F 1F 44 00 00 nop dword ptr 004010B0: 68 18 21 40 00 push offset ??_C@_0BA@EHHIHKNJ@Wrong?5password?6?$AA@ 004010B5: E8 56 FF FF FF call _printf

The central role here is played by the test eax,eax instruction, located at offset 0x4010A7. If eax is 0, the next JE command jumps to 0x40110E. Otherwise, the line Wrong password is pushed to the top of the stack:

Push offset ??_C@_0BA@EHHIHKNJ@Wrong?5password?6?$AA@

and then a function call with a self-explanatory name:

Call_printf

This means that a non-zero EAX value indicates a false password, and zero indicates a true one.

Okay, then let’s move on to analyzing the valid branch of the program, which is done after the jump to 0x40110E. And lurking here is an instruction that puts the string Password OK on the top of the stack, after which the _printf procedure is called, which obviously prints the string to the screen:

0040110E: 68 28 21 40 00 push offset ??_C@_0N@MBEFNJID@Password?5OK?6?$AA@ 00401113: E8 F8 FE FF FF call _printf

The operational considerations are as follows: if you replace the JE command with JNE, the program will reject the true password as incorrect, and accept any incorrect password as true. And if you replace TEST EAX,EAX with XOR EAX,EAX, then after executing this command, the EAX register will always be equal to zero, no matter what password is entered.

All that's left to do is find these same bytes in the executable file and slightly correct them.

Step three. Surgical

Making changes directly to the executable file is serious business. Compressed by the already existing code, we have to be content with only what we have, and it will not be possible to move the teams apart, or even move them, throwing out “extra spare parts” from the protection. After all, this would lead to a shift in the offsets of all other commands, while the values ​​of pointers and jump addresses would remain unchanged and would begin to point in completely different places!

Well, it’s quite easy to deal with “throwing out spare parts” - just fill the code with NOP commands (the opcode of which is 0x90, and not 0x0, as many novice code diggers for some reason think), that is, an empty operation (in fact, NOP is just another form of writing the instruction XCHG EAX,EAX - if interested). With “sliding” it’s much more difficult! Fortunately, PE files always contain a lot of “holes” left over from alignment, and you can place your code or data in them.

But isn't it easier to simply compile the assembled file, having previously made the required changes to it? No, it’s not simpler, and here’s why: if the assembler does not recognize pointers passed to functions (and as we saw, our disassembler could not distinguish them from constants), it, accordingly, will not bother to properly correct them, and, naturally, the program will not work will not be.

We have to cut the program live. The easiest way to do this is with the Hiew utility, which “digests” the PE file format and thereby simplifies the search for the desired fragment. Any version of this hex editor will do. For example, I used the far from newest version 6.86, which gets along well with Windows 10. Let’s launch it by specifying the file name in the command line hiew32 passCompare1.exe, double pressing the Enter key, switch to assembler mode and use the F5 key to go to the required address. As we remember, the TEST command, which checked the result for equality to zero, was located at address 0x4010A7.

So that Hiew can distinguish the address from the offset in the file itself, we precede it with a dot character: .4010A7.

004010A7: 85 C0 test eax,eax 004010A9: 74 63 je 0040110E

Yep, just what we need! Press the F3 key to put Hiew into editing mode, move the cursor to the TEST EAX,EAX command and, pressing the Enter key, replace it with XOR EAX,EAX.

004010A7: 33 C0 xor eax,eax 004010A9: 74 63 je 0040110E

Having noticed with satisfaction that the new command fits neatly into the previous one, press the F9 key to save the changes to disk, and then exit Hiew and try to run the program, entering the first password that comes to mind:

>passCompare1 Enter password:Hello, hat! Password OK

Happened! The defense has fallen! Okay, but how would we act if Hiew didn’t know how to “digest” PE files? Then we would have to resort to contextual search. Let's turn our attention to the hexadecimal dump located by the disassembler to the left of the assembler commands. Of course, if you try to find the sequence 85 C0 - the command code TEST EAX,EAX, nothing good will come of it - there may be several hundred of these TESTs in the program, or even more. But the jump address is most likely different in all branches of the program, and the substring TEST EAX,EAX/JE 0040110E has a good chance of being unique. Let's try to find the corresponding code in the file: 85 C0 74 63 (in Hiew, just press the F7 key).

Oops! Only one entry was found, which is what we actually need. Let's now try to modify the file directly in hex mode, without going into assembler. Let's take note along the way - inversion of the least significant bit of the command code leads to a change in the transition condition to the opposite, that is, 74 JE -> 75 JNE.



Works? I mean, the defense has gone completely crazy - it doesn’t recognize the true passwords, but happily welcomes the others. Amazing!


To be continued?

So, you've read (have you read?) the opening passage of Chris Kaspersky's classic book, Fundamentals of Hacking, with a modern twist. Have we been able to update this knowledge to the current level? Is it worth continuing? Share your opinion on

But what about Spolsky’s advice to learn 1 language per year to develop your horizons? :)

Mikhail Flenov

I don’t know such advice and I don’t recommend it. This makes your horizons better, but not better. When you know 3-4 languages, it’s better to learn one new algorithm at a time to develop your horizons. Even if you never use this algorithm.

Igor

Question from the series "What to do to become a hacker"
To be a hacker you need to:
1. Learn assembly language. Other languages ​​are not needed, the main thing is to know assembler.
2. Wear a sweater and grow a beard. It doesn't matter that you're a girl.
3. Install Linux. It doesn't matter why. Every hacker should have Linux.
In principle, the list can be continued indefinitely. A hacker is first and foremost a specialist, and not a copy of cliches from films and newspapers. Achieve success in one area and you will be happy :).

Zhenya

I think algorithms need to be understood, not memorized. As for the language, you can read a book on 1 language a year, just to have an idea of ​​its capabilities. And then, if necessary, use it

Sergey

There are languages ​​in which you can write “everything I need,” as Mikhail put it. And there are languages ​​in which you can write anything in principle. The second type, I think, includes assembler, C and C++. The rest are either for highly specialized tasks (php, etc.), or are inferior to them in speed (c#, java, etc.). What to choose, everyone decides for themselves, due to their tasks. Everyone should become familiar with the mathematical principles of programming - these are the basics.

klamm

Now, what about Python)

In my opinion, it is not so hacker, it is very simple in syntax, simpler than C#. If we take that the C# and Java languages ​​are high-level languages, then Python is a super-high-level language, since it is purely for application programming; when writing programs in it, the main thing is to be able to use libraries.

And everything that cannot be written in Python is written in C and called from a Python program.

klamm

About how to become a hacker,

catb. org/~esr/faqs/hacker-howto. html

alex

A hacker (from the English hack - to cut) is an extremely qualified IT specialist, a person who understands the very depths of the work of computer systems.
Recently, the concept of a hacker has been leveled almost to the concept of an advanced user. In my opinion, a hacker is a person who has perfect knowledge of assembler and C, and is capable of writing, if not an operating system, then an algorithmic language, which is what they did with varying success during their studies at the institute. A hacker who only knows php or html sounds ridiculous.

Nick

2alex, I think if you know PHP, really know PHP, then in addition you will somehow learn js, not to mention understanding how to break and bypass website security...

Ancort

ASM, C++ and Lisp (somehow they forgot) - these are “hacker” languages, IMHO

Vladimir

I also somehow like C# better, in the OOP style the code is somehow easier to perceive, or something

Ruslan Dauthadzhiev

Again there is a debate about which language is cooler?? An eternal debate on this topic. Regarding Python, it is a purely scripting language for mobile platforms and the web. Supports third-party GUI builders, such as QT. I don’t see any particular coolness in this language. You can program perfectly even in QBasic - it all depends on the imagination and experience of the programmer. Just because a language is outdated doesn't mean it's "dead".

Ruslan Dauthadzhiev

Alex, nowadays programmers are people who can simply work in MS Word :). What would you like? So that a person is immediately born with the opportunity to write his own OS? Everyone starts small. It all depends on a person’s desire to learn and learn something new.

We already understand that you are a “Hacker” and wrote your own language at the university. Thank you..

The first hackers can be considered that small group of people, consisting of experienced programmers and network wizards, who several decades ago stood at the origins of the creation of early microcomputers and participated in ARPAnet experiments. Hacking computers and telephone networks has become a symptom of a hacker culture, which is actually much more complex and is not limited to hacking. How to join this community, acquire the necessary skills, learn to think like a hacker and earn respect and reputation in this environment, you will learn from this article.

Steps

Part 1

Acquiring Basic Skills

    Switch to a Unix-like operating system, such as Linux. Unix is ​​a popular operating system, often used for servers and which gave impetus to the development of the Internet. Although you can use the Internet without knowing Unix, you cannot be an Internet hacker without understanding Unix. For this very reason, today's hacker culture is very Unix-centric. Unix, like Linux, can be used alongside Windows on the same computer. Download Linux or ask a Linux user to help you install the system.

    Help test and debug open source programs. Those who test and debug open source programs are also revered. In this imperfect world, we inevitably spend the largest portion of a program's development time in the debugging phase. This is why any thoughtful open source author will tell you that good beta testers (who know how to clearly describe symptoms, are good at localizing problems, can correct typos, and use a few simple diagnostic routines) are worth their weight in gold.

    • If you are a beginner, try to find a program in development that interests you and become a good beta tester. There is a very natural progression from helping to test programs to helping to debug them and then to helping to modify them. You will learn a lot this way and generate good karma in your relationships with people who will help you later.
  1. Post useful information. Another good thing is to select and accumulate useful and interesting information on web pages or documents such as FAQ (frequently asked questions and answers) and make them publicly available. The hosts of major technical FAQs are almost as respected as the authors of open source software.

    Help keep infrastructure running. Hacker culture (and Internet engineering) is volunteer-based. There is a lot of necessary, but not particularly effective, work that needs to be done to maintain the process: administering mailing lists, moderating news groups, managing large software archives, developing RFCs and other technical standards. People who do this kind of thing well are highly respected, because everyone knows that this kind of work takes a lot of time and is not as fun as playing with codes. This work shows dedication.

  2. Serve the hacker culture itself. Finally, you can serve and spread the culture itself. But you shouldn't do this until you've been at it for a long time and become well known for one of the first four things. There are no clear leaders in hacker culture, but there are "culture heroes", "tribal elders", historians and speakers. When you live in these trenches long enough, you can grow into one of these people.

    • But beware: hackers are wary of their loud-mouthed tribal elders, so the apparent achievement of this kind of glory is fraught with danger. Instead of striving for this, it is better for you not to care about it and then everything will come by itself, and only then you can become modest and merciful in your status.
  • Some companies hire hackers to check how secure their systems are. So you can make good money on this!
  • Try not to get caught and Not do some hacking.
  • Write well in your native language. According to a common stereotype, programmers are not very literate, but in fact, many hackers are very good at speaking the language.
  • Lisp is worth learning for the profound enlightenment you'll gain when you finally master it. This knowledge will make you an excellent programmer for the rest of your life, even if you never really use Lisp itself. You can get initial experience with Lisp in the code editing mode of the Emacs text editor or the Script-Fu plugin for the graphics editor GIMP.
  • Perl makes sense to learn for practical reasons: it is very widely used for active web pages and system administration, so even if you never have to write Perl, you should learn to read it. Many people use Perl to avoid programming in C, which is resource-intensive.
  • Test your knowledge on websites you create.
  • Use your knowledge and skills for good. Being a good hacker is much safer and more profitable for everyone than being a bad hacker. Bad hackers don't have a very good life - they have to go into hiding to avoid problems with the law.
  • Always be careful. Illegal activities can have very serious consequences, and nothing on the Internet is truly anonymous.
  • Don't get involved in anything that could lead to trouble.
  • Ask local companies if they need security systems checked.

Warnings

  • Hacking is an illegal act that can result in serious penalties. Hacking is a crime and is punishable by law.

Programming is a hacker's main tool. If you don't already know any computer language, then I recommend starting with Python. It is clearly designed, thoroughly documented and relatively friendly to beginners. Despite its friendly attitude towards beginners, it is not just a toy, but a very powerful and flexible language, which is excellent for large projects. I have already written a more detailed assessment of Python. There is an excellent beginner's guide and official tutorial on the Python website, and you can also find excellent tutorials elsewhere, one of them being Computer Science Circles.

I used to recommend Java as a language for early learning, but given these criticisms, I changed my mind (see also: “The Pitfalls of Java as a First Programming Language”). A hacker cannot approach a problem like a plumber in a store solves it, he must know what exactly does every component. Therefore, now I am in the opinion that it would be better to study the C and Lisp languages ​​at the beginning, and only after them Java.

There is perhaps a more general approach to this. When you have a good tool to create something, but there is too much language for it and learning it is difficult. Not only programming languages ​​can handle the task, but also various web frameworks such as RubyOnRails, CakePHP, Django can solve the task easily, but will leave you with superficial knowledge and you will not be able to solve a more complex problem or understand the problem if it is quick and the easy solution will not work correctly.

If you decide to dive into serious programming, then you must learn the core of the Unix OS - the C language (pronounced Si). C++ (pronounced Sea Place Place) is very closely related to C, if you know one, then learning the other will not be difficult. Although they are not beginner languages. And, in fact, the more you avoid C programming, the more productive you will be.

C is very efficient and very economical in terms of machine resources. However, using the C language will be effective where manual management of low-level resources such as memory is required. All this low-level code is complex and easy to make mistakes, and also requires a huge amount of your time for debugging (finding and fixing errors). Taking into account the power of modern computers, you can make a compromise decision - the smart thing to do is to choose a language that uses computer resources less efficiently, but more effective in terms of time spent on implementation. That trade-off is Python.

Other languages ​​of prime importance to hackers are Perl and LISP. Perl makes sense to learn for practical reasons: it is very widely used for active web pages and system administration, so even if you never have to write Perl, you should learn to read it. Many people use Perl for this purpose, but I advise you to use Python and avoid C programming unless the task requires economical use of machine resources. You need to understand such code.

LISP is valuable to learn for another reason - you will gain deep knowledge by learning this language to the end. This knowledge will make you an excellent programmer for the rest of your life, even if you never really use LISP itself. (Initial LISP programming skills can be acquired quite easily by creating and modifying extensions to the Emacs text editor or creating Script-Fu plugins for GIMP).

In fact, it's better to learn all five: Python, C/C++, Java, Perl, and LISP. Besides being the most important hacking languages, they demonstrate very different approaches to programming and each will teach valuable approaches.

But keep in mind that you won't reach the level of a hacker or even a regular programmer just by collecting languages ​​- you have to learn to think about how to program in a general way, regardless of any language. To become a true hacker, you must reach a level of knowledge where you can learn a new language in a matter of days, simply by looking at the manual for that language and linking it to your existing knowledge. And to become like this, you need to know several languages ​​that are very different in nature.

I cannot give complete instructions here on how to learn programming - it is a complex art. But I can tell you that books and courses won't do that either - many may majority The best hackers are self-taught. You can learn the functionality of languages ​​(a small part of knowledge) from books, but the type of thinking that makes this knowledge applicable to life can only be acquired through practice and through a certain period of study. What programming can actually teach is (a) reading source code and (b) writing source code .

Peter Norvig, one of Google's leading hackers and co-author of a popular textbook on AI (Artificial Intelligence), wrote a wonderful article called Teach Yourself Programming in Ten Years. His “recipe for successful programming” is worth paying special attention to.

Learning to program is like learning to write good natural language. The best way to do this is to read something written by recognized masters of literature, then write a little yourself; read a little more, write a little more; read even more - write even more... And repeat this until your programs look like a powerful and organized model.

I talked more about this process in How To Learn Hacking. This is a simple set of instructions that is not easy to follow.

Finding good source code to study used to be difficult because there were very few large programs available in source code for young hackers to study and experiment with. Now the situation has changed dramatically: source code programs, development tools, and entire operating systems (all created by hackers) are now widely available. Which brings me straight to the next section...