VYPR
Critical severityNVD Advisory· Published Jan 8, 2021· Updated Sep 16, 2024

Improper Control of Generation of Code ('Code Injection')

CVE-2020-28468

Description

Server-Side Template Injection in pwntools shellcraft generator allows remote code execution before version 4.3.1.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Server-Side Template Injection in pwntools shellcraft generator allows remote code execution before version 4.3.1.

Vulnerability

Details

The shellcraft generator in pwntools prior to version 4.3.1 is vulnerable to Server-Side Template Injection (SSTI) [1][3]. This flaw occurs because user-supplied input is passed unsanitized to the template engine during shellcode generation, allowing an attacker to inject malicious template expressions [2].

Exploitation

An attacker can exploit this vulnerability by providing crafted input to any application that uses the pwntools shellcraft generator with untrusted data. The SSTI can be triggered remotely over the network if the application processes attacker-controlled input [3]. No special privileges are required, as the vulnerability is accessible through standard library interfaces.

Impact

Successful exploitation leads to arbitrary code execution in the context of the Python process running pwntools [3]. This could allow an attacker to execute system commands, access sensitive data, or pivot to other systems.

Mitigation

The issue is fixed in pwntools version 4.3.1 [2]. Users are strongly advised to update to this version or later. No known workarounds exist for earlier versions.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pwntoolsPyPI
< 4.3.14.3.1

Affected products

2

Patches

1
138188eb1c02

Fix pwntools shellcraft SSTI vulnerability

