2019 GXY_Re部分_WriteUp

2024-01-21 11:30
文章标签 2019 部分 re writeup gxy

本文主要是介绍2019 GXY_Re部分_WriteUp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

赛题下载地址:https://www.lanzous.com/b07r91skd

 

0x01 lucky_guy

IDA打开

进入patch_me

进入get_flag

 

随机产生5个数字,每产生一个进入下面switch进行处理

 

 

代码分析

分析得到处理顺序

1中得到f2的初始值"icug`of ",2可能执行多次,3中f1为 "GXY{do_not_",因此可以写出C++代码模拟过程。

 

程序解密

#include <iostream>using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) {char v1;char f2[] = "icug`of ";cout << f2 << endl;for (int i = 0; i < 4; ++i) {for (int j = 0; j <= 7; ++j) {if (j % 2 == 1)v1 = f2[j] - 2;elsev1 = f2[j] - 1;f2[j] = v1;}cout << f2 << endl;}return 0;
}

得到后半部分,"hate_me}"

组合起来就是GXY{do_not_hate_me}

 

get flag!

GXY{do_not_hate_me}

 

0x02 simple_CPP

IDA打开

将代码整体分为了三个部分

 1 if ( v37 > 0 )2   {3     v5 = 0i64;4     do5     {6       v6 = &Memory;                             // v6为输入7       if ( v38 >= 0x10 )8         v6 = Memory;9       v7 = &Dst;                                // Dst=i_will_check_is_debug_or_not
10       if ( (unsigned __int64)qword_140006060 >= 0x10 )
11         v7 = (void **)Dst;
12       v3[v5] = v6[v5] ^ *((_BYTE *)v7 + v4++ % 27);// 输入进行变换
13       ++v5;
14     }
15     while ( v4 < v37 );
16   }

 

 1   do2   {3     v14 = *v13 + v8;                            // 对输入变换后的字符串再进行变换4     ++v12;5     ++v13;6     switch ( v12 )7     {8       case 8:                                   // v11=第8位的9         v11 = v14;
10         goto LABEL_24;
11       case 16:
12         v10 = v14;                              // v11第16位的
13         goto LABEL_24;
14       case 24:                                  // v11=第24位
15         v9 = v14;
16 LABEL_24:
17         v14 = 0i64;
18         break;
19       case 32:
20         sub_1400019C0(std::cout, "ERRO,out of range");
21         exit(1);
22         break;
23     }
24     v8 = v14 << 8;
25   }
26   while ( v12 < (signed int)v37 );

 

 1   v35 = v15[2];                                 // 1-22   v16 = v15[1];3   v17 = *v15;                                   // 1-24   v18 = sub_14000223C(0x20ui64);5   if ( IsDebuggerPresent() )6   {7     sub_1400019C0(std::cout, "Hi , DO not debug me !");8     Sleep(0x7D0u);9     exit(0);
10   }
11   v19 = v16 & v17;
12   *v18 = v16 & v17;
13   v20 = v35 & ~v17;                             // 1-1
14   v18[1] = v20;
15   v21 = ~v16;
16   v22 = v35 & v21;
17   v18[2] = v35 & v21;
18   v23 = v17 & v21;
19   v18[3] = v23;
20   if ( v20 != 1176889593874i64 )
21   {
22     v18[1] = 0i64;
23     v20 = 0i64;
24   }
25   v24 = v20 | v19 | v22 | v23;
26   v25 = v15[1];
27   v26 = v15[2];
28   v27 = v22 & *v15 | v26 & (v19 | v25 & ~*v15 | ~(v25 | *v15));
29   v28 = 0;
30   if ( v27 == 577031497978884115i64 )
31     v28 = v24 == 4483974544037412639i64;
32   if ( (v24 ^ v15[3]) == 4483974543195470111i64 )
33     v0 = v28;
34   if ( (v20 | v19 | v25 & v26) != (~*v15 & v26 | 864693332579200012i64) || v0 != 1 )
35   {
36     sub_1400019C0(std::cout, "Wrong answer!try again");
37     j_j_free(v3);
38   }
39   else
40   {
41     v29 = sub_1400019C0(std::cout, "Congratulations!flag is GXY{");
42     v30 = &Memory;
43     if ( v38 >= 0x10 )
44       v30 = Memory;
45     v31 = sub_140001FD0(v29, v30, v37);
46     sub_1400019C0(v31, "}");
47     j_j_free(v3);
48   }

 

代码分析

针对第三部分:

首先整理第三部分的各个运算式子

