Wintertask

  • winterTASK.exe
    • RESERVE
    • PWN(Level-Paimon)
      • 基础知识准备

winterTASK.exe

一开始没有Hint的时候走了许多弯路,幸好Hint放得早。

RESERVE

先从Level-空开始吧
直接双击打开程序,输入a,结果错误的话就输出nice。
直接IDA64打开程序按F5查看伪c代码

int __cdecl main(int argc, const char **argv, const char **envp)
{CreateThread(0i64, 0i64, StartAddress, 0i64, 0, 0i64);while ( dword_140005034 )Sleep(1u);Sleep(500u);system("pause");return 0;
}

可见重点在于

CreateThread()函数

百度百科对于CreateThread()函数的介绍
调用StartAddress()函数创建了一个新进程,双击查看该函数

__int64 __fastcall StartAddress(LPVOID lpThreadParameter)
{DWORD (__stdcall *i)(LPVOID); // raxDWORD flOldProtect; // [rsp+48h] [rbp+10h] BYREFVirtualProtect(loc_1400011A0, (char *)main - (char *)loc_1400011A0, 0x40u, &flOldProtect);for ( i = loc_1400011A0; (unsigned __int64)i < (unsigned __int64)main; i = (DWORD (__stdcall *)(LPVOID))((char *)i + 1) )*(_BYTE *)i ^= 0x44u;CreateThread(0i64, 0i64, loc_1400011A0, 0i64, 0, 0i64);return 0i64;
}

根据Hint结合BUUCTF-re-[GWCTF 2019]re3与SMC 入门笔记 && HGAME 题目复现 这两篇文章,可知loc_1400011A0为加密块的起始地址,并且在main函数(0x1400015A0)前截止,采用与0x44异或来加密,于是编写的解密脚本。

#include <idc.idc>static main()
{auto addr = 0x1400011A0;auto main = 0x1400015A0;for (; addr < main ; addr++ ){PatchByte(addr, Byte(addr) ^ 0x44);
}
}

解密前:

解密后:

但是loc_1400011A0没有自动生成sub_xxx的函数,先随便选中汇编汇编代码块,按P生成函数,出现了错误,而且标红

按F5查看伪C代码:

_int64 __fastcall sub_1400011A0(LPVOID lpThreadParameter, __int64 a2, __int64 a3, __int64 a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, __int64 a20, __int64 a21)
{__int64 v21; // rdxint v22; // er8int v23; // er9__int64 v24; // rax__int128 v26[6]; // [rsp+20h] [rbp-78h] BYREFint v27; // [rsp+80h] [rbp-18h]v26[0] = 0i64;v27 = 0;v26[1] = 0i64;v26[2] = 0i64;v26[3] = 0i64;v26[4] = 0i64;v26[5] = 0i64;sub_140001760(std::cout, "Give me some words > "); //对应程序开头的输出sub_140001A00(std::cin, v21, v26); //对应输入,但是有两个参数if ( LODWORD(v26[0]) == “PUQC“ && BYTE4(v26[0]) == ”T“ ){rand();JUMPOUT(0x14000121Ai64);}v24 = -1i64;do++v24;while ( *(v26 + v24) );return sub_140001299(SBYTE4(v26[0]),v26,v22,v23,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21);
}

使用sub_140001760与sub_140001A00分别调用cout与cin应该是某种更高级的CPP输入输出方法,CPP Primer Plus才看到300多页,现在先不管,后面再去找找吧。(没有SMC解密之前,以为在这两个是加密函数,看了好久都没看懂QAQ)。

随后的if判断:
关于LODWORD

这是Win32编程中常用的两个宏,
HIWORD是High Word的缩写du,作用是取得某个zhi4字节变量(即32位的值dao)在内存中处于高位的两zhuan个字节,即一个word长的数据,例如对于十六进制数0xCCDDEEFF,那么HIWORD(0xCCDDEEFF)得到的结果就是oxCCDD,正好是一个word值.
同理,LOWORD(0XCCDDEEFF)返回的结果就是0xEEFF,也正好是一个word值.
可以用下面的c语言代码测试一下:
#include <windows.h>
#include <stdio.h>
int main()
{
DWORD dwValue ;
WORD low, high ;
dwValue = 0XCCDDEEFF ;
high = HIWORD(dwValue) ;
low = LOWORD(dwValue) ;
printf(“high = 0x%x, low = 0x%x”, high, low) ;
return 0 ;
}

