Flare-On Challenge 7 Notes

flare on-7

这是我在 Flare-On Challenge 7 期间写的笔记,最终完成了 9 个challenge。

第十个 challenge 是在上海与 Ice、Vvv 学长一起挑战的,在比赛结束的凌晨还在奋战。遗憾的是,由于过于疲惫,且离散数学、密码学基础不牢,卡在了最后一个部分 – 求逆元。

[toc]

2

修复损坏的exe

  1. 填充完整程序的最后一个section
  2. 将重定向表指向0
  3. 将导入表指向0
  4. dump程序

    分析程序

  5. 程序有很多访问非法地址的指令
  6. 总结一下,非法地址本该是data段的地址
  7. 找一下规律,非法的地址似乎是正确地址转后大小序后,进行了偏移操作
  8. 在data段发现2处长字符串,符合main函数中的非法地址的访问
  9. 修复这两处地址后,就是简单的算法逆向了,比较简单,不多说
  10. 运行脚本,得到flag

3

游戏
0x0433FAD处,分数==0x128,弹出胜利界面
强制修改分数,会导致闪退,原因:getPlayerText__Uox5Ls3Q9bP7F7vcih9ag2vQ的拼接处出现overflow

发现2处碰撞的set death:
00432247 set dead 1; 00432232 to jmp
0043235E set dead 2; 00432358 to jmp
修改后,即可无敌,等待分数增长到0x128,出现flag。

4

xls,包含vb脚本
无法运行,提示参数错误

GitHub上下载的p-code反编译工具,反编译出了隐藏的代码,done。

5

手表TPK
简简单单:

1
2
(App.Password + App.Note + App.Step + App.Desc);
("mullethat" + "keep steaks for dinner" + "magic" + "water");

AES Key:248e9d7323a1a3c5d5b3283dcb2b40211a14415b6dcd2a86181721fd74b4befd
AES IV:NoSaltOfTheEarth
解密Runtime.dll,得到base64的图片,解码得到flag

6

程序是一个二维码生成器,当符合某一条件时,会生成flag的二维码。
auto it3 脚本,有反调……
程序是自动生成的,使用Exe2Aut将脚本脱出
脚本使用GetComputerNameA获取计算机名,与sprite.bmp的54字节开始,每一字节的低bit与计算机名相加➗2,随后将其sha256作为key,使用windows的crypto API AES解密内嵌的数据。
提取bmp的低bit,即可获取正确的计算机名
hook程序的GetComputerName,设置为期望的计算机名,即可得到flag。

7

给出了流量包,让我们找到被攻击泄露的东西
漏洞是IIS6.0的webdav缓冲区溢出漏洞
利用了alpha shellcode生成的纯字母shellcode
使用脚本解码shellcode,进行分析
shellcode流程:
建立socket连接,从攻击方服务器收取另一端shellcode,使用rc4解密,key如下图

分析解密后的shellcode

将accounts加密后发送给攻击方,解密流量,得到flag

1
2
3
4
5
roy:h4ve_you_tri3d_turning_1t_0ff_and_0n_ag4in@flare-on.com:goat
moss:Pot-Pocket-Pigeon-Hunt-8:narwhal
jen:Straighten-Effective-Gift-Pity-1:bunny
richmond:Inventor-Hut-Autumn-Tray-6:bird
denholm:123:dog

这个题目使用hash调用dll函数

8

井字棋,电脑先手,下中间
赢电脑出flag
电脑逻辑:
判断中间是否空,空下

封堵每一行的2个O
封堵每一列的2个O

寻找:
左上
右上
左下
右下



上面的都不重要,只需要把X win指向O win,再把flag xor ‘O’ xor ‘X’即可得到flag

感觉我的感情被flare-on欺骗了

9

exe + dll + 2 x sys

