Shellcode: Difference between revisions

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search
imported>GreenC bot
Reformat 1 archive link. Wayback Medic 2.5 per WP:USURPURL and JUDI batch #21aa
 
imported>Curlyquote
m Punctuation
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
{{Short description|Small piece of code used as a payload to exploit a software vulnerability}}
{{Short description |Code intended as a payload to exploit a software vulnerability}}
{{Redirect|Shell code|code written in a shell's command language|Shell script}}
{{no footnotes|date=July 2025}}
{{Redirect|Alphanumeric executable|executable code presented in hexadecimal format|Hex file (disambiguation)}}
{{Redirect |Shell code|code written in a shell's command language|Shell script}}
{{Redirect |Alphanumeric executable|executable code presented in hexadecimal format|Hex file (disambiguation)}}


In [[hacker (computer security)|hacking]], a '''shellcode''' is a small piece of code used as the [[Payload (computing)|payload]] in the [[exploit (computer security)|exploitation]] of a software [[Vulnerability (computing)|vulnerability]]. It is called "shellcode" because it typically starts a [[Shell (computing)|command shell]] from which the attacker can control the compromised machine, but any piece of code that performs a similar task can be called shellcode. Because the function of a payload is not limited to merely spawning a shell, some have suggested that the name shellcode is insufficient.<ref>{{cite book  
'''Shellcode''' is [[executable code]] intended to be used as a [[Payload (computing)|payload]] for [[exploit (computer security)|exploiting]] a [[software]] [[Vulnerability (computing)|vulnerability]]. The term includes ''shell'' because the attack originally described an attack that opens a [[Shell (computing)|command shell]] that the attacker can use to control the target machine, but any code that is injected to gain access that is otherwise not allowed can be called shellcode. For this reason, some consider the name ''shellcode'' to be inaccurate.<ref>{{cite book |title=Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals  
|title=Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals  
|author-first1=James C. |author-last1=Foster |author-first2=Mike |author-last2=Price |publisher=Elsevier Science & Technology Books |date=2005-04-12 |isbn=1-59749-005-9 |url=https://books.google.com/books?id=ZNI5dvBSfZoC}}</ref>
|author-first1=James C. |author-last1=Foster |author-first2=Mike |author-last2=Price |publisher=Elsevier Science & Technology Books |date=2005-04-12 |isbn=1-59749-005-9 |url=https://books.google.com/books?id=ZNI5dvBSfZoC}}</ref> However, attempts at replacing the term have not gained wide acceptance. Shellcode is commonly written in [[machine code]].


When creating shellcode, it is generally desirable to make it both small and executable, which allows it to be used in as wide a variety of situations as possible.<ref name="anley_koziol_2007">{{Cite book |title=The shellcoder's handbook: discovering and exploiting security holes |date=2007 |publisher=Wiley |author-first1=Chris |author-last1=Anley |author-first2=Jack |author-last2=Koziol |isbn=978-0-470-19882-7 |edition=2 |location=Indianapolis, Indiana, UA |oclc=173682537}}</ref> In assembly code, the same function can be performed in a multitude of ways and there is some variety in the lengths of opcodes that can be used for this purpose; good shellcode writers can put these small opcodes to use to create more compact shellcode.<ref>{{Cite book |title=Buffer overflow attacks: detect, exploit, prevent |date=2005 |publisher=Syngress |author-last=Foster |author-first=James C. |isbn=1-59749-022-9 |location=Rockland, MA, USA |oclc=57566682}}</ref> Some have reached the smallest possible size while maintaining stability.<ref>{{Cite web |title=Tiny Execve sh - Assembly Language - Linux/x86 |url=https://github.com/geyslan/SLAE/blob/master/4th.assignment/tiny_execve_sh.asm |access-date=2021-02-01 |website=GitHub}}</ref>
An attack commonly injects [[data]] that consists of executable code into a [[process (computing)|process]] before or as it exploits a vulnerability to gain control. The [[program counter]] is set the shellcode [[entry point]] so that that the shellcode runs. Deploying shellcode is often accomplished by including the code in a file that a vulnerable process downloads and then loads into its memory.


== Types of shellcode ==
Common wisdom dictates that to maximum effectiveness, a shellcode payload should be small.<ref name="anley_koziol_2007">{{Cite book |title=The shellcoder's handbook: discovering and exploiting security holes |date=2007 |publisher=Wiley |author-first1=Chris |author-last1=Anley |author-first2=Jack |author-last2=Koziol |url=https://archive.org/details/Wiley.The.Shellcoders.Handbook.2nd.Edition.Aug.2007/ |isbn=978-0-470-19882-7 |edition=2 |location=Indianapolis, Indiana, UA |oclc=173682537}}</ref> [[Machine code]] provides the flexibility needed to accomplish the goal. Shellcode [[hacker |authors]] leverage small opcodes to create compact shellcode.<ref>{{Cite book |title=Buffer overflow attacks: detect, exploit, prevent |date=2005 |publisher=Syngress |author-last=Foster |author-first=James C. |isbn=1-59749-022-9 |location=Rockland, MA, USA |oclc=57566682}}</ref><ref>{{Cite web |title=Tiny Execve sh - Assembly Language - Linux/x86 |url=https://github.com/geyslan/SLAE/blob/master/4th.assignment/tiny_execve_sh.asm |access-date=2021-02-01 |website=GitHub}}</ref>
Shellcode can either be ''local'' or ''remote'', depending on whether it gives an attacker control over the machine it runs on (local) or over another machine through a network (remote).


=== Local ===
== Types ==
''Local'' shellcode is used by an attacker who has limited access to a machine but can exploit a vulnerability, for example a [[buffer overflow]], in a higher-privileged process on that machine. If successfully executed, the shellcode will provide the attacker access to the machine with the same higher privileges as the targeted process.


=== Remote ===
; Local
''Remote'' shellcode is used when an attacker wants to target a vulnerable process running on another machine on a [[local area network|local network]], [[intranet]], or a [[internet|remote network]]. If successfully executed, the shellcode can provide the attacker access to the target machine across the network. Remote shellcodes normally use standard [[Internet protocol suite|TCP/IP]] [[Stream socket|socket]] connections to allow the attacker access to the shell on the target machine. Such shellcode can be categorized based on how this connection is set up: if the shellcode establishes the connection it is called a "reverse shell", or a ''connect-back'' shellcode because the shellcode ''connects back'' to the attacker's machine. On the other hand, if the attacker establishes the connection, the shellcode is called a ''bindshell'' because the shellcode ''binds'' to a certain port on the victim's machine. There's a peculiar shellcode named ''bindshell random port'' that skips the binding part and listens on a random port made available by the [[operating system]]. Because of that, the ''[https://github.com/geyslan/SLAE/blob/master/improvements/tiny_shell_bind_tcp_random_port_x86_64.asm bindshell random port]'' became the smallest stable bindshell shellcode for [[X86-64|x86_64]] available to this date. A third, much less common type, is ''socket-reuse'' shellcode. This type of shellcode is sometimes used when an exploit establishes a connection to the vulnerable process that is not closed before the shellcode is run. The shellcode can then ''re-use'' this connection to communicate with the attacker. Socket re-using shellcode is more elaborate, since the shellcode needs to find out which connection to re-use and the machine may have many connections open.<ref>{{cite web |url=http://www.blackhatlibrary.net/Shellcode/Socket-reuse |title=Shellcode/Socket-reuse |author=BHA |date=2013-06-06 |access-date=2013-06-07}}</ref>
A local shellcode attack allows an attacker to gain elevated access privilege on their computer. In some cases, exploiting a vulnerability can be achieved by causing an error such as [[buffer overflow]]. If successful, the shellcode enables access to the machine via the elevated privileges granted to the targeted process.


A [[Firewall (computer)|firewall]] can be used to detect outgoing connections made by connect-back shellcode as well as incoming connections made by bindshells. They can, therefore, offer some protection against an attacker, even if the system is vulnerable, by preventing the attacker from connecting to the shell created by the shellcode. One reason why socket re-using shellcode is sometimes used is that it does not create new connections and, therefore, is harder to detect and block.
; Remote
A remote shellcode attack targets a process running on a remote machine {{endash}} on the same [[local area network]], [[intranet]], or on the [[internet]]. If successful, the shellcode provides access to the target machine across the network. The shellcode normally opens a [[Internet protocol suite| TCP/IP]] [[Stream socket| socket]] connection to allow access to a shell on the target machine.  


=== Download and execute ===
A remote shellcode attack can be categorized by its behavior. If the shellcode establishes the connection it is called a ''reverse shell'', or a ''connect-back'' shellcode. On the other hand, if the attacker establishes the connection, the shellcode is called a ''bindshell'' because the shellcode ''binds'' to a certain port on the victim's machine. A ''bindshell random port'' skips the binding part and listens on a random port.{{efn|The ''[https://github.com/geyslan/SLAE/blob/master/improvements/tiny_shell_bind_tcp_random_port_x86_64.asm bindshell random port]'' is the smallest stable bindshell shellcode for [[X86-64|x86_64]] available to date.}} A ''socket-reuse'' shellcode is an exploit that establishes a connection to the vulnerable process that is not closed before the shellcode runs so that the shellcode can re-use the connection to allow remote access. Socket re-using shellcode is more elaborate, since the shellcode needs to find out which connection to re-use and the machine may have many open connections.<ref>{{cite web |url=http://www.blackhatlibrary.net/Shellcode/Socket-reuse |title=Shellcode/Socket-reuse |author=BHA |date=2013-06-06 |access-date=2013-06-07}}</ref>
''Download and execute'' is a type of remote shellcode that ''[[downloads]] and [[Execution (computers)|executes]]'' some form of malware on the target system. This type of shellcode does not spawn a shell, but rather instructs the machine to download a certain executable file off the network, save it to disk and execute it. Nowadays, it is commonly used in [[drive-by download]] attacks, where a victim visits a malicious webpage that in turn attempts to run such a download and execute shellcode in order to install software on the victim's machine. A variation of this type of shellcode downloads and [[Dynamic loading|loads]] a [[Library (computing)|library]].<ref>{{cite web |url=http://skypher.com/index.php/2010/01/11/download-and-loadlibrary-shellcode-released/ |title=Download and LoadLibrary shellcode released |author=SkyLined |date=2010-01-11 |access-date=2010-01-19 |url-status=dead |archive-url=https://web.archive.org/web/20100123014637/http://skypher.com/index.php/2010/01/11/download-and-loadlibrary-shellcode-released/ |archive-date=2010-01-23}}</ref><ref>{{cite web |url=http://code.google.com/p/w32-dl-loadlib-shellcode/ |title=Download and LoadLibrary shellcode for x86 Windows |date=2010-01-11 |access-date=2010-01-19}}</ref> Advantages of this technique are that the code can be smaller, that it does not require the shellcode to spawn a new process on the target system, and that the shellcode does not need code to clean up the targeted process as this can be done by the library loaded into the process.


=== Staged ===
A [[Firewall (computer)|firewall]] can detect outgoing connections made by connect-back shellcode as well as incoming connections made by bindshells, and therefore, offers some protection against an attack. Even if the system is vulnerable, a firewall can prevent the attacker from connecting to the shell created by the shellcode. One reason why socket re-using shellcode is used is that it does not create new connections and, therefore, is harder to detect and block.
When the amount of data that an attacker can inject into the target process is too limited to execute useful shellcode directly, it may be possible to execute it in stages. First, a small piece of shellcode (stage 1) is executed. This code then downloads a larger piece of shellcode (stage 2) into the process's memory and executes it.


=== Egg-hunt ===
; Download and execute
This is another form of ''staged'' shellcode, which is used if an attacker can inject a larger shellcode into the process but cannot determine where in the process it will end up. Small ''egg-hunt'' shellcode is injected into the process at a predictable location and executed. This code then searches the process's address space for the larger shellcode (the ''egg'') and executes it.<ref>{{cite web |url=http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf  
A download and execute shellcode attack [[downloads]] and [[Execution (computers)|executes]] [[malware]] on the target system. This type of shellcode does not spawn a shell, but rather instructs the machine to download a certain executable file from the network and execute it. Nowadays, it is commonly used in [[drive-by download]] attacks, where a victim visits a malicious webpage that in turn attempts to run such a download and execute shellcode in order to install software on the victim's machine.
 
A variation of this attack downloads and [[Dynamic loading| loads]] a [[Library (computing)|library]].<ref>{{cite web |url=http://skypher.com/index.php/2010/01/11/download-and-loadlibrary-shellcode-released/ |title=Download and LoadLibrary shellcode released |author=SkyLined |date=2010-01-11 |access-date=2010-01-19 |url-status=dead |archive-url=https://web.archive.org/web/20100123014637/http://skypher.com/index.php/2010/01/11/download-and-loadlibrary-shellcode-released/ |archive-date=2010-01-23}}</ref><ref>{{cite web |url=http://code.google.com/p/w32-dl-loadlib-shellcode/ |title=Download and LoadLibrary shellcode for x86 Windows |date=2010-01-11 |access-date=2010-01-19}}</ref> Advantages of this technique are that the code can be smaller, that it does not require the shellcode to spawn a new process on the target system, and that the shellcode does not need code to clean up the targeted process as this can be done by the library loaded into the process.
 
; Staged
When the amount of data that an attacker can inject into the target process is too limited to achieve the desired effect, it may be possible to deploy shellcode in stages that progressively provide more access. The first stage might do nothing more than download the second stage than then provides the desired access.
 
; Egg-hunt
An egg-hunt shellcode attack is a staged attack in which the attacker can inject shellcode into a process but does not know where in the process it is. A second-stage shellcode, generally smaller than the first, is injected into the process to search the process's address space for the first shellcode (the ''egg'') and executes it.<ref>{{cite web |url=http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf  
|title=Safely Searching Process Virtual Address Space  
|title=Safely Searching Process Virtual Address Space  
|author=Skape |publisher=nologin |date=2004-03-09 |access-date=2009-03-19}}</ref>
|author=Skape |publisher=nologin |date=2004-03-09 |access-date=2009-03-19}}</ref>


=== Omelette ===
; Omelet
This type of shellcode is similar to ''egg-hunt'' shellcode, but looks for multiple small blocks of data (''eggs'') and recombines them into one larger block (the ''omelette'') that is subsequently executed. This is used when an attacker can only inject a number of small blocks of data into the process.<ref>{{cite web |url=http://skypher.com/wiki/index.php?title=Shellcode/w32_SEH_omelet_shellcode |title=w32 SEH omelet shellcode |author=SkyLined |publisher=Skypher.com |date=2009-03-16 |access-date=2009-03-19 |url-status=dead |archive-url=https://web.archive.org/web/20090323030636/http://skypher.com/wiki/index.php?title=Shellcode%2Fw32_SEH_omelet_shellcode |archive-date=2009-03-23}}</ref>
An omelet shellcode attack, similar to egg-hunt, looks for multiple small blocks of data (''eggs'') and combines them into a larger block (''omelet'') that is then executed. This is used when an attacker is limited on the size of injected code but can inject multiple.<ref>{{cite web |url=http://skypher.com/wiki/index.php?title=Shellcode/w32_SEH_omelet_shellcode |title=w32 SEH omelet shellcode |author=SkyLined |publisher=Skypher.com |date=2009-03-16 |access-date=2009-03-19 |url-status=dead |archive-url=https://web.archive.org/web/20090323030636/http://skypher.com/wiki/index.php?title=Shellcode%2Fw32_SEH_omelet_shellcode |archive-date=2009-03-23}}</ref>
 
==Encoding==
Shellcode is often written in order to work around the restrictions on the data that a process will allow. General techniques include:


==Shellcode execution strategy==
; Optimize for size
An exploit will commonly inject a shellcode into the target process before or at the same time as it exploits a vulnerability to gain control over the [[program counter]]. The program counter is adjusted to point to the shellcode, after which it gets executed and performs its task. Injecting the shellcode is often done by storing the shellcode in data sent over the network to the vulnerable process, by supplying it in a file that is read by the vulnerable process or through the command line or environment in the case of local exploits.
Optimize the code to decrease its size.


==Shellcode encoding==
; Self-modifying code
Because most processes filter or restrict the data that can be injected, shellcode often needs to be written to allow for these restrictions. This includes making the code small, null-free or [[alphanumeric code|alphanumeric]]. Various solutions have been found to get around such restrictions, including:
[[Self-modifying code |Modify its own code]] before executing it to use byte values that are otherwise restricted.
* Design and implementation optimizations to decrease the size of the shellcode.
* Implementation modifications to get around limitations in the range of bytes used in the shellcode.
* [[Self-modifying code]] that modifies a number of the bytes of its own code before executing them to re-create bytes that are normally impossible to inject into the process.


Since [[intrusion detection]] can detect signatures of simple shellcodes being sent over the network, it is often encoded, made self-decrypting or [[polymorphic code|polymorphic]] to avoid detection.
; Encryption
To avoid [[intrusion detection]], encode as self-decrypting or [[polymorphic code |polymorphic]].


===Percent encoding===
; Character encoding
Exploits that target browsers commonly encode shellcode in a JavaScript string using [[percent-encoding]], escape sequence encoding "{{mono|\uXXXX}}" or [[Character encodings in HTML|entity encoding]].<ref>{{cite web |url=http://www.iss.net/security_center/reference/vuln/JavaScript_Large_Unescape.htm |title=JavaScript large number of unescape patterns detected |archive-url=https://web.archive.org/web/20150403203325/http://www.iss.net/security_center/reference/vuln/JavaScript_Large_Unescape.htm |archive-date=2015-04-03 |url-status=dead}}</ref> Some exploits also obfuscate the encoded shellcode string further to prevent detection by [[intrusion detection|IDS]].
An attack that targets a browser might obfuscate shellcode in a [[JavaScript]] string using an expanded character encoding.<ref>{{cite web |url=http://www.iss.net/security_center/reference/vuln/JavaScript_Large_Unescape.htm |title=JavaScript large number of unescape patterns detected |archive-url=https://web.archive.org/web/20150403203325/http://www.iss.net/security_center/reference/vuln/JavaScript_Large_Unescape.htm |archive-date=2015-04-03 |url-status=dead}}</ref> For example, on the [[IA-32]] architecture, here's two unencoded no-operation instructions (used in a [[NOP slide]]):


For example, on the [[IA-32]] architecture, here's how two <code>[[NOP (code)|NOP]]</code> (no-operation) instructions would look, first unencoded:
  90            NOP
  90            NOP
  90            NOP
  90            NOP


{|class=wikitable
As encoded:
|+ Encoded double-NOPs:
* [[percent-encoding |Percent encoded]]: {{code|unescape("%u9090")}}
|-
* [[Unicode]] literal: {{code|\u9090}}
! scope=row | percent-encoding
* [[Character encodings in HTML|HTML/XML character reference]] : {{code|&#x9090;}} or {{code|&#37008;}}
| {{code|unescape("%u9090")}}
|-
! scope=row | unicode literal
| {{code|"\u9090"}}
|-
! scope=row | HTML/XML entity
| {{code|"&#x9090;"}} or {{code|"&#37008;"}}
|}


This instruction is used in [[NOP slide]]s.
; Null-free
Shellcode must be written without zero-value bytes when it is intended to be injected into a [[null-terminated string]] that is copied in the target process via the usual algorithm (i.e. [[strcpy]]) of ending the copy at the first zero byte {{endash}} called the [[null character]] in common [[character set]]s. If the shellcode contained a null, the copy would be truncated and not function properly. To produce null-free code from code that contains nulls, one can replace machine instructions that contain zeroes with instructions that don't. For example, on the [[IA-32]] architecture the instruction to set register EAX to 1 contains zeroes as part of the literal (<code>1</code> expands to <code>0x00000001</code>).


===Null-free shellcode===
B8 01000000    [[MOV (x86 instruction)|MOV]] EAX,1
Most shellcodes are written without the use of [[Null character|null]] bytes because they are intended to be injected into a target process through [[null-terminated string]]s. When a null-terminated string is copied, it will be copied up to and including the first null but subsequent bytes of the shellcode will not be processed. When shellcode that contains nulls is injected in this way, only part of the shellcode would be injected, making it incapable of running successfully.


To produce null-free shellcode from shellcode that contains [[Null character|null]] bytes, one can substitute machine instructions that contain zeroes with instructions that have the same effect but are free of nulls. For example, on the [[IA-32]] architecture one could replace this instruction:
The following instructions accomplish the same goal (EAX containing 1) without embedded zero bytes by first setting EAX to 0, then incrementing EAX to 1:
B8 01000000    [[MOV (x86 instruction)|MOV]] EAX,1          // Set the register EAX to 0x00000001
which contains zeroes as part of the literal (<code>1</code> expands to <code>0x00000001</code>) with these instructions:
33C0          [[XOR (x86 instruction)|XOR]] EAX,EAX        // Set the register EAX to 0x00000000
40            [[INC (x86 instruction)|INC]] EAX            // Increase EAX to 0x00000001
which have the same effect but take fewer bytes to encode and are free of nulls.


==={{anchor|Alphanumeric|Multi-architecture}}Alphanumeric and printable shellcode===
33C0          [[XOR (x86 instruction)|XOR]] EAX,EAX
An '''alphanumeric shellcode''' is a shellcode that consists of or assembles itself on execution into entirely [[alphanumeric]] [[ASCII]] or [[Unicode]] characters such as 0–9, A–Z and a–z.<ref name="Rix_2001">{{cite journal |title=Writing ia32 alphanumeric shellcodes |author=rix |volume=0x0b |issue=57 |id=#0x0f of 0x12 |journal=Phrack |publisher=Phrack Inc. |date=2001-08-11 |url=http://www.phrack.org/issues.html?issue=57&id=15#article |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220308045645/http://phrack.org/issues/57/15.html#article |archive-date=2022-03-08}}</ref><ref name="Obscou_2003">{{cite journal |title=Building IA32 'Unicode-Proof' Shellcodes |author=obscou |date=2003-08-13 |volume=11 |issue=61 |id=#0x0b of 0x0f |journal=Phrack |publisher=Phrack Inc. |url=http://www.phrack.org/issues.html?issue=61&id=11#article |access-date=2008-02-29 |url-status=live |archive-url=https://web.archive.org/web/20220526165740/http://phrack.org/issues/61/11.html#article |archive-date=2022-05-26}}</ref> This type of encoding was created by [[Hacker (computer security)|hacker]]s to hide working [[machine code]] inside what appears to be text. This can be useful to avoid detection of the code and to allow the code to pass through filters that scrub non-alphanumeric characters from strings (in part, such filters were a response to non-alphanumeric shellcode exploits). A similar type of encoding is called ''printable code'' and uses all [[control character|printable]] characters (0–9, A–Z, a–z, !@#%^&*() etc.). A similarly restricted variant is ''ECHOable code'' not containing any characters which are not accepted by the [[ECHO (command)|ECHO]] command. It has been shown that it is possible to create shellcode that looks like normal text in English.<ref name="Mason-Small-Monrose-MacManus_2009">{{cite conference |title=English Shellcode |author-first1=Joshua |author-last1=Mason |author-first2=Sam |author-last2=Small |author-first3=Fabian |author-last3=Monrose |author-first4=Greg |author-last4=MacManus |date=November 2009 |conference=Proceedings of the 16th ACM conference on Computer and Communications Security |location=New York, NY, USA |pages=524–533 |url=http://www.cs.jhu.edu/~sam/ccs243-mason.pdf |access-date=2010-01-10 |url-status=live |archive-url=https://web.archive.org/web/20220526164459/https://www.cs.jhu.edu/~sam/ccs243-mason.pdf |archive-date=2022-05-26}} (10 pages)</ref>
40            [[INC (x86 instruction)|INC]] EAX
Writing alphanumeric or printable code requires good understanding of the [[instruction set architecture]] of the machine(s) on which the code is to be executed. It has been demonstrated that it is possible to write alphanumeric code that is executable on more than one machine,<ref>{{cite web |title=Multi-architecture (x86) and 64-bit alphanumeric shellcode explained |publisher=Blackhat Academy |url=http://www.blackhatlibrary.net/Alphanumeric_shellcode |url-status=dead |archive-url=https://web.archive.org/web/20120621124443/http://www.blackhatlibrary.net/Alphanumeric_shellcode |archive-date=2012-06-21}}</ref> thereby constituting [[multi-architecture executable]] code.


In certain circumstances, a target process will filter any byte from the injected shellcode that is not a [[printable character|printable]] or [[alphanumeric]] character. Under such circumstances, the range of instructions that can be used to write a shellcode becomes very limited. A solution to this problem was published by Rix in [[Phrack]] 57<ref name="Rix_2001"/> in which he showed it was possible to turn any code into alphanumeric code. A technique often used is to create self-modifying code, because this allows the code to modify its own bytes to include bytes outside of the normally allowed range, thereby expanding the range of instructions it can use. Using this trick, a self-modifying decoder can be created that initially uses only bytes in the allowed range. The main code of the shellcode is encoded, also only using bytes in the allowed range. When the output shellcode is run, the decoder can modify its own code to be able to use any instruction it requires to function properly and then continues to decode the original shellcode. After decoding the shellcode the decoder transfers control to it, so it can be executed as normal. It has been shown that it is possible to create arbitrarily complex shellcode that looks like normal text in English.<ref name="Mason-Small-Monrose-MacManus_2009"/>
; {{anchor|Alphanumeric|Multi-architecture}}Text
An alphanumeric shellcode consists of only [[alphanumeric]] characters (0–9, A–Z and a–z).<ref name="Rix_2001">{{cite journal |title=Writing ia32 alphanumeric shellcodes |author=rix |volume=0x0b |issue=57 |id=#0x0f of 0x12 |journal=Phrack |publisher=Phrack Inc. |date=2001-08-11 |url=http://www.phrack.org/issues/57/15 |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220308045645/http://phrack.org/issues/57/15.html#article |archive-date=2022-03-08}}</ref><ref name="Obscou_2003">{{cite journal |title=Building IA32 'Unicode-Proof' Shellcodes |author=obscou |date=2003-08-13 |volume=11 |issue=61 |id=#0x0b of 0x0f |journal=Phrack |publisher=Phrack Inc. |url=http://www.phrack.org/issues/61/11 |access-date=2008-02-29 |url-status=live |archive-url=https://web.archive.org/web/20220526165740/http://phrack.org/issues/61/11.html#article |archive-date=2022-05-26}}</ref> This type of encoding was created by [[Hacker (computer security)|hacker]]s to obfuscate machine code inside what appears to be [[plain text]]. This can be useful to avoid detection of the code—to allow the code to pass through filters that scrub non-alphanumeric characters from strings.{{efn |in part, such filters were a response to non-alphanumeric shellcode exploits}} A similar type of encoding is called ''printable code'' and uses all [[control character|printable]] characters (alphanumeric plus symbols like !@#%^&*). A similarly restricted variant is ''ECHOable code'' not containing any characters which are not accepted by the [[ECHO (command)|ECHO]] command. It has been shown that it is possible to create shellcode that looks like normal text in English.<ref name="Mason-Small-Monrose-MacManus_2009">{{cite conference |title=English Shellcode |author-first1=Joshua |author-last1=Mason |author-first2=Sam |author-last2=Small |author-first3=Fabian |author-last3=Monrose |author-first4=Greg |author-last4=MacManus |date=November 2009 |conference=Proceedings of the 16th ACM conference on Computer and Communications Security |location=New York, NY, USA |pages=524–533 |url=http://www.cs.jhu.edu/~sam/ccs243-mason.pdf |access-date=2010-01-10 |url-status=live |archive-url=https://web.archive.org/web/20220526164459/https://www.cs.jhu.edu/~sam/ccs243-mason.pdf |archive-date=2022-05-26}} (10 pages)</ref>
Writing such shellcode requires in-depth understanding of the [[instruction set architecture]] of the target machines. It has been demonstrated that it is possible to write alphanumeric code that is executable on more than one machine,<ref>{{cite web |title=Multi-architecture (x86) and 64-bit alphanumeric shellcode explained |publisher=Blackhat Academy |url=http://www.blackhatlibrary.net/Alphanumeric_shellcode |url-status=dead |archive-url=https://web.archive.org/web/20120621124443/http://www.blackhatlibrary.net/Alphanumeric_shellcode |archive-date=2012-06-21}}</ref> thereby constituting [[multi-architecture executable]] code.


===Unicode proof shellcode===
A work-around was published by Rix in [[Phrack]] 57<ref name="Rix_2001"/> in which he shows that it is possible to turn any code into alphanumeric code. Often, self-modifying code is leveraged because it allows the code to have byte values that otherwise are not allowed by replacing coded values at runtime. A self-modifying decoder can be created that initially uses only allowed bytes. The main code of the shellcode is encoded, also only using bytes in the allowed range. When the output shellcode is run, the decoder modifies its code to use instructions it requires and then decodes the original shellcode. After decoding the shellcode, the decoder transfers control to it. It has been shown that it is possible to create arbitrarily complex shellcode that looks like normal English text.<ref name="Mason-Small-Monrose-MacManus_2009"/>
Modern programs use [[Unicode]] strings to allow internationalization of text. Often, these programs will convert incoming [[ASCII]] strings to Unicode before processing them. Unicode strings encoded in [[UTF-16]] use two bytes to encode each character (or four bytes for some special characters). When an [[ASCII]] ([[Latin-1]] in general) string is transformed into UTF-16, a zero byte is inserted after each byte in the original string. Obscou proved in [[Phrack]] 61<ref name="Obscou_2003"/> that it is possible to write shellcode that can run successfully after this transformation. Programs that can automatically encode any shellcode into alphanumeric UTF-16-proof shellcode exist, based on the same principle of a small self-modifying decoder that decodes the original shellcode.


==Platforms==
Modern software uses [[Unicode]] to support [[Internationalization and localization]]. Often, input [[ASCII]] text is converted to Unicode before processing. When an ASCII ([[Latin-1]] in general) character is transformed to UTF-16 (16-bit Unicode), a zero byte is inserted after each byte (character) of the original text. Obscou proved in [[Phrack]] 61<ref name="Obscou_2003"/> that it is possible to write shellcode that can run successfully after this transformation. Programs that can automatically encode any shellcode into alphanumeric UTF-16-proof shellcode exist, based on the same principle of a small self-modifying decoder that decodes the original shellcode.
Most shellcode is written in [[machine code]] because of the low level at which the vulnerability being exploited gives an attacker access to the process. Shellcode is therefore often created to target one specific combination of [[Central processing unit|processor]], [[operating system]] and [[service pack]], called a [[Platform (computing)|platform]]. For some exploits, due to the constraints put on the shellcode by the target process, a very specific shellcode must be created. However, it is not impossible for one shellcode to work for multiple exploits, service packs, operating systems and even processors.<ref name="Eugene_2001">{{cite web |title=Architecture Spanning Shellcode |author=eugene |publisher=Phrack Inc. |work=Phrack |date=2001-08-11 |volume=0x0b |issue=57 |id=#0x0e of 0x12 |url=http://www.phrack.org/issues.html?issue=57&id=14#article |access-date=2008-02-29 |url-status=live |archive-url=https://web.archive.org/web/20211109173710/http://phrack.org/issues/57/14.html#article |archive-date=2021-11-09}}</ref><ref name="Nemo_2005">{{cite web |title=OSX - Multi arch shellcode. |author=nemo |work=[[Full disclosure (mailing list)|Full disclosure]] |date=2005-11-13 |url=https://seclists.org/fulldisclosure/2005/Nov/387 |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220526191616/https://seclists.org/fulldisclosure/2005/Nov/387 |archive-date=2022-05-26}}</ref><ref name="Cha-Pak-Brumley-Lipton_2010">{{cite conference |title=Platform-Independent Programs |author-first1=Sang Kil |author-last1=Cha |author-first2=Brian |author-last2=Pak |author-first3=David |author-last3=Brumley |author-link3=David Brumley |author-first4=Richard Jay |author-last4=Lipton |author-link4=Richard Jay Lipton |conference=Proceedings of the 17th ACM conference on Computer and Communications Security (CCS'10) |location=Chicago, Illinois, USA |date=2010-10-08 |orig-date=2010-10-04 |publisher=[[Carnegie Mellon University]], Pittsburgh, Pennsylvania, USA / [[Georgia Institute of Technology]], Atlanta, Georgia, USA |isbn=978-1-4503-0244-9 |doi=10.1145/1866307.1866369 |pages=547–558 |url=https://softsec.kaist.ac.kr/~sangkilc/papers/cha-ccs10.pdf |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220526153147/https://softsec.kaist.ac.kr/~sangkilc/papers/cha-ccs10.pdf |archive-date=2022-05-26}} [https://web.archive.org/web/20220526182333/http://users.ece.cmu.edu/~sangkilc/papers/ccs10-cha.pdf] (12 pages) (See also: [https://security.ece.cmu.edu/pip/index.html])</ref> Such versatility is commonly achieved by creating multiple versions of the shellcode that target the various platforms and creating a header that branches to the correct version for the platform the code is running on. When executed, the code behaves differently for different platforms and executes the right part of the shellcode for the platform it is running on.


==Shellcode analysis==
==Compatibility==
Shellcode cannot be executed directly. In order to analyze what a shellcode attempts to do it must be loaded into another process. One common analysis technique is to write a small C program which holds the shellcode as a byte buffer, and then use a function pointer or use inline assembler to transfer execution to it. Another technique is to use an online tool, such as shellcode_2_exe, to embed the shellcode into a pre-made executable husk which can then be analyzed in a standard debugger. Specialized shellcode analysis tools also exist, such as the iDefense sclog project which was originally released in 2005 as part of the Malcode Analyst Pack. Sclog is designed to load external shellcode files and execute them within an API logging framework. Emulation-based shellcode analysis tools also exist such as the {{Mono|sctest}} application which is part of the cross-platform libemu package. Another emulation-based shellcode analysis tool, built around the libemu library, is {{Mono|scdbg}} which includes a basic debug shell and integrated reporting features.
Generally, shellcode is deployed as machine code since it affords relatively unprotected access to the target process. Since machine code is compatible within a relatively narrow computing context ([[Central processing unit |processor]], [[operating system]] and so on), a shellcode fragment has limited [[compatibility (computing)|compatibility]]. Also, since a shellcode attack tends to work best when the code is small and targeting multiple exploits increases the size, typically the code targets only one exploit. None the less, a single shellcode fragment can work for multiple contexts
and exploits.<ref name="Eugene_2001">{{cite web |title=Architecture Spanning Shellcode |author=eugene |publisher=Phrack Inc. |work=Phrack |date=2001-08-11 |volume=0x0b |issue=57 |id=#0x0e of 0x12 |url=http://www.phrack.org/issues/57/14 |access-date=2008-02-29 |url-status=live |archive-url=https://web.archive.org/web/20211109173710/http://phrack.org/issues/57/14.html#article |archive-date=2021-11-09}}</ref><ref name="Nemo_2005">{{cite web |title=OSX - Multi arch shellcode. |author=nemo |work=[[Full disclosure (mailing list)|Full disclosure]] |date=2005-11-13 |url=https://seclists.org/fulldisclosure/2005/Nov/387 |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220526191616/https://seclists.org/fulldisclosure/2005/Nov/387 |archive-date=2022-05-26}}</ref><ref name="Cha-Pak-Brumley-Lipton_2010">{{cite conference |title=Platform-Independent Programs |author-first1=Sang Kil |author-last1=Cha |author-first2=Brian |author-last2=Pak |author-first3=David |author-last3=Brumley |author-link3=David Brumley |author-first4=Richard Jay |author-last4=Lipton |author-link4=Richard Jay Lipton |conference=Proceedings of the 17th ACM conference on Computer and Communications Security (CCS'10) |location=Chicago, Illinois, USA |date=2010-10-08 |orig-date=2010-10-04 |publisher=[[Carnegie Mellon University]], Pittsburgh, Pennsylvania, USA / [[Georgia Institute of Technology]], Atlanta, Georgia, USA |isbn=978-1-4503-0244-9 |doi=10.1145/1866307.1866369 |pages=547–558 |url=https://softsec.kaist.ac.kr/~sangkilc/papers/cha-ccs10.pdf |access-date=2022-05-26 |url-status=live |archive-url=https://web.archive.org/web/20220526153147/https://softsec.kaist.ac.kr/~sangkilc/papers/cha-ccs10.pdf |archive-date=2022-05-26}} [https://web.archive.org/web/20220526182333/http://users.ece.cmu.edu/~sangkilc/papers/ccs10-cha.pdf] (12 pages) (See also: [https://security.ece.cmu.edu/pip/index.html])</ref> Versatility can be achieved by creating a single fragment that contains an implementation for multiple contexts. Common code branches to the implementation for the runtime context.
 
==Analysis==
As shellcode is generally not executable on its own, in order to study what it does, it is typically loaded into a special process. A common technique is to write a small [[C (programming language)|C]] program that contains the shellcode as data (i.e. in a byte buffer), and transfers control to the instructions encoded in the data [[function pointer]] or inline [[assembly code]]). Another technique is to use an online tool, such as {{mono|shellcode_2_exe}}, to embed the shellcode into a pre-made executable husk which can then be analyzed in a standard debugger. Specialized shellcode analysis tools also exist, such as the iDefense sclog project (originally released in 2005 in the Malcode Analyst Pack). Sclog is designed to load external shellcode files and execute them within an API logging framework. Emulation-based shellcode analysis tools also exist such as the {{Mono|sctest}} application which is part of the cross-platform libemu package. Another emulation-based shellcode analysis tool, built around the libemu library, is {{Mono|scdbg}} which includes a basic debug shell and integrated reporting features.


==See also==
==See also==
* [[Alphanumeric code]]
* {{Annotated link| Computer security}}
* [[Computer security]]
* {{Annotated link| Heap overflow}}
* [[Buffer overflow]]
* {{Annotated link| Metasploit Project}}
* [[Exploit (computer security)]]
* {{Annotated link| Shell shoveling}}
* [[Heap overflow]]
* {{Annotated link| Stack buffer overflow}}
* [[Metasploit Project]]
 
* [[Shell (computing)]]
==Notes==
* [[Shell shoveling]]
{{notelist}}
* [[Stack buffer overflow]]
* [[Vulnerability (computing)]]


==References==
==References==
Line 109: Line 102:
==External links==
==External links==
* [http://www.shell-storm.org/shellcode/ Shell-Storm] Database of shellcodes Multi-Platform.
* [http://www.shell-storm.org/shellcode/ Shell-Storm] Database of shellcodes Multi-Platform.
* [http://www.phrack.org/issues.html?issue=49&id=14#article An introduction to buffer overflows and shellcode]
* [http://www.phrack.org/issues/49/14 An introduction to buffer overflows and shellcode]
*[http://www.infosecwriters.com/text_resources/pdf/basics_of_shellcoding.pdf The Basics of Shellcoding] (PDF) An overview of [[x86]] shellcoding by [http://www.rosiello.org/ Angelo Rosiello]
* [https://web.archive.org/web/20050528022508/http://www.infosecwriters.com/text_resources/pdf/basics_of_shellcoding.pdf The Basics of Shellcoding (PDF)] An overview of x86 shellcoding by Angelo Rosiello
<!-- * {{cite web |last1=Rosiello |first1=Angelo |title=The Basics of Shellcoding (An overview of x86 shellcoding) |url=http://www.infosecwriters.com/text_resources/pdf/basics_of_shellcoding.pdf |access-date=9 October 2025 |archive-url=https://web.archive.org/web/20050528022508/http://www.infosecwriters.com/text_resources/pdf/basics_of_shellcoding.pdf |archive-date=2005-05-28 |date=9 February 2004 |url-status=dead}} -->
* [https://web.archive.org/web/20120109070051/http://goodfellas.shellcode.com.ar/docz/bof/Writing_shellcode.html An introduction to shellcode development]
* [https://web.archive.org/web/20120109070051/http://goodfellas.shellcode.com.ar/docz/bof/Writing_shellcode.html An introduction to shellcode development]
* [https://web.archive.org/web/20080302111910/http://www.metasploit.com/shellcode/ Contains x86 and non-x86 shellcode samples and an online interface for automatic shellcode generation and encoding, from the Metasploit Project]
* [https://web.archive.org/web/20080302111910/http://www.metasploit.com/shellcode/ Contains x86 and non-x86 shellcode samples and an online interface for automatic shellcode generation and encoding, from the Metasploit Project]

Latest revision as of 01:41, 20 December 2025

Template:Short description Script error: No such module "Unsubst". Script error: No such module "redirect hatnote". Script error: No such module "redirect hatnote".

Shellcode is executable code intended to be used as a payload for exploiting a software vulnerability. The term includes shell because the attack originally described an attack that opens a command shell that the attacker can use to control the target machine, but any code that is injected to gain access that is otherwise not allowed can be called shellcode. For this reason, some consider the name shellcode to be inaccurate.[1]

An attack commonly injects data that consists of executable code into a process before or as it exploits a vulnerability to gain control. The program counter is set the shellcode entry point so that that the shellcode runs. Deploying shellcode is often accomplished by including the code in a file that a vulnerable process downloads and then loads into its memory.

Common wisdom dictates that to maximum effectiveness, a shellcode payload should be small.[2] Machine code provides the flexibility needed to accomplish the goal. Shellcode authors leverage small opcodes to create compact shellcode.[3][4]

Types

Local

A local shellcode attack allows an attacker to gain elevated access privilege on their computer. In some cases, exploiting a vulnerability can be achieved by causing an error such as buffer overflow. If successful, the shellcode enables access to the machine via the elevated privileges granted to the targeted process.

Remote

A remote shellcode attack targets a process running on a remote machine

  1. REDIRECT Template:En dash

Template:R protected on the same local area network, intranet, or on the internet. If successful, the shellcode provides access to the target machine across the network. The shellcode normally opens a TCP/IP socket connection to allow access to a shell on the target machine.

A remote shellcode attack can be categorized by its behavior. If the shellcode establishes the connection it is called a reverse shell, or a connect-back shellcode. On the other hand, if the attacker establishes the connection, the shellcode is called a bindshell because the shellcode binds to a certain port on the victim's machine. A bindshell random port skips the binding part and listens on a random port.Template:Efn A socket-reuse shellcode is an exploit that establishes a connection to the vulnerable process that is not closed before the shellcode runs so that the shellcode can re-use the connection to allow remote access. Socket re-using shellcode is more elaborate, since the shellcode needs to find out which connection to re-use and the machine may have many open connections.[5]

A firewall can detect outgoing connections made by connect-back shellcode as well as incoming connections made by bindshells, and therefore, offers some protection against an attack. Even if the system is vulnerable, a firewall can prevent the attacker from connecting to the shell created by the shellcode. One reason why socket re-using shellcode is used is that it does not create new connections and, therefore, is harder to detect and block.

Download and execute

A download and execute shellcode attack downloads and executes malware on the target system. This type of shellcode does not spawn a shell, but rather instructs the machine to download a certain executable file from the network and execute it. Nowadays, it is commonly used in drive-by download attacks, where a victim visits a malicious webpage that in turn attempts to run such a download and execute shellcode in order to install software on the victim's machine.

A variation of this attack downloads and loads a library.[6][7] Advantages of this technique are that the code can be smaller, that it does not require the shellcode to spawn a new process on the target system, and that the shellcode does not need code to clean up the targeted process as this can be done by the library loaded into the process.

Staged

When the amount of data that an attacker can inject into the target process is too limited to achieve the desired effect, it may be possible to deploy shellcode in stages that progressively provide more access. The first stage might do nothing more than download the second stage than then provides the desired access.

Egg-hunt

An egg-hunt shellcode attack is a staged attack in which the attacker can inject shellcode into a process but does not know where in the process it is. A second-stage shellcode, generally smaller than the first, is injected into the process to search the process's address space for the first shellcode (the egg) and executes it.[8]

Omelet

An omelet shellcode attack, similar to egg-hunt, looks for multiple small blocks of data (eggs) and combines them into a larger block (omelet) that is then executed. This is used when an attacker is limited on the size of injected code but can inject multiple.[9]

Encoding

Shellcode is often written in order to work around the restrictions on the data that a process will allow. General techniques include:

Optimize for size

Optimize the code to decrease its size.

Self-modifying code

Modify its own code before executing it to use byte values that are otherwise restricted.

Encryption

To avoid intrusion detection, encode as self-decrypting or polymorphic.

Character encoding

An attack that targets a browser might obfuscate shellcode in a JavaScript string using an expanded character encoding.[10] For example, on the IA-32 architecture, here's two unencoded no-operation instructions (used in a NOP slide):

90             NOP
90             NOP

As encoded:

Null-free

Shellcode must be written without zero-value bytes when it is intended to be injected into a null-terminated string that is copied in the target process via the usual algorithm (i.e. strcpy) of ending the copy at the first zero byte

  1. REDIRECT Template:En dash

Template:R protected called the null character in common character sets. If the shellcode contained a null, the copy would be truncated and not function properly. To produce null-free code from code that contains nulls, one can replace machine instructions that contain zeroes with instructions that don't. For example, on the IA-32 architecture the instruction to set register EAX to 1 contains zeroes as part of the literal (1 expands to 0x00000001).

B8 01000000    MOV EAX,1

The following instructions accomplish the same goal (EAX containing 1) without embedded zero bytes by first setting EAX to 0, then incrementing EAX to 1:

33C0           XOR EAX,EAX
40             INC EAX
Script error: No such module "anchor".Text

An alphanumeric shellcode consists of only alphanumeric characters (0–9, A–Z and a–z).[11][12] This type of encoding was created by hackers to obfuscate machine code inside what appears to be plain text. This can be useful to avoid detection of the code—to allow the code to pass through filters that scrub non-alphanumeric characters from strings.Template:Efn A similar type of encoding is called printable code and uses all printable characters (alphanumeric plus symbols like !@#%^&*). A similarly restricted variant is ECHOable code not containing any characters which are not accepted by the ECHO command. It has been shown that it is possible to create shellcode that looks like normal text in English.[13] Writing such shellcode requires in-depth understanding of the instruction set architecture of the target machines. It has been demonstrated that it is possible to write alphanumeric code that is executable on more than one machine,[14] thereby constituting multi-architecture executable code.

A work-around was published by Rix in Phrack 57[11] in which he shows that it is possible to turn any code into alphanumeric code. Often, self-modifying code is leveraged because it allows the code to have byte values that otherwise are not allowed by replacing coded values at runtime. A self-modifying decoder can be created that initially uses only allowed bytes. The main code of the shellcode is encoded, also only using bytes in the allowed range. When the output shellcode is run, the decoder modifies its code to use instructions it requires and then decodes the original shellcode. After decoding the shellcode, the decoder transfers control to it. It has been shown that it is possible to create arbitrarily complex shellcode that looks like normal English text.[13]

Modern software uses Unicode to support Internationalization and localization. Often, input ASCII text is converted to Unicode before processing. When an ASCII (Latin-1 in general) character is transformed to UTF-16 (16-bit Unicode), a zero byte is inserted after each byte (character) of the original text. Obscou proved in Phrack 61[12] that it is possible to write shellcode that can run successfully after this transformation. Programs that can automatically encode any shellcode into alphanumeric UTF-16-proof shellcode exist, based on the same principle of a small self-modifying decoder that decodes the original shellcode.

Compatibility

Generally, shellcode is deployed as machine code since it affords relatively unprotected access to the target process. Since machine code is compatible within a relatively narrow computing context (processor, operating system and so on), a shellcode fragment has limited compatibility. Also, since a shellcode attack tends to work best when the code is small and targeting multiple exploits increases the size, typically the code targets only one exploit. None the less, a single shellcode fragment can work for multiple contexts and exploits.[15][16][17] Versatility can be achieved by creating a single fragment that contains an implementation for multiple contexts. Common code branches to the implementation for the runtime context.

Analysis

As shellcode is generally not executable on its own, in order to study what it does, it is typically loaded into a special process. A common technique is to write a small C program that contains the shellcode as data (i.e. in a byte buffer), and transfers control to the instructions encoded in the data function pointer or inline assembly code). Another technique is to use an online tool, such as <templatestyles src="Mono/styles.css" />shellcode_2_exe, to embed the shellcode into a pre-made executable husk which can then be analyzed in a standard debugger. Specialized shellcode analysis tools also exist, such as the iDefense sclog project (originally released in 2005 in the Malcode Analyst Pack). Sclog is designed to load external shellcode files and execute them within an API logging framework. Emulation-based shellcode analysis tools also exist such as the <templatestyles src="Mono/styles.css" />sctest application which is part of the cross-platform libemu package. Another emulation-based shellcode analysis tool, built around the libemu library, is <templatestyles src="Mono/styles.css" />scdbg which includes a basic debug shell and integrated reporting features.

See also

Notes

Template:Notelist

References

<templatestyles src="Reflist/styles.css" />

  1. Script error: No such module "citation/CS1".
  2. Script error: No such module "citation/CS1".
  3. Script error: No such module "citation/CS1".
  4. Script error: No such module "citation/CS1".
  5. Script error: No such module "citation/CS1".
  6. Script error: No such module "citation/CS1".
  7. Script error: No such module "citation/CS1".
  8. Script error: No such module "citation/CS1".
  9. Script error: No such module "citation/CS1".
  10. Script error: No such module "citation/CS1".
  11. a b Script error: No such module "Citation/CS1".
  12. a b Script error: No such module "Citation/CS1".
  13. a b Script error: No such module "citation/CS1". (10 pages)
  14. Script error: No such module "citation/CS1".
  15. Script error: No such module "citation/CS1".
  16. Script error: No such module "citation/CS1".
  17. Script error: No such module "citation/CS1". [1] (12 pages) (See also: [2])

Script error: No such module "Check for unknown parameters".

External links

Template:Information security