Jump to content

eiprol

Member
  • Posts

    13
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

eiprol's Achievements

  1. Don't worry, even though I'm not a Go expert, I think I know that one. You are trying to run a "Go source code file" as a binary, that's why It fails. To run a source file, you first have to compile it and build a binary. But in this case, with a go source file, you can also do this (I think you you don't even need sudo): go run wallet-recover.go Which I guess tells the go compiler to run this source file on real time, acting as a binary (or something like that). However, unless you are using my modded source, which takes names and passwords from text files, you still need to add flags to that command, or it won't do anything: go run wallet-recover.go -name yourname -pass yourpass ========= I removed the "strconv" at the top of the file because it was failing for me, but maybe you could leave it and still run it, using the "go run xxxx" I said above. The only thing you have to make sure when commenting the new method and uncommenting the old one, is that after passkey, you have := instead of = BAD: //passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag passkey = *nameFlag + *passFlag // old bad method GOOD: //passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag passkey := *nameFlag + *passFlag // old bad method (I'm not 100% sure, but I think it was without the := on dchapes code. But I might be wrong. Just make sure) ========= I would say without quote marks; but I could be wrong, and both might be valid. The username must be lowercase, no matter what you used. But it must contain any symbol. So: b[o]wler99 The password doesn't have to be lowercase. Could be: PaSsWoRd8213. This is normal, means that it failed to open the wallet (incorrect username or password) (That's why I modified it, to use a bunch of usernames and passwords, instead of going one by one)
  2. Yep, you are right. My mistake. Try again @bowler99 please
  3. Type this and show me the output: echo $GOROOT No matter the output, type this (we are going to try unsetting this $GOROOT variable. I didn't set it, and it's working for me, so let's do it): unset $GOROOT If you type this again, it should be empty now: echo $GOROOT So now, try again this again: go get bitbucket.org/dchapes/ripple/wallet-recover If still fails, type this and paste me the output: ls /home/me/gotest && ls /home/me/go I'm not the GO expert here, not at all, but in the mean time... I think you might be pointing the $GOPATH to your GO installation folder, instead of to the proper one (if that's the case, setting $GOPATH to /home/me/go instead of /home/met/gotest , repeating the nano & source process I said before, could fix it)
  4. It’s totally normal to be paranoid, you don’t have to trust us. Regarding this last post, I totally feel you regarding GOPATH setup; I had some problems too, and found different settings depending on the web I was looking, which is confusing. Let’s go step by step. The error you are getting, saying it’s not a directory, means exactly that; it’s a binary, an executable, and it's on the right place. That's why when you type "which go", it tells you where it is. The go binary. So that's fine. Let's try this: Type this on your terminal: echo $GOPATH What's the output? If it's empty, it's not configured, so let's set it up: 1. First, type this, and a terminal-text-editor will popup nano ~/.bash_profile (With this, you are going to edit a file, and place there the value of $GOPATH. if the line above fails, try again placing the word sudo before nano: sudo nano ...) 2. The screen that appears could be empty, or contain something. Type this on a new line (or at the beginning if it's empty) export GOPATH=$HOME/go 3. Press CTRL+X and it will ask you to save this file. Type Y and press Enter. 4. Ok, now we have saved the file with the value of $GOPATH. Let's reload it typing: source ~/.bash_profile. We are done with this. GOPATH should be configured already! NEXT STEP: Type this and tell me the output: echo $PATH Lets try downloading dchapes script source code (if go is well configured, it should work. Otherwise, paste here the output): go get bitbucket.org/dchapes/ripple/wallet-recover If you are not sure about the username and password you used, you can download my modified source code, which is based on dchapes script: go get github.com/sergioabril/ripple-wallet-recover/wallet-recover Note: If for some reason, it fails when you try "go get" (the code above), saying it can't find go, try changing go for /usr/bin/go. Example: /usr/bin/go get github.com/sergioabril/ripple-wallet-recover/wallet-recover Please let me know when you try all the above, so we can continue to the next step (running the script to decrypt the wallet), or fix any issue you encounter. (Remember to paste here all the output text you get when running these commands. If you are on other computer and can't copy-paste, take a picture with your phone)
  5. Hey guys! I just made a few fixes/changes to dchapes code. Take into account that this is my first time with Go, so the code is rough (and clumsy), but it works. Now the script takes possible usernames and passwords from separate text files (names.txt and words.txt), allowing you to run a sort of brute-force attack on your own wallet, testing a bunch of possible combinations. (It checks both key generation methods, old and new) My Repo: https://github.com/sergioabril/ripple-wallet-recover Release 0.1 (Binary is Mac only for now, sorry): https://github.com/sergioabril/ripple-wallet-recover/releases/tag/v0.1 I hope it could be helpful for somebody someday
  6. Hey, I did something else. I kept on digging on dchapes code, and I think I managed to re-encrypt the decrypted json again, after changing the seed, with a new password. This is the new bas64 wallet, which should be placed on a ripple-wallet.txt for testing: eyJpdiI6IlBhT2lmTmJid0U4cytVVmRZOEJkUXc9PSIsInYiOjEsIml0ZXIiOjEwMDAsImtzIjoyNTYsInRzIjo2NCwibW9kZSI6ImNjbSIsImFkYXRhIjoiJTVCJTVEIiwiY2lwaGVyIjoiYWVzIiwic2FsdCI6IjNpYjA1SFcwZ0FvPSIsImN0IjoibjFObjlRZ0xiRmJEWVNReDBNOE9rWU15NDN3NUdCNi9qaGROT00wK05BaEFIMTQ1Tk84cW1SdDdRNFhiMHBSQ1hOd1ZtZ3FhLzFIdVZPWFRCZnI3T3FjY1JHT3MxRXNmNzhkY1E0MExrVnhhb0ZXREdxT0IrZHFHcVdiVkxjU1RXU1hsU0Iza1NpbU5BMlRBN09BVkdzcThtS3BTcTRPQ282elFJV1E2N1R6d1RXTEpGWkVJTHZUdStDUFYxQ1daMzBXdHdENjM0ckJNYWt2Nk90MWhLaDZhSkxqbCt0dWZ3U2c9In0K These are the credentials for this testing wallet: name: eiprol pass: TestPass01 It uses old encryption system, with name+pass as key. This means: //passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag (NOT) passkey := *nameFlag + *passFlag // old bad method. (YES) This is the wallet, once decrypted (note that I place fake seed&public key on this new test wallet): blob: "{\"master_seed\":\"sp0000f14BuwFAKEw6bTtLKWfaKes\",\"account_id\":\"r9FAKEiz004drXXgGQhxp7BkkQVGuwXXXX\",\"contacts\":[],\"preferred_issuer\":{},\"preferred_second_issuer\":{}}" { "master_seed": "sp0000f14BuwFAKEw6bTtLKWfaKes", "account_id": "r9FAKEiz004drXXgGQhxp7BkkQVGuwXXXX", "contacts": [], "preferred_issuer": {}, "preferred_second_issuer": {} } I would love to help building the ultimate tool, but this is the first time I code something using go, so... it would be a mess. Actually, the modified script I used to encrypt again the wallet is here (don't judge me): // The wallet-recover command is the start of something to decode/encode // wallet blobs as stored at Payward, in the local browser, or exported // as ripple-wallet.txt. // // WARNING: this code is very rough and just thrown together to // expermint with the blob files and make sure I was on the right track. // I've had more perssing issues to deal with and I'm only making this // available in this state as reference for anyone that would find it // easier than look at or using the JavaScript ripple client. // // See https://ripple.com/forum/viewtopic.php?f=2&t=5227#p33011 package main import ( "bytes" "crypto/aes" "crypto/cipher" //"crypto/rand" "crypto/sha256" "encoding/base64" "encoding/json" "flag" "fmt" "io" "io/ioutil" "log" "net/url" "os" //"strconv" "bitbucket.org/dchapes/ripple/crypto/ccm" "golang.org/x/crypto/pbkdf2" ) // encryptedBlob is the JSON struct that is the encrypted blob type encryptedBlob struct { IV base64data `json:"iv"` // initilization vector or nonce for CCM mode V int `json:"v"` // version? Iter int `json:"iter"` // PBKDF2 iteration count KS int `json:"ks"` // keysize in bits TS int `json:"ts"` // CCM tag size in bits Mode string `json:"mode"` // ccm, cbc, … AData string `json:"adata"` // additional authenticated data Cipher string `json:"cipher"` // aes, … Salt base64data `json:"salt"` //PBKDF2 salt CT base64data `json:"ct"` // ciphertext } // walletdata is the JSON struct of the decrypted wallet blob file type walletdata struct { MasterSeed string `json:"master_seed"` AccountID string `json:"account_id"` // redundant, can be calculated from MasterSeed Contacts []struct { Name string Address string } `json:"contacts"` PreferredIssuer map[string]string `json:"preferred_issuer"` PreferredSecondIssuer map[string]string `json:"preferred_second_issuer"` } // base64data is a simple type to handle conversion between // base64encoded strings and raw data bytes. type base64data []byte // MarshalText implements encoding.TextMarshaller and is used by the // json when marshalling JSON. func (b base64data) MarshalText() ([]byte, error) { text := make([]byte, base64.StdEncoding.EncodedLen(len(b))) base64.StdEncoding.Encode(text, b) return text, nil } // UnmarshalText implements encoding.TextUnmarshaller and is used by the // json when unmarshalling JSON. func (b *base64data) UnmarshalText(text []byte) error { if n := base64.StdEncoding.DecodedLen(len(text)); cap(*b) < n { *b = make([]byte, n) } n, err := base64.StdEncoding.Decode(*b, text) *b = (*b)[:n] return err } // int32Array is an hack used for some debug output to approximate // what the JavaScript implementation will print/show when running // it in a console. func (b base64data) int32Array() []int32 { n := len(b) / 4 extra := len(b) % 4 if extra > 0 { n++ } a := make([]int32, n) i, j := 0, 0 for ; j < extra; j++ { a[i] <<= 8 a[i] |= int32(b[j]) } if j != 0 { i++ } for ; i < len(a); i++ { a[i] = int32(b[j]) << 24 a[i] |= int32(b[j+1]) << 16 a[i] |= int32(b[j+2]) << 8 a[i] |= int32(b[j+3]) j += 4 } return a } func (b base64data) int64Array() []int64 { a := make([]int64, 0, (len(b)/4)+1) var tmp int64 for i, bi := range b { tmp <<= 8 tmp |= int64(bi) if i%4 == 3 { a = append(a, tmp) tmp = 0 } } if i := uint(len(b) % 4); i != 0 { tmp <<= 8 * (4 - i) tmp |= int64(0x10000000000) * int64(i<<3) a = append(a, tmp) } return a } func (b base64data) debug(name string) { log.Printf("%s: len=%d, 0x%x = %q = %v", name, len(b), b, b.xString(), b.int32Array()) } func debug(name string, d []byte) { b := base64data(d) log.Printf("%s: len=%d, 0x%x = %q = %v", name, len(d), d, string(d), b.int32Array()) } // ... not used, was the String() function to implement fmt.Stringer func (b base64data) xString() string { text := make([]byte, base64.StdEncoding.EncodedLen(len(b))) base64.StdEncoding.Encode(text, b) return string(text) //return fmt.Sprintf("%s = %v", text, b.int32Array()) } func main() { walletFlag := flag.String("wallet", "ripple-wallet.txt", "input wallet filename, empty for stdin") jsonFlag := flag.Bool("json", false, "dump the encrypted wallet JSON data") nameFlag := flag.String("name", "", "wallet name (required)") passFlag := flag.String("pass", "", "pass-phrase (required)") stubFlag := flag.String("stub", "", "filename to write out a stubbed wallet") flag.Parse() if flag.NArg() != 0 || *nameFlag == "" || *passFlag == "" { flag.Usage() os.Exit(2) // match the exit code used by flag code should be EX_USAGE } // f is a io.Reader of the raw blob data var f *os.File var err error if *walletFlag == "" { f = os.Stdin log.Println("Reading from stdin") } else { f, err = os.Open(*walletFlag) if err != nil { log.Fatalf("Opening %q: %v", *walletFlag, err) } defer f.Close() log.Printf("Opened file %q", *walletFlag) } // base64Decoder is an io.Reader of the base64 decoded blob base64Decoder := base64.NewDecoder(base64.StdEncoding, f) if *jsonFlag { buf, err := ioutil.ReadAll(base64Decoder) if err != nil { log.Fatal("Reading:", err) } log.Println("Decoded", len(buf), "bytes") log.Printf("Raw data:\n%s", buf) pp := new(bytes.Buffer) err = json.Indent(pp, buf, "", " ") if err != nil { log.Fatal("indent JSON failed:", err) } fmt.Println(pp) // XXX already decoded but keeps the later code happy base64Decoder = bytes.NewBuffer(buf) } jsonDecoder := json.NewDecoder(base64Decoder) eBlob := new(encryptedBlob) err = jsonDecoder.Decode(&eBlob) if err != nil { log.Fatal("JSON decoder:", err) } // now eBlob is a encryptedBlob struct with it's fields decoded // and filled in. // The eBlob.CT field is encrypted as specified by the Cipher, // Mode, and other fields. eBlob.IV.debug("IV") eBlob.Salt.debug("salt") log.Print("len(ciphertext):", len(eBlob.CT)) //eBlob.CT.debug("CT") if n := len(eBlob.CT); n > 20 { log.Printf("ciphertext %x…%x", eBlob.CT[:10], eBlob.CT[n-10:]) } if true { // This is the hash used for storage/lookup both in the // local browser and at Payward. blobHash := sha256.Sum256([]byte(*nameFlag + *passFlag)) log.Printf("blobHash: %x", blobHash) } //passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag passkey := *nameFlag + *passFlag // old bad method log.Println("passkey:", passkey) debug("passkey:", []byte(passkey)) key := pbkdf2.Key([]byte(passkey), eBlob.Salt, eBlob.Iter, eBlob.KS/8, sha256.New) debug("key", key) var cb cipher.Block switch eBlob.Cipher { case "aes": cb, err = aes.NewCipher(key) if err != nil { log.Fatal("Error initializing AES:", err) } default: log.Fatalf("Blob encrypted with unsupported cipher %q", eBlob.Cipher) } //log.Println("cipher:", cb) var authmode cipher.AEAD nonce := []byte(eBlob.IV) switch eBlob.Mode { case "ccm": log.Println("tagsize:", eBlob.TS) if eBlob.TS%8 != 0 { log.Fatalf("bad tag size TS=%d, not a multiple of 8", eBlob.TS) } nlen := ccm.MaxNonceLength(len(eBlob.CT) - eBlob.TS/8) log.Println("max nlen:", nlen) if nlen > len(nonce) { nlen = len(nonce) } else { nonce = nonce[:nlen] } log.Println("nlen:", nlen) debug("nonce", nonce) c, err := ccm.NewCCM(cb, eBlob.TS/8, nlen) if err != nil { log.Fatal("Error initializing CCM mode:", err) } log.Println("ccm MaxLength:", c.MaxLength()) authmode = c case "cbc": log.Println("WARNING: using CBC mode, data cannot be authenticated") fallthrough // not supported default: log.Fatalf("Blob encrypted with unsupported cipher mode %q", eBlob.Mode) //case "ocb2": } log.Println("authmode:", authmode) debug("adata", []byte(eBlob.AData)) adata, _ := url.QueryUnescape(eBlob.AData) // XXX debug("adata", []byte(adata)) blob, err := authmode.Open(nil, nonce, eBlob.CT, []byte(adata)) if err != nil { log.Fatal("error decrypting and authenticating blob:", err) } log.Printf("blob: %q", blob) if *jsonFlag { pp := new(bytes.Buffer) err = json.Indent(pp, blob, "", " ") if err != nil { log.Fatal("indent JSON failed:", err) } fmt.Println(pp) } wallet := new(walletdata) err = json.Unmarshal(blob, wallet) if err != nil { log.Fatal("JSON unmarshal failed:", err) } fmt.Printf("Wallet data: %v\n", *wallet) // **************** // eiprol addition // experiment: encrypt with new credentials. Same IV and Salt (not really secure) //1. Modify Wallet Blob wallet.MasterSeed = "sp0000f14BuwFAKEw6bTtLKWfaKes" wallet.AccountID = "r9FAKEiz004drXXgGQhxp7BkkQVGuwXXXX" newBlob, err := json.Marshal(wallet) if err != nil { log.Fatal("NEW JSON marshal failed:", err) } //2. Change User and Password to generate a new key newNameFlag := "eiprol" passkey = newNameFlag + "TestPass01" // old bad method with testpassword log.Println("New passkey:", passkey) key = pbkdf2.Key([]byte(passkey), eBlob.Salt, eBlob.Iter, eBlob.KS/8, sha256.New) //3. New cb var cbnew cipher.Block cbnew, err = aes.NewCipher(key) if err != nil { log.Fatal("Error initializing AES for new Key:", err) } // var authmodeNew cipher.AEAD switch eBlob.Mode { case "ccm": log.Println("tagsize:", eBlob.TS) if eBlob.TS%8 != 0 { log.Fatalf("bad tag size TS=%d, not a multiple of 8", eBlob.TS) } nlen := ccm.MaxNonceLength(len(eBlob.CT) - eBlob.TS/8) log.Println("new max nlen:", nlen) if nlen > len(nonce) { nlen = len(nonce) } else { nonce = nonce[:nlen] } log.Println("new nlen:", nlen) debug("new nonce", nonce) c, err := ccm.NewCCM(cbnew, eBlob.TS/8, nlen) if err != nil { log.Fatal("Error initializing CCM mode:", err) } log.Println("ccm MaxLength:", c.MaxLength()) authmodeNew = c case "cbc": log.Println("WARNING: using CBC mode, data cannot be authenticated") fallthrough // not supported default: log.Fatalf("Blob encrypted with unsupported cipher mode %q", eBlob.Mode) //case "ocb2": } //Create new Encripted blob newEncBlob := new(encryptedBlob) *newEncBlob = *eBlob //Seal CT with new data newEncBlob.CT = authmodeNew.Seal(nil, nonce, newBlob, []byte(adata)) //var outf *os.File var outw io.Writer if *stubFlag == "" { //outw = os.Stdout outw = ioutil.Discard } else { outf, err := os.Create(*stubFlag) if err != nil { log.Fatalf("Opening/creating %q: %v", *stubFlag, err) } defer outf.Close() log.Printf("Opened and truncated file %q", *stubFlag) outw = outf } base64Encoder := base64.NewEncoder(base64.StdEncoding, outw) jsonEncoder := json.NewEncoder(base64Encoder) err = jsonEncoder.Encode(newEncBlob) if err != nil { log.Fatal("JSON encoder:", err) } //err = jsonEncoder.Close() err = base64Encoder.Close() if err != nil { log.Fatal("close:", err) } log.Println("EOF") } I hope it's good enough, but let me know
  7. Thank you so much! Honestly, I had given up until you hit me on reddit... I'm really thankful for that! @amulecregg Since you work with go often, can I ask you something? I had to manually "go run script.go" everytime, because building it with "go build script.go" was creating and old binary with the old passkey code on it, and wasn't working! How is this possible? Do I have to clean anything before rebuilding?
  8. Guys, I got it. A HUGE thank you to you all! Let me explain how, so anyone in my situation can make use of it. I used dchapes script. FIRST Since my wallet was OLD, I had to use the old passkey code on dchape's script, as @amulecregg pointed. So I had to find this line and uncomment it (commenting the one above): //passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag passkey := *nameFlag + *passFlag // old bad method (That also required removing some import at the top of the file) SECOND Then, I created a list of possible usernames and possible passwords, separated by spaces, and placed them on the same folder, on a names.txt file and a words.txt file. I did it automatically with a hand made script, but you could well do it by hand if there are only a few. THIRD I ran this bash script on terminal: for i in $(cat names.txt); do for j in $(cat words.txt); do wallet-recover -json -stub end.txt -name $i -pass $j);done;done; Note that I'm using -stub end.txt, so it creates and writes to a file when it succesfully decrypts the wallet! THE END When the script ended, I couldn't believe that there were an end.txt file on it. I had tried soooo many times without success... but there it was! However, if you open it, you will find another encrypted wallet. what? yes, but don't worry. This means that you have the right name and the right password. Go the your terminal, press ctrl+f / cmd+f, and look for this: master_seed There it is. Your seed. And a few lines above, your username and password. Thank you all! PS: My username was not my nickname, was another simple username I use sometimes. But not related to the public key!
  9. I've just tried looking for it using (what I thought) was my username, but I couldn't find myself either. However, if I paste my public address, it appears, and it says that my nickname (not username) is eiprol. It says it was created on 2013-04-27, which is the exact same date of my ripple-wallet.txt. But It doesn't show any "username:~xxxx" anywhere! Instead, this is what it says: Activated: 2013-04-27 17:15 Nickname: eiprol Activated by: Bitstamp Activated with: 337.50 XRP That's why I thought that eiprol would be my username (which might well not be). Is there any chance I didn't use a username at all back then? I'm confused. Could my email be my username?
  10. Nope, I'm writing it lowercase, just in case. But good to know, thanks! Thanks! I've changed it and I'm trying it again (no luck so far though)
  11. Ok then; do we know if there were any other variant with a different encryption approach? like another combination for the key (instead of the actual length + | + account + password) passkey := strconv.Itoa(len(*nameFlag)) + "|" + *nameFlag + *passFlag This is my json (base64 decoded): {"iv":"PaOifNbbwE8s+UVdY8BdQw==","v":1,"iter":1000,"ks":256,"ts":64,"mode":"ccm","adata":"%5B%5D","cipher":"aes","salt":"3ib05HW0gAo=","ct":"XXXXXX="} (I ended up removing the ct part; I know it's encrypted and shouldn't be much of a problem, but...)
  12. Hi guys, I'm on the same boat. I had a ripple wallet a few years ago (I'm pretty sure it was ~2013), and I kept a "Ripple-wallet.txt" file that I guess I downloaded from somewhere (?). It's base64 encoded, and when decoded, shows the typical json you've been showing around here. I've tried brute-forcing dchapes' wallet-recover.go script with a bunch of possible passwords I placed on a words.txt file, and using as account name my own username (I keep the public XRP address, and when I look it up on a block explorer, I find my username there, so it must be it, right? Or my account name could be different? Like an email, etc). for i in $(cat words.txt) do wallet-recover -name eiprol -pass $i -stub seed.txt -json done However, no luck. I'm getting this error with every single password. : error decrypting and authenticating blob:ccm: message authentication failed Which I guess it means I'm not writing the right password. And I'm pretty sure one of them is the right one. What else could be wrong? Could my wallet be from another client, and therefore need another script (i.e. not involving my account name, or with anything else different). Could I be lacking any dependency of go, making it impossible to decrypt it? Having an empty test wallet around the to check it out would be great. Thank you all!
×
×
  • Create New...