关于BYTE4

Sbyte:代表有符号的8位整数,数值范围从-128 ~ 127,后面跟数字应该就是位移4位了,相当于str[4](猜测)
Byte:代表无符号的8位整数,数值范围从0~255。

详情见IDA Pro反编译代码类型转换参考

LODWORD(v26[0]) == “PUQC“ && BYTE4(v26[0]) == ”T“

第一个字符串是反的”CQUP“,先输入试一下。

虽然什么也没有输出,但是也没有输出"Nice!"。
说明确实是进入到里面执行了,而不是进到sub_140001299里面(sub_140001299如果条件符合就会输出Nice!,等下再看)。
但是字符串为何是反的?想到的关联因素有:

  • __int128 str 为小端序存储方式,后面求解的时候需要特别注意!

但是if代码块里面只有rand()函数和标红的JUMPOUT(0x14000121Ai64),而跳转到的地方和上文中有标红的位置一致。
在查看了IDA出现"sp-analysis failed"和F5(反编译)失败和IDA反编译的几个注意和技巧这两篇文章后,还是第一个靠谱hhh。

第一篇文章大概意思就是说代码里面添加了花指令,通过一些手法来还原代码

发现还原不出来,但是注意到了还是那段汇编代码块,类型为db,而不是代码,一不小心,操作失误,按了右键->转化为代码,竟练出代码坤,哦原赖氏要把那几个

text:000000014000121A                 db 0C1h
.text:000000014000121B ; ---------------------------------------------------------------------------
.text:000000014000121B                 cli
.text:000000014000121B ; ---------------------------------------------------------------------------
.text:000000014000121C                 db    2
.text:000000014000121D                 db  8Bh
.text:000000014000121E                 db 0CAh
.text:000000014000121F                 db 0C1h
.text:0000000140001220                 jmp     near ptr 0CDD11544h
.text:0000000140001220 ; ---------------------------------------------------------------------------
.text:0000000140001225                 db  0Ch
.text:0000000140001226                 db  92h

按C转化为汇编代码,之前那个位置的错误就消失了。按照之前的步骤生成函数,按F5,if语句里面又有了新的内容:

v24 = rand() % 10;if ( v24 + rand() % 10 > 30 ){v25 = sub_140001760(std::cout, "Redrock");std::ostream::operator<<(v25, sub_140001930);}JUMPOUT(0x14000157Ei64);

观察到v24和v25两个变量被用了起来,但是还有其他变量没有用,而且还有JUMPOUT,而且在汇编代码处,还有sp-analysis failse

看来,没有变成代码的 db xxx才是干扰指令,这时,把从0x1400011A0到main函数之前的代码全部选中,生成函数,才得到了正确的函数:

