BUUCTF Re部分wp(四)
[FlareOn5]Minesweeper Championship Registration
java逆向,我把jar解压成了一个class文件和一个.MF文件,把class扔进ida
得到flag
[RoarCTF2019]polyre
拖进ida
控制流平坦化,用deflat处理:
虚假控制流程,看着还是很恶心
这的jnz是必定跳转的,用idapython处理一下
addr = 0x401198
while(addr<0x4020cc):
next_addr = NextHead(addr)
if "ds:dword_603054" in GetDisasm(addr):
while(True):
addr = next_addr
next_addr = NextHead(addr)
if GetMnem(addr)=="jnz":
dest = GetOperandValue(addr,0)
PatchByte(addr,0xe9)
PatchByte(next_addr-1,0x90)
PatchDword(addr+1,dest-next_addr+1)
addr = next_addr
break
else:
addr = next_addr
idapython用法参考了https://blog.csdn.net/oShuangYue12/article/details/85675751
处理之后
main已经可以看懂了,crc64,emm然而我逆不回去。。。
在看了官方wp后,emmm密码学真神奇
[FlareOn6]Overlong
把unk_1242008 解密后输出了,但程序只用了unk前1Ch长度
把push 1ch改为afh,得到flag
[2019红帽杯]childRE
64exe,拖进ida
输入经过变换后以以上方式进行比对,
a="1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./" b="55565653255552225565565555243466334653663544426565555525555222" c="(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&" f="" for i in range(62): for j in range(128): if a[j//23]==b[i] and a[j%23]==c[i]: f+=chr(j) print(f)
#private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
关键在于
得到?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
输入时经过了换位,输入了一串字符测试
c="?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"
a="pqhrsidtujvwkebxylz1mf23n45ogca"
b="abcdefghijklmnopqrstuvwxyz12345"
f=[]
for i in range(31):
f.append(0)
for i in range(31):
for j in range(31):
if b[j]==a[i]:
f[j]=c[i]
break
for i in range(31):
print(f[i],end="")
md5得flag
findkey
根据字符串找到关键函数
创建函数失败,显示
.text:0040191F: The function has undefined instruction/data at the specified address.
Your request has been put in the autoanalysis queue.
往下看
这里连续push了两个,nop掉下面那个
string1加密后 与v21加密后比较,加密v12的sub_401005是与v17异或
string1加密方式使用了CryptCreateHash的md5
a="0kk`d1a`55k222k2a776jbfgd`06cjjb"
b="S"
for i in a:
print(chr(ord(i)^ord(b[0])),end="")
得到md5值,在线求得string1为123321
之后通过sub_401005又将string1与unk_423030异或得到flag
c="123321"
d="57 5E 52 54 49 5F 01 6D 69 46 02 6E 5F 02 6C 57 5B 54 4C"
d=d.split()
for i in range(len(d)):
d[i]=eval("0x"+d[i])
for i in range(len(d)):
print(chr(d[i]^ord(c[i%6])),end="")
[MRCTF2020]hello_world_go
go逆向,没去符号,找到main_main
找到flag
[MRCTF2020]PixelShooter
apk不太会,但这是用unity写的,把Assembly-CSharp.dll用dnspy打开
这有个GameOver
[FlareOn3]Challenge1
又是换表base64
import base64
c="x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"
flag=""
table="ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
table2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in c:
for j in range(len(table)):
if i==table[j]:
flag+=table2[j]
flag=base64.b64decode(flag)
print(flag)
[FlareOn5]Ultimate Minesweeper
毫无游戏体验的扫雷小游戏,c#写的,扔进dnspy
public MainForm()
{
this.InitializeComponent();
this.MineField = new MineField(MainForm.VALLOC_NODE_LIMIT);
this.AllocateMemory(this.MineField);
this.mineFieldControl.DataSource = this.MineField;
this.mineFieldControl.SquareRevealed += this.SquareRevealedCallback;
this.mineFieldControl.FirstClick += this.FirstClickCallback;
this.stopwatch = new Stopwatch();
this.FlagsRemaining = this.MineField.TotalMines;
this.mineFieldControl.MineFlagged += this.MineFlaggedCallback;
this.RevealedCells = new List<uint>();
}
AllocateMemory创建雷区,SquareRevealedCallback判断成功失败
private void AllocateMemory(MineField mf)
{
for (uint num = 0U; num < MainForm.VALLOC_NODE_LIMIT; num += 1U)
{
for (uint num2 = 0U; num2 < MainForm.VALLOC_NODE_LIMIT; num2 += 1U)
{
bool flag = true;
uint num3 = num + 1U;
uint num4 = num2 + 1U;
if (this.VALLOC_TYPES.Contains(this.DeriveVallocType(num3, num4)))
{
flag = false;
}
mf.GarbageCollect[(int)num2, (int)num] = flag;
}
}
}
我本来想法是控制雷的生成
private void AllocateMemory(MineField mf)
{
for (uint num = 0U; num < MainForm.VALLOC_NODE_LIMIT; num += 1U)
{
for (uint num2 = 0U; num2 < MainForm.VALLOC_NODE_LIMIT; num2 += 1U)
{
bool flag = true;
int num3 = (int)(num + 1U);
uint num4 = num2 + 1U;
if ((num3 == 1 && num4 == 1U) || (num3 == 2 && num4 == 2U) || (num3 == 3 && num4 == 3U))
{
flag = false;
}
mf.GarbageCollect[(int)num2, (int)num] = flag;
}
}
}
但是flag是加密过的,需要正确位置解密,所以我改成了这样
private void AllocateMemory(MineField mf)
{
for (uint num = 0U; num < MainForm.VALLOC_NODE_LIMIT; num += 1U)
{
for (uint num2 = 0U; num2 < MainForm.VALLOC_NODE_LIMIT; num2 += 1U)
{
bool flag = true;
uint num3 = num + 1U;
uint num4 = num2 + 1U;
if (this.VALLOC_TYPES.Contains(this.DeriveVallocType(num3, num4)))
{
flag = false;
Console.Write(num3);
Console.Write(num4);//断点下在这
}
mf.GarbageCollect[(int)num2, (int)num] = flag;
}
}
}
这样就得到了坐标,(1D,8),(8,15),(19,1D)
点三个点得到flag
[安洵杯 2019]game
ollvm,用deflat去除,找到关键代码
D0g3是数独的盘,输入被转换后输入盘,结果已经在Sudoku给出来了
a="4693641762894685722843556137219876255986"
b="HJMGJHEKJFLMHJLIKFFLHGIIJEGKFEMLKJFIIMLJ"
#f.add((x[i]+0xf3|~x[i]-0xc) - 20 == eval(a[i]))
flag=[]
t1="@ABCDEFGHIJKLMNO"
t2="LMNOHIJKDEFG@ABC"
#x[i]+0xf3|~x[i]-0xc只改变了第67bit,所以可以换成这样的表
for i in range(len(b)):
for j in range(len(t1)):
if b[i]==t1[j]:
flag.append(t2[j])
for i in range(0,len(flag),2):
temp=flag[i]
flag[i]=flag[i+1]
flag[i+1]=temp
for i in flag:
print(i,end="")
[Zer0pts2020]easy strcmp
strcmp被hook了,输入先进行了转换
a="42 09 4A 49 35 43 0A 41 F0 19 E6 0B F5 F2 0E 0B 2B 28 35 4A 06 3A 0A 4F"
a=a.split()
b="********CENSORED********"
for i in range(len(a)):
print(chr((ord(b[i])+eval("0x"+a[i]))&0xFF),end="")
跑出来有几位不对,调试发现需要+1