DiDa DiDa DiDa

日常开发中,时间的格式化、存储、本地化经常让人疑惑,尤其是不同的编程语言中对于时间的处理方式又大相径庭,甚至同一个数据库中都有不同都存储方式,每次都要查文档。

JavaScript中时间的格式化

1
2
3
4
5
6
7
8
9
# Converts a date to a string following the ISO 8601 Extended Format.
> new Date(1616485415008).toISOString()
'2021-03-23T07:43:35.008Z'
# Converts a date to a string using the UTC timezone.
> new Date(1616485415008).toUTCString()
'Tue, 23 Mar 2021 07:43:35 GMT'
# The toGMTString method converts a date to a string, using Internet GMT conventions.[Deprecated(被遗弃)]
> new Date(1616485415008).toGMTString()
'Tue, 23 Mar 2021 07:43:35 GMT'

UTC VS GMT

GMTUTC是用来追踪时间的标准,而不是时间格式的标准。

GMT时间是通过地球自转来测量时间,但是地球自转并不规律,而且正在缓慢减速,因此格林尼治平时基于天文观测本身的缺陷,已经被原子钟报时的协调世界时(UTC)所取代。UTC是目前最主要的世界时间标准。

IOS-8061 时间格式的标准

IOS-8061是表示日期和时间的国际标准。
在日期和时间中,不同的标准可能需要不同的粒度级别,因此定义了六个级别。

T作为分隔符用来区分日期和时间,Z代表UTC。

六种格式如下:

Read More

本文翻译自:What is Huffman Coding?

什么是哈夫曼编码

霍夫曼编码算法是许多压缩算法的基石,如DEFLATE,它被用于PNG格式的图像和GZIP。

为什么需要关注它

你是否也曾想了解:

  • 如何在不丢失数据的情况下,对数据进行压缩?
  • 为什么某些数据的压缩效果要比其他数据的效果好?
  • GZIP如何工作?

5分钟内了解它

假设我们需要压缩一个字符串(哈夫曼编码可以用于任何数据,但是字符串更好理解)。

在被压缩的文本中,一些字符出现的频率总是比其他字符的高。霍夫曼编码利用这一事实,使得最常用的字符比不常用的字符占用更少的空间。

编码字符串

Read More

今天遇到一个问题,有一个第三方HTTP接口,在本地通过Node.JS可以正常访问,但是CentOS服务器无法访问,错误日志提示:Error: socket hang up

这个错误很明显是socket网络层的错误,还没有到第三方到应用层。为了严重猜想,随便换一个HTTP接口,然后用curl测试,curl返回:curl: (35) error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small

通过错误可以看出来是HTTPS中的SSL/TLS层的问题,通过GOOGLE,发现是目标服务器在握手中返回的加密算法的key长度不够。

通过以下命令在我的机器上执行,可以查看目标服务器返回的key长度

1
2
openssl s_client -connect xxx:443 -cipher "EDH" | grep "Server Temp Key"
openssl s_client -connect www.example.com:443 -cipher "DHE" | grep "Server Temp Key"

以上命令返回中包含Server Temp Key: DH, 1024 bits,key的长度是1024。

接着查看系统的加密策略,执行以下命令返回DEFAULT,继续搜索文档The default system-wide cryptographic policy level offers secure settings for current threat models. It allows the TLS 1.2 and 1.3 protocols, as well as the IKEv2 and SSH2 protocols. The RSA keys and Diffie-Hellman parameters are accepted if they are at least 2048 bits long.发现DEFAULT策略要求key的长度最少为2048

1
2
update-crypto-policies --show
>DEFAULT

修改系统的加密策略:

1
update-crypto-policies --set LEGACY
Read More

最近开始使用GNU的screen来管理terminal的窗口,但是当开窗口多的时候,会面临不知道每个窗口是做什么的,默认的窗口标题也非常不友好,官网文档也没太多描述,最后好不容易找到了设置方法,记录一下配置。

.zshrc文件里添加如下配置