__int64 __fastcall sub_1400011A0(LPVOID lpThreadParameter)
{__int64 v1; // rdxint v2; // ebx__int64 v3; // rax__int64 v4; // raxconst char *v5; // rdx__int64 v6; // rax__int128 v8[6]; // [rsp+20h] [rbp-78h] BYREFint v9; // [rsp+80h] [rbp-18h]v8[0] = 0i64;v9 = 0;v8[1] = 0i64;v8[2] = 0i64;v8[3] = 0i64;v8[4] = 0i64;v8[5] = 0i64;sub_140001760(std::cout, "Give me some words > ");sub_140001A00(std::cin, v1, v8);if ( LODWORD(v8[0]) == 1347768643 && BYTE4(v8[0]) == 84 ) //转换成16进制,发现是ASCII码,转换为字符串{ //这块是另一个level的入口v2 = rand() % 10;if ( v2 + rand() % 10 > 30 ){v3 = sub_140001760(std::cout, "Redrock");std::ostream::operator<<(v3, sub_140001930);}}else{v4 = -1i64;do++v4;while ( *(v8 + v4) ); //这段代码判断字符串长度是否等于8if ( v4 != 8|| 870732 * SBYTE5(v8[0])+ 620576 * SBYTE6(v8[0])+ 687392 * SBYTE3(v8[0])+ 790701 * SBYTE4(v8[0])- 264980 * SLOBYTE(v8[0])- 558068 * SBYTE1(v8[0])- 940616 * SBYTE7(v8[0])- 805665 * SBYTE2(v8[0]) != -1990197|| 242625 * SBYTE5(v8[0])+ 230650 * SBYTE4(v8[0])+ 460946 * SBYTE3(v8[0])+ 269419 * SLOBYTE(v8[0])+ 630862 * SBYTE1(v8[0])- 24920 * SBYTE7(v8[0])- 482510 * SBYTE2(v8[0])- 580412 * SBYTE6(v8[0]) != 50416313|| 340464 * SBYTE2(v8[0])+ 719348 * SBYTE3(v8[0])+ 240775 * SBYTE7(v8[0])+ -207754 * SBYTE1(v8[0])- 470557 * SLOBYTE(v8[0])- 719143 * SBYTE5(v8[0])- 114858 * SBYTE6(v8[0])- 13126 * SBYTE4(v8[0]) != -8167199|| 639378 * SBYTE5(v8[0])+ 903739 * SBYTE2(v8[0])+ 577554 * SBYTE3(v8[0])+ 107894 * SBYTE7(v8[0])- 860840 * SLOBYTE(v8[0])- 657457 * SBYTE6(v8[0])- 358459 * SBYTE4(v8[0])- 179591 * SBYTE1(v8[0]) != 8821640|| 1848 * SBYTE1(v8[0])+ 693461 * SBYTE2(v8[0])+ 862506 * SBYTE7(v8[0])- 208232 * SBYTE6(v8[0])- 664100 * SBYTE4(v8[0])- 192669 * SBYTE5(v8[0])- 354894 * SLOBYTE(v8[0])- 644389 * SBYTE3(v8[0]) != -31320696|| 773383 * SBYTE1(v8[0])+ 154384 * SBYTE7(v8[0])+ 714136 * SBYTE5(v8[0])+ -592212 * SBYTE6(v8[0])- 858737 * SBYTE4(v8[0])- 263859 * SLOBYTE(v8[0])- 130037 * SBYTE3(v8[0])- 997096 * SBYTE2(v8[0]) != -80151959|| 209448 * SBYTE1(v8[0])+ 679897 * SLOBYTE(v8[0])+ 138284 * SBYTE7(v8[0])- 982280 * SBYTE4(v8[0])- 127647 * SBYTE2(v8[0])- 157768 * SBYTE6(v8[0])- 679219 * SBYTE5(v8[0])- 907473 * SBYTE3(v8[0]) != -85049773|| (v5 = "Chongqing No Water No Electric No Network University",802559 * SBYTE4(v8[0])+ 448649 * SBYTE5(v8[0])+ 190047 * SBYTE1(v8[0])+ -256569 * SBYTE7(v8[0])- 813631 * SLOBYTE(v8[0])- 708096 * SBYTE3(v8[0])- 999068 * SBYTE2(v8[0])- 965947 * SBYTE6(v8[0]) != -166206160) ){v5 = "Nice!";}v6 = sub_140001760(std::cout, v5);std::ostream::operator<<(v6, sub_140001930);}dword_140005034 = 0;return 0i64;
}

根据Hint提示,使用z3约束器,这里需要注意,如果把负数变为16进制,再变回10进制,IDA会错误判断

参考文章CG-CTF-re-签到题
写出py脚本:

