modemkicker: init
This commit is contained in:
commit
ee874b28ad
4 changed files with 824 additions and 0 deletions
143
main.go
Normal file
143
main.go
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
flagAddress string
|
||||
flagUsername string
|
||||
flagPassword string
|
||||
)
|
||||
|
||||
const (
|
||||
sessionKey = "SESSION_ID_VIGOR"
|
||||
)
|
||||
|
||||
func makeAddress(page string) string {
|
||||
u, err := url.Parse(flagAddress)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Invalid address (%q): %v", flagAddress, err))
|
||||
}
|
||||
u = u.JoinPath(page)
|
||||
return u.String()
|
||||
}
|
||||
|
||||
type client struct {
|
||||
random string
|
||||
jar *cookiejar.Jar
|
||||
}
|
||||
|
||||
func (c *client) doRequest(ctx context.Context, body io.Reader, method, url, referer string) (*http.Response, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, method, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Add("Referer", referer)
|
||||
req.Header.Add("Origin", makeAddress(""))
|
||||
|
||||
client := &http.Client{
|
||||
Jar: c.jar,
|
||||
}
|
||||
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
func (c *client) getSession(ctx context.Context) error {
|
||||
// Get session.
|
||||
c.random = rand.Text()[:15]
|
||||
form := url.Values{}
|
||||
form.Add("aa", base64.StdEncoding.EncodeToString([]byte(flagUsername)))
|
||||
form.Add("ab", base64.StdEncoding.EncodeToString([]byte(flagPassword)))
|
||||
form.Add("sFormAuthStr", c.random)
|
||||
|
||||
res, err := c.doRequest(ctx, strings.NewReader(form.Encode()), "POST", makeAddress("cgi-bin/wlogin.cgi"), makeAddress("weblogin.htm"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, _ := io.ReadAll(res.Body)
|
||||
|
||||
if strings.Contains(string(body), "Authorization Error") {
|
||||
return fmt.Errorf("authorization error on wlogin.cgi")
|
||||
}
|
||||
|
||||
// Check that auth works.
|
||||
res, err = c.doRequest(ctx, nil, "GET", makeAddress("cgi-bin/cgidashboard.cgi")+fmt.Sprintf("?sFormAuthStr=%s&fid=1", c.random), makeAddress(""))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, _ = io.ReadAll(res.Body)
|
||||
|
||||
if strings.Contains(string(body), "Authorization Error") {
|
||||
return fmt.Errorf("authorization error on cgidashboard.cgi")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) reboot(ctx context.Context) error {
|
||||
form := url.Values{}
|
||||
form.Add("sReboot", "Current")
|
||||
form.Add("submitbnt", "Reboot Now")
|
||||
form.Add("nSch1", "0")
|
||||
form.Add("nSch2", "0")
|
||||
form.Add("nSch3", "0")
|
||||
form.Add("nSch4", "0")
|
||||
form.Add("fid", "0")
|
||||
form.Add("webchange", "0")
|
||||
form.Add("sFormAuthStr", c.random)
|
||||
|
||||
res, err := c.doRequest(ctx, strings.NewReader(form.Encode()), "POST", makeAddress("cgi-bin/reboot.cgi"), makeAddress("doc/rebootsys.sht"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, _ := io.ReadAll(res.Body)
|
||||
|
||||
if strings.Contains(string(body), "Authorization Error") {
|
||||
return fmt.Errorf("authorization error on reboot.cgi")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.StringVar(&flagAddress, "address", "http://192.168.1.1/", "Address of Draytek admin interface")
|
||||
flag.StringVar(&flagUsername, "username", "admin", "Username for authenticating to the Draytek admin interface")
|
||||
flag.StringVar(&flagPassword, "password", "", "Password for authenticating to the Draytek admin interface")
|
||||
flag.Parse()
|
||||
|
||||
if flagPassword == "" {
|
||||
log.Fatalf("-password must be specified")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
jar, _ := cookiejar.New(nil)
|
||||
c := client{
|
||||
jar: jar,
|
||||
}
|
||||
err := c.getSession(ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not get session: %v", err)
|
||||
}
|
||||
|
||||
if err := c.reboot(ctx); err != nil {
|
||||
log.Fatalf("Reboot failed: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Rebooted!")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue