WeChall - Agent Larry

One of our agents (codename Larry) was able to sniff Oracle network traffic deep in the Russian network. First Larry obtained some traffic when users authenticated to the database, this traffic you can find here

Afterwards, Larry sniffed some traffic when the database made some network backup. When he realized how important this could be, the agent immediately forwarded the traffic to the headquarter, but unfortunately the transmission was stopped. We could not make any contact to Larry anymore.

Our experts already analyzed this traffic, and were able to restore the beginning of a database file, which you can find here.

Your goal is to obtain a valid username - password - connect identifier in the following form

database_username/password@database_ip:port/database_name

This challenge fits in the Internet/Forensics section, so use google to find the right tool for it. After you have found the tool, you need a lot of oracle dll's. You can download it from Oracle official site (Oracle Database Client), but I made a small client for this challenge, you can download it here: Oracle DLLs

On the headquarter you found some analyzed Oracle traffic, maybe it will help you to understand more Oracle TNS traffic. You can download it here: example.txt.

And the last information for you, is that the clients were connecting to the database via IP tunneling, but the traffic was captured after the tunneling was terminated.

You don't have too much time to solve this, so you think brute force is not the way...

If you cannot find the tool, don't worry, you will find it Sooner or Later :)

Challenge

Agent Larry(Z 出题)提供了四样东西:

  • dump.pcap — Oracle TNS 认证流量(IP tunneling 结束后抓的)
  • database.rar — 数据库备份流量恢复出的 SYSTEM01.dbf 开头(1MB)
  • oradlls.zip — Oracle 10g 客户端 DLL 集合(oran10.dll 等 29 个)
  • example.txt — 专家分析过的示例流量格式说明

目标是恢复有效连接串:

1
database_username/password@database_ip:port/database_name

题面提示:

  • "brute force is not the way" — 明确排除暴力破解
  • "you will find it Sooner or Later" — 双关:soonerorlater.hu,Laszlo Toth 的 Oracle 密码恢复工具(woraauthbf)

URL

  • 挑战页: https://www.wechall.net/challenge/Z/agent_larry/index.php

解法

1. 解析 pcap — TNS 握手与 O5LOGON 认证

1
tshark -r dump.pcap

两个 TCP 流,客户端 192.168.1.1 → 服务器 192.168.1.4:1521(Oracle 默认端口)。

Connect 包里的 CONNECT_DATA:

1
2
3
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=cekpet)
(CID=(PROGRAM=C:\instantclient_10_2\sqlplus.exe)(HOST=X)(USER=Yuri)))
(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))
  • SERVICE_NAME = cekpet(数据库名)
  • HOST=127.0.0.1 只是 IP tunneling 的假象(example.txt 明示),真实 IP 看 TCP 层 = 192.168.1.4
  • USER=Yuri 只是 sqlplus 的 OS 用户名(AUTH_SID),不是数据库用户名

流 1(yuri 尝试)以失败告终:

1
ORA-01017: invalid username/password; logon denied

流 2 认证包(onegin 登录成功),提取 O5LOGON 认证数据:

1
2
3
4
5
6
AUTH_SESSKEY@...@12F9D4A97818D48E722835A0B92FB5CBD8FFBD66EF307C0F0324FDB8A2F90C4B  (server)
AUTH_SESSKEY@...@1FB2DA0F8EDE694E11A75AB4D1077C2033ED941DE6B5B09789B6EC870430A4E3 (client)
AUTH_PASSWORD@...@AF0EBF4772885A458BE07CD982A19EEAAE6EBD64504031260F8B63A5E882D26B
AUTH_DBNAME.....CEKPET
AUTH_SC_SERVER_HOST.....xp2000
AUTH_SC_SERVICE_NAME.....cekpet

服务器最终确认 USER=ONEGIN(NLS_LANGUAGE='RUSSIAN')→ 登录用户是 onegin

2. 提取数据库 hash

database.rar 解开是 SYSTEM01.dbf(Oracle 10g 数据文件开头 1MB),strings 里能看到 3 个用户及相邻的 password hash:

1
2
3
YURI    A1D41F67E0B29E26
ONEGIN 4FDB184F1CE30572
ANYEGIN E4BA299AAE1AA136

这就是题面说的"不止一个用户,数据库文件里有多个 password hash"。

3. 用 hash 解密流量(Sooner or Later 原理)

Oracle 9i/10g 认证协议(soonerorlater.hu 的文章 oracle_auth_9i10g):

  • Server/Client 的 AUTH_SESSKEY 用 password hash 加密(与 8i 相同的 DES 机制)
  • 因此拿到 password hash 就能解密 AUTH_SESSKEY,再组合出密钥解密 AUTH_PASSWORD → 明文密码
  • 这就是"如果拿到 hash 就能解出流量密码",不需要暴力

工具即 woraauthbf(Laslo Toth),但该工具依赖 oran10.dll 的导出函数 ztvo5kd(解密 AUTH_SESSKEY)、ztvo5csk(XOR+MD5 组合密钥)、ztvo5pd(解密 AUTH_PASSWORD)—— 这正是题面给 oradlls.zip 的原因。

在 Linux 上复现:wine + 32 位 Python (embeddable) + ctypes 加载 oran10.dll:

1
2
3
4
5
6
7
8
9
10
11
# 结构体对齐 woraauthbf.h:
# struct pwd_hash { u8 ver[4]; char hash[40]; } # hash 是 16 字符 hex 字符串
# struct sess_key { s16 l; u8 key[70]; } # key 是 64 字符 hex 字符串, l=0x40
# struct e_key { u8 ver[4]; u8 key[100]; } # ver={0x66,0x10,0,0}
# struct e_key_comb{ u8 ver1[4]; u8 ver2[4]; u8 key[100]; }

ztvo5kd(byref(ekey_srv), byref(skey_srv), byref(phash), 0) # hash 解密 server sesskey
ztvo5kd(byref(ekey_cli), byref(skey_cli), byref(phash), 0) # hash 解密 client sesskey
ztvo5csk(byref(ekey_srv), byref(ekey_cli)) # XOR + MD5 → 组合密钥
memmove(ekey_comb.key, ekey_cli.key, 0x20)
ztvo5pd(byref(ekey_comb), authp, 64, pwd, byref(pwd_len)) # 解密 AUTH_PASSWORD

对 3 个用户 hash 逐一尝试:

1
2
3
YURI    A1D41F67E0B29E26 → rc=-1013 失败
ONEGIN 4FDB184F1CE30572 → rc=0 len=11 tatiana1831 ✅
ANYEGIN E4BA299AAE1AA136 → rc=-1013 失败

ONEGIN 的密码 = tatiana1831

彩蛋:Tatiana 是普希金《叶甫盖尼·奥涅金》的女主角,1831 年是小说完成年份

onegin/tatiana1831@192.168.1.4:1521/cekpet