1
2
3
# dynamic titles for screen
preexec () {
echo -ne "\ek${(s: :)1}\e\\"

.screenrc文件里添加如下配置

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
startup_message off

# GNU Screen - main configuration file
# All other .screenrc files will source this file to inherit settings.
# Author: Christian Wills - cwills.sys@gmail.com

# Allow bold colors - necessary for some reason
attrcolor b ".I"

# Tell screen how to set colors. AB = background, AF=foreground
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
# Enables use of shift-PgUp and shift-PgDn
# termcapinfo xterm|xterms|xs|rxvt ti@:te@
termcapinfo xterm* ti@:te@
# Erase background with current bg color
defbce "on"

# Enable 256 color term
term xterm-256color

# Cache 30000 lines for scroll back
defscrollback 30000

# change command character from ctrl-a to ctrl-b (emacs users may want this)
#escape ^Bb


### pass commands to screen for describing windows
shelltitle '$ |zsh'

### set caption
caption always '%{= kw}[ %{y}%H%{-} ][ %= %-Lw%{+b M}%n%f* %t%{-}%+LW %= ][ %{r}%l%{-} ][ %{c}%c%{-} ]'
Read More
post @ 2021-02-03

最近有一个项目,使用的Node的Request类库来进行HTTP请求获取数据,每个HTTP请求都要用到短效代理。为了提高可用性,加入了重试机制,如果代理失效,则更换代理重试。为了防止代理速度过慢,设置了timeout参数,该参数在文档中的说明是:

1
2
3
timeout - integer containing number of milliseconds, controls two timeouts.
Read timeout: Time to wait for a server to send response headers (and start the response body) before aborting the request.
Connection timeout: Sets the socket to timeout after timeout milliseconds of inactivity. Note that increasing the timeout beyond the OS-wide TCP connection timeout will not have any effect (the default in Linux can be anywhere from 20-120 seconds)

该参数为设置了4秒。但是有些请求竟然1分15秒才返回。

curl对代理进行测试结果如下,由此可见timeout参数并没有生效。

1
2
3
4
5
6
7
8
9
time curl  -vvv -x http://106.5.193.161:4245 baidu.com
* Trying 106.5.193.161...
* TCP_NODELAY set
* Connection failed
* connect to 106.5.193.161 port 4245 failed: Operation timed out
* Failed to connect to 106.5.193.161 port 4245: Operation timed out
* Closing connection 0
curl: (7) Failed to connect to 106.5.193.161 port 4245: Operation timed out
curl -vvv -x http://106.5.193.161:4245 baidu.com 0.00s user 0.01s system 0% cpu 1:15.76 total

于是猜测应该是tcp重试机制导致的,于是打开Wireshark观察网络请求,发现系统尝试发送了10次SYN数据包。

定位到原因之后,有两个解决办法,第一个是在应用层强制超时,第一个是修改系统tcp的重试参数。

为了尽快解决问题,选择第二种方案,由于线上是CentOS,只需要执行即可临时修改syn数据包的重试次数为1。修改后再次通过curl测试,发现可以很快返回超时。

1
sysctl -w net.ipv4.tcp_syn_retries=1
Read More

最近招商银行有一个10元风暴的活动,集喵喵,最高可以兑换5000元礼品卡。但是听同事说,这个兑换需要拼手速。作为工程师,能用程序解决的,坚决不用手解决。(其实是想练习一下遗忘已久的逆向技能

分析思路

第一次尝试,先用Charles抓包,但是发现设置代理之后打开银行app直接闪退,果然大银行,对HTTPS证书进行了校验。失败。
第二次尝试,用rvictl创建iphone的虚拟网络端口,然后用Wireshark监听所有流量,发现确实走的是HTTPS协议,不是tcp。但是由于内容都是加密的,没什么其他收获。
第三次,那就只有祭出必杀器。越狱。

可行的方案

  • 首先对手机进行越狱,由于备用机是iOS13.7,目前没有完美越狱,但是checkra1n可以进行非完美越狱。checkra1n的官网是checkra.in,有一个冒充的钓鱼网站要小心。根据官网的越狱步骤,遇到了一点小问题,我的手机就是无法进入DFU模式,最后把Tyep C的线换成了USB的线才搞定。:(

  • 由于银行对证书有检测,所以必须要干掉证书的检测。github上有一个项目SSL Kill Switch 2可以做这件事儿。而且很顺利,屏蔽掉证书检测之后,可以成功的捕获到所有的HTTPS数据包,但是分析数据包之后,发现并没有什么作用,因为内容都是加密的。

  • 既然数据包没用,那我们就从UI着手,大不了最后模拟点击或者hook事件重放就可以了。既然是内嵌的Webview,第一个想到的就是通过Safair的开发工具进行调试。但是release的App是无法进行调试,因为大部分都不会开启这个功能。但是既然都越狱了,自然有办法。github上的GlobalWebinspect项目可以帮助我们,安装之后,发现可以进行调试了。

  • 既然可以调试web了,那就欢迎进入web的世界~ 剩下的,就是抽丝剥茧找到相应的事件去触发了。

其实,获取礼品不是目的。如何做到,才能技术该追求的。

Read More

之前写爬虫的时候,经常需要从界面入手,找到自己想要的数据,然后看网络请求,来搜索是哪个api返回的数据,一般情况下,都能从网络请求中发现想要的数据。但是当数据做了混淆之后,很多数据是没有办法直接从api中搜索到的。这时候就可以用到MutationObserver API。

MDN上的描述The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. 。简单翻译一下就是,这个接口提供了监控DOM树变化的能力。

MDN的例子

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
// Select the node that will be observed for mutations
const targetNode = document.getElementById('some-id');

// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: true, subtree: true };

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
// Use traditional 'for loops' for IE 11
//如果需要调试的话,只需要在callback里面执行debugger就可以了
for(const mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// Later, you can stop observing
observer.disconnect();
Read More

之前在iPhone上抓包都是用的Charlse,但是只能捕获HTTP和HTTPS对流量。

今天发现了苹果的一个工具叫rvictl,rvi是Remote Virtual Interface的缩写,表示远程虚拟接口。把iPhone通过USB连接电脑之后,通过rvictl就可以创建一个虚拟接口。接下来就可以用tcpdump或者wireshark来监听这个网络接口上的流量。

但是,由于系统升级了Big Sur,目前这个工具在我的电脑上暂时无法使用。只能等下来的版本再测试一下。

Read More
post @ 2020-12-03

今天进行iOS逆向开发,肯定会遇到很多坑,之前的坑都踩过,但是没有记录,这次记录一下。

坑1 签名失败

安装完后mokeyDev之后,在XCode创建一个新项目,但是对于一直报错无法签名,最后查资料可以在target的Build Settings里面增加一个自定义配置,CODE_SIGNING_ALLOWED=NO,最后编译成功。

坑2 无法找到libstdc++类库

这个比较常见,是因为xcode移除了libstdcc,如果类库依赖的话,只需要找到放在对应目录下就可以。

如何查看ipa是否加密

otool -l Target | grep -A 4 LC_ENCRYPTION_INFO

cycrpt 打印当前界面的UI结构

1
2
cy# UIApp.keyWindow.recursiveDescription().toString()
c# [[UIApp keyWindow] _autolayoutTrace].toString()

find controller

Read More

今天需要写一个脚本同时ssh连接到不同到服务器执行任务,并实时观察log,所以需要写一个脚本打开新的terminal,查找后发现可以用macOS的osascript命令,记录一下:

1
osascript -e 'tell application "Terminal" to do script "ls"'

由于连接每次连接ssh都需要输入yes来信任host,可以在~/.ssh/config文件中添加StrictHostKeyChecking no来取消检查,这也可以方便脚本的执行,但是用完记得取消,否则这样做是不安全的。

Read More
⬆︎TOP