---
# System prepended metadata

title: PRS 改版精要

---

# PRS 改版精要
  - [Introduction](#introduction)
  - [Problem](#problem)
  - [Solution](#solution)


# introduction
![](https://i.imgur.com/Z5j0xNL.png)
此張圖為現行的 **Phone Reputation Service (PRS)** 的架構，

現在主要有兩種方式 query PRS，第一種就是當信件進入 Tmase engine 後，
會透過 [Parser 1](https://github.trendmicro.com/CoreTech-ERS/Library-TMASE/blob/d3c6a5a7eae17b3f494e063f54e10a5b83e55ed3/TMASE/src/tmase/CScamFilter.cpp#L439-L447) 去從 Email Body 中抓出並經過前處理後，將 extracted phone 丟到 Eureka 的 prs 參數中，去跟 pattern match 出 RID

第二種則是其他 Team（如 Trend Micro Check) 會直接透過 Eureka API post prs 這個參數來問。

而為了讓兩者去 match pattern 時候的格式是一致的，我們在 Eureka 裡面也做了一個 [Parser 2](https://adc.github.trendmicro.com/CoreTech-ERS/App-eureka/blob/master/internal/msgdecode/decoder.go#L277-L310) 去處理吃進來的 prs value


Tmase 跟 Eureka Parser 的範例如下
check prs 參數（處裡 prs 跟 senderinfo 兩個參數）

```go
// 示例1：原始字符串包含常用分隔符号，包含无效字符
rawString1 := "+1 (555) 123-4567"
processed1, err1 := preprocessPhoneNumber(rawString1)
// 输出：
// processed1 = "15551234567"
// err1 = nil

// 示例2：原始字符串不包含分隔符号，但以 0 开头
rawString2 := "0123456789"
processed2, err2 := preprocessPhoneNumber(rawString2)
// 输出：
// processed2 = "123456789"
// err2 = nil

// 示例3：原始字符串包含非数字字符
rawString3 := "1-800-Flowers"
processed3, err3 := preprocessPhoneNumber(rawString3)
// 输出：
// processed3 = ""
// err3 = Invalid char for phone number: -

// 示例4：原始字符串中的号码长度小于8
rawString4 := "1234567"
processed4, err4 := preprocessPhoneNumber(rawString4)
// 输出：
// processed4 = "1234567"
// err4 = Invalid length for phone number, too short: 1234567

// 示例5：原始字符串中的号码长度大于20
rawString5 := "123456789012345678901"
processed5, err5 := preprocessPhoneNumber(rawString5)
// 输出：
// processed5 = "123456789012345678901"
// err5 = Invalid length for phone number, too long: 123456789012345678901
```

如果出 error 則會[跳過](https://adc.github.trendmicro.com/CoreTech-ERS/App-eureka/blob/master/internal/msgdecode/decoder.go#L378-L381)


與此同時，透過 amps API 搜集 phone number 的 Parser 3，卻有著一些不太一樣的做法， 我們過去從眾多 [來源](https://adc.github.trendmicro.com/CoreTech-ERS/App-pyspark/tree/master/app/PRS2BuildSolution#prs-main-flow) 搜集 phone number，在 post 蒐集到的 phone number 以前，會先在 app-pyspark 做一些 [前處理](https://adc.github.trendmicro.com/CoreTech-ERS/App-pyspark/blob/master/app/PRSFmaSourcing/common.py#L63-L85) ，基本上處理邏輯跟 Parser 1、Parser 2 類似，就是把標點符號拿掉，並把開頭的 0 去掉。接著會把處理後的 phone number post 到 amps prs api，而在進 db 以前，還會經過一段分離 country code 跟 phone number 的 [function](https://adc.github.trendmicro.com/CoreTech-ERS/App-amps-webservice/blob/master/src/SenderPhoneReputationHandler.py#L200-L208)

amps api 分離 country code 跟 phone 的簡單圖示如下
![](https://i.imgur.com/DYvQauZ.png)


# problem
1. Parser 不同步
由前例圖中可以得知，現階段我們各區域的 Parser 並沒有完全統一，例如一組電話號碼 `0912123123`，若是從 App-pyspark 輸入，就會被處理成 `912123123` 才打 amps api，最終存在 DB 的資料即為 `912123123`。但如果是直接打 amps api，則會在 DB 存成 `0912123123` 造成結果是，明明是同一筆電話號碼，卻會有兩種被存在 DB 的形式


2. Query data 跟 pattern data 不一樣（trimmed 0
如前述，經過 Eureka 處理後的電話號碼，會把最開頭的 0 給去掉，例如 `0912123123`，會變成 `912123123` 去跟 pattern mapping。但我們在出 Pattern 的時候，卻沒有把開頭的 0 拿掉，像是下方的 pattern data。這就會變成，明明有電話被紀錄在 DB，但最終經過 Eureka 後，卻會回一個沒 detect 的 RID
``` 
PRS pattern

08030172028,8.0
08064919823,8.0
08011337625,8.0
08067620627,8.0
```
![](https://i.imgur.com/bCHqIlq.png)


3. Phone number hard to define if not E.164(+8869121231123)
    - 現階段我們的 prs 分割 country code 跟 phone number 還是用自己的方式在處理的，而這種做法其實很容易有誤判，像是 `+1 242-555-0123` 的美國手機號碼，就會被我們判成 **Country Code:1242 phone :5550123**

    - 如果非 E.164 格式，則難以界定該電話是哪一國的電話，像是我們在 prs-fma-sourcing 處理 phone number 去打 amps api 時候，有機會把這類的電話號碼的第一個 0 給去掉，造成問題二的現象。簡單來說，去掉 0 並沒有減少 FP 的發生，卻將 phone number 的一些資訊給去掉了，像是 `0912123123` 跟 `00912123123` 這兩個可能是不同國家的電話，卻可能在 DB 內都存成 `912123123`




# Solution
### TMASE
更改 extract 規則
### EUREKA
### APP-PYSPARK PHONE NUMBER COLLECT ETL
### 
DNS prs ask



## 改動

## 改動前數據

## Good to have

## 



#### 問題1
```
08090080406,8.0
08052500440,8.0
08064856158,8.0
09045743349,8.0
08075371143,8.0
09093243477,8.0
08061335270,8.0
08039213999,8.0
08067547313,8.0
09093807976,8.0
09053256421,8.0
```
這些東東 detect 不到

#### 原因
Eureka parser 會把 0 拿掉去 match 

https://github.trendmicro.com/CoreTech-ERS/Library-TMASE/blob/d3c6a5a7eae17b3f494e063f54e10a5b83e55ed3/TMASE/src/tmase/CScamFilter.cpp#L439-L447



## Backward Compatibility
- Tmase 
- Eureka
- RPS API

## Multiple Request Income
Other Request (FBN....)

- FBN

用這樣的方式去把這個處理


## 待處理問題
1. 沒有處理 ATTRIBUTE_MATCHING 這邊如果 prs 是空的該如何處理
2. Tmase Engine parser 改動
3. PRS 有一 ETL 是去找壞壞信，爬出裡面 body 有 phone 然後塞回 DB 的

https://adc.github.trendmicro.com/CoreTech-ERS/App-pyspark/blob/master/app/PRSHoneypotSourcing/prs_honeypot_sourcing.py#L134

但這 ETL 的作法，抓出來看 regex 的 email content 有很大機會碰到 base64 encoded 的 mail body，他好像沒有解開就去 regex match phone number 了(這樣當然啥都 match 不到？），看來我們 insert prs 的東東也沒認真 insert XDDD