v19 = v15[1] & v17[0]
v20 = v15[2] & ~v15[0]
v20 = 1176889593874
v21 = ~v15[1]
v22 = v15[2] & ~v15[1]
v23 = v15[0] & ~v15[1]
v24 = (v15[2] & ~v15[0]) | (v15[1] & v15[0]) | (v15[2] & ~v15[1]) | (v15[0] & ~v15[1])
v24 = 4483974544037412639
v25 = v15[1]
v26 = v15[2]
v27 = (v15[2] & ~v15[1]) & v15[0] | v15[2] & ((v15[1] & v17[0]) | v15[1] &~v15[0] | ~(v15[1] | v15[0]))
v27 = 577031497978884115
v24 ^ v15[3] = 4483974543195470111
((v15[2] & ~v15[0]) | ( v15[1] & v17[0]) | v15[1] & v15[2]) == (~v15[0] & v15[2] | 864693332579200012)

 

使用z3解方程,得到v15[0]~v15[3]的解

# -*- coding:utf-8 -*-from z3 import *x,y,z,w=BitVecs('x y z w',64)s=Solver()s.add((~x)&z==1176889593874)
s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))s.check()
m = s.model()
for i in m:print("%s = 0x%x"%(i,m[i].as_long()))

 

w = 0x32310600
z = 0x8020717153e3013
y = 0xc00020130082c0c
x = 0x3e3a460533286f0d

 

针对第二部分:

将x,y,z,w拼接起来,并将x,y,z补足为16位

li=[]
# 拼接
li.append(hex(m[x].as_long())[2:].rjust(16,"0"))
li.append(hex(m[y].as_long())[2:].rjust(16,"0"))
li.append(hex(m[z].as_long())[2:].rjust(16,"0"))
li.append(hex(m[w].as_long())[2:-2])
print(li)

 

['3e3a460533286f0d', '0c00020130082c0c', '08020717153e3013', '323106']

 

针对第一部分:

就是一个异或的表达式,通过动态调试可以得到Dst的值为"i_will_check_is_debug_or_not",即可得到v7,再将异或逆向就行。

 

脚本解密

# -*- coding:utf-8 -*-from z3 import *debug_str = "i_will_check_is_debug_or_not"
x,y,z,w=BitVecs('x y z w',64)s=Solver()s.add((~x)&z==1176889593874)
s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))s.check()
m = s.model()
for i in m:print("%s = 0x%x"%(i,m[i].as_long()))
flag=""
li=[]
# 拼接
li.append(hex(m[x].as_long())[2:].rjust(16,"0"))
li.append(hex(m[y].as_long())[2:].rjust(16,"0"))
li.append(hex(m[z].as_long())[2:].rjust(16,"0"))
li.append(hex(m[w].as_long())[2:-2])
print(li)v4=0
for i in li:for j in range(0,len(i),2):xx = i[j]+i[j+1]flag += chr(int(xx,16)^ord(debug_str[(v4)%27]))v4 += 1print(flag)

解出来得到的flag为

We1l_D0n
We1l_D0ndeajoa_S
We1l_D0ndeajoa_Slgebra_a
We1l_D0ndeajoa_Slgebra_am_i

 

get flag!

通过官方给的提示,第二部分有问题,给了第二部分的解“e!P0or_a”,替换掉我们得到的,得到正确的flag

GXY{We1l_D0ne!P0or_algebra_am_i}

 

完整WP:链接1,链接2

这篇关于2019 GXY_Re部分_WriteUp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/629383

相关文章

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

项目实战系列三: 家居购项目 第四部分

购物车 🌳购物车🍆显示购物车🍆更改商品数量🍆清空购物车&&删除商品 🌳生成订单 🌳购物车 需求分析 1.会员登陆后, 可以添加家居到购物车 2.完成购物车的设计和实现 3.每添加一个家居,购物车的数量+1, 并显示 程序框架图 1.新建src/com/zzw/furns/entity/CartItem.java, CartItem-家居项模型 /***

码蹄集部分题目(2024OJ赛9.4-9.8;线段树+树状数组)

1🐋🐋配对最小值(王者;树状数组) 时间限制:1秒 占用内存:64M 🐟题目思路 MT3065 配对最小值_哔哩哔哩_bilibili 🐟代码 #include<bits/stdc++.h> using namespace std;const int N=1e5+7;int a[N],b[N],c[N],n,q;struct QUERY{int l,r,id;}que

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

关于断言的部分用法

1、带变量的断言  systemVerilog assertion 中variable delay的使用,##[variable],带变量的延时(可变延时)_assertion中的延时-CSDN博客 2、until 的使用 systemVerilog assertion 中until的使用_verilog until-CSDN博客 3、throughout的使用   常用于断言和假设中的

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

VB和51单片机串口通信讲解(只针对VB部分)

标记:该篇文章全部搬自如下网址:http://www.crystalradio.cn/thread-321839-1-1.html,谢谢啦            里面关于中文接收的部分,大家可以好好学习下,题主也在研究中................... Commport;设置或返回串口号。 SettingS:以字符串的形式设置或返回串口通信参数。 Portopen:设置或返回串口

node快速复制文件或文件夹,排除部分文件(node_modules)

const fs = require('fs')const path = require('path')/*** @description: 获取完整的文件路径* @param {*} url 路径* @return {*} 返回完整的文件路径*/const getPath = (url) => {return path.join(__dirname, url)}/*** @descr