xor解密key:<g~{<it

程序先释放一个cfs.dll,是capcon的能够执行任意ring3代码的驱动,再创建服务。
程序将驱动中0xDC16F3C3B57323替换为BBACABA后,使用PsCreateSystemThread启动一个驱动的线程DriverBootstrap

BBACABA经过sha256后,作为chacha20的key,解密得到一个字符串:H@n $h0t FiRst!

dll中,使用上面的字符串作为key,rc4解密data段的0x018001A9F0,得到flag

总结一下学到的一些内容⬇️

使用hash获取module、函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void get_nt_func_hash() {
int v10 = 0;
for (size_t fun = 0; fun < 2915; fun++)
{
const char* p_name = name[fun];
{
int v8 = 0;
for (int i = 0; ; ++i)
{
__asm {
ror v8, 14;
}
v10 = v8;
if (!p_name[i])
break;
v8 = p_name[i] + v10;
}
printf("%X %s\n", v10, name[fun]);

}
}
}

内核中读取注册表

利用签名的、有漏洞(后门)的驱动加载恶意驱动

1
2
https://github.com/notscimmy/libcapcom
http://news.sina.com.cn/o/2016-10-12/doc-ifxwviax9529258.shtml

Python cryptodome 中有chacha20模块,很方便(记得手动设置nonce)

1
2
from Crypto.Cipher import ChaCha20
ChaCha20.new(key=k, nonce=b'\x00'*8).decrypt(m)

借鉴reactOS的头文件,方便在IDA中创建Windows未公开的结构体

驱动中,RtlImageNtHeader 可以方便的读取、解析NT头

驱动中,调用 PsCreateSystemThread 启动线程,可以在线程中加载驱动

https://www.cnblogs.com/lsh123/p/7357468.html

ZwQuerySystemInformation(SystemModuleInformation, … ) 可以遍历驱动的模块

10

init array中,2次fork
提示输入的在第一个子进程

处理输入在第二个?

两个子进程互相通信

child_1(p1):
SIGTRAP 展开ID
SIGILL rm rf 自杀
SIGSEGV set eip to esp or esp+4
call 0; 引发SIGSEGV, 将流程转向p2

child_2(p2):

first part:
w3lc0mE_t0_Th3_l
second part
4nD_0f_De4th_4nd_d3strUct1oN_4nd

combined:
w3lc0mE_t0_Th3_l4nD_0f_De4th_4nd_d3strUct1oN_4nd
w3lc0mE_t0_Th3_l4nD_0f_De4th_4nd_d3strUct1oN_4nd@no-flare.com
c0ngr4ts_0n_f1n1sh1ng@no-flare.com

There are two hard things in computer science: caching, off by one errors, and comparing really big numbers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
start=get_name_ea_simple("encrypted_strings_2")
while(start<=0x081A5254):
cur=(ida_bytes.get_dword(start))
key=ida_bytes.get_dword(cur)
key=key.to_bytes(4,'little')
len=ida_bytes.get_dword(cur+4)
# print("found key:%x,len:%d"%(key,len))
ret=b''
for j in range(len):
ret+=(key[j%4]^ida_bytes.get_byte(cur+8+j)).to_bytes(1,'little')
print(ret)


start+=4
1
2
3
4
5
6
7
8
9
10
11
b'TracerPid: %d\x00'
b'elf_0n_a_sh3lf@on-flare.com\x00'
b'[email protected]\x00'
b'sm0l_bin_b1g_h34[email protected]\x00'
b'Like a phoenix, I rise from the ashes\x00'
b'I hear Wolfram Alpha is good at doing things with big numbers.\x00'
b'This challenge is so easy it exploits itself.\x00'
b'\xe3vi\x92\xc7\\\xe8\xf5\x85\xc5M\x11\x16\xfa\xf4\xe8\x00'
b'This string is used to calculate the XXTEA key to decrypt the fourth part of the flag.\x00'
b'OOPSIE WOOPSIE!! Uwu We made a mistaky wakey!!!!\x00'
b'TracerPid:\x00'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
start=get_name_ea_simple("encrypted_strings")+4
while(start<=0x81A519C):
cur=(ida_bytes.get_dword(start))
ret=b''
j=0
while(1):
if(ida_bytes.get_byte(cur+j)==0):
break
a1=ida_bytes.get_byte(cur+j)-1
a1*=16
a1&=0xff
a2=ida_bytes.get_byte(cur+j+1)-1
a2&=0xf
ret+=((a1|a2)&0xff).to_bytes(1,'little')
j+=2
print(ret)


start+=8

11

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
$jjw="kcsukccudy";
function from_base64{[System.Convert]::FromBase64String($args[0]);};
[byte[]]$rpl=from_base64("");
function geapmkxsiw
{$kjurpkot=from_base64($args[0]);[System.Text.Encoding]::ASCII.GetString($kjurpkot);};

iex(geapmkxsiw("DQokY3FsdGQ9Ig0KW0RsbEltcG9ydChgImtlcm5lbDMyYCIpXWBucHVibGljIHN0YXRpYyBleHRlcm4gSW50UHRyIEdldEN1cnJlbnRUaHJlYWRJZCgpO2BuDQpbRGxsSW1wb3J0KGAia2VybmVsMzJgIildYG5wdWJsaWMgc3RhdGljIGV4dGVybiBJbnRQdHIgT3BlblRocmVhZCh1aW50IG5vcGV5bGxheCx1aW50IGl0cXhsdnBjLEludFB0ciB3ZW8pO2BuDQpbRGxsSW1wb3J0KGAia2VybmVsMzJgIildYG5wdWJsaWMgc3RhdGljIGV4dGVybiB1aW50IFF1ZXVlVXNlckFQQyhJbnRQdHIgbHhxaSxJbnRQdHIgcWxyLEludFB0ciB0Z29td2psYSk7YG4NCltEbGxJbXBvcnQoYCJrZXJuZWwzMmAiKV1gbnB1YmxpYyBzdGF0aWMgZXh0ZXJuIHZvaWQgU2xlZXBFeCh1aW50IHduaHRpeWd2Yyx1aW50IGlneXYpOyI7DQoNCiR0c2VsY2Z4aHdvPUFkZC1UeXBlIC1tZW1iZXJEZWZpbml0aW9uICRjcWx0ZCAtTmFtZSAnYWx3JyAtbmFtZXNwYWNlIGVsdWVkdmUgLXBhc3N0aHJ1Ow0KDQokZHJ5am1ucHFqPSJmZmN4IjskbmF5dz0iDQpbRGxsSW1wb3J0KGAia2VybmVsMzJgIildYG5wdWJsaWMgc3RhdGljIGV4dGVybiBJbnRQdHIgR2V0Q3VycmVudFByb2Nlc3MoKTtgbg0KW0RsbEltcG9ydChgImtlcm5lbDMyYCIpXWBucHVibGljIHN0YXRpYyBleHRlcm4gSW50UHRyIFZpcnR1YWxBbGxvY0V4KEludFB0ciB3YXNtaHFmeSxJbnRQdHIgaHRkZ3FoZ3B3YWksdWludCB1eG4sdWludCBtZXBnY3BkYnBjLHVpbnQgeGRqcCk7IjsNCg0KJHl3cXBoc3J3PUFkZC1UeXBlIC1tZW1iZXJEZWZpbml0aW9uICRuYXl3IC1OYW1lICdwcW52b2hsZ2dmJyAtbmFtZXNwYWNlIHJtYiAtcGFzc3RocnU7DQo="));
iex(geapmkxsiw("DQoNCiRqa3k9ImVwbmMiOw0KDQoka3doaz0kdHNlbGNmeGh3bzo6T3BlblRocmVhZCgxNiwwLCR0c2VsY2Z4aHdvOjpHZXRDdXJyZW50VGhyZWFkSWQoKSk7DQppZigkeWhpYmJxdz0keXdxcGhzcnc6OlZpcnR1YWxBbGxvY0V4KCR5d3FwaHNydzo6R2V0Q3VycmVudFByb2Nlc3MoKSwwLCRycGwuTGVuZ3RoLDEyMjg4LDY0KSkNCnsNCiBbU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLk1hcnNoYWxdOjpDb3B5KCRycGwsMCwkeWhpYmJxdywkcnBsLmxlbmd0aCk7DQogaWYoJHRzZWxjZnhod286OlF1ZXVlVXNlckFQQygkeWhpYmJxdywka3doaywkeWhpYmJxdykpDQogew0KICAkdHNlbGNmeGh3bzo6U2xlZXBFeCg1LDMpOw0KIH0NCn0NCn=="));



$cqltd="
[DllImport(`"kernel32`")]`npublic static extern IntPtr GetCurrentThreadId();`n
[DllImport(`"kernel32`")]`npublic static extern IntPtr OpenThread(uint nopeyllax,uint itqxlvpc,IntPtr weo);`n
[DllImport(`"kernel32`")]`npublic static extern uint QueueUserAPC(IntPtr lxqi,IntPtr qlr,IntPtr tgomwjla);`n
[DllImport(`"kernel32`")]`npublic static extern void SleepEx(uint wnhtiygvc,uint igyv);";

$tselcfxhwo=Add-Type -memberDefinition $cqltd -Name 'alw' -namespace eluedve -passthru;

$dryjmnpqj="ffcx";$nayw="
[DllImport(`"kernel32`")]`npublic static extern IntPtr GetCurrentProcess();`n
[DllImport(`"kernel32`")]`npublic static extern IntPtr VirtualAllocEx(IntPtr wasmhqfy,IntPtr htdgqhgpwai,uint uxn,uint mepgcpdbpc,uint xdjp);";

$ywqphsrw=Add-Type -memberDefinition $nayw -Name 'pqnvohlggf' -namespace rmb -passthru;
$jky="epnc";

$kwhk=$tselcfxhwo::OpenThread(16,0,$tselcfxhwo::GetCurrentThreadId());
if($yhibbqw=$ywqphsrw::VirtualAllocEx($ywqphsrw::GetCurrentProcess(),0,$rpl.Length,12288,64))
{
[System.Runtime.InteropServices.Marshal]::Copy($rpl,0,$yhibbqw,$rpl.length);
if($tselcfxhwo::QueueUserAPC($yhibbqw,$kwhk,$yhibbqw))
{
$tselcfxhwo::SleepEx(5,3);
}
}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!