from z3 import *
s = Solver()
a1 = [0] * 8
for i in range(8):a1[i] = Int('a1['+ str(i)+']')
for i in range(1,8):s.add(a1[i] >0)s.add(a1[i] <255)
s.add(870732 *  a1[5]+ 620576 *  a1[6]+ 687392 *  a1[3]+ 790701 *  a1[4]- 264980 *  a1[0]- 558068 *  a1[1]- 940616 *  a1[7]- 805665 *  a1[2] == -1990197 )
s.add(242625 *  a1[5]+ 230650 *  a1[4]+ 460946 *  a1[3]+ 269419 *  a1[0] + 630862 *  a1[1]- 24920 *   a1[7]- 482510 *  a1[2]- 580412 *  a1[6] == 50416313)
s.add(340464 *  a1[2]+ 719348 *  a1[3]+ 240775 *  a1[7]+ (-207754 *  a1[1])- 470557 * a1[0] - 719143 *  a1[5]- 114858 *  a1[6]- 13126 *  a1[4] == -8167199)
s.add(639378 *  a1[5] + 903739 *  a1[2] + 577554 *  a1[3] + 107894 *  a1[7 ]- 860840 *  a1[0]- 657457 *  a1[6] - 358459 *  a1[4] - 179591 *  a1[1]  == 8821640)
s.add(1848 *  a1[1] + 693461 *  a1[2] + 862506 *  a1[7] - 208232 *  a1[6] - 664100 *  a1[4] - 192669 *  a1[5] - 354894 *  a1[0]- 644389 *  a1[3]  != -31320696)
s.add(773383 *  a1[1] + 154384 *  a1[7] + 714136 *  a1[5] + (-592212 *  a1[6]) - 858737 *  a1[4] - 263859 *  a1[0]- 130037 *  a1[3] - 997096 *  a1[2]  == -80151959)
s.add(209448 * a1[1] + 679897 * a1[0]+ 138284 * a1[7] - 982280 * a1[4] - 127647 * a1[2] - 157768 * a1[6] - 679219 * a1[5] - 907473 * a1[3]  == -85049773)
s.add(802559 * a1[4] + 448649 * a1[5] + 190047 * a1[1] + (-256569 * a1[7]) - 813631 * a1[0]- 708096 * a1[3] - 999068 * a1[2] - 965947 * a1[6]  == -166206160)
print(s.check())
answer = s.model
print(answer)

得到结果:

转换成字符:
解毕
Level-荧
根据Hint,主要思路为:
通过动态调试,找到条件判断完成后的位置,修改下一段汇编代码,跳转输出。
程序入口点:

根据前面的分析,在判断前,直接JMP到V4赋值的位置

下断点,断点下在:

JMP到赋值的代码块位置 |

再次修改此处汇编代码:

修改之后就会执行转移,

按Ctr +P把之前的修改应用成为补丁,这里也可以在IDA里面修改汇编代码,然后直接把补丁打入程序内,参考IDA打补丁

PWN(Level-Paimon)

基础知识准备

Windows下的PWN以前没有接触过,学习的资料相对于Linux也比较少,先从基础开始吧。

Windows Pwn 学习之路这篇文章包含了Win下PWN的环境配置还有详细的基础知识。
关于vcpkg的环境配置有很多坑,除了文章中提到的,这里列举一下我出现的问题的解决方法。

  1. 必须要安装Visual Studio和一些组件才能正常运行vcpkg
  • 用于CMake和Linux的VisualC++工具
  1. 引用包下载失败解决办法: vcpkg问题-环境配置

  2. 编译时要用
    cmake -B [build directory] -S . -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake 这个命令

然后看一些例题 Windows漏洞利用开发教程Part1