https://github.com/Gallopsled/pwntoolsArusekkNov 29, 2020via ghsa
29 files changed · +95 71
  • pwnlib/constants/__init__.py+7 1 modified
    @@ -145,7 +145,13 @@ def eval(self, string):
             if key not in self._env_store:
                 self._env_store[key] = {key: getattr(self, key) for key in dir(self) if not key.endswith('__')}
     
    -        return Constant('(%s)' % string, safeeval.values(string, self._env_store[key]))
    +        val = safeeval.values(string, self._env_store[key])
    +
    +        # if the expression is not assembly-safe, it is not so vital to preserve it
    +        if set(string) & (set(bytearray(range(32)).decode()) | set('"#$\',.;@[\\]`{}')):
    +            string = val
    +
    +        return Constant('(%s)' % string, val)
     
     
     # To prevent garbage collection
    
  • pwnlib/data/syscalls/generate.py+11 9 modified
    @@ -1,6 +1,7 @@
     #!/usr/bin/env python2
     from __future__ import division
     import argparse
    +import keyword
     import os
     
     from pwnlib import constants
    @@ -62,7 +63,7 @@
     
         for name, arg in zip(argument_names, argument_values):
             if arg is not None:
    -            syscall_repr.append('%s=%r' % (name, arg))
    +            syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
     
             # If the argument itself (input) is a register...
             if arg in allregs:
    @@ -75,8 +76,8 @@
     
             # The argument is not a register.  It is a string value, and we
             # are expecting a string value
    -        elif name in can_pushstr and isinstance(arg, (bytes, six.text_type)):
    -            if not isinstance(arg, bytes):
    +        elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
    +            if isinstance(arg, six.text_type):
                     arg = arg.encode('utf-8')
                 string_arguments[name] = arg
     
    @@ -144,12 +145,11 @@ def can_be_array(arg):
     
     
     def fix_bad_arg_names(func, arg):
    -    if arg.name == 'str':
    -        return 'str_'
         if arg.name == 'len':
             return 'length'
    -    if arg.name == 'repr':
    -        return 'repr_'
    +
    +    if arg.name in ('str', 'repr') or keyword.iskeyword(arg.name):
    +        return arg.name + '_'
     
         if func.name == 'open' and arg.name == 'vararg':
             return 'mode'
    @@ -277,8 +277,10 @@ def generate_one(target):
                 CALL.format(**template_variables)
             ]
     
    -        with open(os.path.join(target, name + '.asm'), 'wt+') as f:
    -            f.write('\n'.join(map(str.strip, lines)))
    +        if keyword.iskeyword(name):
    +            name += '_'
    +        with open(os.path.join(target, name + '.asm'), 'wt') as f:
    +            f.write('\n'.join(map(str.strip, lines)) + '\n')
     
     if __name__ == '__main__':
         p = argparse.ArgumentParser()
    
  • pwnlib/shellcraft/__init__.py+5 2 modified
    @@ -142,8 +142,11 @@ def eval(self, item):
             return constants.eval(item)
     
         def pretty(self, n, comment=True):
    -        if isinstance(n, str):
    -            return repr(n)
    +        if isinstance(n, (str, bytes, list, tuple, dict)):
    +            r = repr(n)
    +            if not comment:  # then it can be inside a comment!
    +                r = r.replace('*/', r'\x2a/')
    +            return r
             if not isinstance(n, six.integer_types):
                 return n
             if isinstance(n, constants.Constant):
    
  • pwnlib/shellcraft/templates/aarch64/freebsd/syscall.asm+1 1 modified
    @@ -36,7 +36,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/aarch64/linux/syscall.asm+4 4 modified
    @@ -1,5 +1,5 @@
     <%
    -  from pwnlib.shellcraft import aarch64
    +  from pwnlib.shellcraft import aarch64, pretty
       from pwnlib.constants import eval
       from pwnlib.abi import linux_aarch64_syscall as abi
       from six import text_type
    @@ -14,7 +14,7 @@ Any of the arguments can be expressions to be evaluated by :func:`pwnlib.constan
     Example:
     
         >>> print(shellcraft.aarch64.linux.syscall(11, 1, 'sp', 2, 0).rstrip())
    -        /* call syscall(11, 1, 'sp', 2, 0) */
    +        /* call syscall(0xb, 1, 'sp', 2, 0) */
             mov  x0, #1
             mov  x1, sp
             mov  x2, #2
    @@ -59,13 +59,13 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
               args.append('?')
           else:
    -          args.append(repr(arg))
    +          args.append(pretty(arg, False))
       while args and args[-1] == '?':
           args.pop()
       syscall_repr = syscall_repr % ', '.join(args)
    
  • pwnlib/shellcraft/templates/aarch64/pushstr_array.asm+1 1 modified
    @@ -39,7 +39,7 @@ string = b''.join(array)
     if len(array) * 8 > 4095:
         raise Exception("Array size is too large (%i), max=4095" % len(array))
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${shellcraft.pretty(array, False)} */
         ${shellcraft.pushstr(string, register1=register1, register2=register2)}
     
         /* push null terminator */
    
  • pwnlib/shellcraft/templates/amd64/freebsd/syscall.asm+1 1 modified
    @@ -79,7 +79,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/amd64/linux/syscall.asm+18 4 modified
    @@ -1,5 +1,5 @@
     <%
    -  from pwnlib.shellcraft import amd64
    +  from pwnlib.shellcraft import amd64, pretty
       from pwnlib.constants import Constant
       from pwnlib.abi import linux_amd64_syscall as abi
       from six import text_type
    @@ -54,7 +54,7 @@ Example:
             ...               'PROT_READ | PROT_WRITE | PROT_EXEC',
             ...               'MAP_PRIVATE | MAP_ANONYMOUS',
             ...               -1, 0).rstrip())
    -            /* call mmap(0, 4096, 'PROT_READ | PROT_WRITE | PROT_EXEC', 'MAP_PRIVATE | MAP_ANONYMOUS', -1, 0) */
    +            /* call mmap(0, 0x1000, 'PROT_READ | PROT_WRITE | PROT_EXEC', 'MAP_PRIVATE | MAP_ANONYMOUS', -1, 0) */
                 push (MAP_PRIVATE | MAP_ANONYMOUS) /* 0x22 */
                 pop r10
                 push -1
    @@ -84,6 +84,20 @@ Example:
                 push SYS_open /* 2 */
                 pop rax
                 syscall
    +        >>> print(shellcraft.amd64.write(0, '*/', 2).rstrip())
    +            /* write(fd=0, buf='\x2a/', n=2) */
    +            /* push b'\x2a/\x00' */
    +            push 0x1010101 ^ 0x2f2a
    +            xor dword ptr [rsp], 0x1010101
    +            mov rsi, rsp
    +            xor edi, edi /* 0 */
    +            push 2
    +            pop rdx
    +            /* call write() */
    +            push SYS_write /* 1 */
    +            pop rax
    +            syscall
    +
     </%docstring>
     <%
       append_cdq = False
    @@ -95,13 +109,13 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
               args.append('?')
           else:
    -          args.append(repr(arg))
    +          args.append(pretty(arg, False))
       while args and args[-1] == '?':
           args.pop()
       syscall_repr = syscall_repr % ', '.join(args)
    
  • pwnlib/shellcraft/templates/amd64/push.asm+3 3 modified
    @@ -1,6 +1,6 @@
     <%
       from pwnlib.util import packing
    -  from pwnlib.shellcraft import amd64
    +  from pwnlib.shellcraft import amd64, pretty
       from pwnlib.shellcraft.amd64 import pushstr
       from pwnlib import constants
       from pwnlib.shellcraft.registers import amd64 as regs
    @@ -31,7 +31,7 @@ Example:
             /* push 1 */
             push 1
         >>> print(pwnlib.shellcraft.amd64.push(256).rstrip())
    -        /* push 256 */
    +        /* push 0x100 */
             push 0x1010201 ^ 0x100
             xor dword ptr [rsp], 0x1010201
         >>> with context.local(os = 'linux'):
    @@ -58,7 +58,7 @@ Example:
             pass
     %>
     %if not is_reg:
    -    /* push ${repr(value_orig)} */
    +    /* push ${pretty(value_orig, False)} */
         ${re.sub(r'^\s*/.*\n', '', amd64.pushstr(packing.pack(value), False), 1)}
     % else:
         push ${value}
    
  • pwnlib/shellcraft/templates/amd64/pushstr_array.asm+3 3 modified
    @@ -1,4 +1,4 @@
    -<% from pwnlib.shellcraft import amd64 %>
    +<% from pwnlib.shellcraft import amd64, pretty %>
     <%docstring>
     Pushes an array/envp-style array of pointers onto the stack.
     
    @@ -25,14 +25,14 @@ word_size = 8
     offset = len(array_str) + word_size
     
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${pretty(array, False)} */
         ${amd64.pushstr(array_str)}
         ${amd64.mov(reg, 0)}
         push ${reg} /* null terminate */
     % for i,arg in enumerate(reversed(array)):
         ${amd64.mov(reg, offset + word_size*i - len(arg))}
         add ${reg}, rsp
    -    push ${reg} /* ${repr(arg)} */
    +    push ${reg} /* ${pretty(arg, False)} */
         <% offset -= len(arg) %>\
     % endfor
         ${amd64.mov(reg,'rsp')}
    
  • pwnlib/shellcraft/templates/amd64/pushstr.asm+1 1 modified
    @@ -77,7 +77,7 @@ Args:
         else:
             extend = b'\x00'
     %>\
    -    /* push ${repr(string)} */
    +    /* push ${pretty(string, False)} */
     % for word in lists.group(8, string, 'fill', extend)[::-1]:
     <%
         sign = packing.u64(word, endian='little', sign='signed')
    
  • pwnlib/shellcraft/templates/arm/freebsd/syscall.asm+1 1 modified
    @@ -36,7 +36,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/arm/linux/open_file.asm+2 1 modified
    @@ -12,6 +12,7 @@ Args:
       from pwnlib.asm import cpp
       from pwnlib.util.safeeval import expr
       from pwnlib.constants.linux import arm as consts
    +  from pwnlib.shellcraft import pretty
       filepath_lab, after = label("filepath"), label("after")
       filepath_out = [hex(ord(c)) for c in filepath]
       while True:
    @@ -31,7 +32,7 @@ Args:
         svc SYS_open
         b ${after}
     
    -    /* The string ${repr(str(filepath))} */
    +    /* The string ${pretty(str(filepath), False)} */
     ${filepath_lab}: .byte ${filepath_out}
     
     ${after}:
    
  • pwnlib/shellcraft/templates/arm/linux/syscall.asm+4 4 modified
    @@ -1,5 +1,5 @@
     <%
    -  from pwnlib.shellcraft import arm
    +  from pwnlib.shellcraft import arm, pretty
       from pwnlib.constants import eval
       from pwnlib.abi import linux_arm_syscall as abi
       from six import text_type
    @@ -14,7 +14,7 @@ Any of the arguments can be expressions to be evaluated by :func:`pwnlib.constan
     Example:
     
         >>> print(shellcraft.arm.linux.syscall(11, 1, 'sp', 2, 0).rstrip())
    -        /* call syscall(11, 1, 'sp', 2, 0) */
    +        /* call syscall(0xb, 1, 'sp', 2, 0) */
             mov  r0, #1
             mov  r1, sp
             mov  r2, #2
    @@ -57,13 +57,13 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
               args.append('?')
           else:
    -          args.append(repr(arg))
    +          args.append(pretty(arg, False))
       while args and args[-1] == '?':
           args.pop()
       syscall_repr = syscall_repr % ', '.join(args)
    
  • pwnlib/shellcraft/templates/arm/pushstr_array.asm+3 3 modified
    @@ -1,4 +1,4 @@
    -<% from pwnlib.shellcraft import arm %>
    +<% from pwnlib.shellcraft import arm, pretty %>
     <%docstring>
     Pushes an array/envp-style array of pointers onto the stack.
     
    @@ -25,13 +25,13 @@ word_size = 4
     offset = len(array_str) + word_size
     
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${pretty(array, False)} */
         ${arm.pushstr(array_str)}
         ${arm.push(0)} /* null terminate */
     % for i,arg in enumerate(reversed(array)):
         ${arm.mov(reg, offset + word_size*i - len(arg))}
         add ${reg}, sp
    -    ${arm.push(reg)} /* ${repr(arg)} */
    +    ${arm.push(reg)} /* ${pretty(arg, False)} */
         <% offset -= len(arg) %>\
     % endfor
         ${arm.mov(reg,'sp')}
    
  • pwnlib/shellcraft/templates/arm/pushstr.asm+2 1 modified
    @@ -1,5 +1,6 @@
     <% from pwnlib.util import lists, packing, fiddling %>
     <% from pwnlib.shellcraft.arm import push %>
    +<% from pwnlib.shellcraft import pretty %>
     <% import six %>
     <%page args="string, append_null = True, register='r7'"/>
     <%docstring>
    @@ -32,7 +33,7 @@ Examples:
         while len(string) % 4:
             string += b'\x41'
     %>\
    -    /* push ${repr(string)} */
    +    /* push ${pretty(string, False)} */
     % for word in packing.unpack_many(string, 32)[::-1]:
         ${push(word, register)}
     % endfor
    
  • pwnlib/shellcraft/templates/i386/cgc/syscall.asm+2 2 modified
    @@ -21,13 +21,13 @@ Any of the arguments can be expressions to be evaluated by :func:`pwnlib.constan
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
               args.append('?')
           else:
    -          args.append(repr(arg))
    +          args.append(pretty(arg, False))
       while args and args[-1] == '?':
           args.pop()
       syscall_repr = syscall_repr % ', '.join(args)
    
  • pwnlib/shellcraft/templates/i386/freebsd/syscall.asm+1 1 modified
    @@ -68,7 +68,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/i386/linux/syscall.asm+1 1 modified
    @@ -93,7 +93,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/i386/pushstr_array.asm+3 3 modified
    @@ -1,4 +1,4 @@
    -<% from pwnlib.shellcraft import i386 %>
    +<% from pwnlib.shellcraft import i386, pretty %>
     <%docstring>
     Pushes an array/envp-style array of pointers onto the stack.
     
    @@ -25,14 +25,14 @@ word_size = 4
     offset = len(array_str) + word_size
     
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${pretty(array, False)} */
         ${i386.pushstr(array_str)}
         ${i386.mov(reg, 0)}
         push ${reg} /* null terminate */
     % for i,arg in enumerate(reversed(array)):
         ${i386.mov(reg, offset + word_size*i - len(arg))}
         add ${reg}, esp
    -    push ${reg} /* ${repr(arg)} */
    +    push ${reg} /* ${pretty(arg, False)} */
         <% offset -= len(arg) %>\
     % endfor
         ${i386.mov(reg,'esp')}
    
  • pwnlib/shellcraft/templates/mips/freebsd/syscall.asm+1 1 modified
    @@ -61,7 +61,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/mips/linux/syscall.asm+1 1 modified
    @@ -91,7 +91,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/mips/pushstr_array.asm+4 4 modified
    @@ -1,4 +1,4 @@
    -<% from pwnlib.shellcraft import mips %>
    +<% from pwnlib.shellcraft import mips, pretty %>
     <%docstring>
     Pushes an array/envp-style array of pointers onto the stack.
     
    @@ -25,14 +25,14 @@ word_size = 4
     offset = len(array_str) + word_size
     
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${pretty(array, False)} */
         ${mips.pushstr(array_str)}
         ${mips.mov(reg, 0)}
         ${mips.push(reg)} /* null terminate */
     % for i,arg in enumerate(reversed(array)):
         ${mips.mov(reg, offset + word_size*i - len(arg))}
    -    add ${reg}, $sp
    -    ${mips.push(reg)} /* ${repr(arg)} */
    +    add ${reg}, $sp, ${reg}
    +    ${mips.push(reg)} /* ${pretty(arg, False)} */
         <% offset -= len(arg) %>\
     % endfor
         ${mips.mov(reg,'$sp')}
    
  • pwnlib/shellcraft/templates/mips/pushstr.asm+2 5 modified
    @@ -1,6 +1,6 @@
     <%
         from pwnlib.util import lists, packing, fiddling
    -    from pwnlib.shellcraft import mips
    +    from pwnlib.shellcraft import mips, pretty
         import six
     %>\
     <%page args="string, append_null = True"/>
    @@ -90,13 +90,10 @@ Args:
                 num = 0x101
             return num
     
    -    def pretty(n):
    -        return hex(n & (2 ** 32 - 1))
    -
         split_string = lists.group(4, string, 'fill', b'\x00')
         stack_offset = len(split_string) * -4
     %>\
    -    /* push ${repr(string)} */
    +    /* push ${pretty(string, False)} */
     % for index, word in enumerate(split_string):
     % if word == b'\x00\x00\x00\x00':
         sw $zero, ${stack_offset+(4 * index)}($sp)
    
  • pwnlib/shellcraft/templates/thumb/freebsd/syscall.asm+1 1 modified
    @@ -36,7 +36,7 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
    
  • pwnlib/shellcraft/templates/thumb/linux/syscall.asm+4 4 modified
    @@ -1,5 +1,5 @@
     <%
    -  from pwnlib.shellcraft import thumb
    +  from pwnlib.shellcraft import thumb, pretty
       from pwnlib.constants import eval
       from pwnlib.abi import linux_arm_syscall as abi
       from six import text_type
    @@ -14,7 +14,7 @@ Any of the arguments can be expressions to be evaluated by :func:`pwnlib.constan
     Example:
     
         >>> print(shellcraft.thumb.linux.syscall(11, 1, 'sp', 2, 0).rstrip())
    -        /* call syscall(11, 1, 'sp', 2, 0) */
    +        /* call syscall(0xb, 1, 'sp', 2, 0) */
             mov r0, #1
             mov r1, sp
             mov r2, #2
    @@ -65,13 +65,13 @@ Example:
           if syscall is None:
               args = ['?']
           else:
    -          args = [repr(syscall)]
    +          args = [pretty(syscall, False)]
     
       for arg in [arg0, arg1, arg2, arg3, arg4, arg5]:
           if arg is None:
               args.append('?')
           else:
    -          args.append(repr(arg))
    +          args.append(pretty(arg, False))
       while args and args[-1] == '?':
           args.pop()
       syscall_repr = syscall_repr % ', '.join(args)
    
  • pwnlib/shellcraft/templates/thumb/push.asm+3 3 modified
    @@ -1,6 +1,6 @@
     <%
       from pwnlib.util import packing
    -  from pwnlib.shellcraft import thumb, registers
    +  from pwnlib.shellcraft import thumb, registers, pretty
       from pwnlib import constants
       from pwnlib.context import context as ctx # Ugly hack, mako will not let it be called context
       import six
    @@ -32,7 +32,7 @@ Example:
             mov r7, #1
             push {r7}
         >>> print(pwnlib.shellcraft.thumb.push(256).rstrip())
    -        /* push 256 */
    +        /* push 0x100 */
             mov r7, #0x100
             push {r7}
         >>> print(pwnlib.shellcraft.thumb.push('SYS_execve').rstrip())
    @@ -61,7 +61,7 @@ if not is_register and isinstance(value, (six.binary_type, six.text_type)):
     % if is_register:
         push {${value}}
     % elif isinstance(value, six.integer_types):
    -    /* push ${repr(value_orig)} */
    +    /* push ${pretty(value_orig, False)} */
         ${re.sub(r'^\s*/.*\n', '', thumb.pushstr(packing.pack(value), False), 1)}
     % else:
         push ${value}
    
  • pwnlib/shellcraft/templates/thumb/pushstr_array.asm+3 3 modified
    @@ -1,4 +1,4 @@
    -<% from pwnlib.shellcraft import thumb %>
    +<% from pwnlib.shellcraft import thumb, pretty %>
     <%docstring>
     Pushes an array/envp-style array of pointers onto the stack.
     
    @@ -25,13 +25,13 @@ word_size = 4
     offset = len(array_str) + word_size
     
     %>\
    -    /* push argument array ${repr(array)} */
    +    /* push argument array ${pretty(array, False)} */
         ${thumb.pushstr(array_str)}
         ${thumb.push(0)} /* null terminate */
     % for i,arg in enumerate(reversed(array)):
         ${thumb.mov(reg, offset + word_size*i - len(arg))}
         add ${reg}, sp
    -    ${thumb.push(reg)} /* ${repr(arg)} */
    +    ${thumb.push(reg)} /* ${pretty(arg, False)} */
         <% offset -= len(arg) %>\
     % endfor
         ${thumb.mov(reg,'sp')}
    
  • pwnlib/shellcraft/templates/thumb/pushstr.asm+2 2 modified
    @@ -1,5 +1,5 @@
     <%
    -  from pwnlib.shellcraft import thumb
    +  from pwnlib.shellcraft import thumb, pretty
       from pwnlib.util import lists, packing
       import six
     %>
    @@ -46,7 +46,7 @@ on your version of binutils.
         while offset % 4:
             offset += 1
     %>\
    -    /* push ${repr(string)} */
    +    /* push ${pretty(string, False)} */
     % for word in lists.group(4, string, 'fill', b'\x00')[::-1]:
         ${thumb.mov(register, packing.unpack(word))}
         push {${register}}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.