Skip to content

Commit db28027

Browse files
author
Wintrmvte
committed
Initial commit
0 parents  commit db28027

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<h1 align="center"> UnChain </h1> <br>
2+
<p align="center">
3+
<a>
4+
<img src="img.png" width="500" height="600">
5+
</a>
6+
</p>
7+
8+
<p align="center">
9+
A tool to find redirection chains in multiple URLs
10+
</p>
11+
12+
13+
14+
## Introduction
15+
16+
<p>
17+
UnChain automates process of finding and following `30X` redirects by extracting "Location" header of HTTP responses.
18+
</p>
19+
20+
## Usage
21+
22+
Specify a single address (or a file containing URLs) using `-u/--url` flag.
23+
24+

img.png

26.5 KB
Loading

unchain

9.97 MB
Binary file not shown.

unchain.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import(
4+
"fmt"
5+
"os"
6+
"net/http"
7+
"strings"
8+
"github.com/akamensky/argparse"
9+
"github.com/olekukonko/tablewriter"
10+
"github.com/fatih/color"
11+
"github.com/common-nighthawk/go-figure"
12+
. "github.com/redcode-labs/Coldfire"
13+
)
14+
15+
func find_redirects(url string){
16+
if !strings.Contains(url, "https://") && !strings.Contains(url, "http:"){
17+
url = "https://"+url
18+
}
19+
table_data := [][]string{}
20+
next_url := url
21+
for i := 0; i < 50; i++{
22+
redir := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {
23+
return http.ErrUseLastResponse }}
24+
res, err := redir.Get(next_url)
25+
if err != nil{
26+
PrintError(err.Error())
27+
}
28+
next_url = res.Header.Get("Location")
29+
sc := IntToStr(res.StatusCode)
30+
url_color := Red
31+
u := next_url
32+
if sc == "200"{
33+
url_color = Green
34+
u = url
35+
}
36+
id := IntToStr(i)
37+
table_data = append(table_data, []string{id, url_color(u), sc})
38+
if sc == "200"{
39+
break
40+
}
41+
}
42+
table := tablewriter.NewWriter(os.Stdout)
43+
table.SetHeader([]string{"ID", "URL", "STATUS CODE"})
44+
table.SetAutoWrapText(false)
45+
table.SetCenterSeparator("*")
46+
table.SetAlignment(tablewriter.ALIGN_CENTER)
47+
table.SetRowSeparator("-")
48+
for v := range table_data {
49+
table.Append(table_data[v])
50+
}
51+
if len(table_data) != 0{
52+
fmt.Println("")
53+
PrintInfo("URL => "+url)
54+
table.Render()
55+
fmt.Println("")
56+
}
57+
}
58+
59+
func print_banner(){
60+
banner := figure.NewFigure("UnChain", "", true)
61+
color.Set(color.FgMagenta)
62+
fmt.Println("")
63+
banner.Print()
64+
color.Unset()
65+
fmt.Println("")
66+
fmt.Println(F("\tCreated by: redcodelabs.io "+Red("<*>")))
67+
fmt.Println("")
68+
}
69+
70+
func main(){
71+
print_banner()
72+
parser := argparse.NewParser("unchain", "")
73+
var URLS *string = parser.String("u", "url", &argparse.Options{Required: true, Help: "File containing urls or a single url"})
74+
err := parser.Parse(os.Args)
75+
ExitOnError(err)
76+
urls := []string{}
77+
if Exists(*URLS){
78+
urls = FileToSlice(*URLS)
79+
} else{
80+
urls = []string{*URLS}
81+
}
82+
for _, u := range urls{
83+
find_redirects(u)
84+
}
85+
}

0 commit comments

Comments
 (0)