红岩网校运维安全部二进制安全方向冬季考核:Winter_Task相关推荐

  1. 运维的职业发展方向有哪些?该如何规划?

    互联网运维工作,以服务为中心,以稳定.安全.高效为三个基本点,确保公司的互联网业务能够7×24小时为用户提供高质量的服务. 运维工作分类 运维的工作方向比较多,随着业务规模的不断发展,越成熟的互联网公 ...

  2. 公有云运维安全常见四大难题及解决方案

    公有云运维安全常见四大难题及解决方案 参考文章: (1)公有云运维安全常见四大难题及解决方案 (2)https://www.cnblogs.com/aliyunblogs/p/5193127.html ...

  3. 永恒之蓝病毒事件所引发的运维安全行业新思考

    一.NSA "永恒之蓝" 勒索蠕虫全球爆发 2017年5月12日爆发的 WannaCry勒索病毒肆虐了全球网络系统,引起各国企业和机构极大恐慌.而这次受害最严重的是Windows系 ...

  4. 阿里云——运维安全中心(堡垒机)

    运维安全中心(堡垒机) 构建云上统一.高效.安全运维通道,保障云端运维.办公权限可管控.操作行为可审计 高效&安全运维 运维安全中心(堡垒机)用于集中管理资产权限,全程监控操作行为,实时还原运 ...

  5. 齐治运维安全培训【初级】练习题

    齐治运维安全培训[初级]练习题 堡垒机支持以下哪些功能? 人员身份鉴别 访问权限控制 VPN 操作行为审计 对管理的服务器进行定期杀毒 哪些设备或系统能够通过堡垒机访问目标资产 手机 平板 Macos ...

  6. 学会linux需要哪些技术,运维安全需要掌握哪些技术呢?linux基础知识学习

    随着IT技术和业务的发展,以及各式各样安全漏洞的涌现,运维与安全这两个专业日渐交融,各企业对于运维安全的重视程度越来越高.安全和运维是业务稳定运行的保障.运维安全的发展前景是非常广阔的,吸引了许多人开 ...

  7. 系统运维安全管理办法_运维安全管理系统-堡垒机

    随着信息化的快速发展与普及,业务运行已于信息化系统密不可分,由于业务需求的不断拓展,信息化系统的建设也在不断深入与增长, 企业的业务系统变得日益复杂,信息化系统俨然已经成为了业务运行保障的重中之重,信 ...

  8. 从乌云看运维安全那点事儿

    本文转自乌云知识库 0x00 背景 运维安全属于企业安全非常重要的一环. 这个环节出现问题,往往会导致非常严重的后果. 本文从乌云上提交的近2000个运维方面的漏洞总结了一下经常出问题的点. 希望各位 ...

  9. 房地产行业IT运维安全就用行云管家堡垒机!

    对于房地产行业而言,安全TI运维是构建数字化企业的核心,是推动其业务发展的信息化支撑体系.所以一个靠谱的IT运维安全软件非常重要.不仅可以省时省力,还能保障网络安全!这里我给推荐行云管家堡垒机! 行云 ...

最新文章

  1. L09-10老男孩Linux运维实战培训-Nginx服务生产实战应用指南05(架构解决方案)
  2. 飒!阿里巴巴 29 个吊炸天的开源项目!
  3. ikbc键盘自动打字_键盘按斤卖,一斤一百块?IKBC W200机械键盘简晒
  4. excel查找空值快捷键_Excel工资表怎么做?3分钟学会利用函数生成工资表
  5. 安装 VMware Workstation Pro 16 并创建 ubuntu 20.04 虚拟机
  6. GDCM:压缩DICOM影像文件的测试程序
  7. 虚机大比拼之HYPER-V
  8. position:relative 与 position:absolute
  9. 二叉树输出(信息学奥赛一本通-T1366)
  10. 【空间】C++内存管理
  11. 【Transformer】10个重要问题概览Transformer全部内容
  12. Red5 流媒体技术(初级了解)
  13. 【TUG 话题探讨003】TUG 专家们如何做 TiDB 性能调优
  14. Towards Binary-Valued Gates for Robust LSTM Training
  15. 6月书讯(上)| 浅夏读新书,与世间万物一起成长
  16. 可视化学习笔记4:使用颜色
  17. python 计算斐波那契数列方法,递归方法求第N项的斐波那契数
  18. newifi3 web认证_newifi新路由3图文设置教程 | 192.168.1.1登陆页面
  19. Win系统 - 关闭 Windows 应用商店自动更新
  20. 互联网晚报 | 10月28日 星期四 | 农夫山泉钟睒睒首次成为中国首富;淘宝购物车分享功能上线;段永平否认牵头OV联合造车...

热门文章

  1. 高工拆解|停产燃油车/钦点英伟达,比亚迪智驾背后的大杂烩
  2. 西安的大学二本类计算机与新网络,西安二本大学最新排名
  3. Android A/B System OTA分析(五)客户端参数
  4. 在centos7.5中解压.tgz
  5. 《HTTP权威指南》第十三章学习总结--摘要认证
  6. 向别人请教问题,不要这样开头
  7. 微信小程序对苹果(ipone)手机不能选择复制的问题解决方法
  8. 随机种子、torch.backends.cudnn.benchmark\.deterministic
  9. 雄安新区海关完成首票数字货币保证金缴纳业务
  10. c语言连连看实验报告,连连看C语言课程设计报告