All posts by BlueCocoa

Play the game that sets you free!

As many of macOS users have already enabled TouchID for sudo by adding the line below to /etc/pam.d/sudo.

auth       sufficient

That's convenient, however, not interesting at all. Let's do something amusing! What about granting root privilege by winning the floppy bird game! Play the game that sets you free \(≧▽≦)/ Σ(・□・;)

This post will roughly be divided into 3 parts,

  1. Get the original sudo project compiled successfully
  2. Add the floppy bird game to sudo
  3. Test and replace the sudo which ships with macOS to sudo-floppy

1. Get the original sudo project compiled successfully

The very first thing is to fetch the latest source code of sudo on At the time of writing, the latest release is Open the sudo.xcodeproj in Xcode after downloading and unzipping the tarball and we can start!

Continue reading Play the game that sets you free!

CVE-2019-14287: Local Privilege Escalation

Yesterday, a local privilege escalation vulnerability of sudo was reported by a security researcher, Joe Vennix. The proof of concept is simple but the exploitation of that can be powerful.

$ sudo -u#-1 whoami

-u#-1 means that, sudo is required to run the command as the user with id equals to -1.

With merely 5 more characters (the highlighted ones) you can do a local privilege escalation for all sudo version prior to 1.8.28. Isn't that amazing (and maybe dangerous as well)? Let's dive into it and see what happens inside. sudo version 1.8.27 will be used for demonstration in this post. (It can be downloaded at

Given that the vulnerability is related to the command line argument, it would be a great idea to the src/parse_args.c file firstly.

Continue reading CVE-2019-14287: Local Privilege Escalation

A Trip to the Blenheim Palace in Oxford

Last weekend, I went to the Blenheim Palace and the city centre of Oxford from Cambridge. 2-hour bus ride was quite a long time, thus I fall asleep serval times. The bus arrived Blenheim Palace at half passed 10, which was right on the open time.

The Blenheim Palace was pretty gorgeous when I stepped inside. But it was not only the Palace that attracted me, but also the garden inside it! Though the weather was cloudy for the most time, the garden of Blenheim Palace was fabulous still! Perhaps this is one of the reasons that it is said to be the finest view in England.

The swan swam on the lake, the small house sat besides the river and the path lay in the forest. Just standing there and looking at the cozy landscape they made up was absolutely breath-taking. If the weather had been better, these landscapes would have been tremendous. ☆〜(ゝ。∂)

(Notice - if you're using cellar network, please be aware that this post contains many photos)

Continue reading A Trip to the Blenheim Palace in Oxford

Using C/C++ for Python Extension

In general, C/C++ can be used to extend the functionality of Python with almost the highest performance you demand. To write a Python extension in C/C++ is relatively easy.

I'll show a simplified extension which is used in real life. This extension is made to extract records in a special file format, .pcap, and .pcap file is used to store the captured network packets so that the network activities can be analysed later.

Although there are many alternatives, they cannot achieve the goal in reasonable time. One of these alternatives is scapy, please don't get me wrong, scapy is a fabulous networking package. It can automatically parse all the records in .pcap file, which is an amazing feature. However, the parsing work will also take significant amount of time, especially for a large .pcap file with hundreds of thousands records inside.

At that time, my goal was quite straightforward. The time when captured the packet, from which source IP the packet was sent, and the destination IP of the packet. Given these demanding, there is no need to parse any record as deep as scapy would do. I can just check whether it contains IP layer or not, and if yes, extract the source IP and destination IP. Otherwise I'll skip to next record. And that's all.

I decided to name the extension as streampcap. And the class name would be StreamPcap so that I can write my Python code as below.

from streampcap import StreamPcap

pcap = StreamPcap("sample.pcap")
packet =
while packet is not None:
    print("{} {} {}".format(packet["time"], packet["ip_src"], packet["ip_dst"]))
    packet =

In order to implement this functionality, python-dev should be installed if the OS is Ubuntu/Debian/CentOS and etc Linux based operating systems. As for macOS, personally I use miniconda to manage the Python environment, and I think that miniconda will automatically get the same thing done. And miniconda is also available for Linux based OS. Life is easier!

Continue reading Using C/C++ for Python Extension

从零开始的 Rust 学习笔记(9)

Well, at this point, The Rust Programming Language demonstrates how to write a command line program, which named minigrep. Followed the textbook, I decided to rewrite the small utility that I mentioned in

The things learnt so far is enough to support me to write a, at least, workable utility. And if you're an expert in Rust, you'll find the following code is ugly and perhaps even not Rust-ish.

However, based on the previous 9 posts of this series, for these who just begins to learn Rust lang like me, the code which will be shown below won't be a giant jump. Nevertheless, there definitely has plenty of room to improve the following code. Any suggestions or questions are welcomed(⁎⁍̴̛ᴗ⁍̴̛⁎)

Furthermore, I googled a lot during writing the code. So I also attached corresponding link in comments.

Continue reading 从零开始的 Rust 学习笔记(9)

One Day in the Centre of Computing History

It was my third day in Cambridgeshire, and it was an adorable sunny day. After looking it up on Google Maps, I decided to go The Centre of Computing History, which attracted me at first glance on the map.

And it turned out to be a wonderful experience there! Basically you can actually get your hands on those old computers, from the 70s all the way to the 90s. They even have some working punch tape machines!

Cocoa on Punch Tape

And here is the encode/decode table~ The whitespace is shown as to avoid vertical mismatches. The small dot . is used for locating the horizontal line and speed. And the big dot denotes the actual punched hole on the tape.

Tape Letters Figures
␣␣.␣␣␣ Delete Delete
␣␣.␣␣• E 3
␣␣.␣•␣ Line Feed Line Feed
␣␣.␣•• A -
␣␣.•␣␣ Space Space
␣␣.•␣• S ,
␣␣.••␣ I 8
␣␣.••• U 7
␣•.␣␣␣ Return Return
␣•.␣␣• D $
␣•.␣•␣ R 4
␣•.␣•• J Bell
␣•.•␣␣ N ,
␣•.•␣• F ]
␣•.••␣ C :
␣•.••• K (
Tape Letters Figures
•␣.␣␣␣ T 5
•␣.␣␣• Z +
•␣.␣•␣ L )
•␣.␣•• W 2
•␣.•␣␣ H I
•␣.•␣• Y 6
•␣.••␣ P 0
•␣.••• Q 1
••.␣␣␣ O 9
••.␣␣• B ?
••.␣•␣ G [
••.␣•• Use Figures Use Figures
••.•␣␣ M .
••.•␣• X /
••.••␣ V =
••.••• Use Letters Use Letters
Continue reading One Day in the Centre of Computing History

Moving to WebP Image with Fallback to PNG

Currently, I'm writing my notes of Rust learning, and it usually comes with many screenshots even in a single post. Though PNG file could serve the original / or best quality, the size of which is considerably large. So it takes a few seconds to load despite using Cloudflare CDN.

WebP has been released years ago by Google, and I'd considered that before. However, in the early days, it only works in Google Chrome. Lacking support in other mainstream browsers was a main barrier for me to adopt it.

And now many browsers support WebP image, and WebP format has also been updated in these years. It could serve nearly the original quality but half or even sometimes less than one third the size of corresponding PNG file.

Yet it's surprised to me that Safari hasn't adopted WebP format, which means I have to provide a fallback. Well then, given that I'm also planning to speed up page load by deferring images, the extra thing would be checking WebP support.

Continue reading Moving to WebP Image with Fallback to PNG

从零开始的 Rust 学习笔记(7)——Lifetime


倒也不是说特别复杂,不过算是很与众不同的一个 feature~Rust的内存安全、无需 GC(垃圾回收) 则是因为有这个 feature(当然,真要在运行时搞事情的话,,编译器静态分析也未必能保证 100% 的安全)


  1. Use After Free
  2. Dangling Pointer

第一种情况的话,可能会导致 Segment Fault,也有可能会被 Hacker 利用,例如有些 iOS 版本上的越狱的一部分,则是基于 kernel 中包含了 UAF 的代码,UAF 的地址上的内容又可以被用户控制,随后通过一系列操作,在 kenrel 某些可以提权的代码里,再次 allocated 并用到这块被用户控制的内存时,就可以实现原本 需要 privileged 的操作了~

对于第二种情况的话,也就是「野指针」,比如某个函数返回了其栈上的内存的指针,而我们知道,当函数返回时,其栈上的内容是会被销毁的( ;´Д`)


#include <stdio.h>

int * stack_ref() {
    // local variable `ret` is located on stack
    int ret = 233;
    // return address of stack memory associated with local variable `ret`
    return &ret;
}   // at this point, the stack memory is no longer valid

int main(int argc, char *argv[]) {
    // get a ref, but on stack
    int * ref = stack_ref();
    // inc 4
    *ref += 4;
    // call that again
    // and please guess the value
    printf("Guess: %d\n", *ref);
Continue reading 从零开始的 Rust 学习笔记(7)——Lifetime